def test_bounded_effect(): q = cirq.NamedQubit('q') # If the gate isn't bounded, you get a type error. op0 = cirq.GateOperation(cirq.SingleQubitGate(), [q]) assert cirq.trace_distance_bound(op0) >= 1 op1 = cirq.GateOperation(cirq.Z**0.000001, [q]) op1_bound = cirq.trace_distance_bound(op1) assert op1_bound == cirq.trace_distance_bound(cirq.Z**0.000001)
def test_with_qubits_and_transform_qubits(): g = cirq.SingleQubitGate() op = cirq.ParallelGateOperation(g, cirq.LineQubit.range(3)) line = cirq.LineQubit.range(3, 0, -1) negline = cirq.LineQubit.range(0, -3, -1) assert op.with_qubits(*line) == cirq.ParallelGateOperation(g, line) assert op.transform_qubits( lambda e: cirq.LineQubit(-e.x)) == cirq.ParallelGateOperation( g, negline)
def test_extrapolate(): # If the gate isn't extrapolatable, you get a type error. g = cirq.ParallelGate(cirq.SingleQubitGate(), 2) with pytest.raises(TypeError): _ = g**0.5 # If the gate is extrapolatable, the effect is applied on the underlying gate. g = cirq.ParallelGate(cirq.Y, 2) assert g**0.5 == cirq.ParallelGate(cirq.Y**0.5, 2) assert cirq.inverse(g) == g**-1 == cirq.ParallelGate(cirq.Y**-1, 2)
def test_validate_gate_errors(): d = square_device(1, 1) d.validate_gate(cirq.IdentityGate(4)) with pytest.raises(ValueError, match="controlled gates must have integer exponents"): d.validate_gate(cirq.CNotPowGate(exponent=0.5)) with pytest.raises(ValueError, match="Unsupported gate"): d.validate_gate(cirq.SingleQubitGate())
def test_with_qubits_and_transform_qubits(): with cirq.testing.assert_deprecated(deadline="v0.14", count=None): g = cirq.SingleQubitGate() op = cirq.ParallelGateOperation(g, cirq.LineQubit.range(3)) line = cirq.LineQubit.range(3, 0, -1) negline = cirq.LineQubit.range(0, -3, -1) assert op.with_qubits(*line) == cirq.ParallelGateOperation(g, line) assert op.transform_qubits( lambda e: cirq.LineQubit(-e.x)) == cirq.ParallelGateOperation( g, negline)
def test_extrapolate(): q = cirq.NamedQubit('q') # If the gate isn't extrapolatable, you get a type error. op0 = cirq.ParallelGateOperation(cirq.SingleQubitGate(), [q]) with pytest.raises(TypeError): _ = op0 ** 0.5 op = cirq.ParallelGateOperation(cirq.Y, [q]) assert op ** 0.5 == cirq.ParallelGateOperation(cirq.Y ** 0.5, [q]) assert cirq.inverse(op) == op ** -1 == cirq.ParallelGateOperation(cirq.Y ** -1, [q])
def test_invalid_parallel_gate_operation(): three_qubit_gate = cirq.ThreeQubitGate() single_qubit_gate = cirq.SingleQubitGate() repeated_qubits = [cirq.GridQubit(0, 0), cirq.GridQubit(0, 0)] with pytest.raises(ValueError) as wrong_gate: cirq.ParallelGateOperation(three_qubit_gate, cirq.NamedQubit("a")) assert str(wrong_gate.value) == "gate must be a single qubit gate" with pytest.raises(ValueError) as bad_qubits: cirq.ParallelGateOperation(single_qubit_gate, repeated_qubits) assert str(bad_qubits.value) == "repeated qubits are not allowed"
def test_controlled_operation_init(): cb = cirq.NamedQubit('ctr') q = cirq.NamedQubit('q') g = cirq.SingleQubitGate() v = cirq.GateOperation(g, (q, )) c = cirq.ControlledOperation(cb, v) assert c.sub_operation == v assert c.control == cb assert c.qubits == (cb, q) assert c == c.with_qubits(cb, q)
def test_phase(): g1 = cirq.SingleQubitGate() g2 = cirq.S g3 = cirq.phase_by(g2, 1, 0) qreg = cirq.LineQubit.range(2) op1 = cirq.ParallelGateOperation(g1, qreg) op2 = cirq.ParallelGateOperation(g2, qreg) assert cirq.phase_by(op2, 1, 0) == cirq.ParallelGateOperation(g3, qreg) with pytest.raises(TypeError): cirq.phase_by(op1, 1, 0)
def test_gate_operation_eq(): g1 = cirq.SingleQubitGate() g2 = cirq.SingleQubitGate() g3 = cirq.TwoQubitGate() r1 = [cirq.NamedQubit('r1')] r2 = [cirq.NamedQubit('r2')] r12 = r1 + r2 r21 = r2 + r1 eq = cirq.testing.EqualsTester() eq.make_equality_group(lambda: cirq.GateOperation(g1, r1)) eq.make_equality_group(lambda: cirq.GateOperation(g2, r1)) eq.make_equality_group(lambda: cirq.GateOperation(g1, r2)) eq.make_equality_group(lambda: cirq.GateOperation(g3, r12)) eq.make_equality_group(lambda: cirq.GateOperation(g3, r21)) eq.add_equality_group(cirq.GateOperation(cirq.CZ, r21), cirq.GateOperation(cirq.CZ, r12)) @cirq.value_equality class PairGate(cirq.Gate, cirq.InterchangeableQubitsGate): """Interchangeable substes.""" def __init__(self, num_qubits): self._num_qubits = num_qubits def num_qubits(self) -> int: return self._num_qubits def qubit_index_to_equivalence_group_key(self, index: int): return index // 2 def _value_equality_values_(self): return self.num_qubits(), def p(*q): return PairGate(len(q)).on(*q) a0, a1, b0, b1, c0 = cirq.LineQubit.range(5) eq.add_equality_group(p(a0, a1, b0, b1), p(a1, a0, b1, b0)) eq.add_equality_group(p(b0, b1, a0, a1)) eq.add_equality_group(p(a0, a1, b0, b1, c0), p(a1, a0, b1, b0, c0)) eq.add_equality_group(p(a0, b0, a1, b1, c0)) eq.add_equality_group(p(a0, c0, b0, b1, a1)) eq.add_equality_group(p(b0, a1, a0, b1, c0))
def test_inverse(): q = cirq.NamedQubit('q') # If the gate isn't reversible, you get a type error. op0 = cirq.GateOperation(cirq.SingleQubitGate(), [q]) assert cirq.inverse(op0, None) is None op1 = cirq.GateOperation(cirq.S, [q]) assert cirq.inverse(op1) == op1**-1 == cirq.GateOperation(cirq.S**-1, [q]) assert cirq.inverse(cirq.S).on(q) == cirq.inverse(cirq.S.on(q))
def test_extrapolate(): q = cirq.NamedQubit('q') # If the gate isn't extrapolatable, you get a type error. op0 = cirq.GateOperation(cirq.SingleQubitGate(), [q]) with pytest.raises(TypeError): _ = op0**0.5 op1 = cirq.GateOperation(cirq.Y, [q]) assert op1**0.5 == cirq.GateOperation(cirq.Y**0.5, [q]) assert (cirq.Y**0.5).on(q) == cirq.Y(q)**0.5
def test_text_diagrammable(): q = cirq.NamedQubit('q') # If the gate isn't diagrammable, you get a type error. op0 = cirq.GateOperation(cirq.SingleQubitGate(), [q]) with pytest.raises(TypeError): _ = cirq.circuit_diagram_info(op0) op1 = cirq.GateOperation(cirq.S, [q]) actual = cirq.circuit_diagram_info(op1) expected = cirq.circuit_diagram_info(cirq.S) assert actual == expected
def test_extrapolate(): with cirq.testing.assert_deprecated(deadline="v0.14", count=None): q = cirq.NamedQubit('q') # If the gate isn't extrapolatable, you get a type error. op0 = cirq.ParallelGateOperation(cirq.SingleQubitGate(), [q]) with pytest.raises(TypeError): _ = op0**0.5 op = cirq.ParallelGateOperation(cirq.Y, [q]) assert op**0.5 == cirq.ParallelGateOperation(cirq.Y**0.5, [q]) assert cirq.inverse(op) == op**-1 == cirq.ParallelGateOperation( cirq.Y**-1, [q])
def test_op_tree_control(): gs = [cirq.SingleQubitGate() for _ in range(10)] op_tree = [ cirq.GateOperation(gs[i], [cirq.NamedQubit(str(i))]) for i in range(10) ] controls = cirq.LineQubit.range(2) controlled_op_tree = cirq.protocols.control(op_tree, controls) expected = [ cirq.ControlledOperation( controls, cirq.GateOperation(gs[i], [cirq.NamedQubit(str(i))])) for i in range(10) ] assert cirq.freeze_op_tree(controlled_op_tree) == tuple(expected)
def test_init_timedelta(): d = square_device(2, 2, holes=[cirq.GridQubit(1, 1)], use_timedelta=True) us = cirq.Duration(nanos=10 ** 3) ms = cirq.Duration(nanos=10 ** 6) q00 = cirq.GridQubit(0, 0) q01 = cirq.GridQubit(0, 1) q10 = cirq.GridQubit(1, 0) assert d.qubits == {q10, q00, q01} assert d.duration_of(cirq.GateOperation(cirq.IdentityGate(1), [q00])) == 100 * us assert d.duration_of(cirq.measure(q00)) == 50 * ms with pytest.raises(ValueError): _ = d.duration_of(cirq.SingleQubitGate().on(q00))
def test_init_timedelta(): d = ion_device(3, use_timedelta=True) ms = 1000 * cirq.Duration(nanos=1) q0 = cirq.LineQubit(0) q1 = cirq.LineQubit(1) q2 = cirq.LineQubit(2) assert d.qubits == {q0, q1, q2} assert d.duration_of(cirq.Z(q0)) == 10 * ms assert d.duration_of(cirq.measure(q0)) == 100 * ms assert d.duration_of(cirq.measure(q0, q1)) == 100 * ms assert d.duration_of(cirq.ops.XX(q0, q1)) == 200 * ms with pytest.raises(ValueError): _ = d.duration_of(cirq.SingleQubitGate().on(q0))
def test_init(): d = square_device(2, 2, holes=[cirq.GridQubit(1, 1)]) ns = cirq.Duration(nanos=1) q00 = cirq.GridQubit(0, 0) q01 = cirq.GridQubit(0, 1) q10 = cirq.GridQubit(1, 0) assert d.qubits == {q00, q01, q10} assert d.duration_of(cirq.Z(q00)) == 0 * ns assert d.duration_of(cirq.measure(q00)) == ns assert d.duration_of(cirq.measure(q00, q01)) == ns assert d.duration_of(cirq.X(q00)) == 2 * ns assert d.duration_of(cirq.CZ(q00, q01)) == 3 * ns with pytest.raises(ValueError): _ = d.duration_of(cirq.SingleQubitGate().on(q00))
def test_unitary(): a = cirq.NamedQubit('a') b = cirq.NamedQubit('b') g = cirq.SingleQubitGate() p = cirq.ParallelGateOperation(g, [a, b]) q = cirq.ParallelGateOperation(cirq.X, [a, b]) assert not cirq.has_unitary(p) assert cirq.unitary(p, None) is None np.testing.assert_allclose(cirq.unitary(q), np.array( [[0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j], [0. + 0.j, 1. + 0.j, 1. + 0.j, 0. + 0.j], [0. + 0.j, 1. + 0.j, 1. + 0.j, 0. + 0.j], [0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j]]), atol=1e-8)
def test_unitary(): with cirq.testing.assert_deprecated(deadline="v0.14", count=None): a = cirq.NamedQubit('a') b = cirq.NamedQubit('b') g = cirq.SingleQubitGate() p = cirq.ParallelGateOperation(g, [a, b]) q = cirq.ParallelGateOperation(cirq.X, [a, b]) assert not cirq.has_unitary(p) assert cirq.unitary(p, None) is None np.testing.assert_allclose( cirq.unitary(q), np.array([ [0.0 + 0.0j, 0.0 + 0.0j, 0.0 + 0.0j, 1.0 + 0.0j], [0.0 + 0.0j, 0.0 + 0.0j, 1.0 + 0.0j, 0.0 + 0.0j], [0.0 + 0.0j, 1.0 + 0.0j, 0.0 + 0.0j, 0.0 + 0.0j], [1.0 + 0.0j, 0.0 + 0.0j, 0.0 + 0.0j, 0.0 + 0.0j], ]), atol=1e-8, )
def test_flatten_to_ops_or_moments(): operations = [ cirq.GateOperation(cirq.SingleQubitGate(), [cirq.NamedQubit(str(i))]) for i in range(10) ] op_tree = [ operations[0], cirq.Moment(operations[1:5]), operations[5:], ] output = [operations[0], cirq.Moment(operations[1:5])] + operations[5:] assert list(cirq.flatten_to_ops_or_moments(op_tree)) == output assert list(cirq.flatten_op_tree(op_tree, preserve_moments=True)) == output # Bad trees. with pytest.raises(TypeError): _ = list(cirq.flatten_to_ops_or_moments(None)) with pytest.raises(TypeError): _ = list(cirq.flatten_to_ops_or_moments(5)) with pytest.raises(TypeError): _ = list(cirq.flatten_to_ops_or_moments([operations[0], (4,)]))
def test_any_unitary_gate_family(): with pytest.raises(ValueError, match='must be a positive integer'): _ = cirq.AnyUnitaryGateFamily(0) for num_qubits in range(1, 6, 2): q = cirq.LineQubit.range(num_qubits) gate = UnitaryGate(num_qubits) for init_num_qubits in [None, num_qubits]: gate_family = cirq.AnyUnitaryGateFamily(init_num_qubits) cirq.testing.assert_equivalent_repr(gate_family) assert gate in gate_family assert gate(*q) in gate_family if init_num_qubits: assert f'{init_num_qubits}' in gate_family.name assert f'{init_num_qubits}' in gate_family.description assert UnitaryGate(num_qubits + 1) not in gate_family else: assert f'Any-Qubit' in gate_family.name assert f'any unitary' in gate_family.description assert cirq.SingleQubitGate() not in cirq.AnyUnitaryGateFamily()
def test_init(): d = ion_device(3) ms = 1000 * cirq.Duration(nanos=1) q0 = cirq.LineQubit(0) q1 = cirq.LineQubit(1) q2 = cirq.LineQubit(2) assert d.qubits == {q0, q1, q2} assert d.duration_of(cirq.Z(q0)) == 10 * ms assert d.duration_of(cirq.measure(q0)) == 100 * ms assert d.duration_of(cirq.measure(q0, q1)) == 100 * ms assert d.duration_of(cirq.ops.XX(q0, q1)) == 200 * ms with pytest.raises(ValueError): _ = d.duration_of(cirq.SingleQubitGate().on(q0)) with pytest.raises(TypeError, match="NamedQubit"): _ = cirq.IonDevice( measurement_duration=ms, twoq_gates_duration=ms, oneq_gates_duration=ms, qubits=[cirq.LineQubit(0), cirq.NamedQubit("a")], )
def test_flatten_op_tree(): operations = [ cirq.GateOperation(cirq.SingleQubitGate(), [cirq.NamedQubit(str(i))]) for i in range(10) ] # Empty tree. assert list(cirq.flatten_op_tree([[[]]])) == [] # Just an item. assert list(cirq.flatten_op_tree(operations[0])) == operations[:1] # Flat list. assert list(cirq.flatten_op_tree(operations)) == operations # Tree. assert list( cirq.flatten_op_tree( (operations[0], operations[1:5], operations[5:]))) == operations # Flatten moment. assert list( cirq.flatten_op_tree((operations[0], cirq.Moment(operations[1:5]), operations[5:]))) == operations # Don't flatten moment. assert list( cirq.flatten_op_tree( (operations[0], cirq.Moment(operations[1:5]), operations[5:]), preserve_moments=True)) == ( [operations[0], cirq.Moment(operations[1:5])] + operations[5:]) # Bad trees. with pytest.raises(TypeError): _ = list(cirq.flatten_op_tree(None)) with pytest.raises(TypeError): _ = list(cirq.flatten_op_tree(5)) with pytest.raises(TypeError): _ = list(cirq.flatten_op_tree([operations[0], (4, )]))
def test_control(): g = cirq.SingleQubitGate() # Ignores empty. assert g.controlled() == cirq.ControlledGate(g) # Combined. cg = g.controlled() assert isinstance(cg, cirq.ControlledGate) assert cg.sub_gate == g assert cg.num_controls() == 1 # Equality ignores ordering but cares about set and quantity. eq = cirq.testing.EqualsTester() eq.add_equality_group(g) eq.add_equality_group( g.controlled(), g.controlled(control_values=[1]), g.controlled(control_qid_shape=(2,)), cirq.ControlledGate(g, num_controls=1), ) eq.add_equality_group( cirq.ControlledGate(g, num_controls=2), g.controlled(control_values=[1, 1]), g.controlled(control_qid_shape=[2, 2]), g.controlled(num_controls=2), g.controlled().controlled(), ) eq.add_equality_group( cirq.ControlledGate(g, control_values=[0, 1]), g.controlled(control_values=[0, 1]), g.controlled(control_values=[0]).controlled(control_values=[1]), ) eq.add_equality_group( cirq.ControlledGate(g, control_qid_shape=[4, 3]), g.controlled(control_qid_shape=[4, 3]), g.controlled(control_qid_shape=[4]).controlled(control_qid_shape=[3]), )
def test_controlled_operation_init(): cb = cirq.NamedQubit('ctr') q = cirq.NamedQubit('q') g = cirq.SingleQubitGate() v = cirq.GateOperation(g, (q, )) c = cirq.ControlledOperation([cb], v) assert c.sub_operation == v assert c.controls == (cb, ) assert c.qubits == (cb, q) assert c == c.with_qubits(cb, q) assert c.control_values == ((1, ), ) assert cirq.qid_shape(c) == (2, 2) c = cirq.ControlledOperation([cb], v, control_values=[0]) assert c.sub_operation == v assert c.controls == (cb, ) assert c.qubits == (cb, q) assert c == c.with_qubits(cb, q) assert c.control_values == ((0, ), ) assert cirq.qid_shape(c) == (2, 2) c = cirq.ControlledOperation([cb.with_dimension(3)], v) assert c.sub_operation == v assert c.controls == (cb.with_dimension(3), ) assert c.qubits == (cb.with_dimension(3), q) assert c == c.with_qubits(cb.with_dimension(3), q) assert c.control_values == ((1, ), ) assert cirq.qid_shape(c) == (3, 2) with pytest.raises(ValueError, match=r'len\(control_values\) != len\(controls\)'): _ = cirq.ControlledOperation([cb], v, control_values=[1, 1]) with pytest.raises(ValueError, match='Control values .*outside of range'): _ = cirq.ControlledOperation([cb], v, control_values=[2]) with pytest.raises(ValueError, match='Control values .*outside of range'): _ = cirq.ControlledOperation([cb], v, control_values=[(1, -1)])
eq.add_equality_group( cirq.GateFamily(CustomXPowGate, name='custom_name', description='custom_description') ) @pytest.mark.parametrize( 'gate_family, gates_to_check', [ ( cirq.GateFamily(CustomXPowGate), [ (CustomX, True), (CustomX ** 0.5, True), (CustomX ** sympy.Symbol('theta'), True), (CustomXPowGate(exponent=0.25, global_shift=0.15), True), (cirq.SingleQubitGate(), False), (cirq.X ** 0.5, False), (None, False), (cirq.GlobalPhaseOperation(1j), False), ], ), ( cirq.GateFamily(CustomX), [ (CustomX, True), (CustomXPowGate(exponent=1, global_shift=0.15), True), (CustomX ** 2, False), (CustomX ** 3, True), (CustomX ** sympy.Symbol('theta'), False), (None, False), (cirq.GlobalPhaseOperation(1j), False),
def test_gate_operation_init(): q = cirq.NamedQubit('q') g = cirq.SingleQubitGate() v = cirq.GateOperation(g, (q, )) assert v.gate == g assert v.qubits == (q, )
def test_inconclusive(): assert not cirq.has_stabilizer_effect(object()) assert not cirq.has_stabilizer_effect('boo') assert not cirq.has_stabilizer_effect(cirq.SingleQubitGate()) assert not cirq.has_stabilizer_effect(No()) assert not cirq.has_stabilizer_effect(NoOp())
def test_not_implemented_diagram(): a = cirq.NamedQubit('a') g = cirq.SingleQubitGate() c = cirq.Circuit() c.append(cirq.ParallelGateOperation(g, [a])) assert 'cirq.ops.gate_features.SingleQubitGate' in str(c)