예제 #1
0
def test_pass_operations_over_single(shift, t_or_f):
    q0, q1 = _make_qubits(2)
    X, Y, Z = (pauli + shift for pauli in Pauli.XYZ)

    op0 = CliffordGate.from_pauli(Y)(q1)
    ps_before = PauliString({q0: X}, t_or_f)
    ps_after = ps_before
    _assert_pass_over([op0], ps_before, ps_after)

    op0 = CliffordGate.from_pauli(X)(q0)
    op1 = CliffordGate.from_pauli(Y)(q1)
    ps_before = PauliString({q0: X, q1: Y}, t_or_f)
    ps_after = ps_before
    _assert_pass_over([op0, op1], ps_before, ps_after)

    op0 = CliffordGate.from_double_map({Z: (X, False), X: (Z, False)})(q0)
    ps_before = PauliString({q0: X, q1: Y}, t_or_f)
    ps_after = PauliString({q0: Z, q1: Y}, t_or_f)
    _assert_pass_over([op0], ps_before, ps_after)

    op1 = CliffordGate.from_pauli(X)(q1)
    ps_before = PauliString({q0: X, q1: Y}, t_or_f)
    ps_after = ps_before.negate()
    _assert_pass_over([op1], ps_before, ps_after)

    ps_after = PauliString({q0: Z, q1: Y}, not t_or_f)
    _assert_pass_over([op0, op1], ps_before, ps_after)
예제 #2
0
def test_init_from_double_map_vs_kwargs(trans1, trans2, from1):
    from2 = from1 + 1
    from1_str, from2_str = (str(frm).lower() + '_to' for frm in (from1, from2))
    gate_kw = CliffordGate.from_double_map(**{
        from1_str: trans1,
        from2_str: trans2
    })
    gate_map = CliffordGate.from_double_map({from1: trans1, from2: trans2})
    # Test initializes the same gate
    assert gate_kw == gate_map
예제 #3
0
 def _pass_single_clifford_gate_over(pauli_map: Dict[ops.QubitId, Pauli],
                                     gate: CliffordGate,
                                     qubit: ops.QubitId,
                                     after_to_before: bool = False) -> bool:
     if qubit not in pauli_map:
         return False
     if not after_to_before:
         gate = gate.inverse()
     pauli, inv = gate.transform(pauli_map[qubit])
     pauli_map[qubit] = pauli
     return inv
예제 #4
0
 def default_decompose(
         self, qubits: Sequence[ops.QubitId]) -> ops.op_tree.OP_TREE:
     q0, q1 = qubits
     right_gate0 = CliffordGate.from_single_map(z_to=(self.pauli0,
                                                      self.invert0))
     right_gate1 = CliffordGate.from_single_map(z_to=(self.pauli1,
                                                      self.invert1))
     left_gate0 = right_gate0.inverse()
     left_gate1 = right_gate1.inverse()
     yield left_gate0(q0)
     yield left_gate1(q1)
     yield ops.Rot11Gate(half_turns=self._exponent)(q0, q1)
     yield right_gate0(q0)
     yield right_gate1(q1)
예제 #5
0
def test_init_90rot_from_single(trans, frm):
    gate = CliffordGate.from_single_map({frm: trans})
    assert gate.transform(frm) == trans
    _assert_not_mirror(gate)
    _assert_no_collision(gate)
    # Check that it decomposes to one gate
    assert len(gate.decompose_rotation()) == 1
    # Check that this is a 90 degree rotation gate
    assert (gate.merged_with(gate).merged_with(gate).merged_with(gate) ==
            CliffordGate.I)
    # Check that flipping the transform produces the inverse rotation
    trans_rev = PauliTransform(trans.to, not trans.flip)
    gate_rev = CliffordGate.from_single_map({frm: trans_rev})
    assert gate.inverse() == gate_rev
예제 #6
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)
예제 #7
0
def test_init_from_double(trans1, trans2, from1):
    from2 = from1 + 1
    gate = CliffordGate.from_double_map({from1: trans1, from2: trans2})
    # Test initializes what was expected
    assert gate.transform(from1) == trans1
    assert gate.transform(from2) == trans2
    _assert_not_mirror(gate)
    _assert_no_collision(gate)
예제 #8
0
def test_init_ident_from_single(trans, frm):
    gate = CliffordGate.from_single_map({frm: trans})
    assert gate.transform(frm) == trans
    _assert_not_mirror(gate)
    _assert_no_collision(gate)
    # Check that it decomposes to zero gates
    assert len(gate.decompose_rotation()) == 0
    # Check that this is an identity gate
    assert gate == CliffordGate.I
예제 #9
0
def test_init_180rot_from_single(trans, frm):
    gate = CliffordGate.from_single_map({frm: trans})
    assert gate.transform(frm) == trans
    _assert_not_mirror(gate)
    _assert_no_collision(gate)
    # Check that it decomposes to one gate
    assert len(gate.decompose_rotation()) == 1
    # Check that this is a 180 degree rotation gate
    assert gate.merged_with(gate) == CliffordGate.I
예제 #10
0
def test_init_from_xz(trans_x, trans_z):
    gate = CliffordGate.from_xz_map(trans_x, trans_z)
    assert gate.transform(Pauli.X) == trans_x
    assert gate.transform(Pauli.Z) == trans_z
    _assert_not_mirror(gate)
    _assert_no_collision(gate)
예제 #11
0
def test_init_value_error(pauli, flip_x, flip_z):
    with pytest.raises(ValueError):
        CliffordGate.from_xz_map((pauli, flip_x), (pauli, flip_z))
예제 #12
0
def _all_clifford_gates():
    for trans_x, trans_z in _all_rotation_pairs():
        yield CliffordGate.from_xz_map(trans_x, trans_z)
예제 #13
0
def test_eq_ne_and_hash():
    eq = EqualsTester()
    for trans_x, trans_z in _all_rotation_pairs():
        gate_gen = lambda: CliffordGate.from_xz_map(trans_x, trans_z)
        eq.make_equality_group(gate_gen)
예제 #14
0
def test_init_invalid():
    with pytest.raises(ValueError):
        CliffordGate.from_single_map()
    with pytest.raises(ValueError):
        CliffordGate.from_single_map({})
    with pytest.raises(ValueError):
        CliffordGate.from_single_map({Pauli.X: (Pauli.X, False)},
                                     y_to=(Pauli.Y, False))
    with pytest.raises(ValueError):
        CliffordGate.from_single_map({
            Pauli.X: (Pauli.X, False),
            Pauli.Y: (Pauli.Y, False)
        })
    with pytest.raises(ValueError):
        CliffordGate.from_double_map()
    with pytest.raises(ValueError):
        CliffordGate.from_double_map({})
    with pytest.raises(ValueError):
        CliffordGate.from_double_map({Pauli.X: (Pauli.X, False)})
    with pytest.raises(ValueError):
        CliffordGate.from_double_map(x_to=(Pauli.X, False))
    with pytest.raises(ValueError):
        CliffordGate.from_single_map({
            Pauli.X: (Pauli.Y, False),
            Pauli.Y: (Pauli.Z, False),
            Pauli.Z: (Pauli.X, False)
        })
    with pytest.raises(ValueError):
        CliffordGate.from_single_map({
            Pauli.X: (Pauli.X, False),
            Pauli.Y: (Pauli.X, False)
        })
예제 #15
0
def test_init_from_pauli(pauli, sqrt, expected):
    gate = CliffordGate.from_pauli(pauli, sqrt=sqrt)
    assert gate == expected
예제 #16
0
    mat = cirq.Circuit.from_ops(
        gate(q0),
        other(q0),
    ).to_unitary_matrix()
    mat_swap = cirq.Circuit.from_ops(
        gate.equivalent_gate_before(other)(q0),
        gate(q0),
    ).to_unitary_matrix()
    assert_allclose_up_to_global_phase(mat, mat_swap)


@pytest.mark.parametrize('gate,sym',
                         ((CliffordGate.I, 'I'), (CliffordGate.H, 'H'),
                          (CliffordGate.X, 'X'), (CliffordGate.X_sqrt, 'X'),
                          (CliffordGate.X_nsqrt, 'X'),
                          (CliffordGate.from_xz_map(
                              (Pauli.Y, False),
                              (Pauli.X, True)), 'X^-0.5-Z^0.5')))
def test_text_diagram_wire_symbols(gate, sym):
    assert gate.text_diagram_wire_symbols() == (sym, )


@pytest.mark.parametrize('gate,exp',
                         ((CliffordGate.I, 1), (CliffordGate.H, 1),
                          (CliffordGate.X, 1), (CliffordGate.X_sqrt, 0.5),
                          (CliffordGate.X_nsqrt, -0.5),
                          (CliffordGate.from_xz_map((Pauli.Y, False),
                                                    (Pauli.X, True)), 1)))
def test_text_diagram_exponent(gate, exp):
    assert gate.text_diagram_exponent() == exp
예제 #17
0
def test_init_from_single_map_vs_kwargs(trans, frm):
    from_str = str(frm).lower() + '_to'
    # pylint: disable=unexpected-keyword-arg
    gate_kw = CliffordGate.from_single_map(**{from_str: trans})
    gate_map = CliffordGate.from_single_map({frm: trans})
    assert gate_kw == gate_map
예제 #18
0
def test_init_from_double_invalid(trans1, trans2, from1):
    from2 = from1 + 1
    # Test throws on invalid arguments
    with pytest.raises(ValueError):
        CliffordGate.from_double_map({from1: trans1, from2: trans2})
예제 #19
0
    commutes_check = cirq.allclose_up_to_global_phase(mat, mat_swap)
    assert commutes == commutes_check


@pytest.mark.parametrize('gate,other',
                         itertools.product(_all_clifford_gates(),
                                           _all_clifford_gates()))
def test_single_qubit_gate_after_switching_order(gate, other):
    q0 = cirq.NamedQubit('q0')
    mat = cirq.Circuit.from_ops(
        gate(q0),
        other(q0),
    ).to_unitary_matrix()
    mat_swap = cirq.Circuit.from_ops(
        gate.equivalent_gate_before(other)(q0),
        gate(q0),
    ).to_unitary_matrix()
    assert_allclose_up_to_global_phase(mat, mat_swap)


@pytest.mark.parametrize(
    'gate,sym,exp',
    ((CliffordGate.I, 'I', 1), (CliffordGate.H, 'H', 1),
     (CliffordGate.X, 'X', 1), (CliffordGate.X_sqrt, 'X', 0.5),
     (CliffordGate.X_nsqrt, 'X', -0.5), (CliffordGate.from_xz_map(
         (Pauli.Y, False), (Pauli.X, True)), 'X^-0.5-Z^0.5', 1)))
def test_text_diagram_info(gate, sym, exp):
    assert gate.text_diagram_info(
        cirq.TextDiagramInfoArgs.UNINFORMED_DEFAULT) == cirq.TextDiagramInfo(
            wire_symbols=(sym, ), exponent=exp)