def test_optimize_u_to_p_sx_p(self): """U(pi/2, 0, pi/4) -> p(-pi/4)-sx-p(p/2). Basis [p, sx].""" qr = QuantumRegister(2, 'qr') circuit = QuantumCircuit(qr) circuit.append(UGate(np.pi / 2, 0, np.pi / 4), [qr[0]]) expected = QuantumCircuit(qr, global_phase=-np.pi / 4) expected.append(PhaseGate(-np.pi / 4), [qr[0]]) expected.append(SXGate(), [qr[0]]) expected.append(PhaseGate(np.pi / 2), [qr[0]]) basis = ['p', 'sx'] passmanager = PassManager() passmanager.append(BasisTranslator(sel, basis)) passmanager.append(Optimize1qGatesDecomposition(basis)) result = passmanager.run(circuit) self.assertEqual(expected, result)
def _circuit_psx(theta, phi, lam, phase, simplify=True, atol=DEFAULT_ATOL): # Shift theta and phi so decomposition is # Phase(phi+pi).SX.Phase(theta+pi).SX.Phase(lam) theta = _mod2pi(theta + np.pi) phi = _mod2pi(phi + np.pi) circuit = QuantumCircuit(1, global_phase=phase - np.pi / 2) # Check for decomposition into minimimal number required SX gates if simplify and np.isclose(abs(theta), np.pi, atol=atol): if not np.isclose(_mod2pi(abs(lam + phi + theta)), [0., 2 * np.pi], atol=atol).any(): circuit.append(PhaseGate(_mod2pi(lam + phi + theta)), [0]) circuit.global_phase += np.pi / 2 elif simplify and np.isclose(abs(theta), [np.pi / 2, 3 * np.pi / 2], atol=atol).any(): if not np.isclose(_mod2pi(abs(lam + theta)), [0., 2 * np.pi], atol=atol).any(): circuit.append(PhaseGate(_mod2pi(lam + theta)), [0]) circuit.append(SXGate(), [0]) if not np.isclose(_mod2pi(abs(phi + theta)), [0., 2 * np.pi], atol=atol).any(): circuit.append(PhaseGate(_mod2pi(phi + theta)), [0]) if np.isclose(theta, [-np.pi / 2, 3 * np.pi / 2], atol=atol).any(): circuit.global_phase += np.pi / 2 else: if not np.isclose(abs(lam), [0., 2 * np.pi], atol=atol).any(): circuit.append(PhaseGate(lam), [0]) circuit.append(SXGate(), [0]) if not np.isclose(abs(theta), [0., 2 * np.pi], atol=atol).any(): circuit.append(PhaseGate(theta), [0]) circuit.append(SXGate(), [0]) if not np.isclose(abs(phi), [0., 2 * np.pi], atol=atol).any(): circuit.append(PhaseGate(phi), [0]) return circuit
def __init__( self, num_state_qubits: int, num_result_qubits: Optional[int] = None, name: str = "RGQFTMultiplier", ) -> None: r""" Args: num_state_qubits: The number of qubits in either input register for state :math:`|a\rangle` or :math:`|b\rangle`. The two input registers must have the same number of qubits. num_result_qubits: The number of result qubits to limit the output to. If number of result qubits is :math:`n`, multiplication modulo :math:`2^n` is performed to limit the output to the specified number of qubits. Default value is ``2 * num_state_qubits`` to represent any possible result from the multiplication of the two inputs. name: The name of the circuit object. """ super().__init__(num_state_qubits, num_result_qubits, name=name) # define the registers qr_a = QuantumRegister(num_state_qubits, name="a") qr_b = QuantumRegister(num_state_qubits, name="b") qr_out = QuantumRegister(self.num_result_qubits, name="out") self.add_register(qr_a, qr_b, qr_out) # build multiplication circuit circuit = QuantumCircuit(*self.qregs, name=name) circuit.append( QFT(self.num_result_qubits, do_swaps=False).to_gate(), qr_out[:]) for j in range(1, num_state_qubits + 1): for i in range(1, num_state_qubits + 1): for k in range(1, self.num_result_qubits + 1): lam = (2 * np.pi) / (2**(i + j + k - 2 * num_state_qubits)) circuit.append( PhaseGate(lam).control(2), [ qr_a[num_state_qubits - j], qr_b[num_state_qubits - i], qr_out[k - 1] ], ) circuit.append( QFT(self.num_result_qubits, do_swaps=False).inverse().to_gate(), qr_out[:]) self.append(circuit.to_gate(), self.qubits)
def cnincrement(circuit, c, q, do_qft=True, amount=1): """Performs +1 on the value of register q, controlled by register c Parameters ---------- circuit : QuantumCircuit Quantum circuit to be appended with increment. q : QuantumRegister Register to be incremented. c : Qubit List Control qubits do_qft : bool (default: True) Whether to include the QFT and iQFT on reg b. amount : float (default: 1) Multiplication factor on addition (i.e. get b+amount*a). Returns ------- circuit : QuantumCircuit Quantum circuit appended with increment. """ # Constants n = len(q) nc = len(c) # Optional QFT if do_qft: circuit.barrier() qft(circuit, q) circuit.barrier() # Actual core (controlled) increm gates for (i, qubit) in enumerate(q): # qcs = QuantumCircuit(1) # qcs.rz(amount*pi/2**(n-i-1),0) # ncrz = qcs.to_gate().control(nc) # circuit.append(ncrz, [*c, qubit]) ncp = PhaseGate(amount * pi / 2**(n - i - 1)).control(nc) circuit.append(ncp, [*c, qubit]) # Optional iQFT if do_qft: circuit.barrier() iqft(circuit, q) circuit.barrier() return circuit
def test_optimize_u_to_phase_gate(self): """U(0, 0, pi/4) -> p(pi/4). Basis [p, sx].""" qr = QuantumRegister(2, "qr") circuit = QuantumCircuit(qr) circuit.append(UGate(0, 0, np.pi / 4), [qr[0]]) expected = QuantumCircuit(qr) expected.append(PhaseGate(np.pi / 4), [qr[0]]) basis = ["p", "sx"] passmanager = PassManager() passmanager.append(BasisTranslator(sel, basis)) passmanager.append(Optimize1qGatesDecomposition(basis)) result = passmanager.run(circuit) msg = f"expected:\n{expected}\nresult:\n{result}" self.assertEqual(expected, result, msg=msg)
def _circuit_psx(theta, phi, lam, phase, simplify=True, atol=DEFAULT_ATOL): # Shift theta and phi so decomposition is # Phase(phi+pi).SX.Phase(theta+pi).SX.Phase(lam) theta = _mod2pi(theta + np.pi) phi = _mod2pi(phi + np.pi) qr = QuantumRegister(1, 'qr') circuit = QuantumCircuit(qr, global_phase=phase - np.pi / 2) # Check for decomposition into minimimal number required SX gates abs_theta = abs(theta) if simplify and math.isclose(abs_theta, np.pi, abs_tol=atol): lam_phi_theta = _mod2pi(lam + phi + theta) abs_lam_phi_theta = _mod2pi(abs(lam + phi + theta)) if not (math.isclose(abs_lam_phi_theta, 0., abs_tol=atol) or math.isclose(abs_lam_phi_theta, 2*np.pi, abs_tol=atol)): circuit._append(PhaseGate(lam_phi_theta), [qr[0]], []) circuit.global_phase += np.pi / 2 elif simplify and (math.isclose(abs_theta, np.pi/2, abs_tol=atol) or math.isclose(abs_theta, 3*np.pi/2, abs_tol=atol)): lam_theta = _mod2pi(lam + theta) abs_lam_theta = _mod2pi(abs(lam + theta)) if not (math.isclose(abs_lam_theta, 0, abs_tol=atol) or math.isclose(abs_lam_theta, 2*np.pi, abs_tol=atol)): circuit._append(PhaseGate(lam_theta), [qr[0]], []) circuit._append(SXGate(), [qr[0]], []) phi_theta = _mod2pi(phi + theta) abs_phi_theta = _mod2pi(abs(phi_theta)) if not (math.isclose(abs_phi_theta, 0, abs_tol=atol) or math.isclose(abs_phi_theta, 2*np.pi, abs_tol=atol)): circuit._append(PhaseGate(_mod2pi(phi + theta)), [qr[0]], []) if (math.isclose(theta, -np.pi / 2, abs_tol=atol) or math.isclose( theta, 3 * np.pi / 2, abs_tol=atol)): circuit.global_phase += np.pi / 2 else: abs_lam = abs(lam) if not (math.isclose(abs_lam, 0., abs_tol=atol) or math.isclose(abs_lam, 2*np.pi, abs_tol=atol)): circuit._append(PhaseGate(lam), [qr[0]], []) circuit._append(SXGate(), [qr[0]], []) if not (math.isclose(abs_theta, 0., abs_tol=atol) or math.isclose(abs_theta, 2*np.pi, abs_tol=atol)): circuit._append(PhaseGate(theta), [qr[0]], []) circuit._append(SXGate(), [qr[0]], []) abs_phi = abs(phi) if not (math.isclose(abs_phi, 0., abs_tol=atol) or math.isclose(abs_phi, 2*np.pi, abs_tol=atol)): circuit._append(PhaseGate(phi), [qr[0]], []) return circuit
def fnz(circuit, qr, phi): phi = _mod_2pi(phi, atol) if abs(phi) > atol: circuit._append(PhaseGate(phi), [qr[0]], [])