def test_qubits(): a = ops.QubitId() b = ops.QubitId() assert Moment([ops.X(a), ops.X(b)]).qubits == {a , b} assert Moment([ops.X(a)]).qubits == {a} assert Moment([ops.CZ(a, b)]).qubits == {a, b}
def test_copy(): a = ops.QubitId() b = ops.QubitId() original = Moment([ops.CZ(a, b)]) copy = original.__copy__() assert original == copy assert id(original) != id(copy)
def test_to_text_diagram_teleportation_to_diagram(): ali = cirq.NamedQubit('(0, 0)') bob = cirq.NamedQubit('(0, 1)') msg = cirq.NamedQubit('(1, 0)') tmp = cirq.NamedQubit('(1, 1)') c = Circuit([ Moment([cirq.H(ali)]), Moment([cirq.CNOT(ali, bob)]), Moment([cirq.X(msg)**0.5]), Moment([cirq.CNOT(msg, ali)]), Moment([cirq.H(msg)]), Moment([cirq.measure(msg), cirq.measure(ali)]), Moment([cirq.CNOT(ali, bob)]), Moment([cirq.CNOT(msg, tmp)]), Moment([cirq.CZ(bob, tmp)]), ]) assert c.to_text_diagram().strip() == """ (0, 0): ───H───@───────────X───────M───@─────────── │ │ │ (0, 1): ───────X───────────┼───────────X───────@─── │ │ (1, 0): ───────────X^0.5───@───H───M───────@───┼─── │ │ (1, 1): ───────────────────────────────────X───@─── """.strip() assert c.to_text_diagram(use_unicode_characters=False).strip() == """ (0, 0): ---H---@-----------X-------M---@----------- | | | (0, 1): -------X-----------|-----------X-------@--- | | (1, 0): -----------X^0.5---@---H---M-------@---|--- | | (1, 1): -----------------------------------X---@--- """.strip() assert c.to_text_diagram(transpose=True, use_unicode_characters=False).strip() == """ (0, 0) (0, 1) (1, 0) (1, 1) | | | | H | | | | | | | @------X | | | | | | | | X^0.5 | | | | | X-------------@ | | | | | | | H | | | | | M | M | | | | | @------X | | | | | | | | @------X | | | | | @-------------@ | | | | """.strip()
def test_with_operation(): a = ops.QubitId() b = ops.QubitId() assert Moment().with_operation(ops.X(a)) == Moment([ops.X(a)]) assert (Moment([ops.X(a)]).with_operation(ops.X(b)) == Moment([ops.X(a), ops.X(b)])) with pytest.raises(ValueError): _ = Moment([ops.X(a)]).with_operation(ops.X(a))
def test_to_text_diagram_extended_gate(): q = cirq.NamedQubit('(0, 0)') q2 = cirq.NamedQubit('(0, 1)') q3 = cirq.NamedQubit('(0, 2)') class FGate(cirq.Gate): def __repr__(self): return 'python-object-FGate:arbitrary-digits' f = FGate() c = Circuit([ Moment([f.on(q)]), ]) # Fallback to repr without extension. diagram = Circuit([ Moment([f.on(q)]), ]).to_text_diagram(use_unicode_characters=False) assert diagram.strip() == """ (0, 0): ---python-object-FGate:arbitrary-digits--- """.strip() # When used on multiple qubits, show the qubit order as a digit suffix. diagram = Circuit([ Moment([f.on(q, q3, q2)]), ]).to_text_diagram(use_unicode_characters=False) assert diagram.strip() == """ (0, 0): ---python-object-FGate:arbitrary-digits:0--- | (0, 1): ---python-object-FGate:arbitrary-digits:2--- | (0, 2): ---python-object-FGate:arbitrary-digits:1--- """.strip() # Succeeds with extension. class FGateAsText(cirq.TextDiagrammableGate): def __init__(self, f_gate): self.f_gate = f_gate def text_diagram_wire_symbols(self, qubit_count=None, use_unicode_characters=True, precision=3): return 'F' diagram = c.to_text_diagram(Extensions( {cirq.TextDiagrammableGate: { FGate: FGateAsText }}), use_unicode_characters=False) assert diagram.strip() == """ (0, 0): ---F--- """.strip()
def test_append_single(): a = cirq.QubitId() c = Circuit() c.append(()) assert c == Circuit() c = Circuit() c.append(cirq.X(a)) assert c == Circuit([Moment([cirq.X(a)])]) c = Circuit() c.append([cirq.X(a)]) assert c == Circuit([Moment([cirq.X(a)])])
def insert( self, index: int, operation_tree: ops.OP_TREE, strategy: InsertStrategy = InsertStrategy.NEW_THEN_INLINE) -> int: """Inserts operations into the middle of the circuit. Args: index: The index to insert all of the operations at. operation_tree: An operation or tree of operations. strategy: How to pick/create the moment to put operations into. Returns: The insertion index that will place operations just after the operations that were inserted by this method. Raises: IndexError: Bad insertion index. ValueError: Bad insertion strategy. """ if not 0 <= index <= len(self.moments): raise IndexError('Insert index out of range: {}'.format(index)) k = index for op in ops.flatten_op_tree(operation_tree): p = self._pick_or_create_inserted_op_moment_index(k, op, strategy) while p >= len(self.moments): self.moments.append(Moment()) self.moments[p] = self.moments[p].with_operation(op) k = max(k, p + 1) if strategy is InsertStrategy.NEW_THEN_INLINE: strategy = InsertStrategy.INLINE return k
def test_diagram_custom_precision(): qa = cirq.NamedQubit('a') c = Circuit([Moment([cirq.X(qa)**0.12341234])]) diagram = c.to_text_diagram(use_unicode_characters=False, precision=5) assert diagram.strip() == """ a: ---X^0.12341--- """.strip()
def test_container_methods(): a = cirq.QubitId() b = cirq.QubitId() c = Circuit([ Moment([cirq.H(a), cirq.H(b)]), Moment([cirq.CZ(a, b)]), Moment([cirq.H(b)]), ]) assert list(c) == list(c.moments) # __iter__ assert list(iter(c)) == list(c.moments) # __reversed__ for free. assert list(reversed(c)) == list(reversed(c.moments)) # __contains__ for free. assert Moment([cirq.H(b)]) in c assert len(c) == 3
def test_none_precision_diagram(): # Test default precision of 3 qa = cirq.NamedQubit('a') c = Circuit([Moment([cirq.X(qa)**0.4921875])]) diagram = c.to_text_diagram(use_unicode_characters=False, precision=None) assert diagram.strip() == """ a: ---X^0.4921875--- """.strip()
def test_diagram_wgate_none_precision(): qa = cirq.NamedQubit('a') test_wgate = ExpWGate(half_turns=0.12341234, axis_half_turns=0.43214321) c = Circuit([Moment([test_wgate.on(qa)])]) diagram = c.to_text_diagram(use_unicode_characters=False, precision=None) assert diagram.strip() == """ a: ---W(0.43214321)^0.12341234--- """.strip()
def test_overly_precise_diagram(): # Test default precision of 3 qa = cirq.NamedQubit('a') c = Circuit([Moment([cirq.X(qa)**0.12345678])]) diagram = c.to_text_diagram(use_unicode_characters=False) assert diagram.strip() == """ a: ---X^0.123--- """.strip()
def test_multiply(): a = cirq.QubitId() c = Circuit() d = Circuit([Moment([cirq.X(a)])]) assert c * 0 == Circuit() assert d * 0 == Circuit() assert d * 2 == Circuit([Moment([cirq.X(a)]), Moment([cirq.X(a)])]) assert 1 * c == Circuit() assert -1 * d == Circuit() assert 1 * d == Circuit([Moment([cirq.X(a)])]) d *= 3 assert d == Circuit( [Moment([cirq.X(a)]), Moment([cirq.X(a)]), Moment([cirq.X(a)])]) with pytest.raises(TypeError): _ = c * 'a' with pytest.raises(TypeError): _ = 'a' * c with pytest.raises(TypeError): c *= 'a'
def test_from_ops(): a = cirq.QubitId() b = cirq.QubitId() actual = Circuit.from_ops( cirq.X(a), [cirq.Y(a), cirq.Z(b)], cirq.CZ(a, b), cirq.X(a), [cirq.Z(b), cirq.Y(a)], ) assert actual == Circuit([ Moment([cirq.X(a)]), Moment([cirq.Y(a), cirq.Z(b)]), Moment([cirq.CZ(a, b)]), Moment([cirq.X(a), cirq.Z(b)]), Moment([cirq.Y(a)]), ])
def test_append_multiple(): a = cirq.QubitId() b = cirq.QubitId() c = Circuit() c.append([cirq.X(a), cirq.X(b)], InsertStrategy.NEW) assert c == Circuit([Moment([cirq.X(a)]), Moment([cirq.X(b)])]) c = Circuit() c.append([cirq.X(a), cirq.X(b)], InsertStrategy.EARLIEST) assert c == Circuit([ Moment([cirq.X(a), cirq.X(b)]), ]) c = Circuit() c.append(cirq.X(a), InsertStrategy.EARLIEST) c.append(cirq.X(b), InsertStrategy.EARLIEST) assert c == Circuit([ Moment([cirq.X(a), cirq.X(b)]), ])
def test_validation(): a = ops.QubitId() b = ops.QubitId() c = ops.QubitId() d = ops.QubitId() _ = Moment([]) _ = Moment([ops.X(a)]) _ = Moment([ops.CZ(a, b)]) _ = Moment([ops.CZ(b, d)]) _ = Moment([ops.CZ(a, b), ops.CZ(c, d)]) _ = Moment([ops.CZ(a, c), ops.CZ(b, d)]) _ = Moment([ops.CZ(a, c), ops.X(b)]) with pytest.raises(ValueError): _ = Moment([ops.X(a), ops.X(a)]) with pytest.raises(ValueError): _ = Moment([ops.CZ(a, c), ops.X(c)]) with pytest.raises(ValueError): _ = Moment([ops.CZ(a, c), ops.CZ(c, d)])
def test_operation_at(): a = cirq.QubitId() b = cirq.QubitId() c = Circuit() assert c.operation_at(a, 0) is None assert c.operation_at(a, -1) is None assert c.operation_at(a, 102) is None c = Circuit([Moment()]) assert c.operation_at(a, 0) is None c = Circuit([Moment([cirq.X(a)])]) assert c.operation_at(b, 0) is None assert c.operation_at(a, 1) is None assert c.operation_at(a, 0) == cirq.X(a) c = Circuit([Moment(), Moment([cirq.CZ(a, b)])]) assert c.operation_at(a, 0) is None assert c.operation_at(a, 1) == cirq.CZ(a, b)
def to_text_diagram_drawer( self, ext: Extensions = None, use_unicode_characters: bool = True, qubit_name_suffix: str = '', precision: Optional[int] = 3, qubit_order: ops.QubitOrderOrList = ops.QubitOrder.DEFAULT, ) -> TextDiagramDrawer: """Returns a TextDiagramDrawer with the circuit drawn into it. Args: ext: For extending gates to implement TextDiagrammableGate. use_unicode_characters: Determines if unicode characters are allowed (as opposed to ascii-only diagrams). qubit_name_suffix: Appended to qubit names in the diagram. precision: Number of digits to use when representing numbers. qubit_order: Determines how qubits are ordered in the diagram. Returns: The TextDiagramDrawer instance. """ if ext is None: ext = Extensions() qubits = ops.QubitOrder.as_qubit_order(qubit_order).order_for( self.qubits()) qubit_map = {qubits[i]: i for i in range(len(qubits))} diagram = TextDiagramDrawer() for q, i in qubit_map.items(): diagram.write(0, i, str(q) + qubit_name_suffix) for moment in [Moment()] * 2 + self.moments + [Moment()]: _draw_moment_in_diagram(moment, ext, use_unicode_characters, qubit_map, diagram, precision) w = diagram.width() for i in qubit_map.values(): diagram.horizontal_line(i, 0, w) return diagram
def test_prev_moment_operating_on(): a = cirq.QubitId() b = cirq.QubitId() c = Circuit() assert c.prev_moment_operating_on([a]) is None assert c.prev_moment_operating_on([a], 0) is None assert c.prev_moment_operating_on([a], 102) is None c = Circuit([Moment([cirq.X(a)])]) assert c.prev_moment_operating_on([a]) == 0 assert c.prev_moment_operating_on([a], 1) == 0 assert c.prev_moment_operating_on([a, b]) == 0 assert c.prev_moment_operating_on([a], 0) is None assert c.prev_moment_operating_on([b]) is None c = Circuit([ Moment([cirq.CZ(a, b)]), Moment(), Moment([cirq.X(a)]), Moment(), ]) assert c.prev_moment_operating_on([a], 4) == 2 assert c.prev_moment_operating_on([a], 3) == 2 assert c.prev_moment_operating_on([a], 2) == 0 assert c.prev_moment_operating_on([a], 1) == 0 assert c.prev_moment_operating_on([a], 0) is None assert c.prev_moment_operating_on([b], 4) == 0 assert c.prev_moment_operating_on([b], 3) == 0 assert c.prev_moment_operating_on([b], 2) == 0 assert c.prev_moment_operating_on([b], 1) == 0 assert c.prev_moment_operating_on([b], 0) is None assert c.prev_moment_operating_on([a, b], 4) == 2 assert c.prev_moment_operating_on([a, b], 3) == 2 assert c.prev_moment_operating_on([a, b], 2) == 0 assert c.prev_moment_operating_on([a, b], 1) == 0 assert c.prev_moment_operating_on([a, b], 0) is None
def test_prev_moment_operating_on_distance(): a = cirq.QubitId() c = Circuit([ Moment(), Moment([cirq.X(a)]), Moment(), Moment(), Moment(), Moment(), ]) assert c.prev_moment_operating_on([a], max_distance=4) is None assert c.prev_moment_operating_on([a], 6, max_distance=4) is None assert c.prev_moment_operating_on([a], 5, max_distance=3) is None assert c.prev_moment_operating_on([a], 4, max_distance=2) is None assert c.prev_moment_operating_on([a], 3, max_distance=1) is None assert c.prev_moment_operating_on([a], 2, max_distance=0) is None assert c.prev_moment_operating_on([a], 1, max_distance=0) is None assert c.prev_moment_operating_on([a], 0, max_distance=0) is None assert c.prev_moment_operating_on([a], 6, max_distance=5) == 1 assert c.prev_moment_operating_on([a], 5, max_distance=4) == 1 assert c.prev_moment_operating_on([a], 4, max_distance=3) == 1 assert c.prev_moment_operating_on([a], 3, max_distance=2) == 1 assert c.prev_moment_operating_on([a], 2, max_distance=1) == 1 assert c.prev_moment_operating_on([a], 6, max_distance=10) == 1 assert c.prev_moment_operating_on([a], 6, max_distance=100) == 1 assert c.prev_moment_operating_on([a], 13, max_distance=500) == 1 # Huge max distances should be handled quickly due to capping. assert c.prev_moment_operating_on([a], 1, max_distance=10**100) is None
def test_job_equality(): eq = EqualsTester() q = ops.QubitId() q2 = ops.QubitId() # Equivalent empty jobs eq.add_equality_group(Job(), Job(Circuit()), Job(Circuit([])), Job(Circuit(), sweeps.Unit)) # Equivalent circuit, different instances eq.add_equality_group(Job(Circuit([Moment([ops.Z(q)])])), Job(Circuit([Moment([ops.Z(q)])]))) # Different Circuit c = Circuit([Moment([ops.CZ(q, q2)])]) eq.add_equality_group(Job(c)) ps1 = sweeps.Points('Example', [42.0]) ps2 = sweeps.Points('Example', [42.0]) ps3 = sweeps.Points('Example', [42.0, 1.4]) eq.add_equality_group(Job(c, ps1, 2), Job(c, ps2, 2)) eq.add_equality_group(Job(c, ps1, 4)) eq.add_equality_group(Job(c, ps3, 2))
def test_to_text_diagram_many_qubits_gate_but_multiple_wire_symbols(): class BadGate(cirq.TextDiagrammableGate): def text_diagram_wire_symbols(self, qubit_count=None, use_unicode_characters=True, precision=3): return 'a', 'a' q1 = cirq.NamedQubit('(0, 0)') q2 = cirq.NamedQubit('(0, 1)') q3 = cirq.NamedQubit('(0, 2)') c = Circuit([Moment([BadGate().on(q1, q2, q3)])]) with pytest.raises(ValueError, match='BadGate'): c.to_text_diagram()
def test_to_text_diagram_custom_order(): qa = cirq.NamedQubit('2') qb = cirq.NamedQubit('3') qc = cirq.NamedQubit('4') c = Circuit([Moment([cirq.X(qa), cirq.X(qb), cirq.X(qc)])]) diagram = c.to_text_diagram( qubit_order=cirq.QubitOrder.sorted_by(lambda e: int(str(e)) % 3), use_unicode_characters=False) assert diagram.strip() == """ 3: ---X--- 4: ---X--- 2: ---X--- """.strip()
def test_iter_ops(): a = cirq.NamedQubit('a') b = cirq.NamedQubit('b') c = Circuit([ Moment([]), Moment([cirq.X(a), cirq.Y(b)]), Moment([]), Moment([cirq.CNOT(a, b)]), Moment([cirq.Z(b), cirq.H(a)]), # Different qubit order Moment([]) ]) expected = [cirq.X(a), cirq.Y(b), cirq.CNOT(a, b), cirq.Z(b), cirq.H(a)] assert list(c.iter_ops()) == expected
def _pick_or_create_inserted_op_moment_index( self, splitter_index: int, op: ops.Operation, strategy: InsertStrategy) -> int: """Determines and prepares where an insertion will occur. Args: splitter_index: The index to insert at. op: The operation that will be inserted. strategy: The insertion strategy. Returns: The index of the (possibly new) moment where the insertion should occur. Raises: ValueError: Unrecognized append strategy. """ if (strategy is InsertStrategy.NEW or strategy is InsertStrategy.NEW_THEN_INLINE): self.moments.insert(splitter_index, Moment()) return splitter_index if strategy is InsertStrategy.INLINE: if (not self._has_op_at(splitter_index - 1, op.qubits) and 0 <= splitter_index - 1 < len(self.moments)): return splitter_index - 1 return self._pick_or_create_inserted_op_moment_index( splitter_index, op, InsertStrategy.NEW) if strategy is InsertStrategy.EARLIEST: if not self._has_op_at(splitter_index, op.qubits): p = self.prev_moment_operating_on(op.qubits, splitter_index) return p + 1 if p is not None else 0 return self._pick_or_create_inserted_op_moment_index( splitter_index, op, InsertStrategy.INLINE) raise ValueError('Unrecognized append strategy: {}'.format(strategy))
def test_qubits(): a = cirq.QubitId() b = cirq.QubitId() c = Circuit([ Moment([cirq.X(a)]), Moment([cirq.X(b)]), ]) assert c.qubits() == {a, b} c = Circuit([ Moment([cirq.X(a)]), Moment([cirq.X(a)]), ]) assert c.qubits() == {a} c = Circuit([ Moment([cirq.CZ(a, b)]), ]) assert c.qubits() == {a, b} c = Circuit([Moment([cirq.CZ(a, b)]), Moment([cirq.X(a)])]) assert c.qubits() == {a, b}
def test_operates_on(): a = ops.QubitId() b = ops.QubitId() c = ops.QubitId() # Empty case. assert not Moment().operates_on([]) assert not Moment().operates_on([a]) assert not Moment().operates_on([b]) assert not Moment().operates_on([a, b]) # One-qubit operation case. assert not Moment([ops.X(a)]).operates_on([]) assert Moment([ops.X(a)]).operates_on([a]) assert not Moment([ops.X(a)]).operates_on([b]) assert Moment([ops.X(a)]).operates_on([a, b]) # Two-qubit operation case. assert not Moment([ops.CZ(a, b)]).operates_on([]) assert Moment([ops.CZ(a, b)]).operates_on([a]) assert Moment([ops.CZ(a, b)]).operates_on([b]) assert Moment([ops.CZ(a, b)]).operates_on([a, b]) assert not Moment([ops.CZ(a, b)]).operates_on([c]) assert Moment([ops.CZ(a, b)]).operates_on([a, c]) assert Moment([ops.CZ(a, b)]).operates_on([a, b, c]) # Multiple operations case. assert not Moment([ops.X(a), ops.X(b)]).operates_on([]) assert Moment([ops.X(a), ops.X(b)]).operates_on([a]) assert Moment([ops.X(a), ops.X(b)]).operates_on([b]) assert Moment([ops.X(a), ops.X(b)]).operates_on([a, b]) assert not Moment([ops.X(a), ops.X(b)]).operates_on([c]) assert Moment([ops.X(a), ops.X(b)]).operates_on([a, c]) assert Moment([ops.X(a), ops.X(b)]).operates_on([a, b, c])
def test_equality(): a = ops.QubitId() b = ops.QubitId() c = ops.QubitId() d = ops.QubitId() eq = EqualsTester() # Default is empty. Iterables get frozen into tuples. eq.add_equality_group(Moment(), Moment([]), Moment(())) eq.add_equality_group( Moment([ops.X(d)]), Moment((ops.X(d),))) # Equality depends on gate and qubits. eq.add_equality_group(Moment([ops.X(a)])) eq.add_equality_group(Moment([ops.X(b)])) eq.add_equality_group(Moment([ops.Y(a)])) # Equality depends on order. eq.add_equality_group(Moment([ops.X(a), ops.X(b)])) eq.add_equality_group(Moment([ops.X(b), ops.X(a)])) # Two qubit gates. eq.make_equality_pair(lambda: Moment([ops.CZ(c, d)])) eq.make_equality_pair(lambda: Moment([ops.CZ(a, c)])) eq.make_equality_pair(lambda: Moment([ops.CZ(a, b), ops.CZ(c, d)])) eq.make_equality_pair(lambda: Moment([ops.CZ(a, c), ops.CZ(b, d)]))
def test_slice(): a = cirq.QubitId() b = cirq.QubitId() c = Circuit([ Moment([cirq.H(a), cirq.H(b)]), Moment([cirq.CZ(a, b)]), Moment([cirq.H(b)]), ]) assert c[0:1] == Circuit([Moment([cirq.H(a), cirq.H(b)])]) assert c[::2] == Circuit( [Moment([cirq.H(a), cirq.H(b)]), Moment([cirq.H(b)])]) assert c[0:1:2] == Circuit([Moment([cirq.H(a), cirq.H(b)])]) assert c[1:3:] == Circuit([Moment([cirq.CZ(a, b)]), Moment([cirq.H(b)])]) assert c[::-1] == Circuit([ Moment([cirq.H(b)]), Moment([cirq.CZ(a, b)]), Moment([cirq.H(a), cirq.H(b)]) ]) assert c[3:0:-1] == Circuit([Moment([cirq.H(b)]), Moment([cirq.CZ(a, b)])]) assert c[0:2:-1] == Circuit()
def test_without_operations_touching(): a = ops.QubitId() b = ops.QubitId() c = ops.QubitId() # Empty case. assert Moment().without_operations_touching([]) == Moment() assert Moment().without_operations_touching([a]) == Moment() assert Moment().without_operations_touching([a, b]) == Moment() # One-qubit operation case. assert (Moment([ops.X(a)]).without_operations_touching([]) == Moment([ops.X(a)])) assert (Moment([ops.X(a)]).without_operations_touching([a]) == Moment()) assert (Moment([ops.X(a)]).without_operations_touching([b]) == Moment([ops.X(a)])) # Two-qubit operation case. assert (Moment([ops.CZ(a, b)]).without_operations_touching([]) == Moment([ops.CZ(a, b)])) assert (Moment([ops.CZ(a, b)]).without_operations_touching([a]) == Moment()) assert (Moment([ops.CZ(a, b)]).without_operations_touching([b]) == Moment()) assert (Moment([ops.CZ(a, b)]).without_operations_touching([c]) == Moment([ops.CZ(a, b)])) # Multiple operation case. assert (Moment([ops.CZ(a, b), ops.X(c)]).without_operations_touching([]) == Moment([ops.CZ(a, b), ops.X(c)])) assert (Moment([ops.CZ(a, b), ops.X(c)]).without_operations_touching([a]) == Moment([ops.X(c)])) assert (Moment([ops.CZ(a, b), ops.X(c)]).without_operations_touching([b]) == Moment([ops.X(c)])) assert (Moment([ops.CZ(a, b), ops.X(c)]).without_operations_touching([c]) == Moment([ops.CZ(a, b)])) assert (Moment([ops.CZ(a, b), ops.X(c)]).without_operations_touching([a, b]) == Moment([ops.X(c)])) assert (Moment([ops.CZ(a, b), ops.X(c)]).without_operations_touching([a, c]) == Moment())