reno.components.EquationPart#

class reno.components.EquationPart(sub_equation_parts=None)#

Bases: object

The base object that represents some portion/subtree of a compute or equation tree.

The purpose of EquationParts is to allow constructing an equation as a “deferred computation” - essentially symbolically creating a compute tree of objects all with .eval() functions that get recursively run later on when a simulation is running/equation is computing (spawned with root ``.eval()`.)

Note

In order to get nice semantics when constructing equations, all math operations applied to an EquationPart get replaced with their corresponding operation EquationPart. This means a 5 + Scalar(4) gets converted into an Operation("+", Scalar(5), Scalar(4))

Parameters:

sub_equation_parts (List[EquationPart]) – The list of all immediate child equation subtrees, e.g. for the operation a + b, the root equation part is the operation +, and [a, b] would be its sub parts. These are used to help search the tree/connect parts of diagrams up. TODO: probably not strictly defined/enforced enough within the code, write tests for this.

Methods

__init__([sub_equation_parts])

clip(min, max)

equal(obj)

eval([t, save, force])

Execute the compute graph for this equation, this needs to be implemented in every subclass.

find_refs_of_type(search_type[, already_checked])

Actually recursive as opposed to seek_refs, returns a list of all equation parts matching passed type.

get_shape()

For now this is returning an integer because we only allow a single additional dimension.

get_type()

Similar to shape, this gets computed recursively, used to automatically determine if the value needs to be initialized with a certain numpy type.

is_static()

Convenience shortcut for reno.utils.is_static() - True if this equation doesn't rely on any dynamic values (thus constant), False if it does.

latex(**kwargs)

Construct a string representation of this portion of the equation for use in a latex display.

not_equal(obj)

pt(**refs)

Get a pytensor graph representing this piece of an equation.

pt_str(**refs)

Construct a string containing relevant pytensor code for this piece of the equation.

seek_refs()

Immediate refs only, depth=1.

series_max()

series_min()

sum([axis])

Attributes

dtype

The type of each underlying value.

shape

The size of the data dimension, 1 by default.

timeseries

Get a timeseries view of the data (includes all historical data across all timesteps.)

__add__(obj)#
__and__(obj)#
__annotations__ = {}#
__dict__ = mappingproxy({'__module__': 'reno.components', '__doc__': 'The base object that represents some portion/subtree of a compute\n    or equation tree.\n\n    The purpose of EquationParts is to allow constructing an equation as a\n    "deferred computation" - essentially symbolically creating a compute\n    tree of objects all with ``.eval()`` functions that get recursively run\n    later on when a simulation is running/equation is computing (spawned with\n    root ``.eval()`.)\n\n    Note:\n        In order to get nice semantics when constructing equations, all math\n        operations applied to an EquationPart get replaced with their\n        corresponding operation EquationPart. This means a ``5 + Scalar(4)``\n        gets converted into an ``Operation("+", Scalar(5), Scalar(4))``\n\n    Args:\n        sub_equation_parts (List[EquationPart]): The list of all **immediate**\n            child equation subtrees, e.g. for the operation ``a + b``, the\n            root equation part is the operation ``+``, and ``[a, b]`` would be\n            its sub parts. These are used to help search the tree/connect\n            parts of diagrams up. TODO: probably not strictly defined/enforced\n            enough within the code, write tests for this.\n    ', '__init__': <function EquationPart.__init__>, '__add__': <function EquationPart.__add__>, '__sub__': <function EquationPart.__sub__>, '__neg__': <function EquationPart.__neg__>, '__mul__': <function EquationPart.__mul__>, '__truediv__': <function EquationPart.__truediv__>, '__mod__': <function EquationPart.__mod__>, '__radd__': <function EquationPart.__radd__>, '__rsub__': <function EquationPart.__rsub__>, '__rmul__': <function EquationPart.__rmul__>, '__rtruediv__': <function EquationPart.__rtruediv__>, '__rmod__': <function EquationPart.__rmod__>, '__lt__': <function EquationPart.__lt__>, '__le__': <function EquationPart.__le__>, '__gt__': <function EquationPart.__gt__>, '__ge__': <function EquationPart.__ge__>, '__and__': <function EquationPart.__and__>, '__rand__': <function EquationPart.__rand__>, '__or__': <function EquationPart.__or__>, '__ror__': <function EquationPart.__ror__>, '__getitem__': <function EquationPart.__getitem__>, 'series_max': <function EquationPart.series_max>, 'series_min': <function EquationPart.series_min>, 'sum': <function EquationPart.sum>, 'timeseries': <property object>, 'shape': <property object>, 'dtype': <property object>, 'equal': <function EquationPart.equal>, 'not_equal': <function EquationPart.not_equal>, 'clip': <function EquationPart.clip>, 'eval': <function EquationPart.eval>, 'latex': <function EquationPart.latex>, 'seek_refs': <function EquationPart.seek_refs>, 'get_shape': <function EquationPart.get_shape>, 'get_type': <function EquationPart.get_type>, 'find_refs_of_type': <function EquationPart.find_refs_of_type>, 'pt': <function EquationPart.pt>, 'pt_str': <function EquationPart.pt_str>, 'is_static': <function EquationPart.is_static>, '__dict__': <attribute '__dict__' of 'EquationPart' objects>, '__weakref__': <attribute '__weakref__' of 'EquationPart' objects>, '__annotations__': {}})#
__ge__(obj)#

Return self>=value.

__getitem__(obj)#
__gt__(obj)#

Return self>value.

__le__(obj)#

Return self<=value.

__lt__(obj)#

Return self<value.

__mod__(obj)#
__module__ = 'reno.components'#
__mul__(obj)#
__neg__()#
__or__(obj)#

Return self|value.

__radd__(obj)#
__rand__(obj)#
__rmod__(obj)#
__rmul__(obj)#
__ror__(obj)#

Return value|self.

__rsub__(obj)#
__rtruediv__(obj)#
__sub__(obj)#
__truediv__(obj)#
__weakref__#

list of weak references to the object

clip(min, max)#
property dtype: type#

The type of each underlying value.

equal(obj)#
eval(t=0, save=False, force=False, **kwargs)#

Execute the compute graph for this equation, this needs to be implemented in every subclass.

Note that throughout a compute tree, this should effectively recurse through .eval() calls to all subparts as well.

Parameters:
  • t (int) – Timestep along simulation at which to evaluate.

  • save (bool) – Whether to store/track/cache the output in a tracked matrix. This is really only applicable to ``TrackedReference``s, but given recursive nature of this function, needs to always be passed down through all subsequent calls.

  • force (bool) – Whether to ignore a previously cached value and compute regardless.

Return type:

int | float | ndarray

find_refs_of_type(search_type, already_checked=None)#

Actually recursive as opposed to seek_refs, returns a list of all equation parts matching passed type.

Parameters:

already_checked (list)

Return type:

list

get_shape()#

For now this is returning an integer because we only allow a single additional dimension. Note that this shape _does not_ incoporate time or batch dimensions, only the “data” dimension if applicable. This should be overridden by subclasses, e.g. operations which would change the shape.

Return type:

int

get_type()#

Similar to shape, this gets computed recursively, used to automatically determine if the value needs to be initialized with a certain numpy type.

Return type:

type

is_static()#

Convenience shortcut for reno.utils.is_static() - True if this equation doesn’t rely on any dynamic values (thus constant), False if it does.

Return type:

bool

latex(**kwargs)#

Construct a string representation of this portion of the equation for use in a latex display. Should probably be overriden in most subclasses, and often needs to be called recursively on sub_equation_parts.

Return type:

str

not_equal(obj)#
pt(**refs)#

Get a pytensor graph representing this piece of an equation.

Parameters:

refs (dict[str, TensorVariable])

Return type:

TensorVariable

pt_str(**refs)#

Construct a string containing relevant pytensor code for this piece of the equation. This is useful for “compiling” into pymc code.

Parameters:

refs (dict[str, str])

Return type:

str

seek_refs()#

Immediate refs only, depth=1.

series_max()#
series_min()#
property shape: int#

The size of the data dimension, 1 by default.

sum(axis=0)#
property timeseries: Operation#

Get a timeseries view of the data (includes all historical data across all timesteps.)