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)
예제 #2
0
 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)
예제 #4
0
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
예제 #7
0
 def fnz(circuit, qr, phi):
     phi = _mod_2pi(phi, atol)
     if abs(phi) > atol:
         circuit._append(PhaseGate(phi), [qr[0]], [])