def _decompose_two_qubit_unitaries(self, op: ops.Operation) -> ops.OP_TREE: # Known matrix? if len(op.qubits) == 2: mat = protocols.unitary(op, None) if mat is not None: return two_qubit_decompositions.two_qubit_matrix_to_operations( op.qubits[0], op.qubits[1], mat, allow_partial_czs=self.allow_partial_czs) return NotImplemented
def optimization_at(self, circuit: circuits.Circuit, index: int, op: ops.Operation ) -> Optional[circuits.PointOptimizationSummary]: if len(op.qubits) != 2: return None old_operations, indices, matrix = ( self._scan_two_qubit_ops_into_matrix(circuit, index, op.qubits)) old_interaction_count = len([old_op for old_op in old_operations if len(old_op.qubits) == 2]) switch_to_new = False switch_to_new |= any(len(old_op.qubits) == 2 and not (isinstance(old_op, ops.GateOperation) and isinstance(old_op.gate, ops.CZPowGate)) for old_op in old_operations) if not self.allow_partial_czs: switch_to_new |= any(isinstance(old_op, ops.GateOperation) and isinstance(old_op.gate, ops.CZPowGate) and old_op.gate.exponent != 1 for old_op in old_operations) # This point cannot be optimized using this method if not switch_to_new and old_interaction_count <= 1: return None # Find a max-3-cz construction. new_operations = ( two_qubit_decompositions.two_qubit_matrix_to_operations( op.qubits[0], op.qubits[1], matrix, self.allow_partial_czs, self.tolerance, False)) new_interaction_count = len([new_op for new_op in new_operations if len(new_op.qubits) == 2]) switch_to_new |= new_interaction_count < old_interaction_count if not switch_to_new: return None return circuits.PointOptimizationSummary( clear_span=max(indices) + 1 - index, clear_qubits=op.qubits, new_operations=new_operations)
def _two_qubit_matrix_to_operations( self, q0: 'cirq.Qid', q1: 'cirq.Qid', mat: np.ndarray, ) -> Sequence['cirq.Operation']: """Decomposes the merged two-qubit gate unitary into the minimum number of CZ gates. Args: q0: The first qubit being operated on. q1: The other qubit being operated on. mat: Defines the operation to apply to the pair of qubits. Returns: A list of operations implementing the matrix. """ return two_qubit_decompositions.two_qubit_matrix_to_operations( q0, q1, mat, self.allow_partial_czs, self.tolerance, False)