calipy.effects  (API)

This module provides the CalipyEffect base class that is used for specifying random and deterministic phenomena affecting measurements and provides a list of basic effects as well as the functionality needed to integrate them into the CalipyProbModel class for simulation and inference.

The classes are
CalipyEffect: Base class from which all concrete effects inherit. Blueprint

for effects that involve known parameters, unknown parameters, and random variables. Provides effect in form of differentiable forward map.

CalipyQuantity: Base class from which all concrete quantities inherit. Blueprint

for quantities, i.e. known parameters, unknown parameters, and random variables that are the building blocks for CalipyEffect objects.

The script is meant solely for educational and illustrative purposes. Written by Jemil Avers Butt, Atlas optimization GmbH, www.atlasoptimization.com.

class calipy.effects.CalipyEffect(type=None, name=None, info=None, **kwargs)

Bases: CalipyNode

The CalipyEffect class provides a comprehensive representation of a specific effect. It is named, explained, and referenced in the effect description. The effect is incorporated as a differentiable function based on torch. This function can depend on known parameters, unknown parameters, and random variables. Known parameters have to be provided during invocation of the effect. During training, unknown parameters and the posterior density of the random variables is inferred. This requires providing a unique name, a prior distribution, and a variational distribution for the random variables.

name = 'CalipyEffect'
class calipy.effects.CalipyQuantity(type=None, name=None, info=None, **kwargs)

Bases: CalipyNode

The CalipyQuantity class provides a comprehensive representation of a specific quantity used in the construction of a CalipyEffect object. This could be a known parameter, an unknown parameter, or a random variable. This quantity is named, explained, and referenced in the quantity description. Quantities are incorporated into the differentiable function that define the CalipyEffect forward pass. Each quantity is subservient to an effect and gets a unique id that reflects this, quantities are local and cannot be shared between effects.

name = 'CalipyQuantity'
class calipy.effects.KnownParam(type=None, name=None, info=None, **kwargs)

Bases: CalipyQuantity

name = 'KnownParam'
class calipy.effects.NoiseAddition(node_structure, **kwargs)

Bases: CalipyEffect

NoiseAddition is a subclass of CalipyEffect that produces an object whose forward() method emulates uncorrelated noise being added to an input.

Parameters:

node_structure (NodeStructure) – Instance of NodeStructure that determines the internal structure (shapes, plate_stacks, plates, aux_data) completely.

Returns:

Instance of the NoiseAddition class built on the basis of node_structure

Return type:

NoiseAddition (subclass of CalipyEffect subclass of CalipyNode)

Example usage: Run line by line to investigate Class

# Investigate 2D noise ------------------------------------------------
#
# i) Imports and definitions
import calipy
import torch
from calipy.base import NodeStructure
from calipy.tensor import CalipyTensor
from calipy.effects import NoiseAddition

# ii) Invoke and investigate class
help(NoiseAddition)
NoiseAddition.mro()
print(NoiseAddition.input_vars_schema)

# iii) Instantiate object
noise_ns = NodeStructure(NoiseAddition)
print(noise_ns)
print(noise_ns.dims)
noise_object = NoiseAddition(noise_ns)

# iv) Create arguments
noise_dims = noise_ns.dims['batch_dims'] + noise_ns.dims['event_dims']
mu = CalipyTensor(torch.zeros(noise_dims.sizes), noise_dims, 'mu')
sigma = CalipyTensor(torch.ones(noise_dims.sizes), noise_dims, 'sigma')
noise_input_vars = NoiseAddition.create_input_vars(mean = mu, standard_deviation = sigma)
print(noise_input_vars)

# v) Pass forward
noisy_output = noise_object.forward(input_vars = noise_input_vars, 
                                    observations = None, 
                                    subsample_index = None)
noisy_output
noisy_output.dims
help(noisy_output)

# vi) Investigate object further
noise_object.dtype_chain
noise_object.id
render_1 = noise_object.render(noise_input_vars)
render_1
render_2 = noise_object.render_comp_graph(noise_input_vars)
render_2
batch_dims = DimTuple((Dim batch_dim,))
batch_dims_description = 'The dims in which the noise is independent'
classmethod create_input_vars(*, mean: calipy.tensor.CalipyTensor, standard_deviation: calipy.tensor.CalipyTensor, validate_args: bool | NoneType = None) DataTuple

Creates a DataTuple for input_vars_schema.

Parameters: mean (<class ‘calipy.tensor.CalipyTensor’>): Required standard_deviation (<class ‘calipy.tensor.CalipyTensor’>): Required validate_args (typing.Union[bool, NoneType]): Optional

Returns:

DataTuple: The constructed DataTuple instance.

classmethod create_observations(*, sample: calipy.tensor.CalipyTensor) DataTuple

Creates a DataTuple for observation_schema.

Parameters: sample (<class ‘calipy.tensor.CalipyTensor’>): Required

Returns:

DataTuple: The constructed DataTuple instance.

default_nodestructure = NodeStructure instance for node class NoiseAddition with dims:   name: batch_dims, obj : DimTuple((Dim batch_dim,)), sizes : [10]   description : The dims in which the noise is independent  name: event_dims, obj : DimTuple((Dim event_dim,)), sizes : [2]   description : The dims in which the noise is copied and repeated
event_dims = DimTuple((Dim event_dim,))
event_dims_description = 'The dims in which the noise is copied and repeated'
forward(input_vars, observations=None, subsample_index=None, **kwargs)

Create noisy samples using input_vars = (mean, standard_deviation) with shapes as indicated in the node_structures’ ‘batch_dims’ and ‘event_dims’.

Parameters:

vars (input) – CalipyDict with keys [‘mean’, ‘standard_deviation’] containing CalipyTensor objects defining the underlying mean onto which noise with distribution N(0, standard_deviation) is added.

param observations: CalipyDict containing a single CalipyTensor

object that is considered to be observed and used for inference.

type observations: CalipyDict param subsample_index: type subsample_index: :return: CalipyTensor representing simulation of a noisy measurement of

the mean.

Return type:

CalipyTensor

input_vars_schema: InputSchema | None = InputSchema:   Required Keys:     - mean     - standard_deviation   Optional Keys:     - validate_args   Defaults:     - validate_args: None   Key Types:     - mean: <class 'calipy.tensor.CalipyTensor'>     - standard_deviation: <class 'calipy.tensor.CalipyTensor'>     - validate_args: typing.Union[bool, NoneType]
name = 'NoiseAddition'
observation_schema: InputSchema | None = InputSchema:   Required Keys:     - sample   Optional Keys:     None   Defaults:     None   Key Types:     - sample: <class 'calipy.tensor.CalipyTensor'>
class calipy.effects.UnknownParameter(node_structure, constraint=Real(), **kwargs)

Bases: CalipyQuantity

UnknownParameter is a subclass of CalipyQuantity that produces an object whose forward() method produces a parameter that is subject to inference.

Parameters:
  • node_structure (NodeStructure) – Instance of NodeStructure that determines the internal structure (shapes, plate_stacks, plates, aux_data) completely.

  • constraint (pyro.distributions.constraints.Constraint) – Pyro constraint that constrains the parameter of a distribution to lie in a pre-defined subspace of R^n like e.g. simplex, positive, …

Returns:

Instance of the UnknownParameter class built on the basis of node_structure

Return type:

UnknownParameter (subclass of CalipyQuantity subclass of CalipyNode)

Example usage: Run line by line to investigate Class

# Investigate 2D bias tensor -------------------------------------------
#
# i) Imports and definitions
import calipy
from calipy.base import NodeStructure
from calipy.effects import UnknownParameter
node_structure = NodeStructure(UnknownParameter)
bias_object = UnknownParameter(node_structure, name = 'tutorial')
#
# ii) Produce bias value
bias = bias_object.forward()
#
# iii) Investigate object
bias_object.dtype_chain
bias_object.id
bias_object.node_structure
bias_object.node_structure.dims
render_1 = bias_object.render()
render_1
render_2 = bias_object.render_comp_graph()
render_2
batch_dims = DimTuple((Dim batch_dim,))
batch_dims_description = 'The dims in which the parameter is copied and repeated'
classmethod create_input_vars() DataTuple

Creates a DataTuple for input_vars_schema.

Parameters:

Returns:

DataTuple: The constructed DataTuple instance.

classmethod create_observations() DataTuple

Creates a DataTuple for observation_schema.

Parameters:

Returns:

DataTuple: The constructed DataTuple instance.

default_nodestructure = NodeStructure instance for node class UnknownParameter with dims:   name: batch_dims, obj : DimTuple((Dim batch_dim,)), sizes : [10]   description : The dims in which the parameter is copied and repeated  name: param_dims, obj : DimTuple((Dim param_dim,)), sizes : [2]   description : The dims of the parameter, in which it can vary
forward(input_vars=None, observations=None, subsample_index=None, **kwargs)

Create a parameter of dimension param_dims.shape that is copied n times where n = batch_dims.size to yield an extendet tensor with the shape [batch_dims.sizes, param_dims.sizes]. It can be passed to subsequent effects and will be tracked to adjust it when training the model.

Parameters:

vars (input) – (Calipy)Dict with inputs, always None for UnknownParameter

param observations: (Calipy)Dict with observations, always None for UnknownParameter type observations: dict param subsample_index: type subsample_index: :return: CalipyTensor containing parameter tensor and dimension info. :rtype: CalipyTensor

input_vars_schema: InputSchema | None = InputSchema:   Required Keys:     None   Optional Keys:     None   Defaults:     None   Key Types:     None
name = 'UnknownParameter'
observation_schema: InputSchema | None = InputSchema:   Required Keys:     None   Optional Keys:     None   Defaults:     None   Key Types:     None
param_dims = DimTuple((Dim param_dim,))
param_dims_description = 'The dims of the parameter, in which it can vary'
class calipy.effects.UnknownVariance(node_structure, **kwargs)

Bases: UnknownParameter

UnknownVariance is a subclass of UnknownParameter that includes a positivity constraint. UnknownParameter is a subclass of CalipyQuantity that produces an object whose forward() method produces a parameter that is subject to inference.

Parameters:
  • node_structure (NodeStructure) – Instance of NodeStructure that determines the internal structure (shapes, plate_stacks, plates, aux_data) completely.

  • constraint (pyro.distributions.constraints.Constraint) – Pyro constraint that constrains the parameter of a distribution to lie in a pre-defined subspace of R^n like e.g. simplex, positive, …

Returns:

Instance of the UnknownParameter class built on the basis of node_structure

Return type:

UnknownParameter (subclass of CalipyQuantity subclass of CalipyNode)

Example usage: Run line by line to investigate Class

# Investigate 2D bias tensor -------------------------------------------
#
# i) Imports and definitions
import calipy
from calipy.base import NodeStructure
from calipy.effects import UnknownParameter
node_structure = NodeStructure(UnknownParameter)
bias_object = UnknownParameter(node_structure, name = 'tutorial')
#
# ii) Produce bias value
bias = bias_object.forward()
#
# iii) Investigate object
bias_object.dtype_chain
bias_object.id
bias_object.node_structure
bias_object.node_structure.dims
render_1 = bias_object.render()
render_1
render_2 = bias_object.render_comp_graph()
render_2
classmethod create_input_vars() DataTuple

Creates a DataTuple for input_vars_schema.

Parameters:

Returns:

DataTuple: The constructed DataTuple instance.

classmethod create_observations() DataTuple

Creates a DataTuple for observation_schema.

Parameters:

Returns:

DataTuple: The constructed DataTuple instance.

docstring = 'UnknownVariance is a subclass of UnknownParameter that includes a positivity constraint.'
name = 'UnknownVariance'