# Source code for stonesoup.models.measurement.linear

import numpy as np

from ...base import Property
from ...types.array import CovarianceMatrix
from ..base import LinearModel, GaussianModel
from .base import MeasurementModel

# TODO: Probably should call this LinearGaussianMeasurementModel
[docs]class LinearGaussian(MeasurementModel, LinearModel, GaussianModel):
r"""This is a class implementation of a time-invariant 1D
Linear-Gaussian Measurement Model.

The model is described by the following equations:

.. math::

y_t = H_k*x_t + v_k,\ \ \ \   v(k)\sim \mathcal{N}(0,R)

where H_k is a (:py:attr:~ndim_meas, :py:attr:~ndim_state) \
matrix and v_k is Gaussian distributed.

"""

noise_covar: CovarianceMatrix = Property(doc="Noise covariance")

@property
def ndim_meas(self):
"""ndim_meas getter method

Returns
-------
:class:int
The number of measurement dimensions
"""

return len(self.mapping)

[docs]    def matrix(self, **kwargs):
"""Model matrix :math:H(t)

Returns
-------
:class:numpy.ndarray of shape \
(:py:attr:~ndim_meas, :py:attr:~ndim_state)
The model matrix evaluated given the provided time interval.
"""

model_matrix = np.zeros((self.ndim_meas, self.ndim_state))
for dim_meas, dim_state in enumerate(self.mapping):
if dim_state is not None:
model_matrix[dim_meas, dim_state] = 1

return model_matrix

[docs]    def function(self, state, noise=False, **kwargs):
"""Model function :math:h(t,x(t),w(t))

Parameters
----------
state: :class:~.State
An input state
noise: :class:numpy.ndarray or bool
An externally generated random process noise sample (the default is
False, in which case no noise will be added
if 'True', the output of :meth:~.Model.rvs is added)

Returns
-------
:class:numpy.ndarray of shape (:py:attr:~ndim_meas, 1)
The model function evaluated given the provided time interval.
"""

if isinstance(noise, bool) or noise is None:
if noise:
noise = self.rvs(num_samples=state.state_vector.shape, **kwargs)
else:
noise = 0

return self.matrix(**kwargs)@state.state_vector + noise

[docs]    def covar(self, **kwargs):
"""Returns the measurement model noise covariance matrix.

Returns
-------
:class:~.CovarianceMatrix of shape\
(:py:attr:~ndim_meas, :py:attr:~ndim_meas)
The measurement noise covariance.
"""

return self.noise_covar