예제 #1
0
파일: raw_types.py 프로젝트: jshede/Cirq
 def _circuit_diagram_info_(self, args: 'cirq.CircuitDiagramInfoArgs'):
     sub_info = protocols.circuit_diagram_info(self._original,
                                               default=NotImplemented)
     if sub_info is NotImplemented:
         return NotImplemented
     sub_info.exponent *= -1
     return sub_info
예제 #2
0
def _op_info_with_fallback(
        op: 'cirq.Operation',
        args: 'cirq.CircuitDiagramInfoArgs') -> 'cirq.CircuitDiagramInfo':
    info = protocols.circuit_diagram_info(op, args, None)
    if info is not None:
        if max(1, len(op.qubits)) != len(info.wire_symbols):
            raise ValueError(
                f'Wanted diagram info from {op!r} for {len(op.qubits)} qubits but got {info!r}'
            )
        return info

    # Use the untagged operation's __str__.
    name = str(op.untagged)

    # Representation usually looks like 'gate(qubit1, qubit2, etc)'.
    # Try to cut off the qubit part, since that would be redundant.
    redundant_tail = f"({', '.join(str(e) for e in op.qubits)})"
    if name.endswith(redundant_tail):
        name = name[:-len(redundant_tail)]

    # Add tags onto the representation, if they exist
    if op.tags:
        name += f'{list(op.tags)}'

    # Include ordering in the qubit labels.
    symbols = (name, ) + tuple(f'#{i + 1}' for i in range(1, len(op.qubits)))

    return protocols.CircuitDiagramInfo(wire_symbols=symbols)
예제 #3
0
def multigate_qcircuit_diagram_info(
    op: ops.Operation,
    args: protocols.CircuitDiagramInfoArgs,
) -> Optional[protocols.CircuitDiagramInfo]:
    if not (isinstance(op, ops.GateOperation)
            and isinstance(op.gate, ops.InterchangeableQubitsGate)):
        return None

    multigate_parameters = get_multigate_parameters(args)
    if multigate_parameters is None:
        return None

    info = protocols.circuit_diagram_info(op, args, default=None)

    min_index, n_qubits = multigate_parameters
    name = escape_text_for_latex(
        str(op.gate).rsplit('**', 1)[0] if isinstance(op, ops.GateOperation
                                                      ) else str(op))
    if (info is not None) and (info.exponent != 1):
        name += '^{' + str(info.exponent) + '}'
    box = r'\multigate{' + str(n_qubits - 1) + '}{' + name + '}'
    ghost = r'\ghost{' + name + '}'
    assert args.qubit_map is not None
    assert args.known_qubits is not None
    symbols = tuple(box if (args.qubit_map[q] == min_index) else ghost
                    for q in args.known_qubits)
    return protocols.CircuitDiagramInfo(symbols,
                                        exponent=info.exponent,
                                        connected=False)
예제 #4
0
    def _circuit_diagram_info_(
        self, args: 'cirq.CircuitDiagramInfoArgs'
    ) -> Optional['protocols.CircuitDiagramInfo']:
        n = len(self.controls)

        sub_args = protocols.CircuitDiagramInfoArgs(
            known_qubit_count=(
                args.known_qubit_count - n if args.known_qubit_count is not None else None
            ),
            known_qubits=(args.known_qubits[n:] if args.known_qubits is not None else None),
            use_unicode_characters=args.use_unicode_characters,
            precision=args.precision,
            qubit_map=args.qubit_map,
        )
        sub_info = protocols.circuit_diagram_info(self.sub_operation, sub_args, None)
        if sub_info is None:
            return NotImplemented

        def get_symbol(vals):
            if tuple(vals) == (1,):
                return '@'
            return f"({','.join(map(str, vals))})"

        wire_symbols = (*(get_symbol(vals) for vals in self.control_values), *sub_info.wire_symbols)
        return protocols.CircuitDiagramInfo(
            wire_symbols=wire_symbols,
            exponent=sub_info.exponent,
            exponent_qubit_index=None
            if sub_info.exponent_qubit_index is None
            else sub_info.exponent_qubit_index + 1,
        )
예제 #5
0
 def _circuit_diagram_info_(
     self, args: 'cirq.CircuitDiagramInfoArgs'
 ) -> Optional['protocols.CircuitDiagramInfo']:
     sub_args = protocols.CircuitDiagramInfoArgs(
         known_qubit_count=args.known_qubit_count,
         known_qubits=args.known_qubits,
         use_unicode_characters=args.use_unicode_characters,
         precision=args.precision,
         label_map=args.label_map,
     )
     sub_info = protocols.circuit_diagram_info(self._sub_operation,
                                               sub_args, None)
     if sub_info is None:
         return NotImplemented  # coverage: ignore
     control_count = len({k for c in self._conditions for k in c.keys})
     wire_symbols = sub_info.wire_symbols + ('^', ) * control_count
     if any(not isinstance(c, value.KeyCondition)
            for c in self._conditions):
         wire_symbols = (wire_symbols[0] + '(conditions=[' + ', '.join(
             str(c) for c in self._conditions) + '])', ) + wire_symbols[1:]
     exponent_qubit_index = None
     if sub_info.exponent_qubit_index is not None:
         exponent_qubit_index = sub_info.exponent_qubit_index + control_count
     elif sub_info.exponent is not None:
         exponent_qubit_index = control_count
     return protocols.CircuitDiagramInfo(
         wire_symbols=wire_symbols,
         exponent=sub_info.exponent,
         exponent_qubit_index=exponent_qubit_index,
     )
예제 #6
0
    def _circuit_diagram_info_(self, args: 'cirq.CircuitDiagramInfoArgs'
                              ) -> 'cirq.CircuitDiagramInfo':
        sub_args = protocols.CircuitDiagramInfoArgs(
            known_qubit_count=(args.known_qubit_count - self.num_controls()
                               if args.known_qubit_count is not None else None),
            known_qubits=(args.known_qubits[self.num_controls():]
                          if args.known_qubits is not None else None),
            use_unicode_characters=args.use_unicode_characters,
            precision=args.precision,
            qubit_map=args.qubit_map)
        sub_info = protocols.circuit_diagram_info(self.sub_gate,
                                                  sub_args,
                                                  None)
        if sub_info is None:
            return NotImplemented

        def get_symbol(vals):
            if tuple(vals) == (1,):
                return '@'
            return '({})'.format(','.join(map(str, vals)))

        return protocols.CircuitDiagramInfo(
            wire_symbols=(*(get_symbol(vals) for vals in self.control_values),
                          *sub_info.wire_symbols),
            exponent=sub_info.exponent)
예제 #7
0
 def _circuit_diagram_info_(
     self, args: protocols.CircuitDiagramInfoArgs
 ) -> protocols.CircuitDiagramInfo:
     sub_info = protocols.circuit_diagram_info(self.sub_gate, args, None)
     if sub_info is None:
         return NotImplemented
     return protocols.CircuitDiagramInfo(wire_symbols=('@', ) +
                                         sub_info.wire_symbols,
                                         exponent=sub_info.exponent)
예제 #8
0
 def _circuit_diagram_info_(self, args: 'cirq.CircuitDiagramInfoArgs'
                           ) -> Optional['cirq.CircuitDiagramInfo']:
     result = protocols.circuit_diagram_info(self.sub_gate, args, None)
     if result is None:
         return None
     wires = list(result.wire_symbols)
     if wires:
         wires[0] += f'[prob={args.format_real(self.probability)}]'
     return result.with_wire_symbols(wires)
예제 #9
0
 def _circuit_diagram_info_(
     self, args: 'cirq.CircuitDiagramInfoArgs'
 ) -> 'cirq.CircuitDiagramInfo':
     sub_op_info = protocols.circuit_diagram_info(self.sub_operation, args, NotImplemented)
     # Add tag to wire symbol if it exists.
     if sub_op_info is not NotImplemented and args.include_tags and sub_op_info.wire_symbols:
         sub_op_info.wire_symbols = (
             sub_op_info.wire_symbols[0] + str(list(self._tags)),
         ) + sub_op_info.wire_symbols[1:]
     return sub_op_info
예제 #10
0
def fallback_qcircuit_diagram_info(
    op: ops.Operation, args: protocols.CircuitDiagramInfoArgs
) -> protocols.CircuitDiagramInfo:
    args = args.with_args(use_unicode_characters=False)
    info = protocols.circuit_diagram_info(op, args, default=None)
    if info is None:
        name = str(op.gate or op)
        n_qubits = len(op.qubits)
        symbols = tuple(f'#{i + 1}' if i else name for i in range(n_qubits))
        info = protocols.CircuitDiagramInfo(symbols)
    return convert_text_diagram_info_to_qcircuit_diagram_info(info)
예제 #11
0
def _wrap_operation(op: ops.Operation) -> ops.Operation:
    new_qubits = [_QCircuitQubit(e) for e in op.qubits]
    diagrammable = known_qcircuit_operation_symbols(op)
    if diagrammable is None:
        info = protocols.circuit_diagram_info(op, default=None)
        if info is not None:
            diagrammable = _TextToQCircuitDiagrammable(
                cast(protocols.SupportsCircuitDiagramInfo, op))
        elif isinstance(op, ops.GateOperation):
            diagrammable = _FallbackQCircuitGate(op.gate)
        else:
            diagrammable = _FallbackQCircuitGate(op)
    return _QCircuitOperation(op, diagrammable).with_qubits(*new_qubits)
예제 #12
0
    def _circuit_diagram_info_(
        self, args: 'cirq.CircuitDiagramInfoArgs'
    ) -> 'cirq.CircuitDiagramInfo':
        diagram_info = protocols.circuit_diagram_info(self.sub_gate, args, NotImplemented)
        if diagram_info == NotImplemented:
            return diagram_info

        # Include symbols for every qubit instead of just one.
        wire_symbols = tuple(diagram_info.wire_symbols) * self._num_copies

        return protocols.CircuitDiagramInfo(
            wire_symbols=wire_symbols, exponent=diagram_info.exponent, connected=False
        )
예제 #13
0
def _wrap_operation(op: ops.Operation) -> ops.Operation:
    new_qubits = [_QCircuitQubit(e) for e in op.qubits]
    diagrammable = fallback_qcircuit_extensions.try_cast(  # type: ignore
        QCircuitDiagrammable, op)
    if diagrammable is None:
        info = protocols.circuit_diagram_info(op, default=None)
        if info is not None:
            diagrammable = _TextToQCircuitDiagrammable(
                cast(protocols.SupportsCircuitDiagramInfo, op))
        else:
            diagrammable = _FallbackQCircuitGate(
                cast(ops.GateOperation, op).gate)
    return _QCircuitOperation(op, diagrammable).with_qubits(*new_qubits)
예제 #14
0
    def _circuit_diagram_info_(
        self, args: 'cirq.CircuitDiagramInfoArgs'
    ) -> 'cirq.CircuitDiagramInfo':
        diagram_info = protocols.circuit_diagram_info(self.gate, args, NotImplemented)
        if diagram_info == NotImplemented:
            return diagram_info

        # Include symbols for every qubit instead of just one
        symbol = diagram_info.wire_symbols[0]
        wire_symbols = (symbol,) * len(self.qubits)

        return protocols.CircuitDiagramInfo(
            wire_symbols=wire_symbols, exponent=diagram_info.exponent, connected=False
        )
예제 #15
0
 def _circuit_diagram_info_(
     self, args: protocols.CircuitDiagramInfoArgs
 ) -> protocols.CircuitDiagramInfo:
     sub_args = protocols.CircuitDiagramInfoArgs(
         known_qubit_count=(args.known_qubit_count - self.num_controls() if
                            args.known_qubit_count is not None else None),
         known_qubits=(args.known_qubits[self.num_controls():]
                       if args.known_qubits is not None else None),
         use_unicode_characters=args.use_unicode_characters,
         precision=args.precision,
         qubit_map=args.qubit_map)
     sub_info = protocols.circuit_diagram_info(self.sub_gate, sub_args,
                                               None)
     if sub_info is None:
         return NotImplemented
     return protocols.CircuitDiagramInfo(
         wire_symbols=('@', ) * self.num_controls() + sub_info.wire_symbols,
         exponent=sub_info.exponent)
예제 #16
0
    def _circuit_diagram_info_(
        self, args: 'cirq.CircuitDiagramInfoArgs'
    ) -> Optional['protocols.CircuitDiagramInfo']:
        n = len(self.controls)

        sub_args = protocols.CircuitDiagramInfoArgs(
            known_qubit_count=(args.known_qubit_count - n if
                               args.known_qubit_count is not None else None),
            known_qubits=(args.known_qubits[n:]
                          if args.known_qubits is not None else None),
            use_unicode_characters=args.use_unicode_characters,
            precision=args.precision,
            label_map=args.label_map,
        )
        sub_info = protocols.circuit_diagram_info(self.sub_operation, sub_args,
                                                  None)
        if sub_info is None:
            return NotImplemented

        def get_symbol(vals):
            if tuple(vals) == (1, ):
                return '@'
            return f"({','.join(map(str, vals))})"

        wire_symbols = (*(get_symbol(vals) for vals in self.control_values),
                        *sub_info.wire_symbols)
        exponent_qubit_index = None
        if sub_info.exponent_qubit_index is not None:
            exponent_qubit_index = sub_info.exponent_qubit_index + len(
                self.control_values)
        elif sub_info.exponent is not None:
            # For a multi-qubit `sub_operation`, if the `exponent_qubit_index` is None, the qubit
            # on which the exponent gets drawn in the controlled case (smallest ordered qubit of
            # sub_operation) can be different from the uncontrolled case (lexicographically largest
            # qubit of sub_operation). See tests for example.
            exponent_qubit_index = len(self.control_values)
        return protocols.CircuitDiagramInfo(
            wire_symbols=wire_symbols,
            exponent=sub_info.exponent,
            exponent_qubit_index=exponent_qubit_index,
        )
예제 #17
0
    def _circuit_diagram_info_(
        self, args: protocols.CircuitDiagramInfoArgs
    ) -> Optional[protocols.CircuitDiagramInfo]:
        n = len(self.controls)

        sub_args = protocols.CircuitDiagramInfoArgs(
            known_qubit_count=(args.known_qubit_count - n if
                               args.known_qubit_count is not None else None),
            known_qubits=(args.known_qubits[n:]
                          if args.known_qubits is not None else None),
            use_unicode_characters=args.use_unicode_characters,
            precision=args.precision,
            qubit_map=args.qubit_map)
        sub_info = protocols.circuit_diagram_info(self.sub_operation, sub_args,
                                                  None)
        if sub_info is None:
            return NotImplemented

        return protocols.CircuitDiagramInfo(wire_symbols=('@', ) * n +
                                            sub_info.wire_symbols,
                                            exponent=sub_info.exponent)
예제 #18
0
 def qcircuit_diagram_info(self, args: protocols.CircuitDiagramInfoArgs
                           ) -> protocols.CircuitDiagramInfo:
     info = protocols.circuit_diagram_info(self.sub, args)
     multigate_parameters = _get_multigate_parameters(self.sub, args)
     if multigate_parameters is not None:
         min_index, n_qubits = multigate_parameters
         name = _escape_text_for_latex(str(self.sub).rsplit('**', 1)[0])
         if info.exponent != 1:
             name += '^{' + str(info.exponent) + '}'
         box = '\multigate{' + str(n_qubits - 1) + '}{' + name + '}'
         ghost = '\ghost{' + name + '}'
         assert args.qubit_map is not None
         assert args.known_qubits is not None
         symbols = tuple(box if (args.qubit_map[q] == min_index) else
                         ghost for q in args.known_qubits)
         return protocols.CircuitDiagramInfo(symbols,
                                             exponent=info.exponent,
                                             connected=False)
     s = [_escape_text_for_latex(e) for e in info.wire_symbols]
     if info.exponent != 1:
         s[0] += '^{' + str(info.exponent) + '}'
     return protocols.CircuitDiagramInfo(tuple('\\gate{' + e + '}'
                                               for e in s))
예제 #19
0
 def __str__(self) -> str:
     return protocols.circuit_diagram_info(self).wire_symbols[0]
예제 #20
0
 def _circuit_diagram_info_(
         self,
         args: 'cirq.CircuitDiagramInfoArgs') -> 'cirq.CircuitDiagramInfo':
     return protocols.circuit_diagram_info(self.gate, args, NotImplemented)
예제 #21
0
 def _circuit_diagram_info_(
     self, args: protocols.CircuitDiagramInfoArgs
 ) -> protocols.CircuitDiagramInfo:
     return protocols.circuit_diagram_info(self.gate, args, NotImplemented)
예제 #22
0
 def __str__(self):
     info = protocols.circuit_diagram_info(self)
     if info.exponent == 1:
         return info.wire_symbols[0]
     return '{}^{}'.format(info.wire_symbols[0], info.exponent)
예제 #23
0
 def __str__(self) -> str:
     info = protocols.circuit_diagram_info(self)
     if info.exponent == 1:
         return info.wire_symbols[0]
     return f'{info.wire_symbols[0]}**{info.exponent}'