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
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()))
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
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
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
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 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