1# Copyright 2021 The Cirq Developers 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14"""An interface for quantum states as targets for operations.""" 15import abc 16from typing import ( 17 TypeVar, 18 TYPE_CHECKING, 19 Generic, 20 Dict, 21 Any, 22 Tuple, 23 Optional, 24 Iterator, 25 List, 26 Sequence, 27 Union, 28) 29 30import numpy as np 31 32from cirq import protocols 33from cirq.type_workarounds import NotImplementedType 34 35if TYPE_CHECKING: 36 import cirq 37 38 39TSelfTarget = TypeVar('TSelfTarget', bound='OperationTarget') 40TActOnArgs = TypeVar('TActOnArgs', bound='cirq.ActOnArgs') 41 42 43class OperationTarget(Generic[TActOnArgs], metaclass=abc.ABCMeta): 44 """An interface for quantum states as targets for operations.""" 45 46 @abc.abstractmethod 47 def create_merged_state(self) -> TActOnArgs: 48 """Creates a final merged state.""" 49 50 @abc.abstractmethod 51 def _act_on_fallback_( 52 self, 53 action: Union['cirq.Operation', 'cirq.Gate'], 54 qubits: Sequence['cirq.Qid'], 55 allow_decompose: bool = True, 56 ) -> Union[bool, NotImplementedType]: 57 """Handles the act_on protocol fallback implementation. 58 59 Args: 60 action: Either a gate or an operation to act on. 61 qubits: The applicable qubits if a gate is passed as the action. 62 allow_decompose: Flag to allow decomposition. 63 64 Returns: 65 True if the fallback applies, else NotImplemented.""" 66 67 def apply_operation(self, op: 'cirq.Operation'): 68 protocols.act_on(op, self) 69 70 @abc.abstractmethod 71 def copy(self: TSelfTarget) -> TSelfTarget: 72 """Copies the object.""" 73 74 @property 75 @abc.abstractmethod 76 def qubits(self) -> Tuple['cirq.Qid', ...]: 77 """Gets the qubit order maintained by this target.""" 78 79 @property 80 @abc.abstractmethod 81 def log_of_measurement_results(self) -> Dict[str, Any]: 82 """Gets the log of measurement results.""" 83 84 @abc.abstractmethod 85 def sample( 86 self, 87 qubits: List['cirq.Qid'], 88 repetitions: int = 1, 89 seed: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None, 90 ) -> np.ndarray: 91 """Samples the state value.""" 92 93 def __getitem__(self, item: Optional['cirq.Qid']) -> TActOnArgs: 94 """Gets the item associated with the qubit.""" 95 96 def __len__(self) -> int: 97 """Gets the number of items in the mapping.""" 98 99 def __iter__(self) -> Iterator[Optional['cirq.Qid']]: 100 """Iterates the keys of the mapping.""" 101