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)
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
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
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)
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
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)
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)
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
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
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)
def test_init_value_error(pauli, flip_x, flip_z): with pytest.raises(ValueError): CliffordGate.from_xz_map((pauli, flip_x), (pauli, flip_z))
def _all_clifford_gates(): for trans_x, trans_z in _all_rotation_pairs(): yield CliffordGate.from_xz_map(trans_x, trans_z)
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)
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) })
def test_init_from_pauli(pauli, sqrt, expected): gate = CliffordGate.from_pauli(pauli, sqrt=sqrt) assert gate == expected
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
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
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})
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)