def assert_decompose_is_consistent_with_unitary(
        val: Any, ignoring_global_phase: bool = False):
    """Uses `val._unitary_` to check `val._phase_by_`'s behavior."""
    # pylint: disable=unused-variable
    __tracebackhide__ = True
    # pylint: enable=unused-variable

    expected = protocols.unitary(val, None)
    if expected is None:
        # If there's no unitary, it's vacuously consistent.
        return
    if isinstance(val, ops.Operation):
        qubits = val.qubits
        dec = protocols.decompose_once(val, default=None)
    else:
        qubits = tuple(devices.LineQid.for_gate(val))
        dec = protocols.decompose_once_with_qubits(val, qubits, default=None)
    if dec is None:
        # If there's no decomposition, it's vacuously consistent.
        return

    actual = circuits.Circuit(dec).unitary(qubit_order=qubits)

    if ignoring_global_phase:
        lin_alg_utils.assert_allclose_up_to_global_phase(actual,
                                                         expected,
                                                         atol=1e-8)
    else:
        # coverage: ignore
        np.testing.assert_allclose(actual, expected, atol=1e-8)
Example #2
0
 def _has_unitary_(self):
     from cirq import protocols, devices
     qubits = devices.LineQid.for_gate(self)
     return all(
         protocols.has_unitary(op)
         for op in protocols.decompose_once_with_qubits(
             self._original, qubits))
Example #3
0
def assert_decompose_is_consistent_with_unitary(
        val: Any, ignoring_global_phase: bool = False):
    """Uses `val._unitary_` to check `val._phase_by_`'s behavior."""

    expected = protocols.unitary(val, None)
    if expected is None:
        # If there's no unitary, it's vacuously consistent.
        return
    qubit_count = len(expected).bit_length() - 1
    if isinstance(val, ops.Operation):
        qubits = val.qubits
        dec = protocols.decompose_once(val, default=None)
    else:
        qubits = tuple(line.LineQubit.range(qubit_count))
        dec = protocols.decompose_once_with_qubits(val, qubits, default=None)
    if dec is None:
        # If there's no decomposition, it's vacuously consistent.
        return

    actual = circuits.Circuit.from_ops(dec).unitary(qubit_order=qubits)

    if ignoring_global_phase:
        lin_alg_utils.assert_allclose_up_to_global_phase(actual,
                                                         expected,
                                                         atol=1e-8)
    else:
        # coverage: ignore
        np.testing.assert_allclose(actual, expected, atol=1e-8)
 def _strat_decompose(self, val: Any, qubits: Sequence['cirq.Qid']) -> bool:
     gate = val.gate if isinstance(val, ops.Operation) else val
     operations = protocols.decompose_once_with_qubits(gate, qubits, None)
     if operations is None or not all(protocols.has_stabilizer_effect(op) for op in operations):
         return NotImplemented
     for op in operations:
         protocols.act_on(op, self)
     return True
Example #5
0
    def _decompose_(self, qubits):
        result = protocols.decompose_once_with_qubits(self.sub_gate,
                                                      qubits[1:],
                                                      NotImplemented)
        if result is NotImplemented:
            return NotImplemented

        return [cop.ControlledOperation(qubits[0], op) for op in result]
Example #6
0
    def _decompose_(self, qubits):
        result = protocols.decompose_once_with_qubits(
            self.sub_gate, qubits[self.num_controls():], NotImplemented)

        if result is NotImplemented:
            return NotImplemented

        decomposed = []
        for op in result:
            decomposed.append(
                cop.ControlledOperation(qubits[:self.num_controls()], op))
        return decomposed
Example #7
0
def assert_decompose_is_consistent_with_unitary(val: Any):
    """Uses `val._unitary_` to check `val._phase_by_`'s behavior."""

    expected = protocols.unitary(val)
    qubit_count = len(expected).bit_length() - 1
    if isinstance(val, ops.Operation):
        qubits = val.qubits
        dec = protocols.decompose_once(val)
    else:
        qubits = tuple(line.LineQubit.range(qubit_count))
        dec = protocols.decompose_once_with_qubits(val, qubits)
    actual = circuits.Circuit.from_ops(dec).to_unitary_matrix(
        qubit_order=qubits)

    lin_alg_utils.assert_allclose_up_to_global_phase(actual,
                                                     expected,
                                                     atol=1e-8)
Example #8
0
    def __pow__(self, power):
        if power == 1:
            return self

        if power == -1:
            decomposed = protocols.decompose_once_with_qubits(
                self, qubits=line_qubit.LineQid.for_gate(self), default=None)
            if decomposed is None:
                return NotImplemented

            inverse_decomposed = protocols.inverse(decomposed, None)
            if inverse_decomposed is None:
                return NotImplemented

            return _InverseCompositeGate(self)

        return NotImplemented
Example #9
0
    def _decompose_(self, qubits):
        if isinstance(self.sub_gate, matrix_gates.MatrixGate):
            # Default decompositions of 2/3 qubit `cirq.MatrixGate` ignores global phase, which is
            # local phase in the controlled variant and hence cannot be ignored.
            return NotImplemented

        result = protocols.decompose_once_with_qubits(
            self.sub_gate, qubits[self.num_controls():], NotImplemented)
        if result is NotImplemented:
            return NotImplemented

        decomposed: List['cirq.Operation'] = []
        for op in result:
            decomposed.append(
                cop.ControlledOperation(qubits[:self.num_controls()], op,
                                        self.control_values))
        return decomposed
Example #10
0
def assert_permutation_decomposition_equivalence(gate: PermutationGate,
                                                 n_qubits: int) -> None:
    qubits = line.LineQubit.range(n_qubits)
    operations = protocols.decompose_once_with_qubits(gate, qubits)
    operations = list(
        cast(Sequence[ops.Operation], ops.flatten_op_tree(operations)))
    mapping = {cast(ops.Qid, q): i for i, q in enumerate(qubits)}
    update_mapping(mapping, operations)
    expected_mapping = {qubits[j]: i for i, j in gate.permutation().items()}
    assert mapping == expected_mapping, (
        "{!r}.permutation({}) doesn't match decomposition.\n"
        '\n'
        'Actual mapping:\n'
        '{}\n'
        '\n'
        'Expected mapping:\n'
        '{}\n'.format(gate, n_qubits, [mapping[q] for q in qubits],
                      [expected_mapping[q] for q in qubits]))
Example #11
0
    def _decompose_(self):
        result = protocols.decompose_once_with_qubits(self.gate, self.qubits,
                                                      NotImplemented)
        if result is not NotImplemented:
            return result

        if isinstance(self.sub_operation.gate, matrix_gates.MatrixGate):
            # Default decompositions of 2/3 qubit `cirq.MatrixGate` ignores global phase, which is
            # local phase in the controlled variant and hence cannot be ignored.
            return NotImplemented

        result = protocols.decompose_once(self.sub_operation, NotImplemented)
        if result is NotImplemented:
            return NotImplemented

        return [
            op.controlled_by(*self.controls,
                             control_values=self.control_values)
            for op in result
        ]
Example #12
0
    def __pow__(self, power):
        if power == 1:
            return self

        if power == -1:
            # HACK: break cycle
            from cirq.line import line_qubit

            decomposed = protocols.decompose_once_with_qubits(
                self,
                qubits=line_qubit.LineQubit.range(self.num_qubits()),
                default=None)
            if decomposed is None:
                return NotImplemented

            inverse_decomposed = protocols.inverse(decomposed, None)
            if inverse_decomposed is None:
                return NotImplemented

            return _InverseCompositeGate(self)

        return NotImplemented
Example #13
0
 def _unitary_(self) -> np.ndarray:
     mat = np.eye(2)
     qubit = named_qubit.NamedQubit('arbitrary')
     for op in protocols.decompose_once_with_qubits(self, (qubit, )):
         mat = protocols.unitary(op).dot(mat)
     return mat
Example #14
0
 def _decompose_(self, qubits):
     return protocols.inverse(
         protocols.decompose_once_with_qubits(self.forward_form, qubits))
Example #15
0
 def _decompose_(self) -> 'cirq.OP_TREE':
     return protocols.decompose_once_with_qubits(self.gate, self.qubits,
                                                 NotImplemented)
Example #16
0
 def _decompose_(self, qubits):
     return protocols.inverse(protocols.decompose_once_with_qubits(self._original, qubits))
Example #17
0
 def _decompose_(self):
     return protocols.decompose_once_with_qubits(self.gate, self.qubits,
                                                 NotImplemented)