def test_two_qubit_approx_eq(): f = cirq.TwoQubitMatrixGate(QFT2) perturb = np.zeros(shape=QFT2.shape, dtype=np.float64) perturb[1, 2] = 0.00000001 assert f.approx_eq(cirq.TwoQubitMatrixGate(QFT2)) assert f.approx_eq(cirq.TwoQubitMatrixGate(QFT2 + perturb)) assert not f.approx_eq(cirq.TwoQubitMatrixGate(HH))
def test_two_qubit_extrapolate(): cz2 = cirq.TwoQubitMatrixGate(np.diag([1, 1, 1, 1j])) cz4 = cirq.TwoQubitMatrixGate(np.diag([1, 1, 1, (1 + 1j) * np.sqrt(0.5)])) i = cirq.TwoQubitMatrixGate(np.eye(4)) assert cz2.extrapolate_effect(0).approx_eq(i) assert cz4.extrapolate_effect(0).approx_eq(i) assert cz2.extrapolate_effect(0.5).approx_eq(cz4)
def test_two_qubit_extrapolate(): cz2 = cirq.TwoQubitMatrixGate(np.diag([1, 1, 1, 1j])) cz4 = cirq.TwoQubitMatrixGate(np.diag([1, 1, 1, (1 + 1j) * np.sqrt(0.5)])) i = cirq.TwoQubitMatrixGate(np.eye(4)) assert (cz2**0).approx_eq(i) assert (cz4**0).approx_eq(i) assert (cz2**0.5).approx_eq(cz4) with pytest.raises(TypeError): _ = cz2**cirq.Symbol('a')
def test_two_qubit_extrapolate(): cz2 = cirq.TwoQubitMatrixGate(np.diag([1, 1, 1, 1j])) cz4 = cirq.TwoQubitMatrixGate(np.diag([1, 1, 1, (1 + 1j) * np.sqrt(0.5)])) i = cirq.TwoQubitMatrixGate(np.eye(4)) assert cirq.approx_eq(cz2**0, i, atol=1e-9) assert cirq.approx_eq(cz4**0, i, atol=1e-9) assert cirq.approx_eq(cz2**0.5, cz4, atol=1e-9) with pytest.raises(TypeError): _ = cz2**sympy.Symbol('a')
def test_two_qubit_approx_eq(): f = cirq.TwoQubitMatrixGate(QFT2) perturb = np.zeros(shape=QFT2.shape, dtype=np.float64) perturb[1, 2] = 1e-8 assert cirq.approx_eq(f, cirq.TwoQubitMatrixGate(QFT2), atol=1e-9) assert not cirq.approx_eq( f, cirq.TwoQubitMatrixGate(QFT2 + perturb), atol=1e-9) assert cirq.approx_eq(f, cirq.TwoQubitMatrixGate(QFT2 + perturb), atol=1e-7) assert not cirq.approx_eq(f, cirq.TwoQubitMatrixGate(HH), atol=1e-9)
def test_two_qubit_consistent(): u = cirq.testing.random_unitary(4) g = cirq.TwoQubitMatrixGate(u) cirq.testing.assert_phase_by_is_consistent_with_unitary(g) cirq.testing.assert_decompose_is_consistent_with_unitary(g) cirq.testing.assert_qasm_is_consistent_with_unitary(g) cirq.testing.assert_has_consistent_apply_unitary(g)
def test_two_qubit_diagram(): a = cirq.NamedQubit('a') b = cirq.NamedQubit('b') c = cirq.NamedQubit('c') c = cirq.Circuit( cirq.TwoQubitMatrixGate(cirq.unitary(cirq.CZ)).on(a, b), cirq.TwoQubitMatrixGate(cirq.unitary(cirq.CZ)).on(c, a)) assert re.match( r""" ┌[ ]+┐ │[0-9\.+\-j ]+│ a: ───│[0-9\.+\-j ]+│───#2─+ │[0-9\.+\-j ]+│ │ │[0-9\.+\-j ]+│ │ └[ ]+┘ │ │[ ]+ │ b: ───#2[─────────]+────┼──+ [ ]+ │ [ ]+ ┌[ ]+┐ [ ]+ │[0-9\.+\-j ]+│ c: ────[──────────]+────│[0-9\.+\-j ]+│──+ [ ]+ │[0-9\.+\-j ]+│ [ ]+ │[0-9\.+\-j ]+│ [ ]+ └[ ]+┘ """.strip(), c.to_text_diagram().strip()) assert re.match( r""" a[ ]+ b c │[ ]+ │ │ ┌[ ]+┐ │ │ │[0-9\.+\-j ]+│ │ │ │[0-9\.+\-j ]+│─#2 │ │[0-9\.+\-j ]+│ │ │ │[0-9\.+\-j ]+│ │ │ └[ ]+┘ │ │ │[ ]+ │ │ │[ ]+ │ ┌[ ]+┐ │[ ]+ │ │[0-9\.+\-j ]+│ #2[─────────]+──┼──│[0-9\.+\-j ]+│ │[ ]+ │ │[0-9\.+\-j ]+│ │[ ]+ │ │[0-9\.+\-j ]+│ │[ ]+ │ └[ ]+┘ │[ ]+ │ │ """.strip(), c.to_text_diagram(transpose=True).strip())
def test_two_qubit_phase_by(): x = np.array([[0, 1], [1, 0]]) y = np.array([[0, -1j], [1j, 0]]) z = np.array([[1, 0], [0, -1]]) xx = cirq.TwoQubitMatrixGate(np.kron(x, x)) yx = cirq.TwoQubitMatrixGate(np.kron(x, y)) xy = cirq.TwoQubitMatrixGate(np.kron(y, x)) yy = cirq.TwoQubitMatrixGate(np.kron(y, y)) assert xx.phase_by(0.25, 0).approx_eq(yx) assert xx.phase_by(0.25, 1).approx_eq(xy) assert xy.phase_by(0.25, 0).approx_eq(yy) assert xy.phase_by(-0.25, 1).approx_eq(xx) zz = cirq.TwoQubitMatrixGate(np.kron(z, z)) assert zz.phase_by(0.25, 0).approx_eq(zz) assert zz.phase_by(0.25, 1).approx_eq(zz)
def circ(v): #Vr = lambda v: ShallowFullStateTensor(2, v) c = cirq.Circuit.from_ops([cirq.TwoQubitMatrixGate(exact_Vr)(*qbs), cirq.inverse(Vr(v)(*qbs))]) sim = cirq.Simulator() ψ = sim.simulate(c).final_state #print(1-np.abs(ψ[0])**2) return 1-np.abs(ψ[0])**2
def test_two_qubit_diagram(): a = cirq.NamedQubit('a') b = cirq.NamedQubit('b') c = cirq.NamedQubit('c') c = cirq.Circuit.from_ops( cirq.TwoQubitMatrixGate(cirq.CZ.matrix()).on(a, b), cirq.TwoQubitMatrixGate(cirq.CZ.matrix()).on(c, a)) assert re.match( """ a: ───┌[ ]+┐───#2─+ │[0-9\\.+\\-j ]+│ │ │[0-9\\.+\\-j ]+│ │ │[0-9\\.+\\-j ]+│ │ │[0-9\\.+\\-j ]+│ │ └[ ]+┘ │ │[ ]+ │ b: ───#2[───────────]+────┼──+ [ ]+ │ c: ────[────────────]+────┌[ ]+┐─── [ ]+ │[0-9\\.+\\-j ]+│ [ ]+ │[0-9\\.+\\-j ]+│ [ ]+ │[0-9\\.+\\-j ]+│ [ ]+ │[0-9\\.+\\-j ]+│ [ ]+ └[ ]+┘ """.strip(), c.to_text_diagram()) assert re.match( """ a[ ]+ b c │[ ]+ │ │ ┌[ ]+┐─#2 │ │[0-9\\.+\\-j ]+│ │ │ │[0-9\\.+\\-j ]+│ │ │ │[0-9\\.+\\-j ]+│ │ │ │[0-9\\.+\\-j ]+│ │ │ └[ ]+┘ │ │ │[ ]+ │ │ #2[───────────]+──┼──┌[ ]+┐ │[ ]+ │ │[0-9\\.+\\-j ]+│ │[ ]+ │ │[0-9\\.+\\-j ]+│ │[ ]+ │ │[0-9\\.+\\-j ]+│ │[ ]+ │ │[0-9\\.+\\-j ]+│ │[ ]+ │ └[ ]+┘ │[ ]+ │ │ """.strip(), c.to_text_diagram(transpose=True))
def test_deprecated(): with capture_logging() as log: _ = cirq.SingleQubitMatrixGate(np.eye(2)) assert len(log) == 1 assert "cirq.SingleQubitMatrixGate" in log[0].getMessage() assert "deprecated" in log[0].getMessage() with capture_logging() as log: _ = cirq.TwoQubitMatrixGate(np.eye(4)) assert len(log) == 1 assert "cirq.TwoQubitMatrixGate" in log[0].getMessage() assert "deprecated" in log[0].getMessage()
def test_QulacsSimulator_TwoQubitMatrixGate(self): qubits = [cirq.LineQubit(i) for i in range(self.qubit_n)] circuit = cirq.Circuit() all_indices = np.arange(self.qubit_n) for _ in range(self.test_repeat): np.random.shuffle(all_indices) index = all_indices[:2] mat = unitary_group.rvs(4) circuit.append( cirq.TwoQubitMatrixGate(mat).on(qubits[index[0]], qubits[index[1]])) self.check_result(circuit)
def test_commutes_on_gates_and_gate_operations(): X, Y, Z = tuple(cirq.unitary(A) for A in (cirq.X, cirq.Y, cirq.Z)) XGate, YGate, ZGate = (cirq.SingleQubitMatrixGate(A) for A in (X, Y, Z)) XXGate, YYGate, ZZGate = (cirq.TwoQubitMatrixGate(cirq.kron(A, A)) for A in (X, Y, Z)) a, b = cirq.LineQubit.range(2) for A in (XGate, YGate, ZGate): assert cirq.commutes(A, A) assert A._commutes_on_qids_(a, A) == None with pytest.raises(TypeError): cirq.commutes(A(a), A) with pytest.raises(TypeError): cirq.commutes(A, A(a)) assert cirq.commutes(A(a), A(a)) assert cirq.commutes(A, XXGate, default='default') == 'default' for A, B in [(XGate, YGate), (XGate, ZGate), (ZGate, YGate), (XGate, cirq.Y), (XGate, cirq.Z), (ZGate, cirq.Y)]: assert not cirq.commutes(A, B) assert cirq.commutes(A(a), B(b)) assert not cirq.commutes(A(a), B(a)) with pytest.raises(TypeError): cirq.commutes(A, B(a)) cirq.testing.assert_commutes_magic_method_consistent_with_unitaries( A, B) for A, B in [(XXGate, YYGate), (XXGate, ZZGate)]: assert cirq.commutes(A, B) with pytest.raises(TypeError): cirq.commutes(A(a, b), B) with pytest.raises(TypeError): cirq.commutes(A, B(a, b)) assert cirq.commutes(A(a, b), B(a, b)) assert cirq.definitely_commutes(A(a, b), B(a, b)) assert (cirq.commutes(A(a, b), B(b, a), default=NotImplemented) == NotImplemented) assert not cirq.definitely_commutes(A(a, b), B(b, a)) cirq.testing.assert_commutes_magic_method_consistent_with_unitaries( A, B) for A, B in [(XGate, XXGate), (XGate, YYGate)]: with pytest.raises(TypeError): cirq.commutes(A, B(a, b)) assert not cirq.definitely_commutes(A, B(a, b)) with pytest.raises(TypeError): assert cirq.commutes(A(b), B) with pytest.raises(TypeError): assert cirq.commutes(A, B) cirq.testing.assert_commutes_magic_method_consistent_with_unitaries( A, B) with pytest.raises(TypeError): assert cirq.commutes(XGate, cirq.X**sympy.Symbol('e')) with pytest.raises(TypeError): assert cirq.commutes(XGate(a), 'Gate') assert cirq.commutes(XGate(a), 'Gate', default='default') == 'default'
def test_random_same_matrix(circuit): a, b = cirq.LineQubit.range(2) same = cirq.Circuit.from_ops( cirq.TwoQubitMatrixGate(circuit.to_unitary_matrix( qubits_that_should_be_present=[a, b])).on(a, b)) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( circuit, same, atol=1e-8) circuit.append(cirq.measure(a)) same.append(cirq.measure(a)) cirq.testing.assert_circuits_with_terminal_measurements_are_equivalent( circuit, same, atol=1e-8)
def unitary_matrix_gate(U): """Creates a Cirq unitary matrix gate from a given matrix. Args: U (numpy.ndarray): an array representing the gate matrix. """ if U.shape == (2, 2): return cirq.SingleQubitMatrixGate(U) if U.shape == (4, 4): return cirq.TwoQubitMatrixGate(U) else: raise qml.DeviceError( "Cirq only supports single-qubit and two-qubit unitary matrix gates. The given matrix had shape {}" .format(U.shape))
def test_trace_distance_bound(): class NoMethod: pass class ReturnsNotImplemented: def _trace_distance_bound_(self): return NotImplemented class ReturnsTwo: def _trace_distance_bound_(self) -> float: return 2.0 class ReturnsConstant: def __init__(self, bound): self.bound = bound def _trace_distance_bound_(self) -> float: return self.bound x = cirq.SingleQubitMatrixGate(cirq.unitary(cirq.X)) cx = cirq.TwoQubitMatrixGate(cirq.unitary(cirq.CX)) cxh = cirq.TwoQubitMatrixGate(cirq.unitary(cirq.CX**0.5)) assert np.isclose(cirq.trace_distance_bound(x), cirq.trace_distance_bound(cirq.X)) assert np.isclose(cirq.trace_distance_bound(cx), cirq.trace_distance_bound(cirq.CX)) assert np.isclose(cirq.trace_distance_bound(cxh), cirq.trace_distance_bound(cirq.CX**0.5)) assert cirq.trace_distance_bound(NoMethod()) == 1.0 assert cirq.trace_distance_bound(ReturnsNotImplemented()) == 1.0 assert cirq.trace_distance_bound(ReturnsTwo()) == 1.0 assert cirq.trace_distance_bound(ReturnsConstant(0.1)) == 0.1 assert cirq.trace_distance_bound(ReturnsConstant(0.5)) == 0.5 assert cirq.trace_distance_bound(ReturnsConstant(1.0)) == 1.0 assert cirq.trace_distance_bound(ReturnsConstant(2.0)) == 1.0
def generate_model_circuit(num_qubits: int, depth: int, *, random_state: Optional[np.random.RandomState] = None ) -> cirq.Circuit: """Generates a model circuit with the given number of qubits and depth. The generated circuit consists of `depth` layers of random qubit permutations followed by random two-qubit gates that are sampled from the Haar measure on SU(4). Args: num_qubits: The number of qubits in the generated circuit. depth: The number of layers in the circuit. random_state: A way to seed the RandomState. Returns: The generated circuit. """ # Setup the circuit and its qubits. qubits = cirq.LineQubit.range(num_qubits) circuit = cirq.Circuit() if random_state is None: random_state = np.random # For each layer. for _ in range(depth): # Generate uniformly random permutation Pj of [0...n-1] perm = random_state.permutation(num_qubits) # For each consecutive pair in Pj, generate Haar random SU(4) # Decompose each SU(4) into CNOT + SU(2) and add to Ci for k in range(0, num_qubits - 1, 2): permuted_indices = [int(perm[k]), int(perm[k + 1])] special_unitary = cirq.testing.random_special_unitary( 4, random_state=random_state) # Convert the decomposed unitary to Cirq operations and add them to # the circuit. circuit.append( cirq.TwoQubitMatrixGate(special_unitary).on( qubits[permuted_indices[0]], qubits[permuted_indices[1]])) # Don't measure all of the qubits at the end of the circuit because we will # need to classically simulate it to compute its heavy set. return circuit
def export_to_cirq(obj): """Imports a gate, operation or circuit from Cirq. Args: obj: the object to be exported to Cirq. Returns: the exported Cirq object (an instance of cirq.Circuit, cirq.GateOperation, or a subclass of cirq.Gate). Raises: TypeError: if export is not supported for the given type. ValueError: if the object cannot be exported successfully. """ if isinstance(obj, circuit.PhasedXGate): return cirq.PhasedXPowGate(exponent=obj.get_rotation_angle() / np.pi, phase_exponent=obj.get_phase_angle() / np.pi) elif isinstance(obj, circuit.RotZGate): return cirq.ZPowGate(exponent=obj.get_rotation_angle() / np.pi) elif isinstance(obj, circuit.ControlledZGate): return cirq.CZPowGate(exponent=1.0) elif isinstance(obj, circuit.MatrixGate): num_qubits = obj.get_num_qubits() operator = obj.get_operator() if num_qubits == 1: return cirq.SingleQubitMatrixGate(operator) elif num_qubits == 2: return cirq.TwoQubitMatrixGate(operator) else: raise ValueError('MatrixGate for %d qubits not supported (Cirq has' ' matrix gates only up to 2 qubits)' % num_qubits) elif isinstance(obj, circuit.Operation): return cirq.GateOperation( export_to_cirq(obj.get_gate()), [cirq.LineQubit(qubit) for qubit in obj.get_qubits()]) elif isinstance(obj, circuit.Circuit): return cirq.Circuit(export_to_cirq(operation) for operation in obj) else: raise TypeError('unknown type: %s' % type(obj).__name__)
def test_allow_partial_czs(): q0, q1 = cirq.LineQubit.range(2) circuit = cirq.Circuit.from_ops(cirq.CZ(q0, q1)**0.5, ) c_orig = cirq.Circuit(circuit) cirq.ConvertToCzAndSingleGates( allow_partial_czs=True).optimize_circuit(circuit) assert circuit == c_orig circuit2 = cirq.Circuit.from_ops( cirq.TwoQubitMatrixGate((np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1j]]))).on(q0, q1)) cirq.ConvertToCzAndSingleGates( allow_partial_czs=True).optimize_circuit(circuit2) two_qubit_ops = list( circuit2.findall_operations(lambda e: len(e.qubits) == 2)) assert len(two_qubit_ops) == 1 gate = two_qubit_ops[0][1].gate assert isinstance(gate, cirq.ops.CZPowGate) and gate.exponent == 0.5
class TestMethods: """Tests the independent methods in the Cirq interface.""" @pytest.mark.parametrize( "U,expected_cirq_operation", [ ( [[1, 0], [0, -1]], cirq.SingleQubitMatrixGate(np.array([[1, 0], [0, -1]])), ), ( [[0, 1j], [-1j, 0]], cirq.SingleQubitMatrixGate(np.array([[0, 1j], [-1j, 0]])), ), ( [[0, 1j, 0, 0], [-1j, 0, 0, 0], [0, 0, 0, 1j], [0, 0, -1j, 0]], cirq.TwoQubitMatrixGate( np.array([[0, 1j, 0, 0], [-1j, 0, 0, 0], [0, 0, 0, 1j], [0, 0, -1j, 0]])), ), ], ) def test_unitary_matrix_gate(self, U, expected_cirq_operation): """Tests that the correct Cirq operation is returned for the unitary matrix gate.""" assert unitary_matrix_gate(np.array(U)) == expected_cirq_operation @pytest.mark.parametrize( "U", [np.eye(6), np.eye(10), np.eye(3), np.eye(3, 5)]) def test_unitary_matrix_gate_error(self, U): """Tests that an error is raised if the given matrix is of wrong format.""" with pytest.raises( qml.DeviceError, match= "Cirq only supports single-qubit and two-qubit unitary matrix gates.", ): unitary_matrix_gate(np.array(U))
def test_two_qubit_eq(): eq = cirq.testing.EqualsTester() eq.make_equality_group(lambda: cirq.TwoQubitMatrixGate(np.eye(4))) eq.make_equality_group(lambda: cirq.TwoQubitMatrixGate(QFT2)) eq.make_equality_group(lambda: cirq.TwoQubitMatrixGate(HH))
def test_two_qubit_init(): x2 = cirq.TwoQubitMatrixGate(QFT2) assert cirq.has_unitary(x2) assert np.alltrue(cirq.unitary(x2) == QFT2)
def test_two_qubit_consistent(): u = cirq.testing.random_unitary(4) g = cirq.TwoQubitMatrixGate(u) cirq.testing.assert_implements_consistent_protocols(g)
def test_str_executes(): assert '1' in str(cirq.SingleQubitMatrixGate(np.eye(2))) assert '0' in str(cirq.TwoQubitMatrixGate(np.eye(4)))
def R(k): p = np.e**((2 * np.pi * 1j) / (2**k)) return cirq.TwoQubitMatrixGate( np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, p]]))
def test_two_qubit_init(): x2 = cirq.TwoQubitMatrixGate(QFT2) assert np.alltrue(x2.matrix() == QFT2)
class TestOperations: """Tests that the CirqDevice correctly handles the requested operations.""" def test_reset_on_empty_circuit(self, cirq_device_1_wire): """Tests that reset resets the internal circuit when it is not initialized.""" assert cirq_device_1_wire.circuit is None cirq_device_1_wire.reset() # Check if circuit is an empty cirq.Circuit assert cirq_device_1_wire.circuit == cirq.Circuit() def test_reset_on_full_circuit(self, cirq_device_1_wire): """Tests that reset resets the internal circuit when it is filled.""" cirq_device_1_wire.pre_apply() cirq_device_1_wire.apply("PauliX", [0], []) # Assert that the queue is filled assert list(cirq_device_1_wire.circuit.all_operations()) cirq_device_1_wire.reset() # Assert that the queue is empty assert not list(cirq_device_1_wire.circuit.all_operations()) def test_pre_apply(self, cirq_device_1_wire): """Tests that pre_apply calls reset.""" cirq_device_1_wire.reset = MagicMock() cirq_device_1_wire.pre_apply() assert cirq_device_1_wire.reset.called # fmt: off @pytest.mark.parametrize("measurement_gate,expected_diagonalization", [ (qml.PauliX(0, do_queue=False), [cirq.H]), (qml.PauliY(0, do_queue=False), [cirq.Z, cirq.S, cirq.H]), (qml.PauliZ(0, do_queue=False), []), (qml.Hadamard(0, do_queue=False), [cirq.Ry(-np.pi / 4)]), ]) # fmt: on def test_pre_measure_single_wire( self, cirq_device_1_wire, measurement_gate, expected_diagonalization ): """Tests that the correct pre-processing is applied in pre_measure.""" cirq_device_1_wire.reset() cirq_device_1_wire._obs_queue = [measurement_gate] cirq_device_1_wire.pre_measure() ops = list(cirq_device_1_wire.circuit.all_operations()) assert len(expected_diagonalization) == len(ops) for i in range(len(expected_diagonalization)): assert ops[i] == expected_diagonalization[i].on(cirq_device_1_wire.qubits[0]) # Note that we DO NOT expect the diagonalization matrices to be the same as you would expect # for the vanilla operators. This is due to the fact that the eigenvalues are listed in ascending # order in the backend. This means if one uses Hermitian(Z), it will actually measure -X.Z.X. # fmt: off @pytest.mark.parametrize("A,U", [ ( [[1, 1j], [-1j, 1]], [[-1 / math.sqrt(2), 1j / math.sqrt(2)], [1 / math.sqrt(2), 1j / math.sqrt(2)]], ), ( [[0, 1], [1, 0]], [[-1 / math.sqrt(2), 1 / math.sqrt(2)], [1 / math.sqrt(2), 1 / math.sqrt(2)]], ), ( [[0, 1j], [-1j, 0]], [[-1 / math.sqrt(2), 1j / math.sqrt(2)], [1 / math.sqrt(2), 1j / math.sqrt(2)]], ), ([[1, 0], [0, -1]], [[0, 1], [1, 0]]), ]) # fmt: on def test_pre_measure_single_wire_hermitian(self, cirq_device_1_wire, tol, A, U): """Tests that the correct pre-processing is applied in pre_measure for single wire hermitian observables.""" cirq_device_1_wire.reset() cirq_device_1_wire._obs_queue = [qml.Hermitian(np.array(A), 0, do_queue=False)] cirq_device_1_wire.pre_measure() ops = list(cirq_device_1_wire.circuit.all_operations()) assert len(ops) == 1 print("Circuit:\n", cirq_device_1_wire.circuit) assert np.allclose(ops[0]._gate._matrix, np.array(U), **tol) # fmt: off @pytest.mark.parametrize("A,U", [ ([ [1, 1j, 0, 0], [-1j, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0] ], [ [0, 0, -1 / math.sqrt(2), 1 / math.sqrt(2)], [-1 / math.sqrt(2), 1j / math.sqrt(2), 0, 0], [0, 0, 1 / math.sqrt(2), 1 / math.sqrt(2)], [1 / math.sqrt(2), 1j / math.sqrt(2), 0, 0], ]) ]) # fmt: on def test_pre_measure_two_wire_hermitian(self, cirq_device_2_wires, tol, A, U): """Tests that the correct pre-processing is applied in pre_measure for two wire hermitian observables.""" cirq_device_2_wires.reset() cirq_device_2_wires._obs_queue = [qml.Hermitian(np.array(A), [0, 1], do_queue=False)] cirq_device_2_wires.pre_measure() ops = list(cirq_device_2_wires.circuit.all_operations()) assert len(ops) == 1 print("Circuit:\n", cirq_device_2_wires.circuit) assert np.allclose(ops[0]._gate._matrix, np.array(U), **tol) def test_hermitian_error(self, cirq_device_3_wires): """Tests that an error is raised for a three-qubit hermitian observable.""" A = np.eye(6) cirq_device_3_wires._obs_queue = [qml.Hermitian(np.array(A), [0, 1, 2], do_queue=False)] with pytest.raises( qml.DeviceError, match="Cirq only supports single-qubit and two-qubit unitary gates and thus only single-qubit and two-qubit Hermitian observables.", ): cirq_device_3_wires.pre_measure() def test_hermitian_matrix_caching(self, cirq_device_1_wire, tol): """Tests that the diagonalizations in pre_measure are properly cached.""" A = np.array([[0, 1], [-1, 0]]) U = np.array([[-1, 1], [1, 1]]) / math.sqrt(2) w = np.array([-1, 1]) cirq_device_1_wire.reset() cirq_device_1_wire._obs_queue = [qml.Hermitian(A, 0, do_queue=False)] with patch("numpy.linalg.eigh", return_value=(w, U)) as mock: cirq_device_1_wire.pre_measure() assert mock.called Hkey = list(cirq_device_1_wire._eigs.keys())[0] assert np.allclose(cirq_device_1_wire._eigs[Hkey]["eigval"], w, **tol) assert np.allclose(cirq_device_1_wire._eigs[Hkey]["eigvec"], U, **tol) with patch("numpy.linalg.eigh", return_value=(w, U)) as mock: cirq_device_1_wire.pre_measure() assert not mock.called # fmt: off @pytest.mark.parametrize( "gate,par,expected_cirq_gates", [ ("PauliX", [], [cirq.X]), ("PauliY", [], [cirq.Y]), ("PauliZ", [], [cirq.Z]), ("Hadamard", [], [cirq.H]), ("S", [], [cirq.S]), ("PhaseShift", [1.4], [cirq.ZPowGate(exponent=1.4 / np.pi)]), ("PhaseShift", [-1.2], [cirq.ZPowGate(exponent=-1.2 / np.pi)]), ("PhaseShift", [2], [cirq.ZPowGate(exponent=2 / np.pi)]), ("RX", [1.4], [cirq.Rx(1.4)]), ("RX", [-1.2], [cirq.Rx(-1.2)]), ("RX", [2], [cirq.Rx(2)]), ("RY", [1.4], [cirq.Ry(1.4)]), ("RY", [0], [cirq.Ry(0)]), ("RY", [-1.3], [cirq.Ry(-1.3)]), ("RZ", [1.4], [cirq.Rz(1.4)]), ("RZ", [-1.1], [cirq.Rz(-1.1)]), ("RZ", [1], [cirq.Rz(1)]), ("Rot", [1.4, 2.3, -1.2], [cirq.Rz(1.4), cirq.Ry(2.3), cirq.Rz(-1.2)]), ("Rot", [1, 2, -1], [cirq.Rz(1), cirq.Ry(2), cirq.Rz(-1)]), ("Rot", [-1.1, 0.2, -1], [cirq.Rz(-1.1), cirq.Ry(0.2), cirq.Rz(-1)]), ( "QubitUnitary", [np.array([[1, 0], [0, 1]])], [cirq.SingleQubitMatrixGate(np.array([[1, 0], [0, 1]]))], ), ( "QubitUnitary", [np.array([[1, 0], [0, -1]])], [cirq.SingleQubitMatrixGate(np.array([[1, 0], [0, -1]]))], ), ( "QubitUnitary", [np.array([[-1, 1], [1, 1]]) / math.sqrt(2)], [cirq.SingleQubitMatrixGate(np.array([[-1, 1], [1, 1]]) / math.sqrt(2))], ), ], ) # fmt: on def test_apply_single_wire(self, cirq_device_1_wire, gate, par, expected_cirq_gates): """Tests that apply adds the correct gates to the circuit for single-qubit gates.""" cirq_device_1_wire.reset() cirq_device_1_wire.apply(gate, wires=[0], par=par) ops = list(cirq_device_1_wire.circuit.all_operations()) assert len(ops) == len(expected_cirq_gates) for i in range(len(ops)): assert ops[i]._gate == expected_cirq_gates[i] # fmt: off @pytest.mark.parametrize("gate,par,expected_cirq_gates", [ ("CNOT", [], [cirq.CNOT]), ("SWAP", [], [cirq.SWAP]), ("CZ", [], [cirq.CZ]), ("CRX", [1.4], [cirq.ControlledGate(cirq.Rx(1.4))]), ("CRX", [-1.2], [cirq.ControlledGate(cirq.Rx(-1.2))]), ("CRX", [2], [cirq.ControlledGate(cirq.Rx(2))]), ("CRY", [1.4], [cirq.ControlledGate(cirq.Ry(1.4))]), ("CRY", [0], [cirq.ControlledGate(cirq.Ry(0))]), ("CRY", [-1.3], [cirq.ControlledGate(cirq.Ry(-1.3))]), ("CRZ", [1.4], [cirq.ControlledGate(cirq.Rz(1.4))]), ("CRZ", [-1.1], [cirq.ControlledGate(cirq.Rz(-1.1))]), ("CRZ", [1], [cirq.ControlledGate(cirq.Rz(1))]), ("CRot", [1.4, 2.3, -1.2], [ cirq.ControlledGate(cirq.Rz(1.4)), cirq.ControlledGate(cirq.Ry(2.3)), cirq.ControlledGate(cirq.Rz(-1.2)), ], ), ("CRot", [1, 2, -1], [ cirq.ControlledGate(cirq.Rz(1)), cirq.ControlledGate(cirq.Ry(2)), cirq.ControlledGate(cirq.Rz(-1)), ], ), ("CRot", [-1.1, 0.2, -1], [ cirq.ControlledGate(cirq.Rz(-1.1)), cirq.ControlledGate(cirq.Ry(0.2)), cirq.ControlledGate(cirq.Rz(-1)), ], ), ("QubitUnitary", [np.eye(4)], [cirq.TwoQubitMatrixGate(np.eye(4))]), ( "QubitUnitary", [np.array([[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]])], [ cirq.TwoQubitMatrixGate( np.array([[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]]) ) ], ), ( "QubitUnitary", [np.array([[1, -1, -1, 1], [-1, -1, 1, 1], [-1, 1, -1, 1], [1, 1, 1, 1]]) / 2], [ cirq.TwoQubitMatrixGate( np.array([[1, -1, -1, 1], [-1, -1, 1, 1], [-1, 1, -1, 1], [1, 1, 1, 1]]) / 2 ) ], ), ]) # fmt: on def test_apply_two_wires(self, cirq_device_2_wires, gate, par, expected_cirq_gates): """Tests that apply adds the correct gates to the circuit for two-qubit gates.""" cirq_device_2_wires.reset() cirq_device_2_wires.apply(gate, wires=[0, 1], par=par) ops = list(cirq_device_2_wires.circuit.all_operations()) assert len(ops) == len(expected_cirq_gates) for i in range(len(ops)): assert ops[i].gate == expected_cirq_gates[i]
def test_two_qubit_matrix_gate(): u = cirq.testing.random_unitary(4) g = cirq.TwoQubitMatrixGate(u) cirq.testing.assert_equivalent_repr(g)
cirq.S, 'SWAP': cirq.SWAP, 'SingleQubitPauliStringGateOperation': cirq.X(Q0), 'SwapPowGate': [cirq.SwapPowGate(), cirq.SWAP**0.5], 'SYC': cirq.google.SYC, 'SycamoreGate': cirq.google.SycamoreGate(), 'T': cirq.T, 'TOFFOLI': cirq.TOFFOLI, 'TwoQubitMatrixGate': cirq.TwoQubitMatrixGate(np.eye(4)), 'UNCONSTRAINED_DEVICE': cirq.UNCONSTRAINED_DEVICE, 'WaitGate': cirq.WaitGate(cirq.Duration(nanos=10)), '_QubitAsQid': [ cirq.NamedQubit('a').with_dimension(5), cirq.GridQubit(1, 2).with_dimension(1) ], 'XPowGate': cirq.X**0.123, 'XX': cirq.XX, 'XXPowGate': [cirq.XXPowGate(), cirq.XX**0.123], 'YPowGate': cirq.Y**0.456,
def test_repr(): assert repr(cirq.SingleQubitMatrixGate(np.eye(2))) == \ 'cirq.SingleQubitMatrixGate({})'.format(repr(np.eye(2))) assert repr(cirq.TwoQubitMatrixGate(np.eye(4))) == \ 'cirq.TwoQubitMatrixGate({})'.format(repr(np.eye(4)))