Beispiel #1
0
def _flatten_to_known_matrix_ops(
        iter_ops: Iterable[ops.Operation],
        ext: Extensions) -> Generator[ops.Operation, None, None]:
    for op in iter_ops:
        # Check if the operation has a known matrix
        known_matrix_gate = ext.try_cast(op.gate, ops.KnownMatrixGate)
        if known_matrix_gate is not None:
            yield op
            continue

        # If not, check if it has a decomposition
        composite_gate = ext.try_cast(op.gate, ops.CompositeGate)
        if composite_gate is not None:
            # Recurse decomposition to get known matrix gates.
            op_tree = composite_gate.default_decompose(op.qubits)
            op_list = ops.flatten_op_tree(op_tree)
            for op in _flatten_to_known_matrix_ops(op_list, ext):
                yield op
            continue

        # Pass measurement gates through
        meas_gate = ext.try_cast(op.gate, ops.MeasurementGate)
        if meas_gate is not None:
            yield op
            continue

        # Otherwise, fail
        raise TypeError(
            'Operation without a known matrix or decomposition: {!r}'.format(
                op))
Beispiel #2
0
 def __init__(self,
              tolerance: float = 1e-8,
              allow_partial_czs: bool = True,
              extensions: Extensions = None) -> None:
     self.tolerance = tolerance
     self.allow_partial_czs = allow_partial_czs
     self.extensions = extensions or Extensions()
Beispiel #3
0
def _wrap_operation(op: ops.Operation,
                    ext: extension.Extensions) -> ops.Operation:
    new_qubits = [_QCircuitQubit(e) for e in op.qubits]
    diagrammable = ext.try_cast(QCircuitDiagrammable, op)
    if diagrammable is None:
        diagrammable = fallback_qcircuit_extensions.cast(
            QCircuitDiagrammable, op)
    return _QCircuitOperation(op, diagrammable).with_qubits(*new_qubits)
Beispiel #4
0
    def __init__(self, composite_gate_extension: Extensions = None) -> None:
        """Construct the optimization pass.

        Args:
            composite_gate_extension: An extension that that can be used
                to supply or override a CompositeGate decomposition.
        """
        self.extension = composite_gate_extension or Extensions()
Beispiel #5
0
def _wrap_operation(op: ops.Operation,
                    ext: extension.Extensions) -> ops.Operation:
    new_qubits = [_QCircuitQubit(e) for e in op.qubits]
    new_gate = ext.try_cast(op.gate, QCircuitDiagrammableGate)
    if new_gate is None:
        new_gate = fallback_qcircuit_extensions.cast(op.gate,
                                                     QCircuitDiagrammableGate)
    return ops.Operation(_QCircuitGate(new_gate), new_qubits)
Beispiel #6
0
def _wrap_operation(op: ops.Operation,
                    ext: extension.Extensions) -> ops.Operation:
    new_qubits = [_QCircuitQubit(e) for e in op.qubits]
    diagrammable = ext.try_cast(QCircuitDiagrammable, op)
    if diagrammable is None:
        diagrammable = fallback_qcircuit_extensions.cast(
            QCircuitDiagrammable, op)
    return _QCircuitOperation(op, diagrammable).with_qubits(*new_qubits)
 def __init__(self,
              tolerance: float = 1e-8,
              allow_partial_czs: bool = True,
              extensions: Extensions = None,
              post_clean_up: Callable[[Sequence[ops.Operation]], ops.OP_TREE
                             ] = lambda op_list: op_list
              ) -> None:
     super().__init__(post_clean_up=post_clean_up)
     self.tolerance = tolerance
     self.allow_partial_czs = allow_partial_czs
     self.extensions = extensions or Extensions()
Beispiel #8
0
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()
Beispiel #9
0
def test_composite_extension_overrides():
    q0, q1 = QubitId(), QubitId()
    cnot = CNOT(q0, q1)
    circuit = Circuit()
    circuit.append(cnot)
    opt = ExpandComposite(composite_gate_extension=Extensions(
        {CompositeGate: {
            CNotGate: lambda e: OtherCNot()
        }}))
    opt.optimize_circuit(circuit)
    expected = Circuit()
    expected.append([Z(q0), Y(q1)**-0.5, CZ(q0, q1), Y(q1)**0.5, Z(q0)])
    assert_equal_mod_empty(expected, circuit)
Beispiel #10
0
def test_operation_to_unitary_matrix():
    ex = Extensions()
    a = cirq.NamedQubit('a')
    b = cirq.NamedQubit('b')

    m = _operation_to_unitary_matrix(cirq.X(a), {a: 0}, ex)
    cirq.testing.assert_allclose_up_to_global_phase(m,
                                                    np.array([[0, 1], [1, 0]]),
                                                    atol=1e-8)

    m = _operation_to_unitary_matrix(cirq.X(a), {a: 0, b: 1}, ex)
    cirq.testing.assert_allclose_up_to_global_phase(
        m, np.kron(cirq.X.matrix(), np.eye(2)))
    cirq.testing.assert_allclose_up_to_global_phase(m,
                                                    np.array([
                                                        [0, 0, 1, 0],
                                                        [0, 0, 0, 1],
                                                        [1, 0, 0, 0],
                                                        [0, 1, 0, 0],
                                                    ]),
                                                    atol=1e-8)

    m = _operation_to_unitary_matrix(cirq.X(a), {a: 1, b: 0}, ex)
    cirq.testing.assert_allclose_up_to_global_phase(m,
                                                    np.array([
                                                        [0, 1, 0, 0],
                                                        [1, 0, 0, 0],
                                                        [0, 0, 0, 1],
                                                        [0, 0, 1, 0],
                                                    ]),
                                                    atol=1e-8)

    m = _operation_to_unitary_matrix(cirq.CNOT(b, a), {a: 0, b: 1}, ex)
    cirq.testing.assert_allclose_up_to_global_phase(m,
                                                    np.array([
                                                        [1, 0, 0, 0],
                                                        [0, 0, 0, 1],
                                                        [0, 0, 1, 0],
                                                        [0, 1, 0, 0],
                                                    ]),
                                                    atol=1e-8)

    m = _operation_to_unitary_matrix(cirq.CNOT(b, a), {a: 1, b: 0}, ex)
    cirq.testing.assert_allclose_up_to_global_phase(m,
                                                    np.array([
                                                        [1, 0, 0, 0],
                                                        [0, 1, 0, 0],
                                                        [0, 0, 0, 1],
                                                        [0, 0, 1, 0],
                                                    ]),
                                                    atol=1e-8)
Beispiel #11
0
def _get_operation_text_diagram_exponent(
        op: ops.Operation, ext: Extensions,
        precision: Optional[int]) -> Optional[str]:
    text_diagram_gate = ext.try_cast(op.gate, ops.TextDiagrammableGate)
    if text_diagram_gate is None:
        return None
    exponent = text_diagram_gate.text_diagram_exponent()
    if exponent == 1:
        return None
    if isinstance(exponent, float) and precision is not None:
        return '{{:.{}}}'.format(precision).format(exponent)
    s = str(exponent)
    if '+' in s or ' ' in s or '-' in s[1:]:
        return '({})'.format(exponent)
    return s
Beispiel #12
0
def inverse(root: op_tree.OP_TREE,
            extensions: Extensions = None) -> op_tree.OP_TREE:
    """Generates OP_TREE inverses.

    Args:
        root: An operation tree containing only invertible operations.
        extensions: For caller-provided implementations of gate inverses.

    Returns:
        An OP_TREE that performs the inverse operation of the given OP_TREE.
    """
    ext = extensions or Extensions()
    return op_tree.transform_op_tree(
        root=root,
        op_transformation=lambda e: _reverse_operation(e, ext),
        iter_transformation=lambda e: reversed(list(e)))
Beispiel #13
0
def _reverse_operation(operation: raw_types.Operation,
                       ext: Extensions) -> raw_types.Operation:
    """Returns the inverse of an operation, if possible.

    Args:
        operation: The operation to reverse.
        ext: Used when casting the operation into a reversible effect.

    Returns:
        An operation on the same qubits but with the inverse gate.

    Raises:
        TypeError: The operation isn't reversible.
    """
    reversible_op = ext.cast(gate_features.ReversibleEffect, operation)
    return cast(raw_types.Operation, reversible_op.inverse())
Beispiel #14
0
def _operations_to_unitary_matrix(iter_ops: Iterable[ops.Operation],
                                  qubit_map: Dict[QubitId, int],
                                  ignore_terminal_measurements: bool,
                                  ext: Extensions) -> np.ndarray:
    # Precondition is that circuit has only terminal measurements.
    total = np.eye(1 << len(qubit_map))
    for op in iter_ops:
        meas_gate = ext.try_cast(op.gate, ops.MeasurementGate)
        if meas_gate is not None:
            if not ignore_terminal_measurements:
                raise TypeError(
                    'Terminal measurement operation but not ignoring these '
                    'measurements: {!r}'.format(op))
            continue  # coverage: ignore
        mat = _operation_to_unitary_matrix(op, qubit_map, ext)
        total = np.matmul(mat, total)
    return total
Beispiel #15
0
def _reverse_operation(operation: raw_types.Operation,
                       extensions: Extensions) -> raw_types.Operation:
    """Returns the inverse of an operation, if possible.

    Args:
        operation: The operation to reverse.

    Returns:
        An operation on the same qubits but with the inverse gate.

    Raises:
        ValueError: The operation's gate isn't reversible.
    """
    gate = extensions.try_cast(operation.gate, gate_features.ReversibleGate)
    if gate is None:
        raise ValueError('Not reversible: {}'.format(operation))
    return raw_types.Operation(gate.inverse(), operation.qubits)
Beispiel #16
0
def test_extension():
    class DummyGate(ops.Gate):
        pass

    optimizer = MergeRotations(extensions=Extensions({
        ops.KnownMatrixGate: {
            DummyGate:
            lambda _: ops.SingleQubitMatrixGate(np.array([[0, 1], [1, 0]]))
        }
    }))

    q = ops.QubitId()
    c = circuits.Circuit([
        circuits.Moment([DummyGate().on(q)]),
    ])
    assert_optimizes(before=c,
                     after=circuits.Circuit([circuits.Moment([ops.X(q)])]),
                     optimizer=optimizer)
Beispiel #17
0
    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
Beispiel #18
0
    def to_unitary_matrix(
            self,
            qubit_order: ops.QubitOrderOrList = ops.QubitOrder.DEFAULT,
            qubits_that_should_be_present: Iterable[QubitId] = (),
            ignore_terminal_measurements: bool = True,
            ext: Extensions = None) -> np.ndarray:
        """Converts the circuit into a unitary matrix, if possible.

        Args:
            qubit_order: Determines how qubits are ordered when passing matrices
                into np.kron.
            ext: The extensions to use when attempting to cast gates into
                KnownMatrixGate instances.
            qubits_that_should_be_present: Qubits that may or may not appear
                in operations within the circuit, but that should be included
                regardless when generating the matrix.
            ignore_terminal_measurements: When set, measurements at the end of
                the circuit are ignored instead of causing the conversion to
                fail.

        Returns:
            A (possibly gigantic) 2d numpy array corresponding to a matrix
            equivalent to the circuit's effect on a quantum state.

        Raises:
            TypeError: The circuit contains gates that don't have a known
                unitary matrix, such as measurement gates, gates parameterized
                by a Symbol, etc.
        """

        if ext is None:
            ext = Extensions()
        qs = ops.QubitOrder.as_qubit_order(qubit_order).order_for(
            self.qubits().union(qubits_that_should_be_present))
        qubit_map = {i: q
                     for q, i in enumerate(qs)}  # type: Dict[QubitId, int]
        matrix_ops = _flatten_to_known_matrix_ops(self.iter_ops(), ext)
        if not self.are_all_measurements_terminal():
            raise TypeError('Circuit contains a non-terminal measurement')
        return _operations_to_unitary_matrix(matrix_ops, qubit_map,
                                             ignore_terminal_measurements, ext)
Beispiel #19
0
def test_recursive_composite_extension_overrides():
    q0, q1 = QubitId(), QubitId()
    swap = SWAP(q0, q1)
    circuit = Circuit()
    circuit.append(swap)
    opt = ExpandComposite(composite_gate_extension=Extensions(
        {CompositeGate: {
            CNotGate: lambda e: OtherCNot()
        }}))
    opt.optimize_circuit(circuit)
    expected = Circuit()
    expected.append([Z(q0), Y(q1)**-0.5, CZ(q0, q1), Y(q1)**0.5, Z(q0)])
    expected.append(
        [Z(q1), Y(q0)**-0.5, CZ(q1, q0),
         Y(q0)**0.5, Z(q1)],
        strategy=InsertStrategy.INLINE)
    expected.append(
        [Z(q0), Y(q1)**-0.5, CZ(q0, q1),
         Y(q1)**0.5, Z(q0)],
        strategy=InsertStrategy.INLINE)
    assert_equal_mod_empty(expected, circuit)
Beispiel #20
0
def _operation_to_unitary_matrix(op: ops.Operation, qubit_map: Dict[QubitId,
                                                                    int],
                                 ext: Extensions) -> np.ndarray:
    known_matrix_gate = ext.try_cast(op.gate, ops.KnownMatrixGate)
    if known_matrix_gate is None:
        raise TypeError('Operation without a known matrix: {!r}'.format(op))
    sub_mat = known_matrix_gate.matrix()
    qubit_count = len(qubit_map)
    bit_locs = [qubit_count - qubit_map[q] - 1 for q in op.qubits][::-1]
    over_mask = ~sum(1 << b for b in bit_locs)

    result = np.zeros(shape=(1 << qubit_count, 1 << qubit_count),
                      dtype=np.complex128)
    for i in range(1 << qubit_count):
        sub_i = sum(_moved_bit(i, b, k) for k, b in enumerate(bit_locs))
        over_i = i & over_mask

        for sub_j in range(sub_mat.shape[1]):
            j = sum(_moved_bit(sub_j, k, b) for k, b in enumerate(bit_locs))
            result[i, over_i | j] = sub_mat[sub_i, sub_j]

    return result
Beispiel #21
0
def _get_operation_text_diagram_symbols(
        op: ops.Operation, ext: Extensions, use_unicode_characters: bool,
        precision: Optional[int]) -> Iterable[str]:
    text_diagram_gate = ext.try_cast(op.gate, ops.TextDiagrammableGate)
    if text_diagram_gate is not None:
        wire_symbols = text_diagram_gate.text_diagram_wire_symbols(
            qubit_count=len(op.qubits),
            use_unicode_characters=use_unicode_characters,
            precision=precision)
        if len(op.qubits) == len(wire_symbols):
            return wire_symbols
        elif len(wire_symbols) == 1:
            return len(op.qubits) * wire_symbols
        else:
            raise ValueError(
                'Multi-qubit operation with TextDiagrammableGate {} that '
                'requires {} qubits but found {} qubits'.format(
                    repr(op.gate), len(wire_symbols), len(op.qubits)))

    name = repr(op.gate)
    if len(op.qubits) == 1:
        return [name]
    return ['{}:{}'.format(name, i) for i in range(len(op.qubits))]
Beispiel #22
0
 def __init__(self, tolerance: float = 1e-8, extensions=None) -> None:
     self.tolerance = tolerance
     self.extensions = extensions or Extensions()
Beispiel #23
0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from cirq import ops
from cirq.extension import Extensions
from cirq.google import xmon_gates

xmon_gate_ext = Extensions()

xmon_gate_ext.add_cast(  # type: ignore
    desired_type=xmon_gates.XmonGate,
    actual_type=ops.XPowGate,
    conversion=lambda e: xmon_gates.ExpWGate(exponent=e.exponent,
                                             phase_exponent=0))

xmon_gate_ext.add_cast(  # type: ignore
    desired_type=xmon_gates.XmonGate,
    actual_type=ops.YPowGate,
    conversion=lambda e: xmon_gates.ExpWGate(exponent=e.exponent,
                                             phase_exponent=0.5))
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from cirq import ops
from cirq.extension import Extensions
from cirq.google import xmon_gates


xmon_gate_ext = Extensions()

xmon_gate_ext.add_cast(
    desired_type=xmon_gates.XmonGate,
    actual_type=ops.RotXGate,
    conversion=lambda e: xmon_gates.ExpWGate(half_turns=e.half_turns,
                                             axis_half_turns=0))

xmon_gate_ext.add_cast(
    desired_type=xmon_gates.XmonGate,
    actual_type=ops.RotYGate,
    conversion=lambda e: xmon_gates.ExpWGate(half_turns=e.half_turns,
                                             axis_half_turns=0.5))

xmon_gate_ext.add_cast(
    desired_type=xmon_gates.XmonGate,
Beispiel #25
0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from cirq import ops
from cirq.extension import Extensions
from cirq.google import xmon_gates

xmon_gate_ext = Extensions()

xmon_gate_ext.add_cast(  # type: ignore
    desired_type=xmon_gates.XmonGate,
    actual_type=ops.RotXGate,
    conversion=lambda e: xmon_gates.ExpWGate(half_turns=e.half_turns,
                                             axis_half_turns=0))

xmon_gate_ext.add_cast(  # type: ignore
    desired_type=xmon_gates.XmonGate,
    actual_type=ops.RotYGate,
    conversion=lambda e: xmon_gates.ExpWGate(half_turns=e.half_turns,
                                             axis_half_turns=0.5))
Beispiel #26
0
        np.real(matrix[0, 0]), np.imag(matrix[0, 0]), np.real(matrix[1, 0]),
        np.imag(matrix[1, 0]), np.real(matrix[0, 1]), np.imag(
            matrix[0, 1]), np.real(matrix[1, 1]), np.imag(matrix[1, 1]))

    # Clean up.
    matrix_repr = matrix_repr.replace('+-', '-')
    matrix_repr = matrix_repr.replace('+0.0i', '')
    matrix_repr = matrix_repr.replace('.0,', ',')
    matrix_repr = matrix_repr.replace('.0}', '}')
    matrix_repr = matrix_repr.replace('.0+', '+')
    matrix_repr = matrix_repr.replace('.0-', '-')

    return QuirkGate({'id': '?', 'matrix': matrix_repr})


quirk_gate_ext = Extensions()
quirk_gate_ext.add_cast(QuirkGate, ops.RotXGate, x_to_known)
quirk_gate_ext.add_cast(QuirkGate, ops.RotYGate, y_to_known)
quirk_gate_ext.add_cast(QuirkGate, ops.RotZGate, z_to_known)
quirk_gate_ext.add_cast(QuirkGate, ExpZGate, z_to_known)
quirk_gate_ext.add_cast(QuirkGate, ExpWGate, w_to_known)
quirk_gate_ext.add_cast(QuirkGate, ops.Rot11Gate, cz_to_known)
quirk_gate_ext.add_cast(QuirkGate, Exp11Gate, cz_to_known)
quirk_gate_ext.add_cast(QuirkGate, ops.CNotGate,
                        lambda e: QuirkGate('•', 'X', can_merge=False))
quirk_gate_ext.add_cast(QuirkGate, ops.SwapGate,
                        lambda e: QuirkGate('Swap', 'Swap'))
quirk_gate_ext.add_cast(QuirkGate, ops.HGate, lambda e: QuirkGate('H'))
quirk_gate_ext.add_cast(QuirkGate, ops.MeasurementGate,
                        lambda e: QuirkGate('Measure'))
Beispiel #27
0
    # Clean up.
    matrix_repr = matrix_repr.replace('+-', '-')
    matrix_repr = matrix_repr.replace('+0.0i', '')
    matrix_repr = matrix_repr.replace('.0,', ',')
    matrix_repr = matrix_repr.replace('.0}', '}')
    matrix_repr = matrix_repr.replace('.0+', '+')
    matrix_repr = matrix_repr.replace('.0-', '-')

    return QuirkOp({
        'id': '?',
        'matrix': matrix_repr
    })


quirk_gate_ext = Extensions()
quirk_gate_ext.add_recursive_cast(
    QuirkOp,
    ops.GateOperation,
    lambda ext, op: ext.try_cast(QuirkOp, op.gate))
quirk_gate_ext.add_cast(QuirkOp, ops.RotXGate, x_to_known)
quirk_gate_ext.add_cast(QuirkOp, ops.RotYGate, y_to_known)
quirk_gate_ext.add_cast(QuirkOp, ops.RotZGate, z_to_known)
quirk_gate_ext.add_cast(QuirkOp, ExpZGate, z_to_known)
quirk_gate_ext.add_cast(QuirkOp, ExpWGate, w_to_known)
quirk_gate_ext.add_cast(QuirkOp, ops.Rot11Gate, cz_to_known)
quirk_gate_ext.add_cast(QuirkOp, Exp11Gate, cz_to_known)
quirk_gate_ext.add_cast(QuirkOp,
                        ops.CNotGate,
                        lambda e: QuirkOp('•', 'X',
                                          can_merge=False))
Beispiel #28
0
    # Clean up.
    matrix_repr = matrix_repr.replace('+-', '-')
    matrix_repr = matrix_repr.replace('+0.0i', '')
    matrix_repr = matrix_repr.replace('.0,', ',')
    matrix_repr = matrix_repr.replace('.0}', '}')
    matrix_repr = matrix_repr.replace('.0+', '+')
    matrix_repr = matrix_repr.replace('.0-', '-')

    return QuirkOp({
        'id': '?',
        'matrix': matrix_repr
    })


quirk_gate_ext = Extensions()
quirk_gate_ext.add_recursive_cast(
    QuirkOp,
    ops.GateOperation,
    lambda ext, op: ext.try_cast(QuirkOp, op.gate))
quirk_gate_ext.add_cast(QuirkOp, ops.RotXGate, x_to_known)
quirk_gate_ext.add_cast(QuirkOp, ops.RotYGate, y_to_known)
quirk_gate_ext.add_cast(QuirkOp, ops.RotZGate, z_to_known)
quirk_gate_ext.add_cast(QuirkOp, ExpZGate, z_to_known)
quirk_gate_ext.add_cast(QuirkOp, ExpWGate, w_to_known)
quirk_gate_ext.add_cast(QuirkOp, ops.Rot11Gate, cz_to_known)
quirk_gate_ext.add_cast(QuirkOp, Exp11Gate, cz_to_known)
quirk_gate_ext.add_cast(QuirkOp,
                        ops.CNotGate,
                        lambda e: QuirkOp('•', 'X',
                                          can_merge=False))