eulerpi.core.models.base_model module

class BaseModel(central_param: ndarray, param_limits: ndarray, name: str | None = None)[source]

Bases: ABC

The base class for all models using the EPI algorithm.

Parameters:
  • central_param (np.ndarray) – The central parameter for the model. (Default value = None)

  • param_limits (np.ndarray) – Box limits for the parameters. The limits are given as a 2D array with shape (param_dim, 2). The parameter limits are used as limits as well as for the movement policy for MCMC sampling, and as boundaries for the grid when using grid-based inference. Overwrite the function param_is_within_domain if the domain is more complex than a box - the grid will still be build based on param_limits, but actual model evaluations only take place within the limits specified in param_is_within_domain. (Default value = None)

  • name (str) – The name of the model. The class name is used if no name is given. (Default value = None)

Note

Examples of model implementations can be found in the Example Models.

abstract forward(param: ndarray) ndarray[source]

Executed the forward pass of the model to obtain data from a parameter.

Parameters:

param (np.ndarray) – The parameter for which the data should be generated.

Returns:

The data generated from the parameter.

Return type:

np.ndarray

Examples:

import numpy as np
from eulerpi.examples.heat import Heat
from eulerpi.core.models import JaxModel
from jax import vmap

# instantiate the heat model
model = Heat()

# define a 3D example parameter for the heat model
example_param = np.array([1.4, 1.6, 0.5])

# the forward simulation is achieved by using the forward method of the model
sim_result = model.forward(example_param)

# in a more realistic scenario, we would like to perform the forward pass on multiple parameters at once
multiple_params = np.array([[1.5, 1.5, 0.5],
                            [1.4, 1.4, 0.6],
                            [1.6, 1.6, 0.4],
                            model.central_param,
                            [1.5, 1.4, 0.4]])
multiple_sim_results = model.forward_vectorized(multiple_params)
forward_and_jacobian(param: ndarray) Tuple[ndarray, ndarray][source]

Evaluates the jacobian and the forward pass of the model at the same time. If the method is not overwritten in a subclass it, it simply calls forward() and jacobian(). It can be vectorized in the same way as the forward and jacobian methods.

Parameters:

param (np.ndarray) – The parameter for which the jacobian should be evaluated.

Returns:

The data generated from the parameter and the jacobian for the variables returned by the forward() method with respect to the parameters.

Return type:

Tuple[np.ndarray, np.ndarray]

forward_vectorized(params: ndarray) ndarray[source]

A vectorized version of the forward function

Parameters:

params (np.ndarray) – an array of parameters, shape (n, self.param_dim)

Returns:

The data vector generated from the vector of parameters, shape (n, self.data_dim)

Return type:

np.ndarray

abstract jacobian(param: ndarray) ndarray[source]

Evaluates the jacobian of the forward() method.

Parameters:

param (np.ndarray) – The parameter for which the jacobian should be evaluated.

Returns:

The jacobian for the variables returned by the forward() method with respect to the parameters.

Return type:

np.ndarray

Examples:

import numpy as np
from eulerpi.examples.heat import Heat
from eulerpi.core.models import JaxModel
from jax import vmap

# instantiate the heat model
model = Heat()

# define a 3D example parameter for the heat model
example_param = np.array([1.4, 1.6, 0.5])

sim_jacobian = model.jacobian(example_param)

# Similar to the forward pass, also the evaluation of the jacobian can be vectorized.
# This yields a 3D array of shape (num_params, data_dim, param_dim) = (4,5,3) in this example.

multiple_params = np.array([[1.5, 1.5, 0.5],
                            [1.4, 1.4, 0.6],
                            model.central_param,
                            [1.5, 1.4, 0.4]])

# try to use jax vmap for vectorization if possible
if isinstance(model, JaxModel):
    multiple_sim_jacobians = vmap(model.jacobian, in_axes=0)(multiple_params)

# if the model is not a jax model, we can use numpy vectorize to vectorize
else:
    multiple_sim_jacobians = np.vectorize(model.jacobian, signature="(n)->(m)")(multiple_params)
param_is_within_domain(param: ndarray) bool[source]

Checks whether a parameter is within the parameter domain of the model. Overwrite this function if your model has a more complex parameter domain than a box. The param_limits are checked automatically.

Parameters:

param (np.ndarray) – The parameter to check.

Returns:

True if the parameter is within the limits.

Return type:

bool

data_dim: int | None = None
param_dim: int | None = None