# perturbsolve_ivp¶

probnum.diffeq.perturbsolve_ivp(f, t0, tmax, y0, rng, method='RK45', perturb='step-lognormal', noise_scale=10.0, adaptive=True, atol=1e-06, rtol=0.001, step=None, time_stops=None)[source]

Solve an initial value problem with a perturbation-based ODE solver.

Parameters:
• f (Callable) – ODE vector field.

• t0 (FloatLike) – Initial time point.

• tmax (FloatLike) – Final time point.

• y0 (ArrayLike) – Initial value.

• rng (Generator) – Random number generator.

• method (str) –

Integration method to use. The following are available (docs adapted from https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html):

• RK45 (default): Explicit Runge-Kutta method of order 5(4) . The error is controlled assuming accuracy of the fourth-order method, but steps are taken using the fifth-order accurate formula (local extrapolation is done). A quartic interpolation polynomial is used for the dense output . Can be applied in the complex domain.

• RK23: Explicit Runge-Kutta method of order 3(2) . The error is controlled assuming accuracy of the second-order method, but steps are taken using the third-order accurate formula (local extrapolation is done). A cubic Hermite polynomial is used for the dense output. Can be applied in the complex domain.

Other integrators are not supported currently.

• perturb (str) –

Which perturbation style to use. Currently, the following methods are supported:

• step-lognormal: Perturbed-step (aka random time-step numerical integration) method with lognormally distributed perturbation of the step-size .

• step-uniform: Perturbed-step (aka random time-step numerical integration) method with uniformly distributed perturbation of the step-size .

Other integrators are not supported currently.

• noise_scale (FloatLike) – Scale of the perturbation. Optional. Default is 10.0. The magnitude of this parameter significantly impacts the width of the posterior.

• adaptive (bool) – Whether to use adaptive steps or not. Default is True.

• atol (FloatLike) – Absolute tolerance of the adaptive step-size selection scheme. Optional. Default is `1e-6`.

• rtol (FloatLike) – Relative tolerance of the adaptive step-size selection scheme. Optional. Default is `1e-3`.

• step (FloatLike | None) – Step size. If atol and rtol are not specified, this step-size is used for a fixed-step ODE solver. If they are specified, this only affects the first step. Optional. Default is None, in which case the first step is chosen as prescribed by `propose_firststep()`.

• time_stops (ArrayLike | None) – Time-points through which the solver must step. Optional. Default is None.

Raises:
• ValueError – If the ‘method’ string does not correspond to a supported method.

• ValueError – If the ‘perturb’ string does not correspond to a supported perturbation style.

Returns:

ODE Solution of the perturbed-step-solver.

Return type:

perturbed.step.PerturbedStepSolution

Examples

```>>> from probnum.diffeq import perturbsolve_ivp
>>> import numpy as np
```

Solve a simple logistic ODE with fixed steps. Per default, perturbsolve_ivp uses a perturbed-step solver with lognormal perturbation.

```>>> rng = np.random.default_rng(seed=2)
>>>
>>> def f(t, x):
...     return 4*x*(1-x)
>>>
>>> y0 = np.array([0.15])
>>> t0, tmax = 0., 1.5
>>> solution = perturbsolve_ivp(
...     f, t0, tmax, y0, rng=rng, step=0.25, method="RK23", adaptive=False
... )
>>> print(np.round(solution.states.mean, 3))
[[0.15 ]
[0.325]
[0.56 ]
[0.772]
[0.893]
[0.964]
[0.989]]
```

Each solution is the result of a randomly-perturbed call of an underlying Runge-Kutta solver. Therefore, if you call it again, the output will be different:

```>>> other_solution = perturbsolve_ivp(
...     f, t0, tmax, y0, rng=rng, step=0.25, method="RK23", adaptive=False
... )
>>> print(np.round(other_solution.states.mean, 3))
[[0.15 ]
[0.319]
[0.57 ]
[0.785]
[0.908]
[0.968]
[0.989]]
```

Other methods, such as RK45 (as well as other perturbation styles) are easily accessible. Let us solve the same equation, with an adaptive RK45 solver that uses uniformly perturbed steps.

```>>> solution = perturbsolve_ivp(
...     f, t0, tmax, y0, rng=rng, atol=1e-5, rtol=1e-6,
... )
>>> print(np.round(solution.states.mean, 3))
[[0.15 ]
[0.152]
[0.167]
[0.26 ]
[0.431]
[0.646]
[0.849]
[0.883]
[0.915]
[0.953]
[0.976]
[0.986]]
```

References