Пример #1
0
def test_pass_operations_over_double(shift, t_or_f1, t_or_f2, neg):
    q0, q1, q2 = _make_qubits(3)
    X, Y, Z = (pauli + shift for pauli in Pauli.XYZ)

    op0 = PauliInteractionGate(Z, t_or_f1, X, t_or_f2)(q0, q1)
    ps_before = PauliString({q0: Z, q2: Y}, neg)
    ps_after = PauliString({q0: Z, q2: Y}, neg)
    _assert_pass_over([op0], ps_before, ps_after)

    op0 = PauliInteractionGate(Y, t_or_f1, X, t_or_f2)(q0, q1)
    ps_before = PauliString({q0: Z, q2: Y}, neg)
    ps_after = PauliString({q0: Z, q2: Y, q1: X}, neg)
    _assert_pass_over([op0], ps_before, ps_after)

    op0 = PauliInteractionGate(Z, t_or_f1, X, t_or_f2)(q0, q1)
    ps_before = PauliString({q0: Z, q1: Y}, neg)
    ps_after = PauliString({q1: Y}, neg)
    _assert_pass_over([op0], ps_before, ps_after)

    op0 = PauliInteractionGate(Y, t_or_f1, X, t_or_f2)(q0, q1)
    ps_before = PauliString({q0: Z, q1: Y}, neg)
    ps_after = PauliString({q0: X, q1: Z}, neg ^ t_or_f1 ^ t_or_f2)
    _assert_pass_over([op0], ps_before, ps_after)

    op0 = PauliInteractionGate(X, t_or_f1, X, t_or_f2)(q0, q1)
    ps_before = PauliString({q0: Z, q1: Y}, neg)
    ps_after = PauliString({q0: Y, q1: Z}, not neg ^ t_or_f1 ^ t_or_f2)
    _assert_pass_over([op0], ps_before, ps_after)
Пример #2
0
def test_get(qubit_pauli_map):
    other = cirq.NamedQubit('other')
    pauli_string = PauliString(qubit_pauli_map)
    for key in qubit_pauli_map:
        assert qubit_pauli_map.get(key) == pauli_string.get(key)
    assert qubit_pauli_map.get(other) == pauli_string.get(other) == None
    assert qubit_pauli_map.get(other, 5) == pauli_string.get(other, 5) == 5
Пример #3
0
def test_zip_paulis(map1, map2, out):
    ps1 = PauliString(map1)
    ps2 = PauliString(map2)
    out_actual = tuple(ps1.zip_paulis(ps2))
    assert len(out_actual) == len(out)
    if len(out) <= 1:
        assert out_actual == out
    assert set(out_actual) == set(out)  # Ignore output order
Пример #4
0
def test_repr():
    q0, q1, q2 = _make_qubits(3)
    pauli_string = PauliString({q2: Pauli.X, q1: Pauli.Y, q0: Pauli.Z})
    assert (repr(pauli_string) == "PauliString({NamedQubit('q0'): Pauli.Z, "
            "NamedQubit('q1'): Pauli.Y, NamedQubit('q2'): Pauli.X}, False)")
    assert (repr(
        pauli_string.negate()) == "PauliString({NamedQubit('q0'): Pauli.Z, "
            "NamedQubit('q1'): Pauli.Y, NamedQubit('q2'): Pauli.X}, True)")
Пример #5
0
def test_map_qubits():
    a, b = (cirq.NamedQubit(name) for name in 'ab')
    q0, q1 = _make_qubits(2)
    qubit_pauli_map1 = {a: Pauli.X, b: Pauli.Y}
    qubit_pauli_map2 = {q0: Pauli.X, q1: Pauli.Y}
    qubit_map = {a: q0, b: q1}
    ps1 = PauliString(qubit_pauli_map1)
    ps2 = PauliString(qubit_pauli_map2)
    assert ps1.map_qubits(qubit_map) == ps2
Пример #6
0
def test_manual_default_decompose():
    q0, q1, q2 = _make_qubits(3)

    mat = cirq.Circuit.from_ops(
        PauliStringPhasor(PauliString({q0: Pauli.Z}))**0.25,
        cirq.Z(q0)**-0.25,
    ).to_unitary_matrix()
    cirq.testing.assert_allclose_up_to_global_phase(mat,
                                                    np.eye(2),
                                                    rtol=1e-7,
                                                    atol=1e-7)

    mat = cirq.Circuit.from_ops(
        PauliStringPhasor(PauliString({q0: Pauli.Y}))**0.25,
        cirq.Y(q0)**-0.25,
    ).to_unitary_matrix()
    cirq.testing.assert_allclose_up_to_global_phase(mat,
                                                    np.eye(2),
                                                    rtol=1e-7,
                                                    atol=1e-7)

    mat = cirq.Circuit.from_ops(
        PauliStringPhasor(PauliString({
            q0: Pauli.Z,
            q1: Pauli.Z,
            q2: Pauli.Z
        }))).to_unitary_matrix()
    cirq.testing.assert_allclose_up_to_global_phase(
        mat, np.diag([1, -1, -1, 1, -1, 1, 1, -1]), rtol=1e-7, atol=1e-7)

    mat = cirq.Circuit.from_ops(
        PauliStringPhasor(PauliString({
            q0: Pauli.Z,
            q1: Pauli.Y,
            q2: Pauli.X
        }))**0.5).to_unitary_matrix()
    cirq.testing.assert_allclose_up_to_global_phase(
        mat,
        np.array([
            [1, 0, 0, -1, 0, 0, 0, 0],
            [0, 1, -1, 0, 0, 0, 0, 0],
            [0, 1, 1, 0, 0, 0, 0, 0],
            [1, 0, 0, 1, 0, 0, 0, 0],
            [0, 0, 0, 0, 1, 0, 0, 1],
            [0, 0, 0, 0, 0, 1, 1, 0],
            [0, 0, 0, 0, 0, -1, 1, 0],
            [0, 0, 0, 0, -1, 0, 0, 1],
        ]) / np.sqrt(2),
        rtol=1e-7,
        atol=1e-7)
Пример #7
0
def test_decompose_with_symbol():
    q0, = _make_qubits(1)
    ps = PauliString({q0: Pauli.Y})
    op = PauliStringPhasor(ps, half_turns=cirq.value.Symbol('a'))
    circuit = cirq.Circuit.from_ops(op)
    cirq.ExpandComposite().optimize_circuit(circuit)
    assert circuit.to_text_diagram() == "q0: ───X^0.5───Z^a───X^-0.5───"

    ps = PauliString({q0: Pauli.Y}, True)
    op = PauliStringPhasor(ps, half_turns=cirq.value.Symbol('a'))
    circuit = cirq.Circuit.from_ops(op)
    cirq.ExpandComposite().optimize_circuit(circuit)
    assert circuit.to_text_diagram(
    ) == "q0: ───X^0.5───X───Z^a───X───X^-0.5───"
Пример #8
0
def test_map_qubits():
    q0, q1, q2, q3 = _make_qubits(4)
    qubit_map = {q1: q2, q0: q3}
    before = PauliStringPhasor(PauliString({
        q0: Pauli.Z,
        q1: Pauli.Y
    }),
                               half_turns=0.1)
    after = PauliStringPhasor(PauliString({
        q3: Pauli.Z,
        q2: Pauli.Y
    }),
                              half_turns=0.1)
    assert before.map_qubits(qubit_map) == after
Пример #9
0
def test_drop_negligible():
    q0, = _make_qubits(1)
    sym = cirq.value.Symbol('a')
    circuit = cirq.Circuit.from_ops(
        PauliStringPhasor(PauliString({q0: Pauli.Z}))**0.25,
        PauliStringPhasor(PauliString({q0: Pauli.Z}))**1e-10,
        PauliStringPhasor(PauliString({q0: Pauli.Z}))**sym,
    )
    expected = cirq.Circuit.from_ops(
        PauliStringPhasor(PauliString({q0: Pauli.Z}))**0.25,
        PauliStringPhasor(PauliString({q0: Pauli.Z}))**sym,
    )
    cirq.DropNegligible().optimize_circuit(circuit)
    cirq.DropEmptyMoments().optimize_circuit(circuit)
    assert circuit == expected
Пример #10
0
def test_default_decompose(paulis, half_turns, neg):
    paulis = [pauli for pauli in paulis if pauli is not None]
    qubits = _make_qubits(len(paulis))

    # Get matrix from decomposition
    pauli_string = PauliString({q: p for q, p in zip(qubits, paulis)}, neg)
    actual = cirq.Circuit.from_ops(
        PauliStringPhasor(pauli_string,
                          half_turns=half_turns)).to_unitary_matrix()

    # Calculate expected matrix
    to_z_mats = {
        Pauli.X: (cirq.Y**-0.5).matrix(),
        Pauli.Y: (cirq.X**0.5).matrix(),
        Pauli.Z: np.eye(2)
    }
    expected_convert = np.eye(1)
    for pauli in paulis:
        expected_convert = np.kron(expected_convert, to_z_mats[pauli])
    t = 1j**(half_turns * 2 * (-1 if neg else 1))
    expected_z = np.diag([1, t, t, 1, t, 1, 1, t][:2**len(paulis)])
    expected = expected_convert.T.conj().dot(expected_z).dot(expected_convert)

    cirq.testing.assert_allclose_up_to_global_phase(actual,
                                                    expected,
                                                    rtol=1e-7,
                                                    atol=1e-7)
Пример #11
0
def pauli_string_to_z_ops(
        pauli_string: PauliString) -> Iterable[ops.Operation]:
    """Yields the single qubit operations to apply before a Pauli string of Zs
    (and apply the inverse of these operations after) to make it equivalent to
    the given pauli_string."""
    for qubit, pauli in pauli_string.items():
        yield CliffordGate.from_single_map({pauli: (Pauli.Z, False)})(qubit)
Пример #12
0
def test_str():
    q0, q1, q2 = _make_qubits(3)
    ps = PauliStringPhasor(
        PauliString({
            q2: Pauli.Z,
            q1: Pauli.Y,
            q0: Pauli.X
        }, False))**0.5
    assert (str(ps) == '{+, q0:X, q1:Y, q2:Z}**0.5')

    ps = PauliStringPhasor(
        PauliString({
            q2: Pauli.Z,
            q1: Pauli.Y,
            q0: Pauli.X
        }, True))**-0.5
    assert (str(ps) == '{-, q0:X, q1:Y, q2:Z}**-0.5')
Пример #13
0
def test_getitem(qubit_pauli_map):
    other = cirq.NamedQubit('other')
    pauli_string = PauliString(qubit_pauli_map)
    for key in qubit_pauli_map:
        assert qubit_pauli_map[key] == pauli_string[key]
    with pytest.raises(KeyError):
        _ = qubit_pauli_map[other]
    with pytest.raises(KeyError):
        _ = pauli_string[other]
Пример #14
0
def test_repr():
    q0, q1, q2 = _make_qubits(3)
    ps = PauliStringPhasor(PauliString({
        q2: Pauli.Z,
        q1: Pauli.Y,
        q0: Pauli.X
    }))**0.5
    assert (
        repr(ps) == 'PauliStringPhasor({+, q0:X, q1:Y, q2:Z}, half_turns=0.5)')

    ps = PauliStringPhasor(
        PauliString({
            q2: Pauli.Z,
            q1: Pauli.Y,
            q0: Pauli.X
        }, True))**-0.5
    assert (repr(ps) ==
            'PauliStringPhasor({-, q0:X, q1:Y, q2:Z}, half_turns=-0.5)')
Пример #15
0
def test_negate():
    q0, q1 = _make_qubits(2)
    qubit_pauli_map = {q0: Pauli.X, q1: Pauli.Y}
    ps1 = PauliString(qubit_pauli_map)
    ps2 = PauliString(qubit_pauli_map, True)
    assert ps1.negate() == -ps1 == ps2
    assert ps1 == ps2.negate() == -ps2
    assert ps1.negate().negate() == ps1
Пример #16
0
def test_try_cast_to():
    class Dummy:
        pass

    op = PauliStringPhasor(PauliString({}))
    ext = cirq.Extensions()
    assert not op.try_cast_to(cirq.CompositeOperation, ext) is None
    assert not op.try_cast_to(cirq.BoundedEffect, ext) is None
    assert not op.try_cast_to(cirq.ParameterizableEffect, ext) is None
    assert not op.try_cast_to(cirq.ExtrapolatableEffect, ext) is None
    assert not op.try_cast_to(cirq.ReversibleEffect, ext) is None
    assert op.try_cast_to(Dummy, ext) is None

    op = PauliStringPhasor(PauliString({}), half_turns=cirq.value.Symbol('a'))
    ext = cirq.Extensions()
    assert not op.try_cast_to(cirq.CompositeOperation, ext) is None
    assert not op.try_cast_to(cirq.BoundedEffect, ext) is None
    assert not op.try_cast_to(cirq.ParameterizableEffect, ext) is None
    assert op.try_cast_to(cirq.ExtrapolatableEffect, ext) is None
    assert op.try_cast_to(cirq.ReversibleEffect, ext) is None
    assert op.try_cast_to(Dummy, ext) is None
Пример #17
0
def test_text_diagram():
    q0, q1, q2 = _make_qubits(3)
    circuit = cirq.Circuit.from_ops(
        PauliStringPhasor(PauliString({q0: Pauli.Z})),
        PauliStringPhasor(PauliString({q0: Pauli.Y}))**0.25,
        PauliStringPhasor(PauliString({
            q0: Pauli.Z,
            q1: Pauli.Z,
            q2: Pauli.Z
        })),
        PauliStringPhasor(
            PauliString({
                q0: Pauli.Z,
                q1: Pauli.Y,
                q2: Pauli.X
            }, True))**0.5,
        PauliStringPhasor(PauliString({
            q0: Pauli.Z,
            q1: Pauli.Y,
            q2: Pauli.X
        }),
                          half_turns=cirq.value.Symbol('a')),
        PauliStringPhasor(PauliString({
            q0: Pauli.Z,
            q1: Pauli.Y,
            q2: Pauli.X
        }, True),
                          half_turns=cirq.value.Symbol('b')))
    assert circuit.to_text_diagram() == """
q0: ───[Z]───[Y]^0.25───[Z]───[Z]────────[Z]─────[Z]──────
                        │     │          │       │
q1: ────────────────────[Z]───[Y]────────[Y]─────[Y]──────
                        │     │          │       │
q2: ────────────────────[Z]───[X]^-0.5───[X]^a───[X]^-b───
""".strip()
Пример #18
0
def test_default_text_diagram():
    class DiagramGate(PauliStringGateOperation, cirq.TextDiagrammable):
        def map_qubits(self, qubit_map):
            pass

        def text_diagram_info(
                self, args: cirq.TextDiagramInfoArgs) -> cirq.TextDiagramInfo:
            return self._pauli_string_diagram_info(args)

    q0, q1, q2 = _make_qubits(3)
    ps = PauliString({q0: Pauli.X, q1: Pauli.Y, q2: Pauli.Z})

    circuit = cirq.Circuit.from_ops(
        DiagramGate(ps),
        DiagramGate(ps.negate()),
    )
    assert circuit.to_text_diagram() == """
q0: ───[X]───[X]───
       │     │
q1: ───[Y]───[Y]───
       │     │
q2: ───[Z]───[Z]───
""".strip()
Пример #19
0
def test_eq_ne_hash():
    q0, q1, q2 = _make_qubits(3)
    eq = EqualsTester()
    eq.make_equality_group(lambda: PauliString({}),
                           lambda: PauliString({}, False))
    eq.add_equality_group(PauliString({}, True))
    for q, pauli in itertools.product((q0, q1), Pauli.XYZ):
        eq.add_equality_group(PauliString({q: pauli}, False))
        eq.add_equality_group(PauliString({q: pauli}, True))
    for q, p0, p1 in itertools.product((q0, q1), Pauli.XYZ, Pauli.XYZ):
        eq.add_equality_group(PauliString({q: p0, q2: p1}, False))
Пример #20
0
def test_on_wrong_number_qubits():
    q0, q1, q2 = _make_qubits(3)

    class DummyGate(PauliStringGateOperation):
        def map_qubits(self, qubit_map):
            ps = self.pauli_string.map_qubits(qubit_map)
            return DummyGate(ps)

    g = DummyGate(PauliString({q0: Pauli.X, q1: Pauli.Y}))

    _ = g.with_qubits(q1, q2)
    with pytest.raises(ValueError):
        _ = g.with_qubits()
    with pytest.raises(ValueError):
        _ = g.with_qubits(q2)
    with pytest.raises(ValueError):
        _ = g.with_qubits(q0, q1, q2)
Пример #21
0
def test_op_calls_validate():
    q0, q1, q2 = _make_qubits(3)
    bad_qubit = cirq.NamedQubit('bad')

    class ValidError(Exception):
        pass

    class ValiGate(PauliStringGateOperation):
        def validate_args(self, qubits):
            super().validate_args(qubits)
            if bad_qubit in qubits:
                raise ValidError()

        def map_qubits(self, qubit_map):
            ps = self.pauli_string.map_qubits(qubit_map)
            return ValiGate(ps)

    g = ValiGate(PauliString({q0: Pauli.X, q1: Pauli.Y, q2: Pauli.Z}))

    _ = g.with_qubits(q1, q0, q2)
    with pytest.raises(ValidError):
        _ = g.with_qubits(q0, q1, bad_qubit)
Пример #22
0
def test_extrapolate_effect_with_symbol():
    eq = cirq.testing.EqualsTester()
    eq.add_equality_group(
        PauliStringPhasor(PauliString({}), half_turns=cirq.value.Symbol('a')),
        PauliStringPhasor(PauliString({}))**cirq.value.Symbol('a'))
    eq.add_equality_group(
        PauliStringPhasor(PauliString({}))**cirq.value.Symbol('b'))
    with pytest.raises(ValueError):
        _ = PauliStringPhasor(PauliString({}),
                              half_turns=0.5)**cirq.value.Symbol('b')
    with pytest.raises(ValueError):
        _ = PauliStringPhasor(PauliString({}),
                              half_turns=cirq.value.Symbol('a'))**0.5
    with pytest.raises(ValueError):
        _ = PauliStringPhasor(
            PauliString({}),
            half_turns=cirq.value.Symbol('a'))**cirq.value.Symbol('b')
Пример #23
0
def test_inverse():
    op1 = PauliStringPhasor(PauliString({}), half_turns=0.25)
    op2 = PauliStringPhasor(PauliString({}), half_turns=-0.25)
    assert op1.inverse() == op2
Пример #24
0
def test_extrapolate_effect():
    op1 = PauliStringPhasor(PauliString({}), half_turns=0.5)
    op2 = PauliStringPhasor(PauliString({}), half_turns=1.5)
    op3 = PauliStringPhasor(PauliString({}), half_turns=0.125)
    assert op1**3 == op2
    assert op1**0.25 == op3
Пример #25
0
def test_eq_ne_hash():
    q0, q1, q2 = _make_qubits(3)
    eq = cirq.testing.EqualsTester()
    ps1 = PauliString({q0: Pauli.X, q1: Pauli.Y, q2: Pauli.Z})
    ps2 = PauliString({q0: Pauli.X, q1: Pauli.Y, q2: Pauli.X})
    eq.make_equality_group(
        lambda: PauliStringPhasor(PauliString({}), half_turns=0.5),
        lambda: PauliStringPhasor(PauliString({}), half_turns=-1.5),
        lambda: PauliStringPhasor(PauliString({}), half_turns=2.5))
    eq.make_equality_group(
        lambda: PauliStringPhasor(PauliString({}, True), half_turns=-0.5))
    eq.add_equality_group(PauliStringPhasor(ps1),
                          PauliStringPhasor(ps1, half_turns=1))
    eq.add_equality_group(PauliStringPhasor(ps1.negate(), half_turns=1))
    eq.add_equality_group(PauliStringPhasor(ps2),
                          PauliStringPhasor(ps2, half_turns=1))
    eq.add_equality_group(PauliStringPhasor(ps2.negate(), half_turns=1))
    eq.add_equality_group(PauliStringPhasor(ps2, half_turns=0.5))
    eq.add_equality_group(PauliStringPhasor(ps2.negate(), half_turns=-0.5))
    eq.add_equality_group(
        PauliStringPhasor(ps1, half_turns=cirq.value.Symbol('a')))
Пример #26
0
def test_from_single(pauli):
    q0, = _make_qubits(1)
    assert PauliString.from_single(q0, pauli) == PauliString({q0: pauli})
Пример #27
0
def test_contains(qubit_pauli_map):
    other = cirq.NamedQubit('other')
    pauli_string = PauliString(qubit_pauli_map)
    for key in qubit_pauli_map:
        assert key in pauli_string
    assert other not in pauli_string
Пример #28
0
def test_keys(qubit_pauli_map):
    pauli_string = PauliString(qubit_pauli_map)
    assert (len(qubit_pauli_map.keys()) == len(pauli_string.keys()) == len(
        pauli_string.qubits()))
    assert (set(qubit_pauli_map.keys()) == set(pauli_string.keys()) == set(
        pauli_string.qubits()))
Пример #29
0
def test_with_parameters_resolved_by():
    op = PauliStringPhasor(PauliString({}), half_turns=cirq.value.Symbol('a'))
    resolver = cirq.study.ParamResolver({'a': 0.1})
    actual = op.with_parameters_resolved_by(resolver)
    expected = PauliStringPhasor(PauliString({}), half_turns=0.1)
    assert actual == expected
Пример #30
0
def test_is_parametrized():
    op = PauliStringPhasor(PauliString({}))
    assert not op.is_parameterized()
    assert not (op**0.1).is_parameterized()
    assert (op**cirq.value.Symbol('a')).is_parameterized()