Compare 3019a50 ... +0 ... 86920be

Coverage Reach
randprocs/markov/integrator/_iwp.py randprocs/markov/integrator/_matern.py randprocs/markov/integrator/_ioup.py randprocs/markov/integrator/_preconditioner.py randprocs/markov/integrator/_integrator.py randprocs/markov/integrator/__init__.py randprocs/markov/integrator/convert/_convert.py randprocs/markov/integrator/convert/__init__.py randprocs/markov/continuous/_sde.py randprocs/markov/continuous/_diffusions.py randprocs/markov/continuous/_mfd.py randprocs/markov/continuous/__init__.py randprocs/markov/discrete/_discrete_gaussian.py randprocs/markov/discrete/_condition_state.py randprocs/markov/discrete/__init__.py randprocs/markov/_transition.py randprocs/markov/_markov_process.py randprocs/markov/utils/_generate_measurements.py randprocs/markov/utils/__init__.py randprocs/markov/__init__.py randprocs/_random_process.py randprocs/_gaussian_process.py randprocs/__init__.py randvars/_random_variable.py randvars/_normal.py randvars/_arithmetic.py randvars/_scipy_stats.py randvars/_constant.py randvars/_categorical.py randvars/__init__.py randvars/_utils.py linops/_linear_operator.py linops/_kronecker.py linops/_arithmetic.py linops/_scaling.py linops/__init__.py linops/_utils.py filtsmooth/gaussian/approx/_extendedkalman.py filtsmooth/gaussian/approx/_unscentedkalman.py filtsmooth/gaussian/approx/_unscentedtransform.py filtsmooth/gaussian/approx/__init__.py filtsmooth/gaussian/_kalmanposterior.py filtsmooth/gaussian/_kalman.py filtsmooth/gaussian/__init__.py filtsmooth/particle/_particle_filter.py filtsmooth/particle/_importance_distributions.py filtsmooth/particle/_particle_filter_posterior.py filtsmooth/particle/__init__.py filtsmooth/optim/_iterated_component.py filtsmooth/optim/_stoppingcriterion.py filtsmooth/optim/_state_space_optimizer.py filtsmooth/optim/_gauss_newton.py filtsmooth/optim/__init__.py filtsmooth/_timeseriesposterior.py filtsmooth/utils/_merge_regression_problems.py filtsmooth/utils/__init__.py filtsmooth/_kalman_filter_smoother.py filtsmooth/__init__.py filtsmooth/_bayesfiltsmooth.py diffeq/odefiltsmooth/initialization_routines/_runge_kutta.py diffeq/odefiltsmooth/initialization_routines/_taylor_mode.py diffeq/odefiltsmooth/initialization_routines/_initialization_routine.py diffeq/odefiltsmooth/initialization_routines/__init__.py diffeq/odefiltsmooth/_ivpfiltsmooth.py diffeq/odefiltsmooth/_kalman_odesolution.py diffeq/odefiltsmooth/__init__.py diffeq/perturbed/step/_perturbedstepsolver.py diffeq/perturbed/step/_perturbedstepsolution.py diffeq/perturbed/step/_perturbation_functions.py diffeq/perturbed/step/__init__.py diffeq/perturbed/scipy_wrapper/_wrapped_scipy_solver.py diffeq/perturbed/scipy_wrapper/_wrapped_scipy_odesolution.py diffeq/perturbed/scipy_wrapper/__init__.py diffeq/perturbed/__init__.py diffeq/stepsize/_steprule.py diffeq/stepsize/__init__.py diffeq/stepsize/_propose_firststep.py diffeq/_odesolver.py diffeq/_perturbsolve_ivp.py diffeq/_probsolve_ivp.py diffeq/_odesolution.py diffeq/__init__.py linalg/solvers/matrixbased.py linalg/solvers/beliefs/_linear_system_belief.py linalg/solvers/beliefs/__init__.py linalg/solvers/_state.py linalg/solvers/policies/_random_unit_vector.py linalg/solvers/policies/_conjugate_gradient.py linalg/solvers/policies/__init__.py linalg/solvers/policies/_linear_solver_policy.py linalg/solvers/__init__.py linalg/solvers/_probabilistic_linear_solver.py linalg/_problinsolve.py linalg/__init__.py problems/zoo/diffeq/_ivp_examples.py problems/zoo/diffeq/_ivp_examples_jax.py problems/zoo/diffeq/__init__.py problems/zoo/linalg/_suitesparse_matrix.py problems/zoo/linalg/_random_spd_matrix.py problems/zoo/linalg/_random_linear_system.py problems/zoo/linalg/__init__.py problems/zoo/filtsmooth/_filtsmooth_problems.py problems/zoo/filtsmooth/__init__.py problems/_problems.py problems/__init__.py quad/_integration_measures.py quad/kernel_embeddings/_kernel_embedding.py quad/kernel_embeddings/_expquad_gauss.py quad/kernel_embeddings/_expquad_lebesgue.py quad/kernel_embeddings/__init__.py quad/bq_methods/bayesian_quadrature.py quad/bq_methods/__init__.py quad/_bayesquad.py quad/__init__.py quad/policies/sample_measure.py quad/policies/__init__.py kernels/_kernel.py kernels/_matern.py kernels/_rational_quadratic.py kernels/_exponentiated_quadratic.py kernels/_polynomial.py kernels/_linear.py kernels/_white_noise.py kernels/__init__.py utils/argutils.py utils/arrayutils.py utils/linalg/_cholesky_updates.py utils/linalg/__init__.py utils/__init__.py _randomvariablelist.py _config.py typing.py __init__.py _probabilistic_numerical_method.py

No flags found

Use flags to group coverage reports by test type, project and/or folders.
Then setup custom commit statuses and notifications for each flag.

e.g., #unittest #integration

#production #enterprise

#frontend #backend

Learn more about Codecov Flags here.

Showing 38 of 93 files from the diff.
Other files ignored by Codecov
tox.ini has changed.

@@ -0,0 +1,5 @@
Loading
1 +
"""Utility functions for Markov processes."""
2 +
3 +
from ._generate_measurements import generate_artificial_measurements
4 +
5 +
__all__ = ["generate_artificial_measurements"]

@@ -0,0 +1,250 @@
Loading
1 +
"""Integrated Ornstein-Uhlenbeck processes."""
2 +
import warnings
3 +
4 +
import numpy as np
5 +
6 +
try:
7 +
    # cached_property is only available in Python >=3.8
8 +
    from functools import cached_property
9 +
except ImportError:
10 +
    from cached_property import cached_property
11 +
12 +
from probnum import randvars
13 +
from probnum.randprocs.markov import _markov_process, continuous
14 +
from probnum.randprocs.markov.integrator import _integrator, _preconditioner
15 +
16 +
17 +
class IntegratedOrnsteinUhlenbeckProcess(_markov_process.MarkovProcess):
18 +
    r"""Integrated Ornstein-Uhlenbeck process.
19 +
20 +
    Convenience access to :math:`\nu` times integrated (:math:`d` dimensional) Ornstein-Uhlenbeck processes.
21 +
22 +
    Parameters
23 +
    ----------
24 +
    driftspeed
25 +
        Drift-speed of the underlying OrnsteinUhlenbeck process.
26 +
    initarg
27 +
        Initial time point.
28 +
    num_derivatives
29 +
        Number of modelled derivatives of the integrated process (''order'', ''number of integrations'').
30 +
        Optional. Default is :math:`\nu=1`.
31 +
    wiener_process_dimension
32 +
        Dimension of the underlying Wiener process.
33 +
        Optional. Default is :math:`d=1`.
34 +
        The dimension of the integrated Wiener process itself is :math:`d(\nu + 1)`.
35 +
    initrv
36 +
        Law of the integrated Wiener process at the initial time point.
37 +
        Optional. Default is a :math:`d(\nu + 1)` dimensional standard-normal distribution.
38 +
    diffuse
39 +
        Whether to instantiate a diffuse prior. A diffuse prior has large initial variances.
40 +
        Optional. Default is `False`.
41 +
        If `True`, and if an initial random variable is not passed, an initial random variable is created,
42 +
        where the initial covariance is of the form :math:`\kappa I_{d(\nu + 1)}`
43 +
        with :math:`\kappa=10^6`.
44 +
        Diffuse priors are used when initial distributions are not known.
45 +
        They are common for filtering-based probabilistic ODE solvers.
46 +
    forward_implementation
47 +
        Implementation of the forward-propagation in the underlying transitions.
48 +
        Optional. Default is `classic`. `sqrt` implementation is more computationally expensive, but also more stable.
49 +
    backward_implementation
50 +
        Implementation of the backward-conditioning in the underlying transitions.
51 +
        Optional. Default is `classic`. `sqrt` implementation is more computationally expensive, but also more stable.
52 +
53 +
    Raises
54 +
    ------
55 +
    Warning
56 +
        If `initrv` is not None and `diffuse` is True.
57 +
58 +
    Examples
59 +
    --------
60 +
    >>> ioup1 = IntegratedOrnsteinUhlenbeckProcess(driftspeed=1., initarg=0.)
61 +
    >>> print(ioup1)
62 +
    <IntegratedOrnsteinUhlenbeckProcess with input_dim=1, output_dim=2, dtype=float64>
63 +
64 +
    >>> ioup2 = IntegratedOrnsteinUhlenbeckProcess(driftspeed=1.,initarg=0., num_derivatives=2)
65 +
    >>> print(ioup2)
66 +
    <IntegratedOrnsteinUhlenbeckProcess with input_dim=1, output_dim=3, dtype=float64>
67 +
68 +
    >>> ioup3 = IntegratedOrnsteinUhlenbeckProcess(driftspeed=1.,initarg=0., wiener_process_dimension=10)
69 +
    >>> print(ioup3)
70 +
    <IntegratedOrnsteinUhlenbeckProcess with input_dim=1, output_dim=20, dtype=float64>
71 +
72 +
    >>> ioup4 = IntegratedOrnsteinUhlenbeckProcess(driftspeed=1.,initarg=0., num_derivatives=4, wiener_process_dimension=1)
73 +
    >>> print(ioup4)
74 +
    <IntegratedOrnsteinUhlenbeckProcess with input_dim=1, output_dim=5, dtype=float64>
75 +
    """
76 +
77 +
    def __init__(
78 +
        self,
79 +
        driftspeed,
80 +
        initarg,
81 +
        num_derivatives=1,
82 +
        wiener_process_dimension=1,
83 +
        initrv=None,
84 +
        diffuse=False,
85 +
        forward_implementation="classic",
86 +
        backward_implementation="classic",
87 +
    ):
88 +
        ioup_transition = IntegratedOrnsteinUhlenbeckTransition(
89 +
            num_derivatives=num_derivatives,
90 +
            wiener_process_dimension=wiener_process_dimension,
91 +
            driftspeed=driftspeed,
92 +
            forward_implementation=forward_implementation,
93 +
            backward_implementation=backward_implementation,
94 +
        )
95 +
        if initrv is not None and diffuse:
96 +
            warnings.warn(
97 +
                "Parameter `diffuse` has no effect, because an `initrv` has been provided."
98 +
            )
99 +
        if initrv is None:
100 +
            if diffuse:
101 +
                scale_cholesky = 1e3
102 +
            else:
103 +
                scale_cholesky = 1.0
104 +
            zeros = np.zeros(ioup_transition.dimension)
105 +
            cov_cholesky = scale_cholesky * np.eye(ioup_transition.dimension)
106 +
            initrv = randvars.Normal(
107 +
                mean=zeros, cov=cov_cholesky ** 2, cov_cholesky=cov_cholesky
108 +
            )
109 +
110 +
        super().__init__(transition=ioup_transition, initrv=initrv, initarg=initarg)
111 +
112 +
113 +
class IntegratedOrnsteinUhlenbeckTransition(
114 +
    _integrator.IntegratorTransition, continuous.LTISDE
115 +
):
116 +
    """Integrated Ornstein-Uhlenbeck process in :math:`d` dimensions."""
117 +
118 +
    def __init__(
119 +
        self,
120 +
        num_derivatives: int,
121 +
        wiener_process_dimension: int,
122 +
        driftspeed: float,
123 +
        forward_implementation="classic",
124 +
        backward_implementation="classic",
125 +
    ):
126 +
        self.driftspeed = driftspeed
127 +
128 +
        _integrator.IntegratorTransition.__init__(
129 +
            self,
130 +
            num_derivatives=num_derivatives,
131 +
            wiener_process_dimension=wiener_process_dimension,
132 +
        )
133 +
        continuous.LTISDE.__init__(
134 +
            self,
135 +
            driftmat=self._driftmat,
136 +
            forcevec=self._forcevec,
137 +
            dispmat=self._dispmat,
138 +
            forward_implementation=forward_implementation,
139 +
            backward_implementation=backward_implementation,
140 +
        )
141 +
142 +
    @cached_property
143 +
    def _driftmat(self):
144 +
        driftmat_1d = np.diag(np.ones(self.num_derivatives), 1)
145 +
        driftmat_1d[-1, -1] = -self.driftspeed
146 +
        return np.kron(np.eye(self.wiener_process_dimension), driftmat_1d)
147 +
148 +
    @cached_property
149 +
    def _forcevec(self):
150 +
        force_1d = np.zeros(self.num_derivatives + 1)
151 +
        return np.kron(np.ones(self.wiener_process_dimension), force_1d)
152 +
153 +
    @cached_property
154 +
    def _dispmat(self):
155 +
        dispmat_1d = np.zeros(self.num_derivatives + 1)
156 +
        dispmat_1d[-1] = 1.0  # Unit Diffusion
157 +
        return np.kron(np.eye(self.wiener_process_dimension), dispmat_1d).T
158 +
159 +
    def forward_rv(
160 +
        self,
161 +
        rv,
162 +
        t,
163 +
        dt=None,
164 +
        compute_gain=False,
165 +
        _diffusion=1.0,
166 +
        **kwargs,
167 +
    ):
168 +
        if dt is None:
169 +
            raise ValueError(
170 +
                "Continuous-time transitions require a time-increment ``dt``."
171 +
            )
172 +
173 +
        # Fetch things into preconditioned space
174 +
        rv = _preconditioner.apply_precon(self.precon.inverse(dt), rv)
175 +
176 +
        # Apply preconditioning to system matrices
177 +
        self.driftmat = self.precon.inverse(dt) @ self.driftmat @ self.precon(dt)
178 +
        self.forcevec = self.precon.inverse(dt) @ self.forcevec
179 +
        self.dispmat = self.precon.inverse(dt) @ self.dispmat
180 +
181 +
        # Discretise and propagate
182 +
        discretised_model = self.discretise(dt=dt)
183 +
        rv, info = discretised_model.forward_rv(
184 +
            rv, t, compute_gain=compute_gain, _diffusion=_diffusion
185 +
        )
186 +
187 +
        # Undo preconditioning and return
188 +
        rv = _preconditioner.apply_precon(self.precon(dt), rv)
189 +
        info["crosscov"] = self.precon(dt) @ info["crosscov"] @ self.precon(dt).T
190 +
        if "gain" in info:
191 +
            info["gain"] = self.precon(dt) @ info["gain"] @ self.precon.inverse(dt).T
192 +
193 +
        self.driftmat = self.precon(dt) @ self.driftmat @ self.precon.inverse(dt)
194 +
        self.forcevec = self.precon(dt) @ self.forcevec
195 +
        self.dispmat = self.precon(dt) @ self.dispmat
196 +
197 +
        return rv, info
198 +
199 +
    def backward_rv(
200 +
        self,
201 +
        rv_obtained,
202 +
        rv,
203 +
        rv_forwarded=None,
204 +
        gain=None,
205 +
        t=None,
206 +
        dt=None,
207 +
        _diffusion=1.0,
208 +
        **kwargs,
209 +
    ):
210 +
        if dt is None:
211 +
            raise ValueError(
212 +
                "Continuous-time transitions require a time-increment ``dt``."
213 +
            )
214 +
215 +
        # Fetch things into preconditioned space
216 +
        rv_obtained = _preconditioner.apply_precon(self.precon.inverse(dt), rv_obtained)
217 +
        rv = _preconditioner.apply_precon(self.precon.inverse(dt), rv)
218 +
        rv_forwarded = (
219 +
            _preconditioner.apply_precon(self.precon.inverse(dt), rv_forwarded)
220 +
            if rv_forwarded is not None
221 +
            else None
222 +
        )
223 +
        gain = (
224 +
            self.precon.inverse(dt) @ gain @ self.precon.inverse(dt).T
225 +
            if gain is not None
226 +
            else None
227 +
        )
228 +
229 +
        # Apply preconditioning to system matrices
230 +
        self.driftmat = self.precon.inverse(dt) @ self.driftmat @ self.precon(dt)
231 +
        self.forcevec = self.precon.inverse(dt) @ self.forcevec
232 +
        self.dispmat = self.precon.inverse(dt) @ self.dispmat
233 +
234 +
        # Discretise and propagate
235 +
        discretised_model = self.discretise(dt=dt)
236 +
        rv, info = discretised_model.backward_rv(
237 +
            rv_obtained=rv_obtained,
238 +
            rv=rv,
239 +
            rv_forwarded=rv_forwarded,
240 +
            gain=gain,
241 +
            t=t,
242 +
            _diffusion=_diffusion,
243 +
        )
244 +
245 +
        # Undo preconditioning and return
246 +
        rv = _preconditioner.apply_precon(self.precon(dt), rv)
247 +
        self.driftmat = self.precon(dt) @ self.driftmat @ self.precon.inverse(dt)
248 +
        self.forcevec = self.precon(dt) @ self.forcevec
249 +
        self.dispmat = self.precon(dt) @ self.dispmat
250 +
        return rv, info

@@ -0,0 +1,5 @@
Loading
1 +
"""Utility functions for integrators."""
2 +
3 +
from ._convert import convert_coordwise_to_derivwise, convert_derivwise_to_coordwise
4 +
5 +
__all__ = ["convert_derivwise_to_coordwise", "convert_coordwise_to_derivwise"]

@@ -9,7 +9,7 @@
Loading
9 9
10 10
import numpy as np
11 11
12 -
from probnum import randvars, statespace
12 +
from probnum import randprocs, randvars
13 13
from probnum.filtsmooth.gaussian.approx import _unscentedtransform
14 14
from probnum.typing import FloatArgType
15 15
@@ -38,7 +38,7 @@
Loading
38 38
        return self.ut.sigma_points(at_this_rv)
39 39
40 40
41 -
class ContinuousUKFComponent(UKFComponent, statespace.SDE):
41 +
class ContinuousUKFComponent(UKFComponent, randprocs.markov.continuous.SDE):
42 42
    """Continuous-time unscented Kalman filter transition.
43 43
44 44
    Parameters
@@ -72,7 +72,7 @@
Loading
72 72
            priorpar=priorpar,
73 73
            special_scale=special_scale,
74 74
        )
75 -
        statespace.SDE.__init__(
75 +
        randprocs.markov.continuous.SDE.__init__(
76 76
            self,
77 77
            non_linear_model.dimension,
78 78
            non_linear_model.driftfun,
@@ -146,7 +146,7 @@
Loading
146 146
        raise NotImplementedError("Not available (yet).")
147 147
148 148
149 -
class DiscreteUKFComponent(UKFComponent, statespace.DiscreteGaussian):
149 +
class DiscreteUKFComponent(UKFComponent, randprocs.markov.discrete.DiscreteGaussian):
150 150
    """Discrete unscented Kalman filter transition."""
151 151
152 152
    def __init__(
@@ -164,7 +164,7 @@
Loading
164 164
            special_scale=special_scale,
165 165
        )
166 166
167 -
        statespace.DiscreteGaussian.__init__(
167 +
        randprocs.markov.discrete.DiscreteGaussian.__init__(
168 168
            self,
169 169
            non_linear_model.input_dim,
170 170
            non_linear_model.output_dim,
@@ -262,7 +262,7 @@
Loading
262 262
        prior,
263 263
        evlvar=0.0,
264 264
    ):
265 -
        discrete_model = statespace.DiscreteGaussian.from_ode(
265 +
        discrete_model = randprocs.discrete.DiscreteGaussian.from_ode(
266 266
            ode=ode, prior=prior, evlvar=evlvar
267 267
        )
268 268
        return cls(discrete_model)

@@ -32,10 +32,10 @@
Loading
32 32
    Examples
33 33
    --------
34 34
    >>> import numpy as np
35 -
    >>> from probnum import statespace
35 +
    >>> from probnum import randprocs
36 36
    >>> obs = [11.4123, -15.5123]
37 37
    >>> loc = [0.1, 0.2]
38 -
    >>> model = statespace.DiscreteLTIGaussian(np.ones((1, 1)), np.ones(1), np.ones((1,1)))
38 +
    >>> model = randprocs.markov.discrete.DiscreteLTIGaussian(np.ones((1, 1)), np.ones(1), np.ones((1,1)))
39 39
    >>> measurement_models = [model, model]
40 40
    >>> rp = TimeSeriesRegressionProblem(observations=obs, locations=loc, measurement_models=measurement_models)
41 41
    >>> rp

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Click to load this diff.
Loading diff...

Learn more Showing 12 files with coverage changes found.

New file src/probnum/randprocs/markov/__init__.py
New
Loading file...
New file src/probnum/randprocs/markov/continuous/__init__.py
New
Loading file...
New file src/probnum/randprocs/markov/integrator/_matern.py
New
Loading file...
New file src/probnum/randprocs/markov/integrator/_ioup.py
New
Loading file...
New file src/probnum/randprocs/markov/integrator/convert/__init__.py
New
Loading file...
New file src/probnum/randprocs/markov/integrator/_preconditioner.py
New
Loading file...
New file src/probnum/randprocs/markov/integrator/__init__.py
New
Loading file...
New file src/probnum/randprocs/markov/integrator/_integrator.py
New
Loading file...
New file src/probnum/randprocs/markov/utils/__init__.py
New
Loading file...
New file src/probnum/randprocs/markov/discrete/__init__.py
New
Loading file...
New file src/probnum/randprocs/markov/integrator/_iwp.py
New
Loading file...
New file src/probnum/randprocs/markov/integrator/convert/_convert.py
New
Loading file...
Files Coverage
src/probnum 0.13% 86.87%
Project Totals (134 files) 86.87%
Loading