eulerpi.core.model module

Module containing an abstract base class and specialized subclasses for use with the EPI algorithm.

class ArtificialModelInterface[source]

Bases: ABC

By inheriting from this interface you indicate that you are providing an artificial parameter dataset, and the corresponding artificial data dataset, which can be used to compare the results from eulerpi with the ground truth.

generate_artificial_data(params: PathLike | str | ndarray) ndarray[source]

This method is called when the user wants to generate artificial data from the model.

Parameters:

params – typing.Union[os.PathLike, str, np.ndarray]: The parameters for which the data should be generated. Can be either a path to a file, a numpy array or a string.

Returns:

The data generated from the parameters.

Return type:

np.ndarray

Raises:

TypeError – If the params argument is not a path to a file, a numpy array or a string.

abstract generate_artificial_params(num_samples: int) ndarray[source]

This method must be overwritten an return an numpy array of num_samples parameters.

Parameters:

num_samples (int) – The number of parameters to generate.

Returns:

The generated parameters.

Return type:

np.ndarray

Raises:

NotImplementedError – If the method is not overwritten in a subclass.

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

Bases: Model

The JaxModel is a base class for models using the JAX library.

It automatically creates the jacobian method based on the forward method. Additionally it jit compiles the forward and jacobian method with jax for faster execution.

Note

To use this class you have to implement your forward method using jax, e. g. jax.numpy. Dont overwrite the __init__ method of JaxModel without calling the super constructor. Else your forward method wont be jitted.

forward_and_jacobian(param: ndarray) Tuple[ndarray, ndarray][source]

Evaluates the jacobian and the forward pass of the model at the same time. This can be more efficient than calling the forward() and jacobian() methods separately.

Parameters:

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

Returns:

The data and the jacobian for a given parameter.

Return type:

Tuple[np.ndarray, np.ndarray]

static forward_method(self, param: ndarray) ndarray[source]

This method is called by the jitted forward method. It is not intended to be called directly.

Parameters:

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

Returns:

The data generated from the parameter.

Return type:

np.ndarray

classmethod init_fw_and_bw()[source]

Calculates the jitted methods for the subclass(es). It is an unintended sideeffect that this happens for all intermediate classes also. E.g. for: class CoronaArtificial(Corona)

jacobian(param: ndarray) ndarray[source]

Jacobian of the forward pass with respect to the parameters.

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

class Model(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.model 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]])

# try to use jax vmap to perform the forward pass on multiple parameters at once
if isinstance(model, JaxModel):
    multiple_sim_results = vmap(model.forward, in_axes=0)(multiple_params)

# if the model is not a jax model, we can use numpy vectorize to perform the forward pass
else:
    multiple_sim_results = np.vectorize(model.forward, signature="(n)->(m)")(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]

is_artificial() bool[source]

Determines whether the model provides artificial parameter and data sets.

Returns:

True if the model inherits from the ArtificialModelInterface

Return type:

bool

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.model 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

The dimension of the data space of the model. It must be defined in the subclass.

param_dim: int | None = None

The dimension of the parameter space of the model. It must be defined in the subclass.

class SBMLModel(sbml_file: str, central_param: ndarray, param_limits: ndarray, timepoints: list, param_ids: list | None = None, state_ids: list | None = None, skip_creation: bool = False, name: str | None = None, **kwargs)[source]

Bases: Model

The SBMLModel class is a wrapper for the AMICI python interface to simulate SBML models using this package.

Parameters:
  • sbml_file (str) – The path to the SBML model file.

  • param_ids (list) – A list of ids of parameter, which will be estimated during the inference. If None all parameter ids are extracted from the SBML model.

  • state_ids (list) – A list of state ids, for which data will be given during the inference. If None all state ids are extracted from the SBML model.

  • timepoints (list) – List of measurement time points, this is where the sbml model is evaluated and compared to the data

  • skip_creation (bool) – If True the model is not created againg based on the SBML file. Instead the model is loaded from a previously created model. (Default value = False)

  • central_param (np.ndarray) – The central parameter for the model

  • param_limits (np.ndarray) – The parameter limits for the model

forward(params)[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.model 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]])

# try to use jax vmap to perform the forward pass on multiple parameters at once
if isinstance(model, JaxModel):
    multiple_sim_results = vmap(model.forward, in_axes=0)(multiple_params)

# if the model is not a jax model, we can use numpy vectorize to perform the forward pass
else:
    multiple_sim_results = np.vectorize(model.forward, signature="(n)->(m)")(multiple_params)
forward_and_jacobian(params: 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]

static indices_from_ids(ids: list, all_ids: list) list[source]

Returns the indices of the ids in the all_ids list.

Parameters:
  • ids (list) – The ids for which the indices should be returned.

  • all_ids (list) – The list of all ids.

Returns:

The indices of the ids in the all_ids list.

Return type:

list

Throws:

ValueError: If one of the ids is not in the all_ids list.

jacobian(params)[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.model 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)
load_amici_model_and_solver()[source]

Loads the AMICI model from the previously generated model.

setSensitivities()[source]

Tell the underlying amici solver to calculate sensitivities based on the attribute self.param_ids

property data_dim

The dimension of a data point returned by the model.

property param_dim

The number of parameters of the model.

add_autodiff(_cls)[source]

Decorator to automatically create the jacobian method based on the forward method. Additionally it jit compiles the forward and jacobian method with jax.

Parameters:

_cls – The class to decorate.

Returns:

The decorated class with the jacobian method and the forward and jacobian method jit compiled with jax.

is_amici_available()[source]