def d0_gate(nqbits): """ Circuit generator for create an Abstract Gate that implements a Reflexion around the state perpendicular to |0>_{n}. Implements operator: I-2|0>_{n}{n}<0| = X^{n}c^{n-1}ZX^{n} Parameters ---------- nqbits : int Number of Qbits of the Abstract Gate Returns ---------- q_rout : QLM Routine Quantum routine wiht the circuit implementation for operator: I-2|0>_{n}{n}<0| """ q_rout = QRoutine() qbits = q_rout.new_wires(nqbits) for i in range(nqbits): q_rout.apply(X, qbits[i]) #Controlled Z gate by n-1 first qbits c_n_z = Z.ctrl(nqbits-1) q_rout.apply(c_n_z, qbits[:-1], qbits[-1]) for i in range(nqbits): q_rout.apply(X, qbits[i]) return q_rout
def q_n_gate(): """ Function generator for creating an AbstractGate for apply an input gate n times Returns ---------- q_rout : quantum routine Routine for applying n times an input gate """ q_rout = QRoutine() q_bits = q_rout.new_wires(qlm_gate.arity) for _ in range(n): q_rout.apply(qlm_gate, q_bits) return q_rout
def generate(self, **kwargs) -> QRoutine: s = kwargs["s"] qrout = QRoutine() qreg = qrout.new_wires(self.nqubits) for i, c in enumerate(s): if c == "0": qrout.apply(X, qreg[i]) elif c != "1": raise Exception("only 1 or 0 admissible, found " % c) qrout.apply(Z.ctrl(self.nqubits - 1), qreg[:-1], qreg[-1]) for i, c in enumerate(s): if c == "0": qrout.apply(X, qreg[i]) return qrout
def uphi0_gate(nqbits): """ Circuit generator for creating gate U_Phi_0 for Phase Amplification Algorithm. For a n+1 qbit system where the quantum state can be decomposed by: |Psi>_{n+1} =a*|Phi_{n}>|1>+b|Phi_{n}>|0>. The function implements a reflexion around the state |Phi_{n}>|1>. The operator implemented is: I-2|Phi_{n}>|0><0|<Phi_{n}| Parameters ---------- nqbits : int Number of Qbits of the Abstract Gate Returns ---------- q_rout : QLM Routine Quantum routine wiht the circuit implementation for operator: I-2|Phi_{n}>|0><0|<Phi_{n}| """ q_rout = QRoutine() qbits = q_rout.new_wires(nqbits) q_rout.apply(X, qbits[-1]) q_rout.apply(Z, qbits[-1]) q_rout.apply(X, qbits[-1]) return q_rout
def _gen_ms(theta, nb_qubits): """ Returns the corresponding MS gate. Args: theta: nb_qubits: Number of qubits affected by the gate Returns: QRoutine object representing the MS gate. """ routine = QRoutine() for first_qb in range(nb_qubits): for second_qb in range(first_qb + 1, nb_qubits): routine.apply(RXX(theta), [first_qb, second_qb]) return routine
def u_phi_gate(): """ Circuit generator for the u_phi_gate. Operation to be implemented: R*P*D_0*P^{+}R^{+} Returns ---------- q_rout : Quantum Routinequantum Quantum Routine with the circuit implementation for operator: R*P*D_0*P^{+}R^{+} """ q_rout = QRoutine() qbits = q_rout.new_wires(nqbits) q_rout.apply(gate.dag(), qbits) d_0 = d0_gate(nqbits) q_rout.apply(d_0, qbits) q_rout.apply(gate, qbits) return q_rout
def RZZ(gamma): op = QRoutine() op.apply(CNOT, [0, 1]) op.apply(RZ(gamma), 1) op.apply(CNOT, [0, 1]) return op
def generate(self, **kwargs): s = kwargs["s"] qrout = QRoutine() qreg = qrout.new_wires(self.nqubits) qout = qrout.new_wires(1) for i, c in enumerate(s): if c == "1": qrout.apply(CNOT, qreg[i], qout) elif c != "0": raise Exception("only 1 or 0 admissible") return qrout
def q_gate(): """ Function generator for creating an AbstractGate for implementation of the Amplification Amplitude Algorithm (Q) Returns ---------- q_rout : quantum routine Routine for Amplitude Amplification Algorithm """ q_rout = QRoutine() qbits = q_rout.new_wires(nqbits) q_rout.apply(uphi0_gate(nqbits), qbits) u_phi_gate = load_uphi_gate(pr_gate) q_rout.apply(u_phi_gate, qbits) return q_rout
def u_C(gamma): op = QRoutine() for qbits in itertools.combinations(range(graph.V), 2): op.apply(RZZ(gamma * graph.E[qbits]), qbits) return op
def u_B(beta): op = QRoutine() for qbit in range(graph.V): op.apply(RX(-beta * 2), qbit) return op
def test1_abstract_gate(self): """ Tests an AbstractGate translation to Qiskit. Only abstract gates defined via a circuit are supported. """ prog = Program() qreg = prog.qalloc(3) routine = QRoutine() for gate_op in PYGATES_1QB: routine.apply(gate_op, [0]) for gate_op in PYGATES_2QB: routine.apply(gate_op, [0, 1]) routine.apply(CCNOT, [0, 1, 2]) routine.apply(SWAP.ctrl(), [0, 1, 2]) prog.apply(routine.box("custom_gate"), qreg) qlm_circuit = prog.to_circ() result = qlm_to_qiskit(qlm_circuit) qiskit_qreg = QuantumRegister(3) qiskit_creg = ClassicalRegister(3) expected = QuantumCircuit(qiskit_qreg, qiskit_creg) for gate_op in qiskit_1qb(expected): gate_op(qiskit_qreg[0]) for gate_op in qiskit_1qb_1prm(expected): gate_op(3.14, qiskit_qreg[0]) for gate_op in qiskit_1qb_2prm(expected): gate_op(3.14, 3.14, qiskit_qreg[0]) for gate_op in qiskit_1qb_3prm(expected): gate_op(3.14, 3.14, 3.14, qiskit_qreg[0]) for gate_op in qiskit_2qb(expected): gate_op(qiskit_qreg[0], qiskit_qreg[1]) for gate_op in qiskit_2qb_1prm(expected): gate_op(3.14, qiskit_qreg[0], qiskit_qreg[1]) expected.ccx(*qiskit_qreg) expected.cswap(*qiskit_qreg) expected.measure(qiskit_qreg, qiskit_creg) LOGGER.debug("qlm_to_qiskit test with a QRoutine:") expected_str = print_qiskit(expected) result_str = print_qiskit(result) self.assertEqual(len(result_str), len(expected_str)) for i in range(len(result.data)): r_name, r_params = extract_qiskit(result.data[i])[0:2] e_name, e_params = extract_qiskit(expected.data[i])[0:2] self.assertEqual(r_name, e_name) self.assertEqual(r_params, e_params)
def standard_toffoli(n): rout = QRoutine() wires = rout.new_wires(n) rout.apply(X.ctrl(n - 1), wires) return rout
def dac_toffoli(n): rout = QRoutine() controls = rout.new_wires(n - 1) target = rout.new_wires(1) if n == 3: rout.apply(X.ctrl(2), controls, target) return rout first_half = (n - 1) // 2 + ((n - 1) % 2) second_half = (n - 1) // 2 with rout.compute(): first_toffoli = dac_toffoli(first_half + 1) first_anc = rout.new_wires(1) rout.apply(first_toffoli, controls[0:first_half], first_anc) rout.set_ancillae(first_anc) if second_half > 1: second_toffoli = dac_toffoli(second_half + 1) second_anc = rout.new_wires(1) rout.apply(second_toffoli, controls[first_half:], second_anc) rout.set_ancillae(second_anc) else: second_anc = controls[-1] rout.apply(X.ctrl(2), first_anc, second_anc, target) rout.uncompute() return rout