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
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))
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)
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
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))