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
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
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)]) composite_gate_3._attach(CnotGate(quantum_r[0], quantum_r[1]))
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", [], [quantum_r[x] for x in range(4)]) composite_gate_3._attach(CnotGate(quantum_r[0], quantum_r[1]))