def simplify_U(theta, phi, lam):
    """Return the gate u1, u2, or u3 implementing U with the fewest pulses.

    The returned gate implements U exactly, not up to a global phase.

    Args:
        theta, phi, lam: input Euler rotation angles for a general U gate

    Returns:
        Gate: one of IdGate, U1Gate, U2Gate, U3Gate.
    """
    gate = U3Gate(theta, phi, lam)
    # Y rotation is 0 mod 2*pi, so the gate is a u1
    if abs(gate.params[0] % (2.0 * math.pi)) < _CUTOFF_PRECISION:
        gate = U1Gate(gate.params[0] + gate.params[1] + gate.params[2])
    # Y rotation is pi/2 or -pi/2 mod 2*pi, so the gate is a u2
    if isinstance(gate, U3Gate):
        # theta = pi/2 + 2*k*pi
        if abs((gate.params[0] - math.pi / 2) % (2.0 * math.pi)) < _CUTOFF_PRECISION:
            gate = U2Gate(gate.params[1],
                          gate.params[2] + (gate.params[0] - math.pi / 2))
        # theta = -pi/2 + 2*k*pi
        if abs((gate.params[0] + math.pi / 2) % (2.0 * math.pi)) < _CUTOFF_PRECISION:
            gate = U2Gate(gate.params[1] + math.pi,
                          gate.params[2] - math.pi + (gate.params[0] + math.pi / 2))
    # u1 and lambda is 0 mod 4*pi so gate is nop
    if isinstance(gate, U1Gate) and abs(gate.params[0] % (4.0 * math.pi)) < _CUTOFF_PRECISION:
        gate = IdGate()
    return gate
Exemple #2
0
    def test_multi_controlled_u1_matrix(self, num_controls):
        """Test the matrix representation of the multi-controlled CU1 gate.

        Based on the test moved here from Aqua:
        https://github.com/Qiskit/qiskit-aqua/blob/769ca8f/test/aqua/test_mcu1.py
        """

        # registers for the circuit
        q_controls = QuantumRegister(num_controls)
        q_target = QuantumRegister(1)

        # iterate over all possible combinations of control qubits
        for ctrl_state in range(2 ** num_controls):
            bitstr = bin(ctrl_state)[2:].zfill(num_controls)[::-1]
            lam = 0.3165354 * pi
            qc = QuantumCircuit(q_controls, q_target)
            for idx, bit in enumerate(bitstr):
                if bit == '0':
                    qc.x(q_controls[idx])

            qc.mcu1(lam, q_controls, q_target[0])

            # for idx in subset:
            for idx, bit in enumerate(bitstr):
                if bit == '0':
                    qc.x(q_controls[idx])

            backend = BasicAer.get_backend('unitary_simulator')
            simulated = execute(qc, backend).result().get_unitary(qc)

            base = U1Gate(lam).to_matrix()
            expected = _compute_control_matrix(base, num_controls, ctrl_state=ctrl_state)
            with self.subTest(msg='control state = {}'.format(ctrl_state)):
                self.assertTrue(matrix_equal(simulated, expected))
    def test_multi_controlled_rotation_gate_matrices(self, num_controls,
                                                     base_gate_name,
                                                     use_basis_gates):
        """Test the multi controlled rotation gates without ancillas.

        Based on the test moved here from Aqua:
        https://github.com/Qiskit/qiskit-aqua/blob/769ca8f/test/aqua/test_mcr.py
        """
        q_controls = QuantumRegister(num_controls)
        q_target = QuantumRegister(1)

        # iterate over all possible combinations of control qubits
        for ctrl_state in range(2**num_controls):
            bitstr = bin(ctrl_state)[2:].zfill(num_controls)[::-1]
            theta = 0.871236 * pi
            qc = QuantumCircuit(q_controls, q_target)
            for idx, bit in enumerate(bitstr):
                if bit == '0':
                    qc.x(q_controls[idx])

            # call mcrx/mcry/mcrz
            if base_gate_name == 'y':
                qc.mcry(theta,
                        q_controls,
                        q_target[0],
                        None,
                        mode='noancilla',
                        use_basis_gates=use_basis_gates)
            else:  # case 'x' or 'z' only support the noancilla mode and do not have this keyword
                getattr(qc, 'mcr' + base_gate_name)(
                    theta,
                    q_controls,
                    q_target[0],
                    use_basis_gates=use_basis_gates)

            for idx, bit in enumerate(bitstr):
                if bit == '0':
                    qc.x(q_controls[idx])

            backend = BasicAer.get_backend('unitary_simulator')
            simulated = execute(qc, backend).result().get_unitary(qc)

            if base_gate_name == 'x':
                rot_mat = RXGate(theta).to_matrix()
            elif base_gate_name == 'y':
                rot_mat = RYGate(theta).to_matrix()
            else:  # case 'z'
                rot_mat = U1Gate(theta).to_matrix()

            expected = _compute_control_matrix(rot_mat,
                                               num_controls,
                                               ctrl_state=ctrl_state)
            with self.subTest(msg='control state = {}'.format(ctrl_state)):
                self.assertTrue(matrix_equal(simulated, expected))
Exemple #4
0
    def _define(self):
        definition = []
        # No controls:
        #   q = b
        # One Control:
        #   q = b, c1
        # Two Controls:
        #   q = c1, c2, b
        q = QuantumRegister(self.total_n, "q")
        rule = []

        angles = [0] * self.n
        for i in range(self.n):
            if self.a & (1 << i):
                for j in range(i, self.n):
                    angles[j] += np.pi / 2**(j - i)

        # Inverse of U1 gates is just a negative theta
        if self._inverse:
            for i in range(len(angles)):
                angles[i] *= -1

        # No controlled bits
        if self.c1 is None and self.c2 is None:
            for i in range(len(angles)):
                rule.append((U1Gate(angles[i]), [q[i]], []))

        # One controlled bit
        if self.c1 and self.c2 is None:
            for i in range(len(angles)):
                rule.append((Cu1Gate(angles[i]), [q[self.total_n - 1],
                                                  q[i]], []))

        # Two controlled bits
        # Uses sqrt of U1 gates which is just half of theta
        if self.c1 and self.c2:
            for i in range(len(angles)):
                rule.append((Cu1Gate(angles[i] / 2.), [q[1], q[i + 2]], []))
                # circ.cu1(angles[i]/2., c2, b[i])
            rule.append((CnotGate(), [q[0], q[1]], []))
            # circ.cx(c1, c2)

            for i in range(len(angles)):
                rule.append((Cu1Gate(-angles[i] / 2.), [q[1], q[i + 2]], []))
                # circ.cu1(-angles[i]/2., c2, b[i])
            rule.append((CnotGate(), [q[0], q[1]], []))
            # circ.cx(c1, c2)
            for i in range(len(angles)):
                rule.append((Cu1Gate(angles[i] / 2.), [q[0], q[i + 2]], []))
                # circ.cu1(angles[i]/2., c1, b[i])

        for inst in rule:
            definition.append(inst)
        self.definition = definition
 def _circuit_u1x(theta, phi, lam, simplify=True, atol=DEFAULT_ATOL):
     # Shift theta and phi so decomposition is
     # U1(phi).X90.U1(theta).X90.U1(lam)
     theta += np.pi
     phi += np.pi
     # Check for decomposition into minimimal number required X90 pulses
     if simplify and np.isclose(abs(theta), np.pi, atol=atol):
         # Zero X90 gate decomposition
         circuit = QuantumCircuit(1)
         circuit.append(U1Gate(lam + phi + theta), [0])
         return circuit
     if simplify and np.isclose(abs(theta), np.pi / 2, atol=atol):
         # Single X90 gate decomposition
         circuit = QuantumCircuit(1)
         circuit.append(U1Gate(lam + theta), [0])
         circuit.append(RXGate(np.pi / 2), [0])
         circuit.append(U1Gate(phi + theta), [0])
         return circuit
     # General two-X90 gate decomposition
     circuit = QuantumCircuit(1)
     circuit.append(U1Gate(lam), [0])
     circuit.append(RXGate(np.pi / 2), [0])
     circuit.append(U1Gate(theta), [0])
     circuit.append(RXGate(np.pi / 2), [0])
     circuit.append(U1Gate(phi), [0])
     return circuit
class TestParameterCtrlState(QiskitTestCase):
    """Test gate equality with ctrl_state parameter."""
    @data((RXGate(0.5), CRXGate(0.5)), (RYGate(0.5), CRYGate(0.5)),
          (RZGate(0.5), CRZGate(0.5)), (XGate(), CXGate()),
          (YGate(), CYGate()), (ZGate(), CZGate()),
          (U1Gate(0.5), CU1Gate(0.5)), (SwapGate(), CSwapGate()),
          (HGate(), CHGate()), (U3Gate(0.1, 0.2, 0.3), CU3Gate(0.1, 0.2, 0.3)))
    @unpack
    def test_ctrl_state_one(self, gate, controlled_gate):
        """Test controlled gates with ctrl_state
        See https://github.com/Qiskit/qiskit-terra/pull/4025
        """
        self.assertEqual(gate.control(1, ctrl_state='1'), controlled_gate)
Exemple #7
0
 def _circuit_u1x(theta, phi, lam, simplify=True, atol=DEFAULT_ATOL):
     # Check for U1 and U2 decompositions into minimimal
     # required X90 pulses
     if simplify and np.allclose([theta, phi], [0., 0.], atol=atol):
         # zero X90 gate decomposition
         circuit = QuantumCircuit(1)
         circuit.append(U1Gate(lam), [0])
         return circuit
     if simplify and np.isclose(theta, np.pi / 2, atol=atol):
         # single X90 gate decomposition
         circuit = QuantumCircuit(1)
         circuit.append(U1Gate(lam - np.pi / 2), [0])
         circuit.append(RXGate(np.pi / 2), [0])
         circuit.append(U1Gate(phi + np.pi / 2), [0])
         return circuit
     # General two-X90 gate decomposition
     circuit = QuantumCircuit(1)
     circuit.append(U1Gate(lam), [0])
     circuit.append(RXGate(np.pi / 2), [0])
     circuit.append(U1Gate(theta + np.pi), [0])
     circuit.append(RXGate(np.pi / 2), [0])
     circuit.append(U1Gate(phi + np.pi), [0])
     return circuit
Exemple #8
0
 def test_controlled_u1(self):
     """Test creation of controlled u1 gate"""
     theta = 0.5
     self.assertEqual(U1Gate(theta).control(), Cu1Gate(theta))
 def test_controlled_u1(self):
     """Test the creation of a controlled U1 gate."""
     theta = 0.5
     self.assertEqual(U1Gate(theta).control(), CU1Gate(theta))