Source code for probnum.diffeq.ode.ivp

"""The folder is called "ode" but this module is "ivp" because in the future, there
might be more ode-based problems, such as bvp."""
# pylint: disable=unused-variable

import numpy as np

from probnum.diffeq.ode.ode import ODE


[docs]class IVP(ODE): """Initial value problems (IVP). This class descibes initial value problems based on systems of first order ordinary differential equations (ODEs), .. math:: \\dot y(t) = f(t, y(t)), \\quad y(t_0) = y_0, \\quad t \\in [t_0, T] It provides options for defining custom right-hand side (RHS) functions, their Jacobians and closed form solutions. Since we use them for probabilistic ODE solvers these functions fit into the probabilistic framework as well. That is, the initial value is a RandomVariable object with some distribution that reflects the prior belief over the initial value. To recover "classical" initial values one can use the Constant distribution. Parameters ---------- timespan : (float, float) Time span of IVP. initrv : RandomVariable, RandomVariable that describes the belief over the initial value. Usually its distribution is Constant (noise-free) or Normal (noisy). To replicate "classical" initial values use the Constant distribution. Implementation depends on the mean of this RandomVariable, so please only use RandomVariable objects with available means, e.g. Constants or Normals. rhs : callable, signature: ``(t, y, **kwargs)`` RHS function :math:`f : [0, T] \\times \\mathbb{R}^d \\rightarrow \\mathbb{R}^d` of the ODE system. As such it takes a float and an np.ndarray of shape (d,) and returns a np.ndarray of shape (d,). As of now, no vectorization is supported (nor needed). jac : callable, signature: ``(t, y, **kwargs)``, optional Jacobian of RHS function :math:`J_f : [0, T] \\times \\mathbb{R}^d \\rightarrow \\mathbb{R}^d` of the ODE system. As such it takes a float and an np.ndarray of shape (d,) and returns a np.ndarray of shape (d,). As of now, no vectorization is supported (nor needed). sol : callable, signature: ``(t, **kwargs)``, optional Solution of IVP. See Also -------- ODE : Abstract interface for ordinary differential equations. Examples -------- >>> from probnum.diffeq import IVP >>> rhsfun = lambda t, y, **kwargs: 2.0*y >>> from probnum import random_variables as rvs >>> initrv = rvs.Constant(0.1) >>> timespan = (0, 10) >>> ivp = IVP(timespan, initrv, rhsfun) >>> print(ivp.rhs(0., 2.)) 4.0 >>> print(ivp.timespan) [0, 10] >>> print(ivp.t0) 0 >>> initrv = rvs.Normal(0.1, 1.0) >>> ivp = IVP(timespan, initrv, rhsfun) >>> jac = lambda t, y, **kwargs: 2.0 >>> ivp = IVP(timespan, initrv, rhs=rhsfun, jac=jac) >>> print(ivp.rhs(0., 2.)) 4.0 >>> print(ivp.jacobian(100., -1)) 2.0 """ def __init__(self, timespan, initrv, rhs, jac=None, hess=None, sol=None): self.initrv = initrv super().__init__(timespan=timespan, rhs=rhs, jac=jac, hess=hess, sol=sol) @property def initialdistribution(self): """Distribution of the initial random variable.""" return self.initrv @property def initialrandomvariable(self): """Initial random variable.""" return self.initrv @property def dimension(self): """Spatial dimension of the IVP problem. Depends on the mean of the initial random variable. """ if np.isscalar(self.initrv.mean): return 1 else: return len(self.initrv.mean)