Source code for qtealeaves.observables.overlap

# This code is part of qtealeaves.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
"""
Distance observable will measure the distance of the quantum system
to one or more pure states defined within this observable as filenames.
We measure the overlap and return a complex number <phi | psi>.
"""

import logging
from typing import TYPE_CHECKING, Any, Self

from qtealeaves.emulator import ATTN, MPS, TTN, StateVector
from qtealeaves.tooling import QTeaLeavesError

from .tnobase import _TNObsBase

if TYPE_CHECKING:
    from qtealeaves.abstracttns.abstract_tn import _AbstractTN
else:
    _AbstractTN = Any

__all__ = ["Overlap"]
logger = logging.getLogger(__name__)


[docs] class Overlap(_TNObsBase): """ Distance observable will measure the distance of the quantum system to one or more pure states defined within this observable as filenames. We measure the overlap and return a complex number :math:`\\rangle\\phi | \\psi\\langle`. **Arguments** name : str Define a label under which we can find the observable in the result dictionary. path_to_state : str Filename to the state. The default extension for formatted Fortran TTNs is ``.ttn`` and for unformatted Fortran TTNs is ``.ttnbin``. Other file extension might be added. """ # mypy triggered because of StateVector _measurable_ansaetze = (MPS, TTN, ATTN, StateVector) # type: ignore[assignment] def __init__(self, name: str, path_to_state: str): super().__init__(name) self.path_to_state = [path_to_state] self.check_extension(path_to_state)
[docs] @classmethod def empty(cls) -> Self: """ Documentation see :func:`_TNObsBase.empty`. """ obj = cls("x", "x.ttn") obj.name = [] obj.path_to_state = [] return obj
def __iadd__(self, other: Any) -> Self: """ Documentation see :func:`_TNObsBase.__iadd__`. """ if isinstance(other, Overlap): self.name += other.name self.path_to_state += other.path_to_state else: raise QTeaLeavesError( f"__iadd__ not defined for types {type(self)} and {type(other)}." ) return self
[docs] def measure( self, state: _AbstractTN, operators: Any = None, **kwargs: Any, ) -> dict[str, Any]: """ Measure the overlap between the current state and self.path_to_state, and save it in the results buffer. Both have to be pure states. Args: state : instance of class from :py:mod:`qtealeaves.emulator` The state to measure the observable on. operators : instance of :py:class:`qtealeaves.operators.TNOperators` The operators to be measured. Not used for this observable, therefore set to None. **kwargs : dict Additional keyword arguments, see :func:`_TNObsBase.measure`. """ # we allow as before only the same ansatz ansatz_cls = state.__class__ if len(self.name) == 0: return self.results_buffer if not self.check_measurable(ansatz_cls): logger.warning("Observable %s not measurable for %s", self.name, str(state)) return self.results_buffer for jj, name_jj in enumerate(self.name): path_jj = self.path_to_state[jj] psi_tn = ansatz_cls.read(path_jj, tensor_backend=state.tensor_backend) self.results_buffer[name_jj] = state.dot(psi_tn) # type: ignore[attr-defined] return self.results_buffer
[docs] @classmethod def check_extension(cls, path_to_state: str) -> None: """ Check that the file uses a valid file extension at least readable by some simulation. """ if "." not in path_to_state: raise QTeaLeavesError("No file extension detected.") file_extension = path_to_state.split(".")[-1] if not any( ansatz.extension in file_extension for ansatz in cls._measurable_ansaetze ): raise QTeaLeavesError( f"Unknown extension for pure state: {file_extension}." )