Exemplo n.º 1
0
    def setup(self, linearization_implementation):
        measvar = 0.1024
        initrv = randvars.Normal(np.ones(2), measvar * np.eye(2))
        regression_problem, statespace_components = filtsmooth_zoo.pendulum(
            measurement_variance=measvar,
            timespan=(0.0, 4.0),
            step=0.0075,
            initrv=initrv,
        )

        linearization, implementation = linearization_implementation
        _lin_method = {
            "ekf":
            functools.partial(
                filtsmooth.DiscreteEKFComponent,
                forward_implementation=implementation,
                backward_implementation=implementation,
            ),
            "ukf":
            filtsmooth.DiscreteUKFComponent,
        }[linearization]

        linearized_dynmod = _lin_method(
            statespace_components["dynamics_model"])
        linearized_measmod = _lin_method(
            statespace_components["measurement_model"])

        self.kalman_filter = filtsmooth.Kalman(
            dynamics_model=linearized_dynmod,
            measurement_model=linearized_measmod,
            initrv=statespace_components["initrv"],
        )
        self.filtering_posterior, _ = self.kalman_filter.filter(
            regression_problem)
Exemplo n.º 2
0
    def setup(self, linearization_implementation, num_samples):
        measvar = 0.1024
        initrv = randvars.Normal(np.ones(2), measvar * np.eye(2))
        rng = np.random.default_rng(seed=1)
        regression_problem, info = filtsmooth_zoo.pendulum(
            rng=rng,
            measurement_variance=measvar,
            timespan=(0.0, 4.0),
            step=0.0075,
            initrv=initrv,
        )
        prior_process = info["prior_process"]

        linearization, implementation = linearization_implementation
        _lin_method = {
            "ekf":
            functools.partial(
                filtsmooth.gaussian.approx.DiscreteEKFComponent,
                forward_implementation=implementation,
                backward_implementation=implementation,
            ),
            "ukf":
            filtsmooth.gaussian.approx.DiscreteUKFComponent,
        }[linearization]

        self.dense_locations = np.sort(
            np.unique(
                np.random.uniform(
                    low=regression_problem.locations[0],
                    high=1.2 * regression_problem.locations[-1],
                    size=int(1.2 * len(regression_problem.locations)),
                )))

        linearized_dynmod = _lin_method(prior_process.transition)
        linearized_measmod = _lin_method(
            regression_problem.measurement_models[0])
        regression_problem.measurement_models = [linearized_measmod] * len(
            regression_problem.locations)

        prior_process = randprocs.markov.MarkovProcess(
            transition=linearized_dynmod,
            initrv=prior_process.initrv,
            initarg=regression_problem.locations[0],
        )

        self.kalman_filter = filtsmooth.gaussian.Kalman(
            prior_process=prior_process)

        self.filtering_posterior, _ = self.kalman_filter.filter(
            regression_problem)
        self.smoothing_posterior = self.kalman_filter.smooth(
            filter_posterior=self.filtering_posterior)
Exemplo n.º 3
0
    def test_transition_rv(self):
        """forward_rv() not possible for original model but for the linearised model."""
        # pylint: disable=not-callable
        _, statespace_components = filtsmooth_zoo.pendulum()
        nonlinear_model = statespace_components["dynamics_model"]
        initrv = statespace_components["initrv"]
        linearised_model = self.linearising_component_pendulum(nonlinear_model)

        with self.subTest("Baseline should not work."):
            with self.assertRaises(NotImplementedError):
                nonlinear_model.forward_rv(initrv, 0.0)
        with self.subTest("Linearisation happens."):
            linearised_model.forward_rv(initrv, 0.0)
    def test_transition_rv(self, rng):
        """forward_rv() is only possible for the linearised model."""
        # pylint: disable=not-callable
        _, info = filtsmooth_zoo.pendulum(rng=rng)
        non_linear_model = info["prior_process"].transition
        initrv = info["prior_process"].initrv
        linearised_model = self.linearizing_component(non_linear_model)

        # Baseline: non-linear model should not work
        with pytest.raises(NotImplementedError):
            non_linear_model.forward_rv(initrv, 0.0)

        # Linearized model works
        rv, _ = linearised_model.forward_rv(initrv, 0.0)
        assert isinstance(rv, randvars.RandomVariable)
    def test_filtsmooth_pendulum(self, rng):
        # pylint: disable=not-callable
        # Set up test problem

        # If this measurement variance is not really small, the sampled
        # test data can contain an outlier every now and then which
        # breaks the test, even though it has not been touched.
        regression_problem, info = filtsmooth_zoo.pendulum(
            rng=rng, measurement_variance=0.0001)
        prior_process = info["prior_process"]
        measmods = regression_problem.measurement_models

        ekf_dyna = self.linearizing_component(prior_process.transition)
        ekf_meas = [self.linearizing_component(mm) for mm in measmods]

        regression_problem = problems.TimeSeriesRegressionProblem(
            locations=regression_problem.locations,
            observations=regression_problem.observations,
            measurement_models=ekf_meas,
            solution=regression_problem.solution,
        )

        initrv = prior_process.initrv
        prior_process = randprocs.markov.MarkovProcess(
            transition=ekf_dyna,
            initrv=initrv,
            initarg=regression_problem.locations[0])
        method = filtsmooth.gaussian.Kalman(prior_process)

        # Compute filter/smoother solution
        posterior, _ = method.filtsmooth(regression_problem)
        filtms = posterior.filtering_posterior.states.mean
        smooms = posterior.states.mean

        # Compute RMSEs and assert they are well-behaved.
        comp = regression_problem.solution[:, 0]
        normaliser = np.sqrt(comp.size)
        filtrmse = np.linalg.norm(filtms[:, 0] - comp) / normaliser
        smoormse = np.linalg.norm(smooms[:, 0] - comp) / normaliser
        obs_rmse = (
            np.linalg.norm(regression_problem.observations[:, 0] - comp) /
            normaliser)

        assert smoormse < filtrmse < obs_rmse, (smoormse, filtrmse, obs_rmse)
Exemplo n.º 6
0
    def setup(self, linearization_implementation, num_samples):
        measvar = 0.1024
        initrv = randvars.Normal(np.ones(2), measvar * np.eye(2))
        regression_problem, statespace_components = filtsmooth_zoo.pendulum(
            measurement_variance=measvar,
            timespan=(0.0, 4.0),
            step=0.0075,
            initrv=initrv,
        )

        linearization, implementation = linearization_implementation
        _lin_method = {
            "ekf":
            functools.partial(
                filtsmooth.DiscreteEKFComponent,
                forward_implementation=implementation,
                backward_implementation=implementation,
            ),
            "ukf":
            filtsmooth.DiscreteUKFComponent,
        }[linearization]

        self.dense_locations = np.sort(
            np.unique(
                np.random.uniform(
                    low=regression_problem.locations[0],
                    high=1.2 * regression_problem.locations[-1],
                    size=int(1.2 * len(regression_problem.locations)),
                )))

        linearized_dynmod = _lin_method(
            statespace_components["dynamics_model"])
        linearized_measmod = _lin_method(
            statespace_components["measurement_model"])

        self.kalman_filter = filtsmooth.Kalman(
            dynamics_model=linearized_dynmod,
            measurement_model=linearized_measmod,
            initrv=statespace_components["initrv"],
        )
        self.filtering_posterior, _ = self.kalman_filter.filter(
            regression_problem)
        self.smoothing_posterior = self.kalman_filter.smooth(
            filter_posterior=self.filtering_posterior)
Exemplo n.º 7
0
def fixture_problem(request, rng):
    initarg = request.param
    return filtsmooth_zoo.pendulum(rng=rng, step=0.12, initarg=initarg)
Exemplo n.º 8
0
import probnum.problems.zoo.filtsmooth as filtsmooth_zoo


def rng():
    return np.random.default_rng(seed=123)


# The logistic ODE problem is not random, so it does not get a random number generator.
all_filtmooth_setups = pytest.mark.parametrize(
    "filtsmooth_setup",
    [
        filtsmooth_zoo.benes_daum(rng=rng()),
        filtsmooth_zoo.car_tracking(rng=rng()),
        filtsmooth_zoo.logistic_ode(),
        filtsmooth_zoo.ornstein_uhlenbeck(rng=rng()),
        filtsmooth_zoo.pendulum(rng=rng()),
    ],
)


@all_filtmooth_setups
def test_types(filtsmooth_setup):
    regression_problem, info = filtsmooth_setup
    assert isinstance(regression_problem, problems.TimeSeriesRegressionProblem)
    assert isinstance(regression_problem.observations, np.ndarray)
    assert isinstance(regression_problem.locations, np.ndarray)
    assert isinstance(regression_problem.solution, np.ndarray)
    assert isinstance(info, dict)
    assert "prior_process" in info

def problem():
    return filtsmooth_zoo.pendulum(step=0.12)
Exemplo n.º 10
0
    def test_filtsmooth_pendulum(self):
        # pylint: disable=not-callable
        # Set up test problem
        regression_problem, statespace_components = filtsmooth_zoo.pendulum()

        # Linearise problem
        ekf_meas = self.linearising_component_pendulum(
            statespace_components["measurement_model"])
        ekf_dyna = self.linearising_component_pendulum(
            statespace_components["dynamics_model"])
        method = filtsmooth.Kalman(ekf_dyna, ekf_meas,
                                   statespace_components["initrv"])

        # Compute filter/smoother solution
        posterior, _ = method.filtsmooth(regression_problem)
        filtms = posterior.filtering_posterior.states.mean
        smooms = posterior.states.mean

        # Compute RMSEs
        comp = regression_problem.solution[:, 0]
        normaliser = np.sqrt(comp.size)
        filtrmse = np.linalg.norm(filtms[:, 0] - comp) / normaliser
        smoormse = np.linalg.norm(smooms[:, 0] - comp) / normaliser
        obs_rmse = (
            np.linalg.norm(regression_problem.observations[:, 0] - comp) /
            normaliser)

        # If desired, visualise.
        if VISUALISE:
            obs, tms, states = (
                regression_problem.observations,
                regression_problem.locations,
                regression_problem.solution,
            )
            fig, (ax1, ax2) = plt.subplots(1, 2)
            fig.suptitle("Noisy pendulum model (%.2f " % smoormse +
                         "< %.2f < %.2f?)" % (filtrmse, obs_rmse))
            ax1.set_title("Horizontal position")
            ax1.plot(tms[1:], obs[:, 0], ".", alpha=0.25, label="Observations")
            ax1.plot(
                tms[1:],
                np.sin(states)[1:, 0],
                "-",
                linewidth=4,
                alpha=0.5,
                label="Truth",
            )
            ax1.plot(tms[1:], np.sin(filtms)[1:, 0], "-", label="Filter")
            ax1.plot(tms[1:], np.sin(smooms)[1:, 0], "-", label="Smoother")
            ax1.set_xlabel("time")
            ax1.set_ylabel("horizontal pos. = sin(angular)")
            ax1.legend()

            ax2.set_title("Angular position")
            ax2.plot(
                tms[1:],
                states[1:, 0],
                "-",
                linewidth=4,
                alpha=0.5,
                label="Truth",
            )
            ax2.plot(tms[1:], filtms[1:, 0], "-", label="Filter")
            ax2.plot(tms[1:], smooms[1:, 0], "-", label="Smoother")
            ax2.set_xlabel("time")
            ax2.set_ylabel("angular pos.")
            ax2.legend()
            plt.show()

        # Test if RMSEs behave well.
        self.assertLess(smoormse, filtrmse)
        self.assertLess(filtrmse, obs_rmse)
Exemplo n.º 11
0
    def test_filtsmooth_pendulum(self):
        # pylint: disable=not-callable
        # Set up test problem

        # If this measurement variance is not really small, the sampled
        # test data can contain an outlier every now and then which
        # breaks the test, even though it has not been touched.
        regression_problem, statespace_components = filtsmooth_zoo.pendulum(
            measurement_variance=0.0001)

        # Linearise problem
        ekf_meas = self.linearising_component_pendulum(
            statespace_components["measurement_model"])
        ekf_dyna = self.linearising_component_pendulum(
            statespace_components["dynamics_model"])
        method = filtsmooth.Kalman(ekf_dyna, ekf_meas,
                                   statespace_components["initrv"])

        # Compute filter/smoother solution
        posterior, _ = method.filtsmooth(regression_problem)
        filtms = posterior.filtering_posterior.states.mean
        smooms = posterior.states.mean

        # Compute RMSEs
        comp = regression_problem.solution[:, 0]
        normaliser = np.sqrt(comp.size)
        filtrmse = np.linalg.norm(filtms[:, 0] - comp) / normaliser
        smoormse = np.linalg.norm(smooms[:, 0] - comp) / normaliser
        obs_rmse = (
            np.linalg.norm(regression_problem.observations[:, 0] - comp) /
            normaliser)

        # If desired, visualise.
        if self.visualise:
            # pylint: disable=import-outside-toplevel
            try:
                import matplotlib.pyplot as plt
            except ImportError as err:
                raise ImportError(
                    "Install matplotlib to visualise the test functions."
                ) from err

            obs, tms, states = (
                regression_problem.observations,
                regression_problem.locations,
                regression_problem.solution,
            )
            fig, (ax1, ax2) = plt.subplots(1, 2)
            fig.suptitle("Noisy pendulum model (%.2f " % smoormse +
                         "< %.2f < %.2f?)" % (filtrmse, obs_rmse))
            ax1.set_title("Horizontal position")
            ax1.plot(tms[0:], obs[:, 0], ".", alpha=0.25, label="Observations")
            ax1.plot(
                tms[1:],
                np.sin(states)[1:, 0],
                "-",
                linewidth=4,
                alpha=0.5,
                label="Truth",
            )
            ax1.plot(tms[1:], np.sin(filtms)[1:, 0], "-", label="Filter")
            ax1.plot(tms[1:], np.sin(smooms)[1:, 0], "-", label="Smoother")
            ax1.set_xlabel("time")
            ax1.set_ylabel("horizontal pos. = sin(angular)")
            ax1.legend()

            ax2.set_title("Angular position")
            ax2.plot(
                tms[1:],
                states[1:, 0],
                "-",
                linewidth=4,
                alpha=0.5,
                label="Truth",
            )
            ax2.plot(tms[1:], filtms[1:, 0], "-", label="Filter")
            ax2.plot(tms[1:], smooms[1:, 0], "-", label="Smoother")
            ax2.set_xlabel("time")
            ax2.set_ylabel("angular pos.")
            ax2.legend()
            plt.show()

        # Test if RMSEs behave well.
        self.assertLess(smoormse, filtrmse)
        self.assertLess(filtrmse, obs_rmse)
import numpy as np
import pytest

import probnum.problems.zoo.filtsmooth as filtsmooth_zoo
from probnum import problems

all_filtmooth_setups = pytest.mark.parametrize(
    "filtsmooth_setup",
    [
        filtsmooth_zoo.benes_daum(),
        filtsmooth_zoo.car_tracking(),
        filtsmooth_zoo.logistic_ode(),
        filtsmooth_zoo.ornstein_uhlenbeck(),
        filtsmooth_zoo.pendulum(),
    ],
)


@all_filtmooth_setups
def test_types(filtsmooth_setup):
    regression_problem, statespace_components = filtsmooth_setup
    assert isinstance(regression_problem, problems.RegressionProblem)
    assert isinstance(regression_problem.observations, np.ndarray)
    assert isinstance(regression_problem.locations, np.ndarray)
    assert isinstance(regression_problem.solution, np.ndarray)
    assert isinstance(statespace_components, dict)
    assert "dynamics_model" in statespace_components
    assert "measurement_model" in statespace_components
    assert "initrv" in statespace_components