def test_gate_operation_eq(): g1 = cirq.Gate() g2 = cirq.Gate() 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(g1, r12)) eq.make_equality_group(lambda: cirq.GateOperation(g1, r21)) eq.add_equality_group(cirq.GateOperation(cirq.CZ, r21), cirq.GateOperation(cirq.CZ, r12)) # Interchangeable subsets. class PairGate(cirq.Gate, cirq.InterchangeableQubitsGate): def qubit_index_to_equivalence_group_key(self, index: int): return index // 2 p = PairGate() 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_freeze_op_tree(): operations = [ cirq.GateOperation(cirq.Gate(), [cirq.NamedQubit(str(i))]) for i in range(10) ] # Empty tree. assert cirq.freeze_op_tree([[[]]]) == (((), ), ) # Just an item. assert cirq.freeze_op_tree(operations[0]) == operations[0] # Flat list. assert cirq.freeze_op_tree(operations) == tuple(operations) # Tree. assert (cirq.freeze_op_tree( (operations[0], (operations[i] for i in range(1, 5)), operations[5:])) == (operations[0], tuple(operations[1:5]), tuple(operations[5:]))) # Bad trees. with pytest.raises(TypeError): cirq.freeze_op_tree(None) with pytest.raises(TypeError): cirq.freeze_op_tree(5) with pytest.raises(TypeError): _ = cirq.freeze_op_tree([operations[0], (4, )])
def test_transform_leaves(): gs = [cirq.Gate() for _ in range(10)] operations = [ cirq.GateOperation(gs[i], [cirq.NamedQubit(str(i))]) for i in range(10) ] expected = [ cirq.GateOperation(gs[i], [cirq.NamedQubit(str(i) + 'a')]) for i in range(10) ] def move_left(op: cirq.GateOperation): return cirq.GateOperation(op.gate, [ cirq.NamedQubit(cast(cirq.NamedQubit, q).name + 'a') for q in op.qubits ]) def move_tree_left_freeze(root): return cirq.freeze_op_tree(cirq.transform_op_tree(root, move_left)) # Empty tree. assert move_tree_left_freeze([[[]]]) == (((), ), ) # Just an item. assert move_tree_left_freeze(operations[0]) == expected[0] # Flat list. assert move_tree_left_freeze(operations) == tuple(expected) # Tree. assert (move_tree_left_freeze( (operations[0], operations[1:5], operations[5:])) == (expected[0], tuple(expected[1:5]), tuple(expected[5:])))
def test_flatten_op_tree(): operations = [ cirq.GateOperation(cirq.Gate(), [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 # 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_transform_internal_nodes(): operations = [ cirq.GateOperation(cirq.Gate(), [cirq.LineQubit(2 * i)]) for i in range(10) ] def skip_first(op): first = True for item in op: if not first: yield item first = False def skip_tree_freeze(root): return cirq.freeze_op_tree( cirq.transform_op_tree(root, iter_transformation=skip_first)) # Empty tree. assert skip_tree_freeze([[[]]]) == () assert skip_tree_freeze([[[]], [[], []]]) == (((), ), ) # Just an item. assert skip_tree_freeze(operations[0]) == operations[0] # Flat list. assert skip_tree_freeze(operations) == tuple(operations[1:]) # Tree. assert (skip_tree_freeze( (operations[1:5], operations[0], operations[5:])) == (operations[0], tuple(operations[6:])))
def test_bounded_effect(): q = cirq.NamedQubit('q') # If the gate isn't bounded, you get a type error. op0 = cirq.GateOperation(cirq.Gate(), [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_transform_bad_tree(): with pytest.raises(TypeError): _ = list(cirq.transform_op_tree(None)) with pytest.raises(TypeError): _ = list(cirq.transform_op_tree(5)) with pytest.raises(TypeError): _ = list(cirq.flatten_op_tree(cirq.transform_op_tree([ cirq.GateOperation(cirq.Gate(), [cirq.NamedQubit('q')]), (4,) ])))
def test_inverse(): q = cirq.NamedQubit('q') # If the gate isn't reversible, you get a type error. op0 = cirq.GateOperation(cirq.Gate(), [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.Gate(), [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.Gate(), [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_inverse(): q = cirq.NamedQubit('q') # If the gate isn't reversible, you get a type error. op0 = cirq.GateOperation(cirq.Gate(), [q]) assert not cirq.can_cast(cirq.ReversibleEffect, op0) with pytest.raises(TypeError): _ = op0.inverse() op1 = cirq.GateOperation(cirq.S, [q]) assert cirq.can_cast(cirq.ReversibleEffect, op1) assert op1.inverse() == cirq.GateOperation(cirq.S.inverse(), [q]) assert cirq.S.inverse().on(q) == cirq.S.on(q).inverse()
def test_bounded_effect(): q = cirq.NamedQubit('q') # If the gate isn't bounded, you get a type error. op0 = cirq.GateOperation(cirq.Gate(), [q]) assert not cirq.can_cast(cirq.BoundedEffect, op0) with pytest.raises(TypeError): _ = op0.trace_distance_bound() op1 = cirq.GateOperation(cirq.Z**0.000001, [q]) assert cirq.can_cast(cirq.BoundedEffect, op1) assert op1.trace_distance_bound() == ( cirq.Z**0.000001).trace_distance_bound()
def test_with_qubits_and_transform_qubits(): g = cirq.Gate() op = cirq.GateOperation(g, cirq.LineQubit.range(3)) assert op.with_qubits(*cirq.LineQubit.range(2) ) == cirq.GateOperation(g, cirq.LineQubit.range(2)) assert op.transform_qubits(lambda e: cirq.LineQubit(-e.x) ) == cirq.GateOperation(g, [cirq.LineQubit(0), cirq.LineQubit(-1), cirq.LineQubit(-2)]) # The gate's constraints should be applied when changing the qubits. with pytest.raises(ValueError): _ = cirq.Y(cirq.LineQubit(0)).with_qubits(cirq.LineQubit(0), cirq.LineQubit(1))
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(cg.ExpZGate().on(q00)) == 0 * ns assert d.duration_of(cirq.measure(q00)) == ns assert d.duration_of(cirq.measure(q00, q01)) == ns assert d.duration_of(cg.ExpWGate().on(q00)) == 2 * ns assert d.duration_of(cg.Exp11Gate().on(q00, q01)) == 3 * ns with pytest.raises(ValueError): _ = d.duration_of(cirq.Gate().on(q00))
def test_text_diagrammable(): q = cirq.NamedQubit('q') # If the gate isn't diagrammable, you get a type error. op0 = cirq.GateOperation(cirq.Gate(), [q]) assert not cirq.can_cast(cirq.TextDiagrammable, op0) with pytest.raises(TypeError): _ = op0.text_diagram_info(cirq.TextDiagramInfoArgs.UNINFORMED_DEFAULT) op1 = cirq.GateOperation(cirq.S, [q]) assert cirq.can_cast(cirq.TextDiagrammable, op1) actual = op1.text_diagram_info(cirq.TextDiagramInfoArgs.UNINFORMED_DEFAULT) expected = cirq.S.text_diagram_info( cirq.TextDiagramInfoArgs.UNINFORMED_DEFAULT) assert actual == expected
def test_extrapolate(): q = cirq.NamedQubit('q') # If the gate isn't extrapolatable, you get a type error. op0 = cirq.GateOperation(cirq.Gate(), [q]) assert not cirq.can_cast(cirq.ExtrapolatableEffect, op0) with pytest.raises(TypeError): _ = op0.extrapolate_effect(0.5) with pytest.raises(TypeError): _ = op0**0.5 op1 = cirq.GateOperation(cirq.Y, [q]) assert cirq.can_cast(cirq.ExtrapolatableEffect, op1) assert op1**0.5 == op1.extrapolate_effect(0.5) == cirq.GateOperation( cirq.Y**0.5, [q]) assert (cirq.Y**0.5).on(q) == cirq.Y(q)**0.5
def test_parameterizable_effect(): q = cirq.NamedQubit('q') r = cirq.ParamResolver({'a': 0.5}) # If the gate isn't parameterizable, you get a type error. op0 = cirq.GateOperation(cirq.Gate(), [q]) assert not cirq.can_cast(cirq.ParameterizableEffect, op0) with pytest.raises(TypeError): _ = op0.is_parameterized() with pytest.raises(TypeError): _ = op0.with_parameters_resolved_by(r) op1 = cirq.GateOperation(cirq.RotZGate(half_turns=cirq.Symbol('a')), [q]) assert cirq.can_cast(cirq.ParameterizableEffect, op1) assert op1.is_parameterized() op2 = op1.with_parameters_resolved_by(r) assert not op2.is_parameterized() assert op2 == cirq.S.on(q)
def test_gate_operation_init(): q = cirq.NamedQubit('q') g = cirq.Gate() v = cirq.GateOperation(g, (q, )) assert v.gate == g assert v.qubits == (q, )
def test_operation_init(): q = cirq.QubitId() g = cirq.Gate() v = cirq.Operation(g, (q, )) assert v.gate == g assert v.qubits == (q, )