def _scan_single_qubit_ops( circuit: Circuit, index: Optional[int], qubit: ops.QubitId) -> Tuple[List[int], List[ops.Operation]]: operations = [] # type: List[ops.Operation] indices = [] # type: List[int] while index is not None: op = cast(ops.Operation, circuit.operation_at(qubit, index)) if len(op.qubits) != 1 or protocols.unitary(op, None) is None: break indices.append(index) operations.append(op) index = circuit.next_moment_operating_on([qubit], index + 1) return indices, operations
def _scan_two_qubit_ops_into_matrix( self, circuit: Circuit, index: Optional[int], qubits: Tuple[ops.QubitId, ...] ) -> Tuple[List[ops.Operation], List[int], np.ndarray]: """Accumulates operations affecting the given pair of qubits. The scan terminates when it hits the end of the circuit, finds an operation without a known matrix, or finds an operation that interacts the given qubits with other qubits. Args: circuit: The circuit to scan for operations. index: The index to start scanning forward from. qubits: The pair of qubits we care about. Returns: A tuple containing: 0. The operations. 1. The moment indices those operations were on. 2. A matrix equivalent to the effect of the scanned operations. """ product = np.eye(4, dtype=np.complex128) all_operations = [] touched_indices = [] while index is not None: operations = list({circuit.operation_at(q, index) for q in qubits}) op_data = [ self._op_to_matrix(op, qubits) for op in operations if op is not None ] # Stop at any non-constant or non-local interaction. if any(e is None for e in op_data): break present_ops = [op for op in operations if op] present_op_data = cast(List[np.ndarray], op_data) for op_mat in present_op_data: product = np.dot(op_mat, product) all_operations.extend(present_ops) touched_indices.append(index) index = circuit.next_moment_operating_on(qubits, index + 1) return all_operations, touched_indices, product
def _scan_single_qubit_ops( self, circuit: Circuit, index: Optional[int], qubit: ops.QubitId) -> Tuple[List[int], List[ops.KnownMatrix]]: operations = [] # type: List[ops.KnownMatrix] indices = [] # type: List[int] while index is not None: op = cast(ops.Operation, circuit.operation_at(qubit, index)) if len(op.qubits) != 1: break operation = self.extensions.try_cast(ops.KnownMatrix, op) if operation is None: break indices.append(index) operations.append(operation) index = circuit.next_moment_operating_on([qubit], index + 1) return indices, operations
def test_operation_at(): a = cirq.QubitId() b = cirq.QubitId() c = Circuit() assert c.operation_at(a, 0) is None assert c.operation_at(a, -1) is None assert c.operation_at(a, 102) is None c = Circuit([Moment()]) assert c.operation_at(a, 0) is None c = Circuit([Moment([cirq.X(a)])]) assert c.operation_at(b, 0) is None assert c.operation_at(a, 1) is None assert c.operation_at(a, 0) == cirq.X(a) c = Circuit([Moment(), Moment([cirq.CZ(a, b)])]) assert c.operation_at(a, 0) is None assert c.operation_at(a, 1) == cirq.CZ(a, b)