EmrysFilter 0.1.0
State estimation utilities in C++23 using Eigen
Loading...
Searching...
No Matches
Emrys::GaussianParams< Space_, Scalar_ > Class Template Reference

A Gaussian distribution: a mean and covariance in a space. More...

#include <EmrysFilter/Distributions/Gaussian.h>

Public Types

using MomentsType = Moments<Space_, Scalar_>
 the mean and covariance together
using Scalar = typename MomentsType::Scalar
 the scalar type
using Index = typename MomentsType::Index
 Eigen's index type.
using VectorType = typename MomentsType::VectorType
 a value, such as the mean
using DifferenceVectorType = typename MomentsType::DifferenceVectorType
 a difference, such as a residual
using MatrixType = typename MomentsType::MatrixType
 a matrix over differences
using SpaceType = Space_
 the space the values live in
using DensityType = Gaussian<Space_, Scalar_>
 the view toDensity() returns

Public Member Functions

 GaussianParams ()
 Constructs a Gaussian in a default space, with a zero mean and covariance, which factorize() rejects until a covariance is set.
 GaussianParams (Index n)
 Constructs a Gaussian with n value coordinates, with a zero mean and covariance.
 GaussianParams (MomentsType moments)
 Constructs a Gaussian from moments, in a default space resized to fit them.
template<MatrixExpression Mean, CovarianceExpression Cov>
requires internal::SizedByLength<Space_>
 GaussianParams (Mean &&mean, Cov &&cov)
 Constructs a Gaussian from mean and cov, moving either one passed as an rvalue of the stored type.
 GaussianParams (Space_ space)
 Constructs a Gaussian in space, with a zero mean and covariance.
 GaussianParams (Space_ space, Index n)
 Constructs a Gaussian with n value coordinates in space, with a zero mean and covariance.
 GaussianParams (Space_ space, MomentsType moments)
 Constructs a Gaussian from moments in space, which is resized to fit them if it has one resizable block.
template<MatrixExpression Mean, CovarianceExpression Cov>
 GaussianParams (Space_ space, Mean &&mean, Cov &&cov)
 GaussianParams(mean, cov) in space.
 GaussianParams (GaussianParams const &other)
 Copies the data and any valid factorization.
 GaussianParams (GaussianParams &&other) noexcept
 Moves the data and any valid factorization; a view of other may not be read afterward.
GaussianParams & operator= (GaussianParams const &other)
 Copies the data and any valid factorization; a view of this object may not be read afterward.
GaussianParams & operator= (GaussianParams &&other) noexcept
 Moves the data and any valid factorization; a view of either object may not be read afterward.
Index valueDimension () const
Index differenceDimension () const
void resize (Index n)
 Resizes mean, covariance, and factorization, and the space's resizable block, to n value coordinates.
template<typename Path, typename MeanDerived, typename CovDerived, typename CrossDerived>
void insert (Index element, Eigen::MatrixBase< MeanDerived > const &mean, Eigen::MatrixBase< CovDerived > const &cov, Eigen::MatrixBase< CrossDerived > const &cross)
 Inserts the entries mean into the resizable block named by the tag path Path, before its element element, with covariance cov and cross-covariance cross with the existing entries (a row per difference coordinate of the new entries and a column per existing one, in order).
template<typename Path, typename MeanDerived, typename CovDerived>
void insert (Index element, Eigen::MatrixBase< MeanDerived > const &mean, Eigen::MatrixBase< CovDerived > const &cov)
 insert() of entries independent of the existing ones.
template<typename Path>
void erase (Index element, Index count=1)
 Removes count elements of the resizable block named by the tag path Path, starting at its element element: the marginal of the rest.
Space_ const & space () const
MomentsType const & moments () const
VectorType const & mean () const
MatrixType const & covarianceLower () const
template<typename Path>
auto mean () const
template<typename Path>
auto mean (Index element) const
 mean<Path>() of repetition element of the repeated block Path starts at (see marginal<Path>(element)).
template<typename Path>
auto covariance () const
template<typename Path>
auto covariance (Index element) const
 covariance<Path>() of repetition element of the repeated block Path starts at.
template<typename RowPath, typename ColPath>
auto covariance () const
template<MatrixExpression Mean>
void setMean (Mean &&mean)
 Sets the mean, normalized by the space, moving mean if it is an rvalue of the stored type.
template<CovarianceExpression Cov>
void setCovariance (Cov &&cov)
 Sets the covariance, moving cov if it is an rvalue of the stored type, and invalidates the factorization.
void scaleToConfidence (Scalar probability)
 Scales the covariance so that its one-standard-deviation ellipsoid is the probability confidence region, and invalidates the factorization.
std::expected< MatrixType, GaussianError > covariance () const
std::expected< MatrixType, GaussianError > precision () const
std::expected< MatrixType, GaussianError > covarianceRoot () const
std::expected< MatrixType, GaussianError > precisionRoot () const
template<typename Path>
auto marginal () const &
template<typename Path>
void marginal () const &&=delete
 A marginal of a temporary would outlive it; copy the marginal of a named Gaussian instead.
template<typename Path>
auto marginal (Index element) const &
template<typename Path>
void marginal (Index element) const &&=delete
 A marginal of a temporary would outlive it.
template<typename GivenPath, typename Derived>
auto conditional (Eigen::MatrixBase< Derived > const &values) const
template<typename GivenPath, typename Derived>
auto conditionalWithEvidence (Eigen::MatrixBase< Derived > const &values) const
std::expected< void, GaussianError > factorize () const
 Factorizes the covariance if it has changed since the last factorization.
template<typename R>
std::expected< void, GaussianError > factorize (R const &repair)
 factorize(), repairing a covariance that is not positive definite by repair, a Repair: g.factorize(roots::ridge()).
std::expected< DensityType, GaussianError > toDensity () const &
 Factorizes the covariance if needed (see factorize()), which writes the cache and so is not safe on one object from two threads at once.
void toDensity () const &&=delete
 A density of a temporary would outlive it.
template<typename R>
std::expected< DensityType, GaussianError > toDensity (R const &repair) &
 toDensity(), repairing a covariance that is not positive definite by repair (see factorize(R const &)): g.toDensity(roots::ridge()).
template<typename R>
void toDensity (R const &) &&=delete
 A density of a temporary would outlive it.

Static Public Attributes

static constexpr int ValueDimensionAtCompileTime = MomentsType::ValueDimensionAtCompileTime
 the length of a value, or Eigen::Dynamic
static constexpr int MaxValueDimensionAtCompileTime = MomentsType::MaxValueDimensionAtCompileTime
 a bound on the length of a value, or Eigen::Dynamic
static constexpr int DifferenceDimensionAtCompileTime = MomentsType::DifferenceDimensionAtCompileTime
 the length of a difference and the rows of the covariance, or Eigen::Dynamic
static constexpr int MaxDifferenceDimensionAtCompileTime = MomentsType::MaxDifferenceDimensionAtCompileTime
 a bound on the length of a difference, or Eigen::Dynamic
static constexpr bool IsParams = true
 parameters, which views check
static constexpr bool IsInfoForm = false
 holds the covariance, not the precision [gaussian-forms]
static constexpr bool IsSqrtForm = false
 holds the covariance whole, not a factor [gaussian-forms]

Detailed Description

template<Space Space_, RealScalar Scalar_ = double>
class Emrys::GaussianParams< Space_, Scalar_ >

A Gaussian distribution: a mean and covariance in a space.

The multivariate normal distribution, with the space's \( \boxplus \) and \( \boxminus \) in place of addition and subtraction where its coordinates are not plain.

toDensity() factorizes the covariance (if it has changed since the last factorization) and returns a Gaussian, which evaluates the density. The density checks this object for changes: reading it after this object has changed in any way is a programmer error caught by EMRYS_FILTER_ASSERT (decisions.md [view-stamp]). The check detects the change and prevents nothing: it does not synchronize threads or block the mutators (see Distributions). Share the Gaussian between threads, or a copy of moments(), rather than this object: its const members factorize into a cache (see factorize()).

marginal() returns a read-only view of a subset of the entries, which checks only this object's size and structure: its values may change under the marginal, which sees them, but reading the marginal after a resize, an insert() or erase(), or an assignment is a programmer error. Neither view may outlive this object, and neither may be made from a temporary.

The space's value dimension always matches the mean's length. insert() and erase() grow and shrink the space's resizable block in place, such as adding or dropping a landmark, and resize() resizes it whole.

The space describes how each coordinate behaves (see Spaces). The mean is normalized whenever it is set, and residuals are normalized before they are used, so a periodic coordinate's mean stays in range and its residuals take the short way around. Densities use the nearest image only (see Spaces).

Only the lower triangle of the covariance is read by the factorization. Changing the mean does not invalidate the factorization.

Template Parameters
Space_space of the coordinates, which sets the dimension and the storage bound (see Spaces)
Scalar_scalar type, double by default
See also
class Gaussian, class Moments

Constructor & Destructor Documentation

◆ GaussianParams() [1/4]

template<Space Space_, RealScalar Scalar_ = double>
Emrys::GaussianParams< Space_, Scalar_ >::GaussianParams ( Index n)
inlineexplicit

Constructs a Gaussian with n value coordinates, with a zero mean and covariance.

A space with one resizable block is resized to n; any other must already have n coordinates. A space with several resizable blocks must be given, with its counts.

◆ GaussianParams() [2/4]

template<Space Space_, RealScalar Scalar_ = double>
template<MatrixExpression Mean, CovarianceExpression Cov>
requires internal::SizedByLength<Space_>
Emrys::GaussianParams< Space_, Scalar_ >::GaussianParams ( Mean && mean,
Cov && cov )
inline

Constructs a Gaussian from mean and cov, moving either one passed as an rvalue of the stored type.

cov may be a diagonal, its variances: GaussianParams<State>{mean, variances.asDiagonal()}.

◆ GaussianParams() [3/4]

template<Space Space_, RealScalar Scalar_ = double>
Emrys::GaussianParams< Space_, Scalar_ >::GaussianParams ( Space_ space,
Index n )
inline

Constructs a Gaussian with n value coordinates in space, with a zero mean and covariance.

A space with one resizable block is resized to n; any other must already have n coordinates.

◆ GaussianParams() [4/4]

template<Space Space_, RealScalar Scalar_ = double>
Emrys::GaussianParams< Space_, Scalar_ >::GaussianParams ( GaussianParams< Space_, Scalar_ > const & other)
inline

Copies the data and any valid factorization.

Views of other do not see the copy.

Member Function Documentation

◆ conditional()

template<Space Space_, RealScalar Scalar_ = double>
template<typename GivenPath, typename Derived>
auto Emrys::GaussianParams< Space_, Scalar_ >::conditional ( Eigen::MatrixBase< Derived > const & values) const
inlinenodiscard
Returns
a copy of the distribution of the other coordinates given that the subspace named by the path GivenPath (a tag or a TagPath) equals values, which are in that subspace. The result is in the space of the remaining blocks: a Composite that loses a block is replaced by the blocks it has left.

\( \mu_{a|b} = \mu_a \boxplus K (v \boxminus \mu_b) \) and \( \Sigma_{a|b} = \Sigma_{aa} - K \Sigma_{ba} \), with \( K = \Sigma_{ab} \Sigma_{bb}^{-1} \) (internal::conditionMoments(), which gives the source). Uses a pivoted LDLT, so it always produces a result, exact for values on the support when the given block is known exactly (decisions.md [innovation-cholesky]); for a numerically singular source the result may fail toDensity(). conditionalWithEvidence() also returns the log-density of values.

◆ conditionalWithEvidence()

template<Space Space_, RealScalar Scalar_ = double>
template<typename GivenPath, typename Derived>
auto Emrys::GaussianParams< Space_, Scalar_ >::conditionalWithEvidence ( Eigen::MatrixBase< Derived > const & values) const
inlinenodiscard
Returns
conditional() and the log-evidence of values, as a GaussianConditional.

The log-evidence is \( \log p(b = v) \), the log-density of values under the marginal of the given subspace, which conditioning computes anyway. A mixture's conditional keeps it in its weights; a single Gaussian has no weight, so it returns it beside the result. A Rao-Blackwellized update weights each particle or grid point by it (decisions.md [conditional-evidence]).

Returns
the conditional and its evidence, or GaussianError::NotPositiveDefinite if the given block's covariance \( \Sigma_{bb} \) is not positive definite: a block known exactly has no density, so its values have no evidence (decisions.md [innovation-cholesky])

◆ covariance() [1/3]

template<Space Space_, RealScalar Scalar_ = double>
std::expected< MatrixType, GaussianError > Emrys::GaussianParams< Space_, Scalar_ >::covariance ( ) const
inlinenodiscard
Returns
the covariance, with both triangles filled from the lower one. Never fails: it returns std::expected so that every form of the Gaussian has the same four accessors (decisions.md [gaussian-forms]), which generic code reaches through the GaussianForm concept. covarianceLower() reads the stored matrix without a copy.
See also
precision(), covarianceRoot(), precisionRoot()

◆ covariance() [2/3]

template<Space Space_, RealScalar Scalar_ = double>
template<typename RowPath, typename ColPath>
auto Emrys::GaussianParams< Space_, Scalar_ >::covariance ( ) const
inlinenodiscard
Returns
the cross-covariance of the blocks named by the paths RowPath and ColPath, read from the lower triangle: a matrix with a row per difference coordinate of the first and a column per difference coordinate of the second, or a coefficient if each is a single coordinate.

◆ covariance() [3/3]

template<Space Space_, RealScalar Scalar_ = double>
template<typename Path>
auto Emrys::GaussianParams< Space_, Scalar_ >::covariance ( ) const
inlinenodiscard
Returns
the covariance of the block named by the path Path, at its rows of differences (see diffIdx()), read from the lower triangle: a lazy expression that must not outlive this object, or a variance for a single coordinate.

◆ covarianceLower()

template<Space Space_, RealScalar Scalar_ = double>
MatrixType const & Emrys::GaussianParams< Space_, Scalar_ >::covarianceLower ( ) const
inlinenodiscard
Returns
the stored covariance, over differences, of which only the lower triangle is guaranteed to be read: a reference, with no copy and no failure. covariance() returns it with both triangles filled, and covariance<Path>() a block of it.

◆ covarianceRoot()

template<Space Space_, RealScalar Scalar_ = double>
std::expected< MatrixType, GaussianError > Emrys::GaussianParams< Space_, Scalar_ >::covarianceRoot ( ) const
inlinenodiscard
Returns
the lower-triangular Cholesky factor \( L \), with \( L L^T = \Sigma \) and zeros above the diagonal, from the cached factorization (see factorize()), or its GaussianError.

◆ differenceDimension()

template<Space Space_, RealScalar Scalar_ = double>
Index Emrys::GaussianParams< Space_, Scalar_ >::differenceDimension ( ) const
inlinenodiscard
Returns
the number of rows and columns of the covariance (see Spaces)

◆ erase()

template<Space Space_, RealScalar Scalar_ = double>
template<typename Path>
void Emrys::GaussianParams< Space_, Scalar_ >::erase ( Index element,
Index count = 1 )
inline

Removes count elements of the resizable block named by the tag path Path, starting at its element element: the marginal of the rest.

The space's block shrinks to match.

◆ factorize() [1/2]

template<Space Space_, RealScalar Scalar_ = double>
std::expected< void, GaussianError > Emrys::GaussianParams< Space_, Scalar_ >::factorize ( ) const
inlinenodiscard

Factorizes the covariance if it has changed since the last factorization.

Calling this ahead of time moves the cost of factorization out of a later toDensity() call.

It is const because it changes nothing a caller can see: it writes only the cached factorization, which toDensity(), precision(), covarianceRoot(), and precisionRoot() also fill when it is missing. So none of them is safe to call from two threads at once on the same object until a factorization has succeeded; after that they only read. Threads should share the Gaussian that toDensity() returns instead (see Distributions).

Returns
nothing on success, or a GaussianError if the covariance is not positive definite or not finite.
See also
toDensity(), GaussianError

◆ factorize() [2/2]

template<Space Space_, RealScalar Scalar_ = double>
template<typename R>
std::expected< void, GaussianError > Emrys::GaussianParams< Space_, Scalar_ >::factorize ( R const & repair)
inlinenodiscard

factorize(), repairing a covariance that is not positive definite by repair, a Repair: g.factorize(roots::ridge()).

If the factorization fails with GaussianError::NotPositiveDefinite, it is retried on the matrix repair returns, which for roots::ridge() is the covariance with a ridge on its diagonal, and if that succeeds, the repaired matrix becomes the covariance. Otherwise the covariance is unchanged. It is not const, since replacing the covariance is a change that views of this object see. Axes are refused: a density's factor is the Cholesky factor, and axes that cannot fail would hide a covariance that is not positive definite (decisions.md [covariance-repair]).

Returns
nothing on success, GaussianError::NonFinite if the covariance is not finite, the error of repair if it fails, or GaussianError::NotPositiveDefinite if the repaired covariance still fails to factorize, as a zero covariance does with roots::ridge()
See also
roots::Ridge, Repair

◆ insert()

template<Space Space_, RealScalar Scalar_ = double>
template<typename Path, typename MeanDerived, typename CovDerived, typename CrossDerived>
void Emrys::GaussianParams< Space_, Scalar_ >::insert ( Index element,
Eigen::MatrixBase< MeanDerived > const & mean,
Eigen::MatrixBase< CovDerived > const & cov,
Eigen::MatrixBase< CrossDerived > const & cross )
inline

Inserts the entries mean into the resizable block named by the tag path Path, before its element element, with covariance cov and cross-covariance cross with the existing entries (a row per difference coordinate of the new entries and a column per existing one, in order).

The space's block grows to match.

An element is one repetition of a Repeated block, or one coordinate of a resizable Linear or Periodic block; mean holds one or more whole elements.

◆ marginal() [1/2]

template<Space Space_, RealScalar Scalar_ = double>
template<typename Path>
auto Emrys::GaussianParams< Space_, Scalar_ >::marginal ( ) const &
inlinenodiscard
Returns
a read-only view of the subspace named by the path Path (a tag or a TagPath), whose space is that subspace with its parameters. It checks this object's shape.
See also
class GaussianMarginal

◆ marginal() [2/2]

template<Space Space_, RealScalar Scalar_ = double>
template<typename Path>
auto Emrys::GaussianParams< Space_, Scalar_ >::marginal ( Index element) const &
inlinenodiscard
Returns
a read-only view of repetition element of a repeated block (see idx()), such as one vehicle of a fleet. Path starts at the repeated block, and may go on inside it: marginal<TagPath<Fleet, Heading>>(k) is vehicle k's heading. Its space is that of one repetition, or of the block the path ends at.

◆ mean() [1/2]

template<Space Space_, RealScalar Scalar_ = double>
template<typename Path>
auto Emrys::GaussianParams< Space_, Scalar_ >::mean ( ) const
inlinenodiscard
Returns
the entries of the mean in the block named by the path Path (a tag or a TagPath): g.mean<Position>(). A lazy expression that keeps the block's fixed size, or a coefficient for a single coordinate.

◆ mean() [2/2]

template<Space Space_, RealScalar Scalar_ = double>
VectorType const & Emrys::GaussianParams< Space_, Scalar_ >::mean ( ) const
inlinenodiscard
Returns
the mean, a value in the space

◆ moments()

template<Space Space_, RealScalar Scalar_ = double>
MomentsType const & Emrys::GaussianParams< Space_, Scalar_ >::moments ( ) const
inlinenodiscard
Returns
the mean and covariance together

◆ precision()

template<Space Space_, RealScalar Scalar_ = double>
std::expected< MatrixType, GaussianError > Emrys::GaussianParams< Space_, Scalar_ >::precision ( ) const
inlinenodiscard
Returns
the precision \( \Lambda = \Sigma^{-1} \), solved with the cached factorization (see factorize()), or its GaussianError.

◆ precisionRoot()

template<Space Space_, RealScalar Scalar_ = double>
std::expected< MatrixType, GaussianError > Emrys::GaussianParams< Space_, Scalar_ >::precisionRoot ( ) const
inlinenodiscard
Returns
\( L^{-1} \), the triangular factor of the precision that this form gives cheapest: \( (L^{-1})^T L^{-1} = \Sigma^{-1} \). It is lower triangular, as the covariance forms' factors are, where the information forms give an upper-triangular one [gaussian-forms]. Or the GaussianError of factorize().

◆ resize()

template<Space Space_, RealScalar Scalar_ = double>
void Emrys::GaussianParams< Space_, Scalar_ >::resize ( Index n)
inline

Resizes mean, covariance, and factorization, and the space's resizable block, to n value coordinates.

Contents are unspecified afterward. To grow or shrink the block element by element, keeping the contents, use insert() and erase(), as a space with several resizable blocks must.

◆ scaleToConfidence()

template<Space Space_, RealScalar Scalar_ = double>
void Emrys::GaussianParams< Space_, Scalar_ >::scaleToConfidence ( Scalar probability)
inline

Scales the covariance so that its one-standard-deviation ellipsoid is the probability confidence region, and invalidates the factorization.

The Mahalanobis distance squared \( (x - \mu)^T \Sigma^{-1} (x - \mu) \) of a draw is chi-squared with \( k \) degrees of freedom, the difference dimension, so the region holding probability of the mass is the unit ellipsoid of \( \chi^{2\,-1}_k(p) \, \Sigma \), the covariance this sets. Does nothing to a Gaussian of dimension zero.

Parameters
probabilitythe confidence, in \( (0, 1) \)
See also
chiSquaredQuantile()

◆ setCovariance()

template<Space Space_, RealScalar Scalar_ = double>
template<CovarianceExpression Cov>
void Emrys::GaussianParams< Space_, Scalar_ >::setCovariance ( Cov && cov)
inline

Sets the covariance, moving cov if it is an rvalue of the stored type, and invalidates the factorization.

Only its lower triangle is read, so cov need not be symmetric: an upper triangle that disagrees is ignored, not an error. cov may be a diagonal, its variances.

◆ setMean()

template<Space Space_, RealScalar Scalar_ = double>
template<MatrixExpression Mean>
void Emrys::GaussianParams< Space_, Scalar_ >::setMean ( Mean && mean)
inline

Sets the mean, normalized by the space, moving mean if it is an rvalue of the stored type.

Does not invalidate the factorization.

◆ space()

template<Space Space_, RealScalar Scalar_ = double>
Space_ const & Emrys::GaussianParams< Space_, Scalar_ >::space ( ) const
inlinenodiscard
Returns
the space, with its sizes

◆ toDensity() [1/2]

template<Space Space_, RealScalar Scalar_ = double>
std::expected< DensityType, GaussianError > Emrys::GaussianParams< Space_, Scalar_ >::toDensity ( ) const &
inlinenodiscard

Factorizes the covariance if needed (see factorize()), which writes the cache and so is not safe on one object from two threads at once.

Returns
a Gaussian that checks this object, or a GaussianError if the covariance is not positive definite or not finite.
See also
factorize(), class Gaussian, GaussianError

◆ toDensity() [2/2]

template<Space Space_, RealScalar Scalar_ = double>
template<typename R>
std::expected< DensityType, GaussianError > Emrys::GaussianParams< Space_, Scalar_ >::toDensity ( R const & repair) &
inlinenodiscard

toDensity(), repairing a covariance that is not positive definite by repair (see factorize(R const &)): g.toDensity(roots::ridge()).

Returns
a Gaussian that checks this object, or the GaussianError from factorize(R const &)

◆ valueDimension()

template<Space Space_, RealScalar Scalar_ = double>
Index Emrys::GaussianParams< Space_, Scalar_ >::valueDimension ( ) const
inlinenodiscard
Returns
the number of coordinates of the mean (see Spaces)

The documentation for this class was generated from the following file: