leaspy.variables ================ .. py:module:: leaspy.variables Submodules ---------- .. toctree:: :maxdepth: 1 /reference/api/leaspy/variables/dag/index /reference/api/leaspy/variables/distributions/index /reference/api/leaspy/variables/specs/index /reference/api/leaspy/variables/state/index /reference/api/leaspy/variables/utilities/index Classes ------- .. autoapisummary:: leaspy.variables.VariablesDAG Package Contents ---------------- .. py:class:: VariablesDAG Bases: :py:obj:`collections.abc.Mapping` Directed acyclic graph of symbolic variables used in a leaspy model with efficient topologically sorted bidirectional access. :Parameters: **variables** : :class:`~typing.Mapping` [ :class:`~leaspy.variables.specs.VariableName`, :class:`~leaspy.variables.specs.VariableInterface`] A dictionary mapping variable names to their specification objects (e.g., `IndepVariable`, `LinkedVariable`, etc.). **direct_ancestors** : :class:`~leaspy.variables.specs.VariablesToFrozenSet` A dictionary mapping each variable name to the set of variable names it directly depends on (i.e., its parents). Use :meth:`~leaspy.variables.dag.VariablesDAG.from_dict()` class method to reach the natural dependencies of linked variables. .. rubric:: Notes Internally, this class precomputes: * ``direct_children``: inverse of `direct_ancestors`, mapping each node to its immediate dependents. * ``sorted_variables_names``: a topological ordering of variable names (roots to leaves). * ``sorted_children``: all transitive children of a node in topological order. * ``sorted_ancestors``: all transitive ancestors of a node in topological order. * ``sorted_variables_by_type``: variables grouped and ordered by their Python class/type. In general the VariablesDAG is not a tree because the graph may not be totally connected and may have multiple roots. It is not a multi-tree either since there may be multiple directed paths between two nodes - e.g. `logistic_model = f[g, b(g), ...]`. However, we do assume that there is no cycle in the graph (not checked currently), which is equivalent to be topologically sortable. In order to improve the efficiency of the algorithms, a node-wise sorted children and ancestors mappings are computed. These mappings are useful to: - perform computations and caching of intermediate variable dependencies - quickly reset all dependent nodes upon a modification Finally, we do not store children nor ancestors in a specific node class to avoid cross-references in such nodes. .. rubric:: References https://en.wikipedia.org/wiki/Directed_acyclic_graph#Computational_problems .. only:: latex .. rubric:: Examples >>> from leaspy.variables import VariablesDAG >>> from leaspy.variables.specs import IndepVariable, LinkedVariable >>> d_vars = { "x": IndepVariable(), "y": LinkedVariable(lambda *, x: -x), } >>> dag = VariablesDAG.from_dict(d_vars) .. !! processed by numpydoc !! .. py:attribute:: variables :type: Mapping[leaspy.variables.specs.VariableName, leaspy.variables.specs.VariableInterface] Dictionary of variable names to their corresponding variable specification objects. .. !! processed by numpydoc !! .. py:attribute:: direct_ancestors :type: leaspy.variables.specs.VariablesToFrozenSet Mapping of variable names to their direct ancestors. .. !! processed by numpydoc !! .. py:attribute:: direct_children :type: leaspy.variables.specs.VariablesToFrozenSet Mapping of variable names to their direct children. .. !! processed by numpydoc !! .. py:attribute:: sorted_variables_names :type: tuple[leaspy.variables.specs.VariableName, Ellipsis] Tuple of variable names sorted in topological order (from roots to leaves). .. !! processed by numpydoc !! .. py:attribute:: sorted_children :type: Mapping[leaspy.variables.specs.VariableName, tuple[leaspy.variables.specs.VariableName, Ellipsis]] Mapping of all children of a given variable in a topological order. .. !! processed by numpydoc !! .. py:attribute:: sorted_ancestors :type: Mapping[leaspy.variables.specs.VariableName, tuple[leaspy.variables.specs.VariableName, Ellipsis]] Mapping of all ancestor of a given variable in a topological order. .. !! processed by numpydoc !! .. py:attribute:: sorted_variables_by_type :type: Mapping[Type[leaspy.variables.specs.VariableInterface], Mapping[leaspy.variables.specs.VariableName, leaspy.variables.specs.VariableInterface]] The sorted variables, but stratified per variable type, to easily access them. .. !! processed by numpydoc !! .. py:method:: from_dict(input_dictionary) :classmethod: Instantiate a new DAG of variables from a dictionary of variables. This method is using :class:`~leaspy.variables.specs.LinkedVariable` dependencies as direct ancestors. :Parameters: **input_dictionary** : :class:`~typing.Mapping` [:class:`~leaspy.variables.specs.VariableName` , :class:`~leaspy.variables.specs.VariableInterface`] The dictionary to use to create the DAG. :Returns: :class:`VariablesDAG` A new instance of `VariablesDAG` with the computed direct ancestor relationships. .. !! processed by numpydoc !! .. py:method:: compute_topological_order_and_path_matrix(direct_children, direct_ancestors) :staticmethod: Produce a topological sorting of the DAG. This relies on a modified Kahn's algorithm to produce a topological sorting of DAG, and the corresponding path matrix as a by-product. :Parameters: **direct_children** : :class:`~leaspy.variables.specs.VariablesToFrozenSet` Mapping from each variable to its direct children. **direct_ancestors** : :class:`~leaspy.variables.specs.VariablesToFrozenSet` Mapping from each variable to its direct ancestors. :Returns: **sorted_nodes** : :obj:`tuple` [:class:`~leaspy.variables.specs.VariableName`, ...] Nodes in a topological order. **path_matrix** : :class:`torch.Tensor` [:obj:`bool`] Boolean triangle superior (strict) matrix indicating whether there is a (directed) path between nodes. .. rubric:: Notes The algorithm has linear complexity with the O(number of edges + number of nodes). Input nodes are sorted by name in order to have fully reproducible output of the initial order of nodes and edges. (Thus renaming nodes may change the output, due to non-uniqueness of topological order) .. !! processed by numpydoc !! .. py:method:: compute_sorted_children_and_ancestors(sorted_nodes, path_matrix) :staticmethod: Produce node-wise topologically sorted children and ancestors from provided nodes. :Parameters: **sorted_nodes** : :obj:`tuple` of :class:`~leaspy.variables.specs.VariableName` The sorted nodes. **path_matrix** : :class:`torch.Tensor` A binary 2D tensor where `path_matrix[i, j] == 1` indicates a path from node `i` to node `j`. Assumes the row/column indices correspond to the order of `sorted_nodes`. :Returns: **sorted_children** : :obj:`dict` [:class:`~leaspy.variables.specs.VariableName`, :obj:`tuple` [:class:`~leaspy.variables.specs.VariableName`, ...]] The sorted children. **sorted_ancestors** : :obj:`dict` [:class:`~leaspy.variables.specs.VariableName`, :obj:`tuple` [:class:`~leaspy.variables.specs.VariableName`, ...]] The sorted ancestors. .. !! processed by numpydoc !! .. py:property:: individual_variable_names :type: tuple[leaspy.variables.specs.VariableName, Ellipsis] Returns a tuple of variable names corresponding to the individual variables. :Returns: :obj:`tuple` of :class:`~leaspy.variables.specs.VariableName` The individual variable names. .. !! processed by numpydoc !!