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)
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))
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
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]
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
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)
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
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
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]))
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 ]
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
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
def _decompose_(self, qubits): return protocols.inverse( protocols.decompose_once_with_qubits(self.forward_form, qubits))
def _decompose_(self) -> 'cirq.OP_TREE': return protocols.decompose_once_with_qubits(self.gate, self.qubits, NotImplemented)
def _decompose_(self, qubits): return protocols.inverse(protocols.decompose_once_with_qubits(self._original, qubits))
def _decompose_(self): return protocols.decompose_once_with_qubits(self.gate, self.qubits, NotImplemented)