Exemple #1
0
    def _build_composite_gate(self, x, qr):
        composite_gate = CompositeGate(
            "first_order_expansion", [],
            [qr[i] for i in range(self._num_qubits)])

        for _ in range(self._depth):
            for i in range(x.shape[0]):
                composite_gate._attach(U2Gate(0, np.pi, qr[i]))
                composite_gate._attach(U1Gate(2 * x[i], qr[i]))

        return composite_gate
    def _build_composite_gate(self, x, qr):
        composite_gate = CompositeGate(
            "second_order_expansion", [],
            [qr[i] for i in range(self._num_qubits)])

        for _ in range(self._depth):
            for i in range(x.shape[0]):
                composite_gate._attach(U2Gate(0, np.pi, qr[i]))
                composite_gate._attach(U1Gate(2 * x[i], qr[i]))
            for src, targs in self._entangler_map.items():
                for targ in targs:
                    composite_gate._attach(CnotGate(qr[src], qr[targ]))
                    composite_gate._attach(
                        U1Gate(2 * (np.pi - x[src]) * (np.pi - x[targ]),
                               qr[targ]))
                    composite_gate._attach(CnotGate(qr[src], qr[targ]))

        return composite_gate
Exemple #3
0
 def _convert_to_basis_gates(gates):
     if isinstance(gates, list):
         return [Custom._convert_to_basis_gates(gate) for gate in gates]
     elif isinstance(gates, CompositeGate):
         gates_data = [
             Custom._convert_to_basis_gates(gate) for gate in gates.data
         ]
         gates = CompositeGate(gates.name,
                               gates.param,
                               gates.arg,
                               circuit=gates.circuit)
         gates.data = gates_data
         return gates
     else:
         if isinstance(gates, RYGate):
             return U3Gate(gates.param[0], 0, 0, gates.arg[0])
         elif isinstance(gates, RZGate):
             return U1Gate(gates.param[0], gates.arg[0])
         elif isinstance(gates, CnotGate):
             return gates
         else:
             raise RuntimeError(
                 'Unexpected component {} from the initialization circuit.'.
                 format(gates.qasm()))
Exemple #4
0
def createCG3(circ, args, anc_cl, n, reg, reg2, pie, anc, a_cl):
    """
    Creates a CompositeGate cgate with a series of instructions controlled
    by ClassicalRegister anc_cl holding the value 3. 
    Parameters:
    circ: QuantumCircuit
    args: List containing (Register, index) pairs that the CompositeGate
          will affect.
    reg, reg2, anc: QuantumRegisters
    anc_cl, a_cl: ClassicalRegisters
    n: integer
    pie: float representing pi (3.14..)
    Returns:
    cgate: CompositeGate     
    """
    cgate = CompositeGate("cl_" + str(3), [pie], args, circuit=circ)
    #Compute (reg - reg2)/2
    cgate = subtract.subtract(circ, n, pie, reg, reg2, cgate, -1, anc_cl, 3)
    cgate = divideBy2(cgate, n, circ, reg, anc_cl, 3, anc, a_cl)
    return cgate
Exemple #5
0
def createCG(circ, args, anc_cl, n, num, anc, a_cl, \
    reg, reg2 = None, reg3 = None):
    """
    Creates a CompositeGate cgate with a series of instructions controlled
    by ClassicalRegister anc_cl holding the value num. 
    Parameters:
    circ: QuantumCircuit
    args: List containing (Register, index) pairs that the CompositeGate
          will affect.
    reg, reg2, reg3, anc: QuantumRegisters
    anc_cl, a_cl: ClassicalRegisters
    n, num: integers
    pie: float representing pi (3.14..)
    Returns:
    cgate: CompositeGate     
    """
    cgate = CompositeGate("cl_" + str(num), [], args, circuit=circ)
    cgate = divideBy2(cgate, n, circ, reg, anc_cl, num, anc, a_cl)
    if num == 0:
        cgate = divideBy2(cgate, n, circ, reg2, anc_cl, num, anc, a_cl)
        cgate = multiplyBy2(cgate, n, circ, reg3, anc_cl, num)
    return cgate
Exemple #6
0
    def _multiplex(self, bottom_gate, bottom_qubit_index, list_of_angles):
        """
        Internal recursive method to create gates to perform rotations on the
        imaginary qubits: works by rotating LSB (and hence ALL imaginary
        qubits) by combo angle and then flipping sign (by flipping the bit,
        hence moving the complex amplitudes) of half the imaginary qubits
        (CNOT) followed by another combo angle on LSB, therefore executing
        conditional (on MSB) rotations, thereby disentangling LSB.
        """
        list_len = len(list_of_angles)
        target_qubit = self.nth_qubit_from_least_sig_qubit(bottom_qubit_index)

        # Case of no multiplexing = base case for recursion
        if list_len == 1:
            return bottom_gate(list_of_angles[0], target_qubit)

        local_num_qubits = int(math.log2(list_len)) + 1
        control_qubit = self.nth_qubit_from_least_sig_qubit(
            local_num_qubits - 1 + bottom_qubit_index)

        # calc angle weights, assuming recursion (that is the lower-level
        # requested angles have been correctly implemented by recursion
        angle_weight = scipy.kron([[0.5, 0.5], [0.5, -0.5]],
                                  numpy.identity(2 ** (local_num_qubits - 2)))

        # calc the combo angles
        list_of_angles = (angle_weight * numpy.matrix(
            list_of_angles).transpose()).reshape(-1).tolist()[0]

        combine_composite_gates = CompositeGate(
            "multiplex" + local_num_qubits.__str__(), [], self.arg)

        # recursive step on half the angles fulfilling the above assumption
        combine_composite_gates._attach(
            self._multiplex(bottom_gate, bottom_qubit_index,
                            list_of_angles[0:(list_len // 2)]))

        # combine_composite_gates.cx(control_qubit,target_qubit) -> does not
        # work as expected because checks circuit
        # so attach CNOT as follows, thereby flipping the LSB qubit
        combine_composite_gates._attach(CnotGate(control_qubit, target_qubit))

        # implement extra efficiency from the paper of cancelling adjacent
        # CNOTs (by leaving out last CNOT and reversing (NOT inverting) the
        # second lower-level multiplex)
        sub_gate = self._multiplex(
            bottom_gate, bottom_qubit_index, list_of_angles[(list_len // 2):])
        if isinstance(sub_gate, CompositeGate):
            combine_composite_gates._attach(sub_gate.reverse())
        else:
            combine_composite_gates._attach(sub_gate)

        # outer multiplex keeps final CNOT, because no adjacent CNOT to cancel
        # with
        if self.num_qubits == local_num_qubits + bottom_qubit_index:
            combine_composite_gates._attach(CnotGate(control_qubit,
                                                     target_qubit))

        return combine_composite_gates
Exemple #7
0
quantum_r = QuantumRegister(4, "qr")
classical_r = ClassicalRegister(4, "cr")
circuit = QuantumCircuit(quantum_r, classical_r)

circuit.h(quantum_r[0])

circuit.rx(0, quantum_r[0])

circuit.cx(quantum_r[0], quantum_r[1])
circuit.cx(quantum_r[0], quantum_r[1])

circuit.h(quantum_r[0])

circuit.cx(quantum_r[0], quantum_r[1])
composite_gate_1 = CompositeGate("composite1", [],
                                 [quantum_r[x] for x in range(4)])
composite_gate_1._attach(CnotGate(quantum_r[0], quantum_r[1]))
circuit._attach(composite_gate_1)

circuit.h(quantum_r[0])

composite_gate_2 = CompositeGate("composite2", [],
                                 [quantum_r[x] for x in range(4)])
composite_gate_2._attach(CnotGate(quantum_r[0], quantum_r[1]))
circuit._attach(composite_gate_2)
circuit.cx(quantum_r[0], quantum_r[1])

circuit.h(quantum_r[0])

composite_gate_3 = CompositeGate("composite3", [],
                                 [quantum_r[x] for x in range(4)])
}
Q_program = QuantumProgram(specs=Q_SPECS)
circuit = Q_program.get_circuit("Circuit")
quantum_r = Q_program.get_quantum_register("qr")
classical_r = Q_program.get_classical_register('cr')

circuit.h(quantum_r[0])
circuit.rx(0, quantum_r[0])

circuit.cx(quantum_r[0], quantum_r[1])
circuit.cx(quantum_r[0], quantum_r[1])

circuit.h(quantum_r[0])

circuit.cx(quantum_r[0], quantum_r[1])
composite_gate_1 = CompositeGate("composite1", [],
                                 [quantum_r[x] for x in range(4)])

composite_gate_1._attach(CnotGate(quantum_r[0], quantum_r[1]))
circuit._attach(composite_gate_1)

circuit.h(quantum_r[0])

composite_gate_2 = CompositeGate("composite2", [],
                                 [quantum_r[x] for x in range(4)])
composite_gate_2._attach(CnotGate(quantum_r[0], quantum_r[1]))
circuit._attach(composite_gate_2)
circuit.cx(quantum_r[0], quantum_r[1])

circuit.h(quantum_r[0])

composite_gate_3 = CompositeGate("composite3", [],
    def _multiplex(self, bottom_gate, bottom_qubit_index, list_of_angles):
        """
        Internal recursive method to create gates to perform rotations on the
        imaginary qubits: works by rotating LSB (and hence ALL imaginary
        qubits) by combo angle and then flipping sign (by flipping the bit,
        hence moving the complex amplitudes) of half the imaginary qubits
        (CNOT) followed by another combo angle on LSB, therefore executing
        conditional (on MSB) rotations, thereby disentangling LSB.
        """
        list_len = len(list_of_angles)
        target_qubit = self.nth_qubit_from_least_sig_qubit(bottom_qubit_index)

        # Case of no multiplexing = base case for recursion
        if list_len == 1:
            return bottom_gate(list_of_angles[0], target_qubit)

        local_num_qubits = int(math.log2(list_len)) + 1
        control_qubit = self.nth_qubit_from_least_sig_qubit(
            local_num_qubits - 1 + bottom_qubit_index)

        # calc angle weights, assuming recursion (that is the lower-level
        # requested angles have been correctly implemented by recursion
        angle_weight = scipy.kron([[0.5, 0.5], [0.5, -0.5]],
                                  numpy.identity(2 ** (local_num_qubits - 2)))

        # calc the combo angles
        list_of_angles = (angle_weight * numpy.matrix(
            list_of_angles).transpose()).reshape(-1).tolist()[0]

        combine_composite_gates = CompositeGate(
            "multiplex" + local_num_qubits.__str__(), [], self.arg)

        # recursive step on half the angles fulfilling the above assumption
        combine_composite_gates._attach(
            self._multiplex(bottom_gate, bottom_qubit_index,
                            list_of_angles[0:(list_len // 2)]))

        # combine_composite_gates.cx(control_qubit,target_qubit) -> does not
        # work as expected because checks circuit
        # so attach CNOT as follows, thereby flipping the LSB qubit
        combine_composite_gates._attach(CnotGate(control_qubit, target_qubit))

        # implement extra efficiency from the paper of cancelling adjacent
        # CNOTs (by leaving out last CNOT and reversing (NOT inverting) the
        # second lower-level multiplex)
        sub_gate = self._multiplex(
            bottom_gate, bottom_qubit_index, list_of_angles[(list_len // 2):])
        if isinstance(sub_gate, CompositeGate):
            combine_composite_gates._attach(sub_gate.reverse())
        else:
            combine_composite_gates._attach(sub_gate)

        # outer multiplex keeps final CNOT, because no adjacent CNOT to cancel
        # with
        if self.num_qubits == local_num_qubits + bottom_qubit_index:
            combine_composite_gates._attach(CnotGate(control_qubit,
                                                     target_qubit))

        return combine_composite_gates
Exemple #10
0
def compute_gcd(first, second, n, gcd_factor):
    """
    Computes the GCD of two numbers stored in QuantumRegisters a and b.
    Parameters:
    first, second, gcd_factor: Bit strings
    n: integer representing the length of the bit strings
    Returns:
    zero_status, gcd_factor, a_value, equality_status, b_value: Bit strings
     representing whether one or both of the numbers are equal to zero, 
     the factor by which to multiply b_value to obtain the GCD, the value
     stored in register a, whether the two numbers are equal to each other, 
     and the value stored in register b, respectively. 
    """
    a = QuantumRegister(n, "aq")
    b = QuantumRegister(n, "bq")
    anc = QuantumRegister(2, "ancq")
    res = QuantumRegister(n, "resq")
    zero = QuantumRegister(2, "zq")
    anc_cl = ClassicalRegister(2, "anccl")
    zero_cl = ClassicalRegister(2, "zcl")
    a_cl = ClassicalRegister(n, "acl")
    b_cl = ClassicalRegister(n, "bcl")
    res_cl = ClassicalRegister(n, "cl")
    qc = QuantumCircuit(a,
                        b,
                        anc,
                        res,
                        zero,
                        anc_cl,
                        zero_cl,
                        res_cl,
                        a_cl,
                        b_cl,
                        name="qc")

    for i in range(0, n):
        if first[i] == "1":
            qc.x(a[n - (i + 1)])

    for i in range(0, n):
        if second[i] == "1":
            qc.x(b[n - (i + 1)])

    for i in range(0, n):
        if gcd_factor[i] == "1":
            qc.x(res[n - (i + 1)])

    qc.measure(a, res_cl)
    qc.x(zero[0]).c_if(res_cl, 0)
    qc.measure(b, res_cl)
    qc.x(zero[1]).c_if(res_cl, 0)
    qc.measure(zero, zero_cl)
    #Resetting the zero qreg to 0, with zero_cl holding the zero status
    qc.x(zero[0]).c_if(res_cl, 0)
    qc.measure(a, res_cl)
    qc.x(zero[1]).c_if(res_cl, 0)
    #Resetting res_cl to zero again.
    for i in range(n):
        qc.measure(zero[0], res_cl[i])

    #Checking for equality
    args = [a[x] for x in range(n)] + [b[x] for x in range(n)]
    csub = CompositeGate("csub", [math.pi], args, circuit="qc")
    csub = subtract.subtract(qc, n, math.pi, a, b, csub, -1)
    qc.measure(a, res_cl)
    qc.x(zero[0]).c_if(res_cl, 0)
    cadd = CompositeGate("csub", [math.pi], args, circuit="qc")
    cadd = subtract.subtract(qc, n, math.pi, a, b, cadd, 1)

    #Checking if either b, a or both are zero - if they are, then swap
    #the 1 in res_q out for a zero
    qc.swap(res[0], zero[0]).c_if(zero_cl, 1)
    qc.swap(res[0], zero[0]).c_if(zero_cl, 2)
    qc.swap(res[0], zero[0]).c_if(zero_cl, 3)
    #flip the 1 in zero_q to make zero_q on the zero state again.
    qc.x(zero[0]).c_if(zero_cl, 1)
    qc.x(zero[0]).c_if(zero_cl, 2)
    qc.x(zero[0]).c_if(zero_cl, 3)

    zero_status, gcd_factor, b_value, equality_status, a_value  =  \
     gcd_main.gcd(qc, a, b, res, anc, zero, zero_cl, anc_cl, res_cl,
      n, a_cl, b_cl)

    return zero_status, gcd_factor, b_value, equality_status, a_value