leaspy.variables.state ====================== .. py:module:: leaspy.variables.state .. autoapi-nested-parse:: This module defines the State of stateful models. A state contains 2 main components: 1. The relationships between the variables through a :class:`~leaspy.variables.dag.VariablesDAG` 2. The values of each variable of the DAG as a mapping between variable names and their values The State class is crucial for stateful models with its logic for efficiently retrieving variable values. This class relies on a caching mechanism that enables quick queries. .. !! processed by numpydoc !! Classes ------- .. autoapisummary:: leaspy.variables.state.StateForkType leaspy.variables.state.State Module Contents --------------- .. py:class:: StateForkType(*args, **kwds) Bases: :py:obj:`enum.Enum` The strategy used to cache forked values in :class:`.State`. REF : Reference-based caching Cached values are stored by reference, meaning no copying occurs. Mutating the original variables after caching will affect the cached version. COPY : Deep copy-based caching Cached values are stored via `copy.deepcopy`, ensuring they are independent of the originals. .. rubric:: Notes - Use `REF` for efficiency when you're certain the original values will not be mutated after caching. - Use `COPY` to ensure isolation between the cached values and any subsequent modifications. - If using `REF` beware that values will NOT be copied (it only keeps references of values), so do NOT mutate them directly or the behavior will be unexpected. .. !! processed by numpydoc !! .. py:attribute:: REF .. py:attribute:: COPY .. py:method:: to_cache(d) Get the values to cache, depending on forking type. .. !! processed by numpydoc !! .. py:class:: State(dag, *, auto_fork_type = None) Bases: :py:obj:`collections.abc.MutableMapping` Dictionary of cached values corresponding to the stateless DAG instance. :Parameters: **dag** : :class:`~leaspy.variables.dag.VariablesDAG` The stateless DAG which state will hold values for. **auto_fork_type** : :class:`~leaspy.variables.state.StateForkType` or None (default) Refer to :class:`~leaspy.variables.state.StateForkType` class and :attr:`auto_fork_type` :Attributes: **dag** : :class:`~leaspy.variables.dag.VariablesDAG` The stateless DAG which the state instance will hold values for. **auto_fork_type** : :class:`~leaspy.variables.state.StateForkType` or None If not `StateForkType.NONE` each dictionary assignment will lead to the partial caching of previous value and all its children, so they can be reverted without computation. The exact caching strategy depends on flag (caching by reference or by copy) Can be manually set or via `auto_fork` context manager. **_tracked_variables** : :ob:`set[:class:`~leaspy.variables.specs.VariableName`, ...] .. **_values** : :class:`~leaspy.variables.specs.VariablesLazyValuesRW` Private cache for values (computations are lazy thus some values may be None). All not None values are always self-consistent with respect to DAG dependencies. **_last_fork** : None or Optional[:class:`~leaspy.variables.specs.VariablesLazyValuesRO`] If not None, holds the previous partial state values so they may be `.revert()`. Automatically populated on assignment operations as soon as `auto_fork_type` is not `NONE`. Example: if you set a new value for `a`, then value of `a` and of all its children just before assignment are held until either reversion or a new assignment. .. !! processed by numpydoc !! .. py:attribute:: dag .. py:attribute:: auto_fork_type :value: None .. py:property:: tracked_variables :type: set[leaspy.variables.specs.VariableName, Ellipsis] Get the set of variable names currently tracked by the State. :Returns: ;obj:`set`[:class:`~leaspy.variables.specs.VariableName`, ...] A set containing the names of the tracked variables. .. !! processed by numpydoc !! .. py:method:: track_variables(variable_names) Add some variables to the tracked variables. :Parameters: **variable_names** : :obj:`~typing.Iterable` of :class:`~leaspy.variables.specs.VariableName` The names of the variables to be added to the tracked variables. .. !! processed by numpydoc !! .. py:method:: track_variable(variable_name) Add a single variable to the tracked variables. :Parameters: **variable_name** : :class:`~leaspy.variables.specs.VariableName` The name of the variable to be added to the tracked variables. .. !! processed by numpydoc !! .. py:method:: untrack_variables(variable_names) Remove some variables from the tracked variables. :Parameters: **variable_names** : :obj:`~typing.Iterable` of :class:`~leaspy.variables.specs.VariableName` The names of the variables to be removed from the tracked variables. .. !! processed by numpydoc !! .. py:method:: untrack_variable(variable_name) Remove a single variable from the tracked variables. :Parameters: **variable_name** : :class:`~leaspy.variables.specs.VariableName` The name of the variable to be removed from the tracked variables. .. !! processed by numpydoc !! .. py:method:: clear() Reset last forked state and reset all values to their canonical values. .. !! processed by numpydoc !! .. py:method:: clone(*, disable_auto_fork = False, keep_last_fork = False) Clone current state without copying the DAG. :Parameters: **disable_auto_fork** : :obj:`bool`, optional Whether to allow auto-fork or not. Default=False. **keep_last_fork** : :obj:`bool`, optional Whether to keep the last fork or not. Default=False. :Returns: :class:`~leaspy.variables.state.State` The new cloned state instance. .. !! processed by numpydoc !! .. py:method:: auto_fork(type = StateForkType.REF) Provide a context manager interface with temporary `auto_fork_type` set to `type`. :Parameters: **type** : :class:`~leaspy.variables.state.StateForkType` or None, optional The temporary auto-forking strategy to use within the context. Defaults to `StateForkType.REF`. :Yields: None Control returns to the caller with the temporary forking strategy applied. .. !! processed by numpydoc !! .. py:method:: is_variable_set(name) Returns True if the variable is in the DAG and if its value is not None. :Parameters: **name** : :class:`~leaspy.variables.specs.VariableName` The name of the variable to check. :Returns: :obj:`bool` True if the variable exists in the DAG and its value has been set (i.e., is not None). False otherwise. .. !! processed by numpydoc !! .. py:method:: are_variables_set(variable_names) Returns True if all the variables are in the DAG with values different from None. :Parameters: **variable_names** : :obj:`Iterable`[:class:`~leaspy.variables.specs.VariableName`] A collection of variable names to check. :Returns: :obj:`bool` True if all variables exist in the DAG and their values are set (i.e., not None). False otherwise. .. !! processed by numpydoc !! .. py:method:: put(variable_name, variable_value, *, indices = (), accumulate = False) Smart and protected assignment of a variable value, but potentially on a subset of indices, adding (accumulating) values and OUT-OF-PLACE. :Parameters: **variable_name** : :class:`~leaspy.variables.specs.VariableName` The name of the variable. **variable_value** : :class:`~leaspy.variables.specs.VariableValue` The new value to put in the variable name. **indices** : :obj:`tuple` of :obj:`int`, optional If set, the operation will happen on a subset of indices. Default=() **accumulate** : :obj:`bool`, optional If set to True, the new variable value will be added to the old value. Otherwise, it will be assigned. Default=False .. !! processed by numpydoc !! .. py:method:: precompute_all() Pre-compute all values of the graph (assuming leaves already have valid values). .. !! processed by numpydoc !! .. py:method:: revert(subset = None, *, right_broadcasting = True) Revert state to previous forked state. Forked state is then reset. :Parameters: **subset** : :class:`~leaspy.variables.specs.VariableValue` or None If not None, the reversion is only partial: * subset = True <=> revert previous state for those indices * subset = False <=> keep current state for those indices User is responsible for having tensor values that are consistent with `subset` shape (i.e. valid broadcasting) for the forked node and all of its children. When the current OR forked state is not set (value = None) on a particular node of forked DAG, then the reverted result is always None. **right_broadcasting** : :obj:`bool`, optional If True and if `subset` is not None, then the subset of indices to revert uses right-broadcasting, instead of the standard left-broadcasting. Default=True. :Raises: :exc:`LeaspyInputError` If no forked state exists to revert from (i.e., `.auto_fork()` context was not used). .. !! processed by numpydoc !! .. py:method:: to_device(device) Move values to the specified device (in-place). :Parameters: **device** : :class:`torch.device` .. .. !! processed by numpydoc !! .. py:method:: put_population_latent_variables(method) " Initialize all population latent variables in the state with predefined values. :Parameters: **method** : obj:`str` or :class:`~leaspy.variables.specs.LatentVariableInitType` or None The method used to initialize the variables. If None, all population latent variables will be unset (set to None). Otherwise, the corresponding initialization function will be called for each variable using the provided method. .. !! processed by numpydoc !! .. py:method:: put_individual_latent_variables(method = None, *, n_individuals = None, df = None) Initialize all individual latent variables in the state with predefined values. :Parameters: **method** : :obj:`str` or :class:`~leaspy.variables.specs.LatentVariableInitType`, optional The method used to initialize the variables. If None, the variables will be unset (set to None). If provided, an initialization function will be called per variable. When `method` is not None, `n_individuals` must be specified. **n_individuals** : :obl:`int`, optional Number of individuals to initialize. Required when `method` is not None and `df` is not provided. **df** : :obj:`pandas.DataFrame`, optional A DataFrame from which to directly extract the individual latent variable values. It must contain columns named 'tau' and 'xi' for direct assignment of these variables. If the "sources" variable is present, the DataFrame should include columns named 'sources_0', 'sources_1', ..., up to the expected number of source variables. :Raises: :exc:`LeaspyInputError` If `method` is specified without `n_individuals`, or if required columns are missing in `df`. .. !! processed by numpydoc !! .. py:method:: save(output_folder, iteration = None) Save the tracked variable values of the state. :Parameters: **output_folder** : :obj:`str` The path to the output folder in which the state's tracked variables should be saved. **iteration** : :obj:`int`, optional The iteration number when this method is called from an algorithm. This iteration number will appear at the beginning of the row. .. !! processed by numpydoc !! .. py:method:: get_tensor_value(variable_name) Return the value of the provided variable as a torch tensor. :Parameters: **variable_name** : :class:`~leaspy.variables.specs.VariableName` The name of the variable for which to retrieve the value. :Returns: :class:`~leaspy.variables.specs.VariableValue` The value of the variable. .. !! processed by numpydoc !! .. py:method:: get_tensor_values(variable_names) Return the values of the provided variables as torch tensors. :Parameters: **variable_names** : :class:`~typing.Iterable` of :class:`~leaspy.variables.specs.VariableName` The names of the variables for which to retrieve the values. :Returns: :obj:`tuple` of :class:`~leaspy.variables.specs.VariableValue` The values of the variables. .. !! processed by numpydoc !!