def state_vector(self, copy: bool = None) -> np.ndarray:
        """Return the state vector at the end of the computation.

        The state is returned in the computational basis with these basis
        states defined by the qubit_map. In particular the value in the
        qubit_map is the index of the qubit, and these are translated into
        binary vectors where the last qubit is the 1s bit of the index, the
        second-to-last is the 2s bit of the index, and so forth (i.e. big
        endian ordering).

        Example:
             qubit_map: {QubitA: 0, QubitB: 1, QubitC: 2}
             Then the returned vector will have indices mapped to qubit basis
             states like the following table

                |     | QubitA | QubitB | QubitC |
                | :-: | :----: | :----: | :----: |
                |  0  |   0    |   0    |   0    |
                |  1  |   0    |   0    |   1    |
                |  2  |   0    |   1    |   0    |
                |  3  |   0    |   1    |   1    |
                |  4  |   1    |   0    |   0    |
                |  5  |   1    |   0    |   1    |
                |  6  |   1    |   1    |   0    |
                |  7  |   1    |   1    |   1    |
        """
        if copy is None:
            _compat._warn_or_error(
                "Starting in v0.16, state_vector will not copy the state by default. "
                "Explicitly set copy=True to copy the state.")
            copy = True
        return self.final_state_vector.copy(
        ) if copy else self.final_state_vector
Exemplo n.º 2
0
    def _base_iterator(self, circuit: 'cirq.AbstractCircuit',
                       qubits: Tuple['cirq.Qid', ...],
                       initial_state: Any) -> Iterator[TStepResult]:
        """Iterator over StepResult from Moments of a Circuit.

        Args:
            circuit: The circuit to simulate.
            qubits: Specifies the canonical ordering of the qubits. This
                is often used in specifying the initial state, i.e. the
                ordering of the computational basis states.
            initial_state: The initial state for the simulation. The form of
                this state depends on the simulation implementation. See
                documentation of the implementing class for details.

        Yields:
            StepResults from simulating a Moment of the Circuit.
        """
        # In 0.16 (or 1.0) _base_iterator should be made abstract. Then _create_simulation_state,
        # _create_act_on_args, and _core_iterator can all be removed from this class completely.
        # (They were only required because of this implementation, which has been moved to
        # SimulatorBase instead).
        _compat._warn_or_error(
            'Custom implementations of `cirq.SimulatesIntermediateState` should implement'
            ' `_base_iterator` directly rather than implementing both `_create_simulation_state`'
            ' and `_core_iterator`. The default implementation of `_base_iterator` will be removed'
            ' in v0.16, and the method will become abstract.')
        if not isinstance(qubits, tuple):
            _compat._warn_or_error(
                'The `qubits` parameter of `_base_iterator` will expect an explicit'
                ' `Tuple[cirq.Qid, ...]` beginning in v0.16.')
            qubits = ops.QubitOrder.as_qubit_order(qubits).order_for(
                circuit.all_qubits())
        sim_state = self._create_simulation_state(initial_state, qubits)
        return self._core_iterator(circuit, sim_state)
Exemplo n.º 3
0
    def transpose_to_qubit_order(self: TSelf,
                                 qubits: Sequence['cirq.Qid'],
                                 *,
                                 inplace=False) -> TSelf:
        """Physically reindexes the state by the new basis.

        Args:
            qubits: The desired qubit order.
            inplace: True to perform this operation inplace.

        Returns:
            The state with qubit order transposed and underlying representation
            updated.

        Raises:
            ValueError: If the provided qubits do not match the existing ones.
        """
        if len(self.qubits) != len(qubits) or set(qubits) != set(self.qubits):
            raise ValueError(
                f'Qubits do not match. Existing: {self.qubits}, provided: {qubits}'
            )
        args = self if inplace else copy.copy(self)
        if self._state is not None:
            args._state = self._state.reindex(self.get_axes(qubits))
        else:
            _warn_or_error(
                'Pass a `QuantumStateRepresentation` into the `SimulationState` constructor.'
                ' The `_on_` overrides will be removed in cirq v0.16.')
            self._on_transpose_to_qubit_order(qubits, args)
        args._set_qubits(qubits)
        return args
Exemplo n.º 4
0
    def _create_simulation_state(
            self, initial_state: Any,
            qubits: Sequence['cirq.Qid']) -> TSimulatorState:
        """Creates the state for a simulator.

        Custom simulators should implement this method.

        Args:
            initial_state: The initial state for the simulation. The form of
                this state depends on the simulation implementation. See
                documentation of the implementing class for details.
            qubits: Determines the canonical ordering of the qubits. This
                is often used in specifying the initial state, i.e. the
                ordering of the computational basis states.

        Returns:
            The `TSimulatorState` for this simulator.
        """
        _compat._warn_or_error(
            '`_create_act_on_args` has been renamed to `_create_simulation_state` in the'
            ' SimulatesIntermediateState interface, so simulators need to rename that method'
            f' implementation as well before v0.16. {type(self)}'
            ' has no `_create_simulation_state` method, so falling back to `_create_act_on_args`.'
            ' This fallback functionality will be removed in v0.16.')
        # When cleaning this up in v0.16, mark `_create_simulation_state` as @abc.abstractmethod,
        # remove this implementation, and delete `_create_act_on_args` entirely.
        return self._create_act_on_args(initial_state, qubits)
Exemplo n.º 5
0
def _measurement_key_names_from_magic_methods(val: Any) -> Optional[AbstractSet[str]]:
    """Uses the measurement key related magic methods to get the keys for this object."""

    getter = getattr(val, '_measurement_key_names_', None)
    result = NotImplemented if getter is None else getter()
    if result is not NotImplemented and result is not None:
        return set(result)
    getter = getattr(val, '_measurement_keys_', None)
    result = NotImplemented if getter is None else getter()
    if result is not NotImplemented and result is not None:
        _warn_or_error(
            f'_measurement_keys_ was used but is deprecated.\n'
            f'It will be removed in cirq v0.13.\n'
            f'Use _measurement_key_names_ instead.\n'
        )
        return set(result)

    getter = getattr(val, '_measurement_key_name_', None)
    result = NotImplemented if getter is None else getter()
    if result is not NotImplemented and result is not None:
        return {result}
    getter = getattr(val, '_measurement_key_', None)
    result = NotImplemented if getter is None else getter()
    if result is not NotImplemented and result is not None:
        _warn_or_error(
            f'_measurement_key_ was used but is deprecated.\n'
            f'It will be removed in cirq v0.13.\n'
            f'Use _measurement_key_name_ instead.\n'
        )
        return {result}

    return result
Exemplo n.º 6
0
    def _create_partial_simulation_state(
        self,
        initial_state: Any,
        qubits: Sequence['cirq.Qid'],
        classical_data: 'cirq.ClassicalDataStore',
    ) -> TSimulationState:
        """Creates an instance of the TSimulationState class for the simulator.

        It represents the supplied qubits initialized to the provided state.

        Args:
            initial_state: The initial state to represent. An integer state is
                understood to be a pure state. Other state representations are
                simulator-dependent.
            qubits: The sequence of qubits to represent.
            classical_data: The shared classical data container for this
                simulation.
        """
        _compat._warn_or_error(
            '`_create_partial_act_on_args` has been renamed to `_create_partial_simulation_state`'
            ' in the SimulatorBase class, so simulators need to rename that method'
            f' implementation as well before v0.16. {type(self)}'
            ' has no `_create_partial_simulation_state` method, so falling back to'
            ' `_create_partial_act_on_args`. This fallback functionality will be removed in v0.16.'
        )
        # When cleaning this up in v0.16, mark `_create_partial_simulation_state` as
        # @abc.abstractmethod, remove this implementation, and delete `_create_partial_act_on_args`
        # entirely.
        return self._create_partial_act_on_args(initial_state, qubits,
                                                classical_data)
Exemplo n.º 7
0
 def __new__(cls, *args, **kwargs):
     if cls is Result:
         _warn_or_error(
             "Result constructor is deprecated and will be removed in cirq v0.15. "
             "Use the ResultDict constructor instead, or another concrete subclass."
         )
         return ResultDict(*args, **kwargs)
     return super().__new__(cls)
Exemplo n.º 8
0
 def _from_json_dict_(cls, constant: str, **kwargs):
     _compat._warn_or_error(
         f'NamedConstantXmonDevice was used but is deprecated.\n'
         f'It will be removed in cirq v0.15.\n')
     if constant in ['cirq.google.Foxtail', 'cirq_google.Foxtail']:
         return Foxtail
     if constant in ['cirq.google.Bristlecone', 'cirq_google.Bristlecone']:
         return Bristlecone
     raise ValueError(f'Unrecognized xmon device name: {constant!r}')
Exemplo n.º 9
0
 def _measurement_key_names_(self) -> Optional[Iterable[str]]:
     getter = getattr(self.gate, '_measurement_key_names_', None)
     if getter is not None:
         return getter()
     getter = getattr(self.gate, '_measurement_keys_', None)
     if getter is not None:
         _warn_or_error(f'_measurement_keys_ was used but is deprecated.\n'
                        f'It will be removed in cirq v0.13.\n'
                        f'Use _measurement_key_names_ instead.\n')
         return getter()
     return NotImplemented
Exemplo n.º 10
0
 def _base_iterator(self, circuit: 'cirq.AbstractCircuit',
                    qubits: Tuple['cirq.Qid', ...],
                    initial_state: Any) -> Iterator[TStepResultBase]:
     if not isinstance(qubits, tuple):
         _compat._warn_or_error(
             'The `qubits` parameter of `_base_iterator` will expect an explicit'
             ' `Tuple[cirq.Qid, ...]` beginning in v0.16.')
         qubits = ops.QubitOrder.as_qubit_order(qubits).order_for(
             circuit.all_qubits())
     sim_state = self._create_simulation_state(initial_state, qubits)
     return self._core_iterator(circuit, sim_state)
Exemplo n.º 11
0
 def kronecker_product(self: TSelf,
                       other: TSelf,
                       *,
                       inplace=False) -> TSelf:
     """Joins two state spaces together."""
     args = self if inplace else copy.copy(self)
     if self._state is not None and other._state is not None:
         args._state = self._state.kron(other._state)
     else:
         _warn_or_error(
             'Pass a `QuantumStateRepresentation` into the `SimulationState` constructor.'
             ' The `_on_` overrides will be removed in cirq v0.16.')
         self._on_kronecker_product(other, args)
     args._set_qubits(self.qubits + other.qubits)
     return args
Exemplo n.º 12
0
    def state_vector(self, copy: Optional[bool] = None):
        """Return the state vector at this point in the computation.

        The state is returned in the computational basis with these basis
        states defined by the qubit_map. In particular the value in the
        qubit_map is the index of the qubit, and these are translated into
        binary vectors where the last qubit is the 1s bit of the index, the
        second-to-last is the 2s bit of the index, and so forth (i.e. big
        endian ordering).

        Example:
             qubit_map: {QubitA: 0, QubitB: 1, QubitC: 2}
             Then the returned vector will have indices mapped to qubit basis
             states like the following table

                |     | QubitA | QubitB | QubitC |
                | :-: | :----: | :----: | :----: |
                |  0  |   0    |   0    |   0    |
                |  1  |   0    |   0    |   1    |
                |  2  |   0    |   1    |   0    |
                |  3  |   0    |   1    |   1    |
                |  4  |   1    |   0    |   0    |
                |  5  |   1    |   0    |   1    |
                |  6  |   1    |   1    |   0    |
                |  7  |   1    |   1    |   1    |

        Args:
            copy: If True, then the returned state is a copy of the state
                vector. If False, then the state vector is not copied,
                potentially saving memory. If one only needs to read derived
                parameters from the state vector and store then using False
                can speed up simulation by eliminating a memory copy.
        """
        if copy is None:
            _compat._warn_or_error(
                "Starting in v0.16, state_vector will not copy the state by default. "
                "Explicitly set copy=True to copy the state."
            )
            copy = True
        if self._state_vector is None:
            self._state_vector = np.array([1])
            state = self._merged_sim_state
            if state is not None:
                vector = state.target_tensor
                size = np.prod(vector.shape, dtype=np.int64)
                self._state_vector = np.reshape(vector, size)
        return self._state_vector.copy() if copy else self._state_vector
def _measurement_key_names_from_magic_methods(
    val: Any, ) -> Union[FrozenSet[str], NotImplementedType, None]:
    """Uses the measurement key related magic methods to get the key strings for this object."""

    getter = getattr(val, '_measurement_key_names_', None)
    result = NotImplemented if getter is None else getter()
    if result is not NotImplemented and result is not None:
        if not isinstance(result, FrozenSet):
            _compat._warn_or_error(
                f'The _measurement_key_names_ implementation of {type(val)} must return a'
                f' frozenset instead of {type(result)} by v0.16.')
            return frozenset(result)
        return result

    getter = getattr(val, '_measurement_key_name_', None)
    result = NotImplemented if getter is None else getter()
    if result is not NotImplemented and result is not None:
        return frozenset([result])

    return result
Exemplo n.º 14
0
    def copy(self: TSelf, deep_copy_buffers: bool = True) -> TSelf:
        """Creates a copy of the object.

        Args:
            deep_copy_buffers: If True, buffers will also be deep-copied.
            Otherwise the copy will share a reference to the original object's
            buffers.

        Returns:
            A copied instance.
        """
        args = copy.copy(self)
        args._classical_data = self._classical_data.copy()
        if self._state is not None:
            args._state = self._state.copy(deep_copy_buffers=deep_copy_buffers)
        else:
            _warn_or_error(
                'Pass a `QuantumStateRepresentation` into the `SimulationState` constructor.'
                ' The `_on_` overrides will be removed in cirq v0.16.')
            self._on_copy(args, deep_copy_buffers)
        return args
Exemplo n.º 15
0
def control_keys(val: Any) -> FrozenSet['cirq.MeasurementKey']:
    """Gets the keys that the value is classically controlled by.

    Args:
        val: The object that may be classically controlled.

    Returns:
        The measurement keys the value is controlled by. If the value is not
        classically controlled, the result is the empty tuple.
    """
    getter = getattr(val, '_control_keys_', None)
    result = NotImplemented if getter is None else getter()
    if result is not NotImplemented and result is not None:
        if not isinstance(result, FrozenSet):
            _compat._warn_or_error(
                f'The _control_keys_ implementation of {type(val)} must return a'
                f' frozenset instead of {type(result)} by v0.16.')
            return frozenset(result)
        return result

    return frozenset()
Exemplo n.º 16
0
    def __init__(
        self,
        prng: Optional[np.random.RandomState] = None,
        qubits: Optional[Sequence['cirq.Qid']] = None,
        log_of_measurement_results: Optional[Dict[str, List[int]]] = None,
        classical_data: Optional['cirq.ClassicalDataStore'] = None,
        state: Optional[TState] = None,
    ):
        """Inits SimulationState.

        Args:
            prng: The pseudo random number generator to use for probabilistic
                effects.
            qubits: Determines the canonical ordering of the qubits. This
                is often used in specifying the initial state, i.e. the
                ordering of the computational basis states.
            log_of_measurement_results: A mutable object that measurements are
                being recorded into.
            classical_data: The shared classical data container for this
                simulation.
            state: The underlying quantum state of the simulation.
        """
        if qubits is None:
            qubits = ()
        classical_data = classical_data or value.ClassicalDataDictionaryStore(
            _records={
                value.MeasurementKey.parse_serialized(k): [tuple(v)]
                for k, v in (log_of_measurement_results or {}).items()
            })
        super().__init__(qubits=qubits, classical_data=classical_data)
        if prng is None:
            prng = cast(np.random.RandomState, np.random)
        self._prng = prng
        self._state = cast(TState, state)
        if state is None:
            _warn_or_error(
                'This function will require a valid `state` input in cirq v0.16.'
            )
Exemplo n.º 17
0
 def factor(self: TSelf,
            qubits: Sequence['cirq.Qid'],
            *,
            validate=True,
            atol=1e-07,
            inplace=False) -> Tuple[TSelf, TSelf]:
     """Splits two state spaces after a measurement or reset."""
     extracted = copy.copy(self)
     remainder = self if inplace else copy.copy(self)
     if self._state is not None:
         e, r = self._state.factor(self.get_axes(qubits),
                                   validate=validate,
                                   atol=atol)
         extracted._state = e
         remainder._state = r
     else:
         _warn_or_error(
             'Pass a `QuantumStateRepresentation` into the `SimulationState` constructor.'
             ' The `_on_` overrides will be removed in cirq v0.16.')
         self._on_factor(qubits, extracted, remainder, validate, atol)
     extracted._set_qubits(qubits)
     remainder._set_qubits([q for q in self.qubits if q not in qubits])
     return extracted, remainder