def test_next_moment_operating_on_distance(): a = cirq.QubitId() c = Circuit([ Moment(), Moment(), Moment(), Moment(), Moment([cirq.X(a)]), Moment(), ]) assert c.next_moment_operating_on([a], 0, max_distance=4) is None assert c.next_moment_operating_on([a], 1, max_distance=3) is None assert c.next_moment_operating_on([a], 2, max_distance=2) is None assert c.next_moment_operating_on([a], 3, max_distance=1) is None assert c.next_moment_operating_on([a], 4, max_distance=0) is None assert c.next_moment_operating_on([a], 0, max_distance=5) == 4 assert c.next_moment_operating_on([a], 1, max_distance=4) == 4 assert c.next_moment_operating_on([a], 2, max_distance=3) == 4 assert c.next_moment_operating_on([a], 3, max_distance=2) == 4 assert c.next_moment_operating_on([a], 4, max_distance=1) == 4 assert c.next_moment_operating_on([a], 5, max_distance=0) is None assert c.next_moment_operating_on([a], 1, max_distance=5) == 4 assert c.next_moment_operating_on([a], 3, max_distance=5) == 4 assert c.next_moment_operating_on([a], 1, max_distance=500) == 4 # Huge max distances should be handled quickly due to capping. assert c.next_moment_operating_on([a], 5, max_distance=10**100) is None
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_next_moment_operating_on(): a = cirq.QubitId() b = cirq.QubitId() c = Circuit() assert c.next_moment_operating_on([a]) is None assert c.next_moment_operating_on([a], 0) is None assert c.next_moment_operating_on([a], 102) is None c = Circuit([Moment([cirq.X(a)])]) assert c.next_moment_operating_on([a]) == 0 assert c.next_moment_operating_on([a], 0) == 0 assert c.next_moment_operating_on([a, b]) == 0 assert c.next_moment_operating_on([a], 1) is None assert c.next_moment_operating_on([b]) is None c = Circuit( [Moment(), Moment([cirq.X(a)]), Moment(), Moment([cirq.CZ(a, b)])]) assert c.next_moment_operating_on([a], 0) == 1 assert c.next_moment_operating_on([a], 1) == 1 assert c.next_moment_operating_on([a], 2) == 3 assert c.next_moment_operating_on([a], 3) == 3 assert c.next_moment_operating_on([a], 4) is None assert c.next_moment_operating_on([b], 0) == 3 assert c.next_moment_operating_on([b], 1) == 3 assert c.next_moment_operating_on([b], 2) == 3 assert c.next_moment_operating_on([b], 3) == 3 assert c.next_moment_operating_on([b], 4) is None assert c.next_moment_operating_on([a, b], 0) == 1 assert c.next_moment_operating_on([a, b], 1) == 1 assert c.next_moment_operating_on([a, b], 2) == 3 assert c.next_moment_operating_on([a, b], 3) == 3 assert c.next_moment_operating_on([a, b], 4) is None