예제 #1
0
    def test_adder_inverse(self, name, a_int, b_int):
        """
        Test the adder + adder_inverse. The output should be equal to the
        original state of the circuit.
        """
        bits = binary.get_required_bits(a_int, b_int)
        self._prepare_adder_circuit(bits)

        qregs.initialize_qureg_given_int(a_int, self.a, self.qc)
        qregs.initialize_qureg_given_int(b_int, self.b, self.qc)
        adder.adder_circuit(self.qc, self.cin, self.a, self.b, self.cout)
        adder.adder_circuit_i(self.qc, self.cin, self.a, self.b, self.cout)

        # Measure results
        ans = ClassicalRegister(self.b.size + self.cout.size, "ans")
        self.qc.add_register(ans)
        for j in range(self.b.size):
            self.qc.measure(self.b[j], ans[j])
        self.qc.measure(self.cout[0], ans[self.b.size])

        ###############################################################
        # execute the program on qasm
        ###############################################################
        counts = CircuitTestCase.execute_qasm(self.qc).get_counts()
        expected = binary.get_bitstring_from_int(b_int, ans.size)
        self._del_qubits()
        self.assertEqual(len(counts), 1)
        self.assertIn(expected, counts)
예제 #2
0
    def test_adder(self, name, a_int, b_int):
        """
        Add a_int and b_int and check their result.
        The number of bits used to represent the ints is computed at runtime.
        """
        bits = binary.get_required_bits(a_int, b_int)
        self._prepare_adder_circuit(bits)

        qregs.initialize_qureg_given_int(a_int, self.a, self.qc)
        qregs.initialize_qureg_given_int(b_int, self.b, self.qc)

        # Apply the adder
        adder.adder_circuit(self.qc, self.cin, self.a, self.b, self.cout)

        # Measure the output register in the computational basis
        ans = ClassicalRegister(self.b.size + self.cout.size, "ans")
        self.qc.add_register(ans)
        for j in range(self.b.size):
            self.qc.measure(self.b[j], ans[j])
        self.qc.measure(self.cout[0], ans[self.b.size])

        ###############################################################
        # execute the program on qasm
        ###############################################################
        counts = CircuitTestCase.execute_qasm(self.qc).get_counts()
        expected = binary.get_bitstring_from_int(a_int + b_int, ans.size)
        self._del_qubits()
        self.assertEqual(len(counts), 1)
        self.assertIn(expected, counts)
    def test_fast_population_count(self, name):
        nwr_dict = hwc.get_circuit_for_qubits_weight_get_pattern(len(name))
        result_bit_length = len(nwr_dict['results'])
        a = QuantumRegister(nwr_dict['n_lines'], 'a')
        cin = QuantumRegister(1, 'cin')
        cout = QuantumRegister(nwr_dict['n_couts'], 'cout')
        cr = ClassicalRegister(len(nwr_dict['results']))
        qc = QuantumCircuit(cin, a, cout, cr, name='test_fpt_{0}'.format(name))

        _ = qregs.initialize_qureg_given_bitstring(name, a, qc)

        to_measure_qubits = hwc.get_circuit_for_qubits_weight(
            qc, a, cin, cout, nwr_dict)

        for i, qb in enumerate(to_measure_qubits):
            qc.measure(qb, cr[i])

        result = CircuitTestCase.execute_qasm(qc, 2048)
        counts = result.get_counts()
        self.logger.info(counts)
        exp_w = name.count("1")
        exp_w_bitstring = binary.get_bitstring_from_int(
            exp_w, result_bit_length)
        self.assertEqual(len(counts), 1)
        self.assertIn(exp_w_bitstring, counts)
예제 #4
0
    def test_halves_sum(self, name, a_int, bits):
        """
        Add two halves of a register on a given number of bits
        """
        if bits % 2 == 1:
            bits = bits + 1
        self.logger.debug("n bits = {0}".format(bits))
        binary.check_enough_bits(a_int, bits)
        half_bits = int(bits / 2)
        # WARNING: also self.b is set, be careful to not use it
        self._prepare_adder_circuit(bits)

        # Initialize a to its value
        qregs.initialize_qureg_given_int(a_int, self.a, self.qc)

        adder.adder_circuit(self.qc, self.cin,
                            [self.a[i] for i in range(half_bits)],
                            [self.a[i]
                             for i in range(half_bits, bits)], self.cout)

        # Measure the output register in the computational basis
        ans = ClassicalRegister(half_bits + self.cout.size, "ans")
        self.qc.add_register(ans)
        for j in range(half_bits, bits):
            self.qc.measure(self.a[j], ans[j - half_bits])
        self.qc.measure(self.cout[0], ans[half_bits])

        counts = self.execute_qasm(self.qc).get_counts()
        self.logger.debug("counts {0}".format(counts))
        a_str = binary.get_bitstring_from_int(a_int, bits)
        a_half1_int = binary.get_int_from_bitstring(a_str[0:half_bits])
        a_half2_int = binary.get_int_from_bitstring(a_str[half_bits:bits])
        # a_half1_int = int(a_str[0:half_bits], 2)
        # a_half2_int = int(a_str[half_bits:bits], 2)
        self.logger.debug("a first half = {0}".format(a_half1_int))
        self.logger.debug("a second half = {0}".format(a_half2_int))
        expected = binary.get_bitstring_from_int(a_half1_int + a_half2_int,
                                                 half_bits + 1)
        self.logger.debug(" '{0}': expected".format(expected))
        self._del_qubits()
        self.assertEqual(len(counts), 1)
        self.assertIn(expected, counts)
예제 #5
0
def initialize_qureg_given_int(a_int, qreg, circuit):
    """
    Given a decimal integer, initialize the qreg to the proper value
    corresponding to it. Basically, if a_int is 11, i.e. 1011 in binary,
    the function negate bits 3, 2 and 0 of the qreg. Note that the qreg has the
    most significant bit in the leftmost part (big endian)

    :param a_int: the integer in decimal base
    :param qreg: the QuantumRegister on which the integer should be set
    :param circuit: the QuantumCircuit containing the q_reg
    """
    a_str = binary.get_bitstring_from_int(a_int, len(qreg))
    return initialize_qureg_given_bitstring(a_str, qreg, circuit)
예제 #6
0
 def test_initialize_complemented_qureg_give_int(self, name, a_int):
     bits = binary.get_required_bits(a_int)
     qreg = QuantumRegister(bits)
     qc = QuantumCircuit(qreg)
     has_op = qregs.initialize_qureg_to_complement_of_int(a_int, qreg, qc)
     if (not has_op):
         self.skipTest("No operation to perform given bitstring")
     vec = CircuitTestCase.execute_statevector(qc).get_statevector(qc)
     exp_vec = [0] * (2**bits)
     neg_bs = binary.get_negated_bistring(
         binary.get_bitstring_from_int(a_int, bits))
     neg_i = binary.get_int_from_bitstring(neg_bs)
     exp_vec[neg_i] = 1
     f = state_fidelity(vec, exp_vec)
     self.assertAlmostEqual(f, 1)
def get_circuit_for_qubits_weight_check(circuit,
                                        a_qs,
                                        cin_q,
                                        cout_qs,
                                        eq_q,
                                        anc_q,
                                        weight_int,
                                        patterns_dict,
                                        mode='advanced'):
    equal_str = binary.get_bitstring_from_int(weight_int,
                                              len(patterns_dict['results']))
    circuit.barrier()
    result_qubits = get_circuit_for_qubits_weight(circuit, a_qs, cin_q,
                                                  cout_qs, patterns_dict)
    circuit.barrier()
    _ = qregs.initialize_qureg_to_complement_of_bitstring(
        equal_str, result_qubits, circuit)
    circuit.barrier()

    circuit.mct([qb for qb in result_qubits], eq_q[0], anc_q, mode=mode)
    circuit.barrier()
    return result_qubits
예제 #8
0
def initialize_qureg_to_complement_of_int(a_int, qreg, circuit):
    a_str = binary.get_bitstring_from_int(a_int, len(qreg))
    return initialize_qureg_to_complement_of_bitstring(a_str, qreg, circuit)
예제 #9
0
    def test_weight_equals_w_hadamards(self, name, eq_int, bits):
        """
        Test how the adder works when using hadamards.
        The idea is to check the weight of a single register, which could be
        in any state. After adding the two halves of the register to get its
        weight, we check this weight against the given eq_int. If the two
        weights are equal, we set a specific register to 1.
        """
        # Prepare qubits
        if bits % 2 == 1:
            bits = bits + 1
        half_bits = int(bits / 2)
        binary.check_enough_bits(eq_int, half_bits + 1)
        equal_str = binary.get_bitstring_from_int(eq_int, half_bits + 1)
        self.logger.debug("equal_str = {0}".format(equal_str))

        # In reality, instead of two separete register, we should have one
        # single register and compute its weight. However, it changes pretty
        # much nothing to just use two separate registers.
        self._prepare_adder_circuit(half_bits)
        eq = QuantumRegister(1, 'eq')
        anc = QuantumRegister(1, 'anc')

        # Have to measure a, b and eq
        ans = ClassicalRegister(self.a.size + self.b.size + eq.size, "ans")
        self.qc.add_register(eq, anc, ans)

        # Hadamards a and b
        self.qc.h(self.a)
        self.qc.h(self.b)
        # Apply the adder
        adder.adder_circuit(self.qc, self.cin, self.a, self.b, self.cout)

        # Add the negated equal_str to {cout, b}. Note that the result of
        # a + b is stored in [cout_0, b_n, b_{n_1}, ..., b_0], w/ the most
        # significant bit on cout.
        qregs.initialize_qureg_to_complement_of_bitstring(
            equal_str, [qb for qb in self.b] + [self.cout[0]], self.qc)

        # If output is 11..1, i.e. a + b == eq_int, set eq to 1
        self.qc.mct([qb for qb in self.b] + [qcout for qcout in self.cout],
                    eq[0],
                    anc,
                    mode='advanced')

        # Restore b
        qregs.initialize_qureg_to_complement_of_bitstring(
            equal_str, [qb for qb in self.b] + [self.cout[0]], self.qc)
        adder.adder_circuit_i(self.qc, self.cin, self.a, self.b, self.cout)

        # Measure a, b, eq
        for i, qr in enumerate(chain(self.a, self.b, eq)):
            self.qc.measure(qr, ans[i])

        ###############################################################
        # execute the program on qasm
        ###############################################################
        counts = CircuitTestCase.execute_qasm(self.qc).get_counts()
        self._del_qubits()
        # self.logger.debug(counts)
        # The idea is that the eq qubit is the first bit of the result state.
        # If it is one, it should mean that a + b == eq_int. So, we get the
        # full state and check the correctness of the equality.
        for i in counts.keys():
            if i[0] == '1':
                self.logger.debug("Eq active, full state is {0}".format(i))
                a_int = binary.get_int_from_bitstring(i[1:half_bits + 1])
                b_int = binary.get_int_from_bitstring(i[half_bits + 1:bits +
                                                        1])
                self.assertEqual(a_int + b_int, eq_int)