def test_commutes(): for A, B in itertools.product([cirq.X, cirq.Y, cirq.Z], repeat=2): assert cirq.commutes(A, B) == (A == B) with pytest.raises(TypeError): assert cirq.commutes(cirq.X, 'X') assert cirq.commutes(cirq.X, 'X', default='default') == 'default' assert cirq.commutes(cirq.Z, cirq.read_json(json_text=cirq.to_json(cirq.Z)))
def test_commutes_tolerance(): atol = 0.5 x = np.array([[0, 1], [1, 0]]) z = np.array([[1, 0], [0, -1]]) # Pays attention to specified tolerance. assert cirq.commutes(x, x + z * 0.1, atol=atol) assert not cirq.commutes(x, x + z * 0.5, atol=atol)
def test_commutes_pauli(gate, pauli, half_turns): # TODO(#4328) cirq.X**1 should be _PauliX instead of XPowGate pauli_gate = pauli if half_turns == 1 else pauli**half_turns q0 = cirq.NamedQubit('q0') mat = cirq.Circuit(gate(q0), pauli_gate(q0)).unitary() mat_swap = cirq.Circuit(pauli_gate(q0), gate(q0)).unitary() commutes = cirq.commutes(gate, pauli_gate) commutes_check = np.allclose(mat, mat_swap) assert commutes == commutes_check, f"gate: {gate}, pauli {pauli}"
def test_commutes(): f = cirq.DensePauliString m = cirq.MutableDensePauliString assert cirq.commutes(f('XX'), m('ZZ')) assert cirq.commutes(2 * f('XX'), m('ZZ', coefficient=3)) assert cirq.commutes(2 * f('IX'), 3 * f('IX')) assert not cirq.commutes(f('IX'), f('IZ')) assert cirq.commutes(f('IIIXII'), cirq.X(cirq.LineQubit(3))) assert cirq.commutes(f('IIIXII'), cirq.X(cirq.LineQubit(2))) assert not cirq.commutes(f('IIIXII'), cirq.Z(cirq.LineQubit(3))) assert cirq.commutes(f('IIIXII'), cirq.Z(cirq.LineQubit(2))) assert cirq.commutes(f('XX'), "test", default=NotImplemented) is NotImplemented
def test_swap_permutation_gate(): no_decomp = lambda op: (isinstance(op, cirq.GateOperation) and op.gate == cirq.SWAP) a, b = cirq.NamedQubit('a'), cirq.NamedQubit('b') gate = cca.SwapPermutationGate() assert gate.num_qubits() == 2 circuit = cirq.Circuit(gate(a, b)) circuit = cirq.expand_composite(circuit, no_decomp=no_decomp) assert tuple(circuit.all_operations()) == (cirq.SWAP(a, b), ) no_decomp = lambda op: (isinstance(op, cirq.GateOperation) and op.gate == cirq.CZ) circuit = cirq.Circuit(cca.SwapPermutationGate(cirq.CZ)(a, b)) circuit = cirq.expand_composite(circuit, no_decomp=no_decomp) assert tuple(circuit.all_operations()) == (cirq.CZ(a, b), ) assert cirq.commutes(gate, cirq.ZZ) with pytest.raises(TypeError): cirq.commutes(gate, cirq.CCZ)
def test_commutes_single_qubit_gate(gate, other): q0 = cirq.NamedQubit('q0') mat = cirq.Circuit( gate(q0), other(q0), ).unitary() mat_swap = cirq.Circuit( other(q0), gate(q0), ).unitary() commutes = cirq.commutes(gate, other) commutes_check = cirq.allclose_up_to_global_phase(mat, mat_swap) assert commutes == commutes_check
def test_commutes_single_qubit_gate(gate, other): q0 = cirq.NamedQubit('q0') gate_op = gate(q0) other_op = other(q0) mat = cirq.Circuit(gate_op, other_op).unitary() mat_swap = cirq.Circuit(other_op, gate_op).unitary() commutes = cirq.commutes(gate, other) commutes_check = cirq.allclose_up_to_global_phase(mat, mat_swap) assert commutes == commutes_check # Test after switching order mat_swap = cirq.Circuit(gate.equivalent_gate_before(other)(q0), gate_op).unitary() assert_allclose_up_to_global_phase(mat, mat_swap, rtol=1e-7, atol=1e-7)
def test_commutes_notimplemented_type(): with pytest.raises(TypeError): cirq.commutes(cirq.SingleQubitCliffordGate.X, 'X') assert cirq.commutes(cirq.SingleQubitCliffordGate.X, 'X', default='default') == 'default' with pytest.raises(TypeError): cirq.commutes(cirq.CliffordGate.X, 'X') assert cirq.commutes(cirq.CliffordGate.X, 'X', default='default') == 'default'
def test_commutes_pauli(gate, pauli, half_turns): pauli_gate = pauli ** half_turns q0 = cirq.NamedQubit('q0') mat = cirq.Circuit( gate(q0), pauli_gate(q0), ).unitary() mat_swap = cirq.Circuit( pauli_gate(q0), gate(q0), ).unitary() commutes = cirq.commutes(gate, pauli) commutes_check = cirq.allclose_up_to_global_phase(mat, mat_swap) assert commutes == commutes_check
def check_commutability(pauli_sum): """Return False if at least one pair of terms in pauli_sum is not commutable. Args: pauli_sum: `cirq.PauliSum` object to be checked if all of terms inside are commutable each other. """ for term1 in pauli_sum: for term2 in pauli_sum: if not cirq.commutes(term1, term2): raise ValueError("Given an operator has non-commutable " "terms, whose exponentiation is not " "supported yet: {} and {}".format( term1, term2))
def test_commutes_on_matrices(): I, X, Y, Z = (cirq.unitary(A) for A in (cirq.I, cirq.X, cirq.Y, cirq.Z)) IX, IY = (np.kron(I, A) for A in (X, Y)) XI, YI, ZI = (np.kron(A, I) for A in (X, Y, Z)) XX, YY, ZZ = (np.kron(A, A) for A in (X, Y, Z)) for A in (X, Y, Z): assert cirq.commutes(I, A) assert cirq.commutes(A, A) assert cirq.commutes(I, XX, default='default') == 'default' for A, B in [(X, Y), (X, Z), (Z, Y), (IX, IY), (XI, ZI)]: assert not cirq.commutes(A, B) assert not cirq.commutes(A, B, atol=1) assert cirq.commutes(A, B, atol=2) for A, B in [(XX, YY), (XX, ZZ), (ZZ, YY), (IX, YI), (IX, IX), (ZI, IY)]: assert cirq.commutes(A, B)
def check_commutability(pauli_sum): """Determines whether pairs of terms in `pauli_sum` are commutable. Args: pauli_sum: `cirq.PauliSum` object to be checked if all of terms inside are commutable each other. Raises: ValueError: If one or more term pairs in `pauli_sum` are not commutable. """ for term1 in pauli_sum: for term2 in pauli_sum: if not cirq.commutes(term1, term2): raise ValueError("Given an operator has non-commutable " "terms, whose exponentiation is not " "supported yet: {} and {}".format( term1, term2))
def test_commutes(): a = cirq.NamedQubit('a') b = cirq.NamedQubit('b') c = cirq.NamedQubit('c') d = cirq.NamedQubit('d') moment = cirq.Moment([cirq.X(a), cirq.Y(b), cirq.H(c)]) assert NotImplemented == cirq.commutes(moment, a, default=NotImplemented) assert cirq.commutes(moment, cirq.X(a)) assert cirq.commutes(moment, cirq.Y(b)) assert cirq.commutes(moment, cirq.H(c)) assert cirq.commutes(moment, cirq.H(d)) # X and H do not commute assert not cirq.commutes(moment, cirq.H(a)) assert not cirq.commutes(moment, cirq.H(b)) assert not cirq.commutes(moment, cirq.X(c))
def test_commutes(): q0, q1 = cirq.LineQubit.range(2) assert cirq.commutes(cirq.measure(q0, key='a'), cirq.X(q1).with_classical_controls('b')) assert cirq.commutes( cirq.X(q1).with_classical_controls('b'), cirq.measure(q0, key='a')) assert cirq.commutes( cirq.X(q0).with_classical_controls('a'), cirq.H(q1).with_classical_controls('a')) assert cirq.commutes( cirq.X(q0).with_classical_controls('a'), cirq.X(q0).with_classical_controls('a')) assert not cirq.commutes(cirq.measure(q0, key='a'), cirq.X(q1).with_classical_controls('a')) assert not cirq.commutes( cirq.X(q1).with_classical_controls('a'), cirq.measure(q0, key='a')) assert not cirq.commutes( cirq.X(q0).with_classical_controls('a'), cirq.H(q0).with_classical_controls('a'))
def test_operation_commutes_using_overlap_and_unitary(): class CustomCnotGate(cirq.Gate): def num_qubits(self) -> int: return 2 def _unitary_(self): return cirq.unitary(cirq.CNOT) custom_cnot_gate = CustomCnotGate() class CustomCnotOp(cirq.Operation): def __init__(self, *qs: cirq.Qid): self.qs = qs def _unitary_(self): return cirq.unitary(cirq.CNOT) @property def qubits(self): return self.qs def with_qubits(self, *new_qubits): raise NotImplementedError() class NoDetails(cirq.Operation): def __init__(self, *qs: cirq.Qid): self.qs = qs @property def qubits(self): return self.qs def with_qubits(self, *new_qubits): raise NotImplementedError() a, b, c = cirq.LineQubit.range(3) # If ops overlap with known unitaries, fallback to matrix commutation. assert not cirq.commutes(CustomCnotOp(a, b), CustomCnotOp(b, a)) assert not cirq.commutes(CustomCnotOp(a, b), CustomCnotOp(b, c)) assert cirq.commutes(CustomCnotOp(a, b), CustomCnotOp(c, b)) assert cirq.commutes(CustomCnotOp(a, b), CustomCnotOp(a, b)) # If ops don't overlap, they commute. Even when no specified unitary. assert cirq.commutes(CustomCnotOp(a, b), NoDetails(c)) # If ops overlap and there's no unitary, result is indeterminate. assert cirq.commutes(CustomCnotOp(a, b), NoDetails(a), default=None) is None # Same stuff works with custom gate, or mix of custom gate and custom op. assert cirq.commutes(custom_cnot_gate(a, b), CustomCnotOp(a, b)) assert cirq.commutes(custom_cnot_gate(a, b), custom_cnot_gate(a, b)) assert cirq.commutes(custom_cnot_gate(a, b), CustomCnotOp(c, b)) assert cirq.commutes(custom_cnot_gate(a, b), custom_cnot_gate(c, b)) assert not cirq.commutes(custom_cnot_gate(a, b), CustomCnotOp(b, a)) assert not cirq.commutes(custom_cnot_gate(a, b), custom_cnot_gate(b, a)) assert not cirq.commutes(custom_cnot_gate(a, b), CustomCnotOp(b, c)) assert not cirq.commutes(custom_cnot_gate(a, b), custom_cnot_gate(b, c))
def test_commutes(): assert cirq.commutes(np.empty((0, 0)), np.empty((0, 0))) assert not cirq.commutes(np.empty((1, 0)), np.empty((0, 1))) assert not cirq.commutes(np.empty((0, 1)), np.empty((1, 0))) assert not cirq.commutes(np.empty((1, 0)), np.empty((1, 0))) assert not cirq.commutes(np.empty((0, 1)), np.empty((0, 1))) assert cirq.commutes(np.array([[1]]), np.array([[2]])) assert cirq.commutes(np.array([[1]]), np.array([[0]])) x = np.array([[0, 1], [1, 0]]) y = np.array([[0, -1j], [1j, 0]]) z = np.array([[1, 0], [0, -1]]) xx = np.kron(x, x) zz = np.kron(z, z) assert cirq.commutes(x, x) assert cirq.commutes(y, y) assert cirq.commutes(z, z) assert not cirq.commutes(x, y) assert not cirq.commutes(x, z) assert not cirq.commutes(y, z) assert cirq.commutes(xx, zz) assert cirq.commutes(xx, np.diag([1, -1, -1, 1 + 1e-9]))
def test_tagged_operation_forwards_protocols(): """The results of all protocols applied to an operation with a tag should be equivalent to the result without tags. """ q1 = cirq.GridQubit(1, 1) q2 = cirq.GridQubit(1, 2) h = cirq.H(q1) tag = 'tag1' tagged_h = cirq.H(q1).with_tags(tag) np.testing.assert_equal(cirq.unitary(tagged_h), cirq.unitary(h)) assert cirq.has_unitary(tagged_h) assert cirq.decompose(tagged_h) == cirq.decompose(h) assert cirq.pauli_expansion(tagged_h) == cirq.pauli_expansion(h) assert cirq.equal_up_to_global_phase(h, tagged_h) assert np.isclose(cirq.channel(h), cirq.channel(tagged_h)).all() assert cirq.measurement_key(cirq.measure(q1, key='blah').with_tags(tag)) == 'blah' parameterized_op = cirq.XPowGate(exponent=sympy.Symbol('t'))(q1).with_tags(tag) assert cirq.is_parameterized(parameterized_op) resolver = cirq.study.ParamResolver({'t': 0.25}) assert cirq.resolve_parameters(parameterized_op, resolver) == cirq.XPowGate(exponent=0.25)( q1 ).with_tags(tag) assert cirq.resolve_parameters_once(parameterized_op, resolver) == cirq.XPowGate(exponent=0.25)( q1 ).with_tags(tag) y = cirq.Y(q1) tagged_y = cirq.Y(q1).with_tags(tag) assert tagged_y ** 0.5 == cirq.YPowGate(exponent=0.5)(q1) assert tagged_y * 2 == (y * 2) assert 3 * tagged_y == (3 * y) assert cirq.phase_by(y, 0.125, 0) == cirq.phase_by(tagged_y, 0.125, 0) controlled_y = tagged_y.controlled_by(q2) assert controlled_y.qubits == ( q2, q1, ) assert isinstance(controlled_y, cirq.Operation) assert not isinstance(controlled_y, cirq.TaggedOperation) clifford_x = cirq.SingleQubitCliffordGate.X(q1) tagged_x = cirq.SingleQubitCliffordGate.X(q1).with_tags(tag) assert cirq.commutes(clifford_x, clifford_x) assert cirq.commutes(tagged_x, clifford_x) assert cirq.commutes(clifford_x, tagged_x) assert cirq.commutes(tagged_x, tagged_x) assert cirq.trace_distance_bound(y ** 0.001) == cirq.trace_distance_bound( (y ** 0.001).with_tags(tag) ) flip = cirq.bit_flip(0.5)(q1) tagged_flip = cirq.bit_flip(0.5)(q1).with_tags(tag) assert cirq.has_mixture(tagged_flip) assert cirq.has_channel(tagged_flip) flip_mixture = cirq.mixture(flip) tagged_mixture = cirq.mixture(tagged_flip) assert len(tagged_mixture) == 2 assert len(tagged_mixture[0]) == 2 assert len(tagged_mixture[1]) == 2 assert tagged_mixture[0][0] == flip_mixture[0][0] assert np.isclose(tagged_mixture[0][1], flip_mixture[0][1]).all() assert tagged_mixture[1][0] == flip_mixture[1][0] assert np.isclose(tagged_mixture[1][1], flip_mixture[1][1]).all() qubit_map = {q1: 'q1'} qasm_args = cirq.QasmArgs(qubit_id_map=qubit_map) assert cirq.qasm(h, args=qasm_args) == cirq.qasm(tagged_h, args=qasm_args) cirq.testing.assert_has_consistent_apply_unitary(tagged_h)
def test_commutes(): assert cirq.commutes(cirq.ZPowGate(exponent=sympy.Symbol('t')), cirq.Z) assert cirq.commutes(cirq.Z, cirq.Z(cirq.LineQubit(0)), default=None) is None assert cirq.commutes(cirq.Z**0.1, cirq.XPowGate(exponent=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.MatrixGate(A) for A in (X, Y, Z)) XXGate, YYGate, ZZGate = (cirq.MatrixGate(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, atol=1e-8) is NotImplemented 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)) 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'