Exemple #1
0
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))
Exemple #2
0
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)
Exemple #3
0
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')
Exemple #4
0
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')
Exemple #5
0
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)
Exemple #6
0
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)
Exemple #7
0
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())
Exemple #8
0
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)
Exemple #9
0
 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
Exemple #10
0
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))
Exemple #11
0
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()
Exemple #12
0
 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)
Exemple #13
0
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)
Exemple #15
0
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
Exemple #17
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
Exemple #18
0
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
Exemple #20
0
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))
Exemple #21
0
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))
Exemple #22
0
def test_two_qubit_init():
    x2 = cirq.TwoQubitMatrixGate(QFT2)
    assert cirq.has_unitary(x2)
    assert np.alltrue(cirq.unitary(x2) == QFT2)
Exemple #23
0
def test_two_qubit_consistent():
    u = cirq.testing.random_unitary(4)
    g = cirq.TwoQubitMatrixGate(u)
    cirq.testing.assert_implements_consistent_protocols(g)
Exemple #24
0
def test_str_executes():
    assert '1' in str(cirq.SingleQubitMatrixGate(np.eye(2)))
    assert '0' in str(cirq.TwoQubitMatrixGate(np.eye(4)))
Exemple #25
0
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]]))
Exemple #26
0
def test_two_qubit_init():
    x2 = cirq.TwoQubitMatrixGate(QFT2)
    assert np.alltrue(x2.matrix() == QFT2)
Exemple #27
0
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]
Exemple #28
0
def test_two_qubit_matrix_gate():
    u = cirq.testing.random_unitary(4)
    g = cirq.TwoQubitMatrixGate(u)
    cirq.testing.assert_equivalent_repr(g)
Exemple #29
0
 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,
Exemple #30
0
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)))