def test_circuit_diagram_tagged_global_phase(): # Tests global phase operation q = cirq.NamedQubit('a') global_phase = cirq.GlobalPhaseOperation( coefficient=-1.0).with_tags('tag0') # Just global phase in a circuit assert (cirq.circuit_diagram_info(global_phase, default='default') == 'default') cirq.testing.assert_has_diagram(cirq.Circuit(global_phase), "\n\nglobal phase: π['tag0']", use_unicode_characters=True) cirq.testing.assert_has_diagram(cirq.Circuit(global_phase), "\n\nglobal phase: π", use_unicode_characters=True, include_tags=False) expected = cirq.CircuitDiagramInfo(wire_symbols=(), exponent=1.0, connected=True, exponent_qubit_index=None, auto_exponent_parens=True) # Operation with no qubits and returns diagram info with no wire symbols class NoWireSymbols(cirq.GlobalPhaseOperation): def _circuit_diagram_info_( self, args: 'cirq.CircuitDiagramInfoArgs' ) -> 'cirq.CircuitDiagramInfo': return expected no_wire_symbol_op = NoWireSymbols(coefficient=-1.0).with_tags('tag0') assert (cirq.circuit_diagram_info(no_wire_symbol_op, default='default') == expected) cirq.testing.assert_has_diagram(cirq.Circuit(no_wire_symbol_op), "\n\nglobal phase: π['tag0']", use_unicode_characters=True) # Two global phases in one moment tag1 = cirq.GlobalPhaseOperation(coefficient=1j).with_tags('tag1') tag2 = cirq.GlobalPhaseOperation(coefficient=1j).with_tags('tag2') c = cirq.Circuit([cirq.X(q), tag1, tag2]) cirq.testing.assert_has_diagram(c, """\ a: ─────────────X─────────────────── global phase: π['tag1', 'tag2']""", use_unicode_characters=True, precision=2) # Two moments with global phase, one with another tagged gate c = cirq.Circuit([cirq.X(q).with_tags('x_tag'), tag1]) c.append(cirq.Moment([cirq.X(q), tag2])) cirq.testing.assert_has_diagram(c, """\ a: ─────────────X['x_tag']─────X────────────── global phase: 0.5π['tag1'] 0.5π['tag2'] """, use_unicode_characters=True, include_tags=True)
def test_reset_channel_text_diagram(): assert cirq.circuit_diagram_info(cirq.ResetChannel()) == cirq.CircuitDiagramInfo( wire_symbols=('R',) ) assert cirq.circuit_diagram_info(cirq.ResetChannel(3)) == cirq.CircuitDiagramInfo( wire_symbols=('R',) )
def test_measurement_gate_diagram(): # Shows observable & key. assert cirq.circuit_diagram_info( cirq.PauliMeasurementGate([cirq.X], key='test') ) == cirq.CircuitDiagramInfo(("M(X)('test')",)) # Shows multiple observables. assert cirq.circuit_diagram_info( cirq.PauliMeasurementGate([cirq.X, cirq.Y, cirq.Z], 'a') ) == cirq.CircuitDiagramInfo(("M(X)('a')", 'M(Y)', 'M(Z)')) # Omits key when it is the default. a = cirq.NamedQubit('a') b = cirq.NamedQubit('b') cirq.testing.assert_has_diagram( cirq.Circuit(cirq.measure_single_paulistring(cirq.X(a) * cirq.Y(b))), """ a: ───M(X)─── │ b: ───M(Y)─── """, ) cirq.testing.assert_has_diagram( cirq.Circuit(cirq.measure_single_paulistring(cirq.X(a) * cirq.Y(b), key='test')), """ a: ───M(X)('test')─── │ b: ───M(Y)─────────── """, )
def test_inverse_composite_diagram_info(): class Gate(cirq.Gate): def _decompose_(self, qubits): return cirq.S.on(qubits[0]) def num_qubits(self) -> int: return 1 c = cirq.inverse(Gate()) assert cirq.circuit_diagram_info(c, default=None) is None class Gate2(cirq.Gate): def _decompose_(self, qubits): return cirq.S.on(qubits[0]) def num_qubits(self) -> int: return 1 def _circuit_diagram_info_(self, args): return 's!' c = cirq.inverse(Gate2()) assert cirq.circuit_diagram_info(c) == cirq.CircuitDiagramInfo( wire_symbols=('s!',), exponent=-1 )
def test_circuit_diagram_info_value_wrapping(): single_info = cirq.CircuitDiagramInfo(('Single',)) class ReturnInfo: def _circuit_diagram_info_(self, args): return single_info class ReturnTuple: def _circuit_diagram_info_(self, args): return 'Single', class ReturnString: def _circuit_diagram_info_(self, args): return 'Single' assert (cirq.circuit_diagram_info(ReturnInfo()) == cirq.circuit_diagram_info(ReturnTuple()) == cirq.circuit_diagram_info(ReturnString()) == single_info) double_info = cirq.CircuitDiagramInfo(('Single', 'Double',)) class ReturnDoubleInfo: def _circuit_diagram_info_(self, args): return double_info class ReturnDoubleTuple: def _circuit_diagram_info_(self, args): return 'Single', 'Double' assert (cirq.circuit_diagram_info(ReturnDoubleInfo()) == cirq.circuit_diagram_info(ReturnDoubleTuple()) == double_info)
def test_circuit_diagram(): class TaggyTag: """Tag with a custom repr function to test circuit diagrams.""" def __repr__(self): return 'TaggyTag()' h = cirq.H(cirq.GridQubit(1, 1)) tagged_h = h.with_tags('tag1') non_string_tag_h = h.with_tags(TaggyTag()) expected = cirq.CircuitDiagramInfo( wire_symbols=("H['tag1']",), exponent=1.0, connected=True, exponent_qubit_index=None, auto_exponent_parens=True, ) args = cirq.CircuitDiagramInfoArgs(None, None, None, None, None, False) assert cirq.circuit_diagram_info(tagged_h) == expected assert cirq.circuit_diagram_info(tagged_h, args) == cirq.circuit_diagram_info(h) c = cirq.Circuit(tagged_h) diagram_with_tags = "(1, 1): ───H['tag1']───" diagram_without_tags = "(1, 1): ───H───" assert str(cirq.Circuit(tagged_h)) == diagram_with_tags assert c.to_text_diagram() == diagram_with_tags assert c.to_text_diagram(include_tags=False) == diagram_without_tags c = cirq.Circuit(non_string_tag_h) diagram_with_non_string_tag = "(1, 1): ───H[TaggyTag()]───" assert c.to_text_diagram() == diagram_with_non_string_tag assert c.to_text_diagram(include_tags=False) == diagram_without_tags
def test_generalized_amplitude_damping_channel_text_diagram(): a = cirq.generalized_amplitude_damp(0.1, 0.39558391) assert cirq.circuit_diagram_info( a, args=round_to_6_prec) == cirq.CircuitDiagramInfo( wire_symbols=('GAD(0.1,0.395584)', )) assert cirq.circuit_diagram_info( a, args=round_to_2_prec) == cirq.CircuitDiagramInfo( wire_symbols=('GAD(0.1,0.4)', ))
def test_asymmetric_depolarizing_channel_text_diagram(): a = cirq.asymmetric_depolarize(1 / 9, 2 / 9, 3 / 9) assert (cirq.circuit_diagram_info( a, args=round_to_6_prec) == cirq.CircuitDiagramInfo( wire_symbols=('A(0.111111,0.222222,0.333333)', ))) assert (cirq.circuit_diagram_info( a, args=round_to_2_prec) == cirq.CircuitDiagramInfo( wire_symbols=('A(0.11,0.22,0.33)', )))
def test_depolarizing_channel_text_diagram(): d = cirq.depolarize(0.1234567) assert (cirq.circuit_diagram_info( d, args=round_to_6_prec) == cirq.CircuitDiagramInfo( wire_symbols=('D(0.123457)', ))) assert (cirq.circuit_diagram_info( d, args=round_to_2_prec) == cirq.CircuitDiagramInfo( wire_symbols=('D(0.12)', )))
def test_amplitude_damping_channel_text_diagram(): ad = cirq.amplitude_damp(0.38059322) assert cirq.circuit_diagram_info( ad, args=round_to_6_prec) == cirq.CircuitDiagramInfo( wire_symbols=('AD(0.380593)', )) assert cirq.circuit_diagram_info( ad, args=round_to_2_prec) == cirq.CircuitDiagramInfo( wire_symbols=('AD(0.38)', ))
def test_phase_damping_channel_text_diagram(): pd = cirq.phase_damp(0.1000009) assert cirq.circuit_diagram_info( pd, args=round_to_6_prec) == cirq.CircuitDiagramInfo( wire_symbols=('PD(0.100001)', )) assert cirq.circuit_diagram_info( pd, args=round_to_2_prec) == cirq.CircuitDiagramInfo( wire_symbols=('PD(0.1)', ))
def test_phase_flip_channel_text_diagram(): pf = cirq.phase_flip(0.987654) assert cirq.circuit_diagram_info( pf, args=round_to_6_prec) == cirq.CircuitDiagramInfo( wire_symbols=('PF(0.987654)', )) assert cirq.circuit_diagram_info( pf, args=round_to_2_prec) == cirq.CircuitDiagramInfo( wire_symbols=('PF(0.99)', ))
def test_bit_flip_channel_text_diagram(): bf = cirq.bit_flip(0.1234567) assert cirq.circuit_diagram_info( bf, args=round_to_6_prec) == cirq.CircuitDiagramInfo( wire_symbols=('BF(0.123457)', )) assert cirq.circuit_diagram_info( bf, args=round_to_2_prec) == cirq.CircuitDiagramInfo( wire_symbols=('BF(0.12)', ))
def test_measurement_gate_diagram(): # Shows key. assert cirq.circuit_diagram_info(cirq.MeasurementGate(1)) == cirq.CircuitDiagramInfo(("M('')",)) assert cirq.circuit_diagram_info( cirq.MeasurementGate(1, key='test') ) == cirq.CircuitDiagramInfo(("M('test')",)) # Uses known qubit count. assert ( cirq.circuit_diagram_info( cirq.MeasurementGate(3), cirq.CircuitDiagramInfoArgs( known_qubits=None, known_qubit_count=3, use_unicode_characters=True, precision=None, qubit_map=None, ), ) == cirq.CircuitDiagramInfo(("M('')", 'M', 'M')) ) # Shows invert mask. assert cirq.circuit_diagram_info( cirq.MeasurementGate(2, invert_mask=(False, True)) ) == cirq.CircuitDiagramInfo(("M('')", "!M")) # Omits key when it is the default. a = cirq.NamedQubit('a') b = cirq.NamedQubit('b') cirq.testing.assert_has_diagram( cirq.Circuit(cirq.measure(a, b)), """ a: ───M─── │ b: ───M─── """, ) cirq.testing.assert_has_diagram( cirq.Circuit(cirq.measure(a, b, invert_mask=(True,))), """ a: ───!M─── │ b: ───M──── """, ) cirq.testing.assert_has_diagram( cirq.Circuit(cirq.measure(a, b, key='test')), """ a: ───M('test')─── │ b: ───M─────────── """, )
def test_depolarizing_channel_text_diagram_two_qubits(): d = cirq.depolarize(0.1234567, n_qubits=2) assert cirq.circuit_diagram_info( d, args=round_to_6_prec) == cirq.CircuitDiagramInfo( wire_symbols=('D(0.123457)', )) assert cirq.circuit_diagram_info( d, args=round_to_2_prec) == cirq.CircuitDiagramInfo( wire_symbols=('D(0.12)', )) assert cirq.circuit_diagram_info( d, args=no_precision) == cirq.CircuitDiagramInfo( wire_symbols=('D(0.1234567)', ))
def test_multi_asymmetric_depolarizing_channel_text_diagram(): a = cirq.asymmetric_depolarize(error_probabilities={'II': 2 / 3, 'XX': 1 / 3}) assert cirq.circuit_diagram_info(a, args=no_precision) == cirq.CircuitDiagramInfo( wire_symbols=('A(II:0.6666666666666666, XX:0.3333333333333333)',) ) assert cirq.circuit_diagram_info(a, args=round_to_6_prec) == cirq.CircuitDiagramInfo( wire_symbols=('A(II:0.666667, XX:0.333333)',) ) assert cirq.circuit_diagram_info(a, args=round_to_2_prec) == cirq.CircuitDiagramInfo( wire_symbols=('A(II:0.67, XX:0.33)',) )
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_controlled_diagram_exponent(): for q in itertools.permutations(cirq.LineQubit.range(5)): for idx in [None, 0, 1]: op = MockGate(idx)(*q[:2]).controlled_by(*q[2:]) add = 0 if idx is None else idx assert cirq.circuit_diagram_info(op).exponent_qubit_index == len( q[2:]) + add
def _circuit_diagram_info_(self, args): sub_info = cirq.circuit_diagram_info(self.sub_gate) return cirq.CircuitDiagramInfo( ('{}:{}'.format(sub_info.wire_symbols[0], ''.join( map(str, self.sub_levels))), ), exponent=sub_info.exponent, )
def __str__(self) -> str: diagram = cirq.TextDiagramDrawer() qubits = cast(Set[cirq.GridQubit], self._metadata.qubit_set) # Don't print out extras newlines if the row/col doesn't start at 0 min_col = min(q.col for q in qubits) min_row = min(q.row for q in qubits) for q in qubits: info = cirq.circuit_diagram_info(q, default=None) qubit_name = info.wire_symbols[0] if info else str(q) diagram.write(q.col - min_col, q.row - min_row, qubit_name) # Find pairs that are connected by two-qubit gates. Pair = Tuple[cirq.GridQubit, cirq.GridQubit] pairs = sorted( {cast(Pair, tuple(pair)) for pair in self._metadata.qubit_pairs}) # Draw lines between connected pairs. Limit to horizontal/vertical # lines since that is all the diagram drawer can handle. for q1, q2 in pairs: if q1.row == q2.row or q1.col == q2.col: diagram.grid_line(q1.col - min_col, q1.row - min_row, q2.col - min_col, q2.row - min_row) return diagram.render(horizontal_spacing=3, vertical_spacing=2, use_unicode_characters=True)
def test_diagram(): class NoDetailsGate(cirq.Gate): def num_qubits(self) -> int: raise NotImplementedError() assert cirq.circuit_diagram_info(NoDetailsGate().with_probability(0.5), None) is None a, b = cirq.LineQubit.range(2) cirq.testing.assert_has_diagram( cirq.Circuit(cirq.CNOT(a, b).with_probability(0.125)), """ 0: ───@[prob=0.125]─── │ 1: ───X─────────────── """, ) cirq.testing.assert_has_diagram( cirq.Circuit(cirq.CNOT(a, b).with_probability(0.125)), """ 0: ───@[prob=0.1]─── │ 1: ───X───────────── """, precision=1, )
def test_circuit_diagram_info(): assert cirq.circuit_diagram_info(CY) == cirq.CircuitDiagramInfo( wire_symbols=('@', 'Y'), exponent=1) assert cirq.circuit_diagram_info(cirq.ControlledGate( cirq.Y**0.5)) == cirq.CircuitDiagramInfo(wire_symbols=('@', 'Y'), exponent=0.5) assert cirq.circuit_diagram_info(cirq.ControlledGate( cirq.S)) == cirq.CircuitDiagramInfo(wire_symbols=('@', 'S'), exponent=1) class UndiagrammableGate(cirq.Gate): pass assert cirq.circuit_diagram_info(cirq.ControlledGate(UndiagrammableGate()), default=None) is None
def _circuit_diagram_info_(self, args): info = cirq.circuit_diagram_info( self.gate, args, default=NotImplemented) sub_qid_shape = cirq.qid_shape(self.gate) sep = ' ' if any(d > 10 for d in sub_qid_shape) else '' syms = tuple( f'{sym}:{sep.join(map(str, range(d)))}' for sym, d in zip(info.wire_symbols, cirq.qid_shape(self.gate)) )
def test_non_diagrammable_subop(): qbits = cirq.LineQubit.range(2) class UndiagrammableGate(cirq.SingleQubitGate): pass undiagrammable_op = UndiagrammableGate()(qbits[1]) c_op = cirq.ControlledOperation(qbits[:1], undiagrammable_op) assert cirq.circuit_diagram_info(c_op, default=None) is None
def test_uninformed_circuit_diagram_info(): qbits = cirq.LineQubit.range(3) mock_gate = MockGate() c_op = cirq.ControlledOperation(qbits[:1], mock_gate(*qbits[1:])) args = protocols.CircuitDiagramInfoArgs.UNINFORMED_DEFAULT assert (cirq.circuit_diagram_info(c_op, args) == cirq.CircuitDiagramInfo( wire_symbols=('@', 'MOCK'), exponent=1, connected=True)) assert mock_gate.captured_diagram_args == args
def test_circuit_diagram(): h = cirq.H(cirq.GridQubit(1, 1)) tagged_h = h.with_tags('tag1') expected = cirq.CircuitDiagramInfo(wire_symbols=("H['tag1']", ), exponent=1.0, connected=True, exponent_qubit_index=None, auto_exponent_parens=True) args = cirq.CircuitDiagramInfoArgs(None, None, None, None, None, False) assert cirq.circuit_diagram_info(tagged_h) == expected assert (cirq.circuit_diagram_info(tagged_h, args) == cirq.circuit_diagram_info(h)) c = cirq.Circuit(tagged_h) diagram_with_tags = "(1, 1): ───H['tag1']───" diagram_without_tags = "(1, 1): ───H───" assert str(cirq.Circuit(tagged_h)) == diagram_with_tags assert c.to_text_diagram() == diagram_with_tags assert c.to_text_diagram(include_tags=False) == diagram_without_tags
def test_uninformed_circuit_diagram_info(): qbits = cirq.LineQubit.range(3) mock_gate = MockGate() cgate = cirq.ControlledGate(mock_gate)(*qbits) args = cirq.CircuitDiagramInfoArgs.UNINFORMED_DEFAULT assert (cirq.circuit_diagram_info(cgate, args) == cirq.CircuitDiagramInfo( wire_symbols=('@', 'MOCK'), exponent=1, connected=True)) assert mock_gate.captured_diagram_args == args
def test_non_diagrammable_subop(): qbits = cirq.LineQubit.range(2) class UndiagrammableGate(cirq.testing.SingleQubitGate): def _has_mixture_(self): return True undiagrammable_op = UndiagrammableGate()(qbits[1]) c_op = cirq.ControlledOperation(qbits[:1], undiagrammable_op) assert cirq.circuit_diagram_info(c_op, default=None) is None
def _circuit_diagram_info_(self, args: 'cirq.CircuitDiagramInfoArgs'): sub_result = cirq.circuit_diagram_info(self.base_operation) sign_char = '-' if self.exponent_sign == -1 else '' symbols = list(sub_result.wire_symbols) symbols.extend(f'A{i}' for i in range(len(self.register))) return cirq.CircuitDiagramInfo( tuple(symbols), exponent=f'({sign_char}A/2^{len(self.register)})', exponent_qubit_index=sub_result.exponent_qubit_index or 0, auto_exponent_parens=False, )
def test_circuit_diagram_info_pass_fail(): class C: pass class D: def _circuit_diagram_info_(self, args): return NotImplemented class E: def _circuit_diagram_info_(self, args): return cirq.CircuitDiagramInfo(('X',)) assert cirq.circuit_diagram_info(C(), default=None) is None assert cirq.circuit_diagram_info(D(), default=None) is None assert cirq.circuit_diagram_info(E(), default=None) == cirq.CircuitDiagramInfo( ('X',)) with pytest.raises(TypeError, match='no _circuit_diagram_info'): _ = cirq.circuit_diagram_info(C()) with pytest.raises(TypeError, match='returned NotImplemented'): _ = cirq.circuit_diagram_info(D()) assert cirq.circuit_diagram_info(E()) == cirq.CircuitDiagramInfo(('X',))