Source code for qutip.core.options

# Required for Sphinx to follow autodoc_type_aliases
from __future__ import annotations

from ..settings import settings
from .numpy_backend import np as qt_np
import numpy
from typing import overload, Literal, Any
import types

__all__ = ["CoreOptions"]


class QutipOptions:
    """
    Class for basic functionality for qutip's options.

    Define basic method to wrap an ``options`` dict.
    Default options are in a class _options dict.

    Options can also act as properties. The ``_properties`` map options keys to
    a function to call when the ``QutipOptions`` become the default.
    """

    _options: dict[str, Any] = {}
    _properties = {}
    _settings_name = None  # Where the default is in settings

    def __init__(self, **options):
        self.options = self._options.copy()
        for key in set(options) & set(self.options):
            self[key] = options.pop(key)
        if options:
            raise KeyError(f"Options {set(options)} are not supported.")

    def __contains__(self, key: str) -> bool:
        return key in self.options

    def __getitem__(self, key: str) -> Any:
        # Let the dict catch the KeyError
        return self.options[key]

    def __setitem__(self, key: str, value: Any) -> None:
        # Let the dict catch the KeyError
        self.options[key] = value
        if (
            key in self._properties
            and self is getattr(settings, self._settings_name)
        ):
            self._properties[key](value)

    def __repr__(self, full: bool = True) -> str:
        out = [f"<{self.__class__.__name__}("]
        for key, value in self.options.items():
            if full or value != self._options[key]:
                out += [f"    '{key}': {repr(value)},"]
        out += [")>"]
        if len(out) - 2:
            return "\n".join(out)
        else:
            return "".join(out)

    def __enter__(self):
        self._backup = getattr(settings, self._settings_name)
        self._set_as_global_default()

    def __exit__(
        self,
        exc_type: type[BaseException] | None,
        exc_value: BaseException | None,
        exc_traceback: types.TracebackType | None,
    ) -> None:
        self._backup._set_as_global_default()

    def _set_as_global_default(self):
        setattr(settings, self._settings_name, self)
        for key in self._properties:
            self._properties[key](self.options[key])


[docs] class CoreOptions(QutipOptions): """ Options used by the core of qutip such as the tolerance of :obj:`.Qobj` comparison or coefficient's format. Values can be changed in ``qutip.settings.core`` or by using context: ``with CoreOptions(atol=1e-6): ...`` ******** Options: ******** auto_tidyup : bool Whether to tidyup during sparse operations. auto_tidyup_dims : bool [False] Use auto tidyup dims on multiplication, tensor, etc. Without auto_tidyup_dims: ``basis([2, 2]).dims == [[2, 2], [1, 1]]`` With auto_tidyup_dims: ``basis([2, 2]).dims == [[2, 2], [1]]`` atol : float {1e-12} General absolute tolerance. Used in various functions to round off small values. rtol : float {1e-12} General relative tolerance. auto_tidyup_atol : float {1e-14} The absolute tolerance used in automatic tidyup (see the ``auto_tidyup`` parameter above) and the default value of ``atol`` used in :meth:`Qobj.tidyup`. function_coefficient_style : str {"auto"} The signature expected by function coefficients. The options are: - "pythonic": the signature should be ``f(t, ...)`` where ``t`` is the time and the ``...`` are the remaining arguments passed directly into the function. E.g. ``f(t, w, b=5)``. - "dict": the signature shoule be ``f(t, args)`` where ``t`` is the time and ``args`` is a dict containing the remaining arguments. E.g. ``f(t, {"w": w, "b": 5})``. - "auto": select automatically between the two options above based on the signature of the supplied function. If the function signature is exactly ``f(t, args)`` then ``dict`` is used. Otherwise ``pythonic`` is used. default_dtype : Nonetype, str, type {None} When set, functions creating :obj:`.Qobj`, such as :func:"qeye" or :func:"rand_herm", will use the specified data type. Any data-layer known to ``qutip.data.to`` is accepted. When ``None``, these functions will default to a sensible data type. """ _options = { # use auto tidyup "auto_tidyup": True, # use auto tidyup dims on multiplication "auto_tidyup_dims": False, # general absolute tolerance "atol": 1e-12, # general relative tolerance "rtol": 1e-12, # use auto tidyup absolute tolerance "auto_tidyup_atol": 1e-14, # signature style expected by function coefficients "function_coefficient_style": "auto", # Default Qobj dtype for Qobj create function "default_dtype": None, # Expect, trace, etc. will return real for hermitian matrices. # Hermiticity checks can be slow, stop jitting, etc. "auto_real_casting": True, # Default backend is numpy "numpy_backend": numpy } _settings_name = "core" _properties = { "numpy_backend": qt_np._qutip_setting_backend, } @overload def __getitem__( self, key: Literal["auto_tidyup", "auto_tidyup_dims", "auto_real_casting"], ) -> bool: ... @overload def __getitem__( self, key: Literal["atol", "rtol", "auto_tidyup_atol"] ) -> float: ... @overload def __getitem__( self, key: Literal["function_coefficient_style"] ) -> str: ... @overload def __getitem__(self, key: Literal["default_dtype"]) -> str | None: ... def __getitem__(self, key: str) -> Any: # Let the dict catch the KeyError return self.options[key] @overload def __setitem__( self, key: Literal["auto_tidyup", "auto_tidyup_dims", "auto_real_casting"], value: bool, ) -> None: ... @overload def __setitem__( self, key: Literal["atol", "rtol", "auto_tidyup_atol"], value: float ) -> None: ... @overload def __setitem__( self, key: Literal["function_coefficient_style"], value: str ) -> None: ... @overload def __setitem__( self, key: Literal["default_dtype"], value: str | None ) -> None: ... def __setitem__(self, key: str, value: Any) -> None: # Let the dict catch the KeyError super().__setitem__(key, value)
# Creating the instance of core options to use everywhere. # settings.core = CoreOptions() CoreOptions()._set_as_global_default()