EmrysFilter 0.1.0
State estimation utilities in C++23 using Eigen
Loading...
Searching...
No Matches
Emrys::GridGaussianParams< Grid_, Covariance_, Component_ > Class Template Reference

The parameters of a Rao-Blackwellized point-mass filter's state: the cells of a grid still alive, their probabilities, and for each a Gaussian, or a hybrid of Gaussians, over the rest of the state. More...

#include <EmrysFilter/Distributions/GridGaussian.h>

Public Types

using GridType = Grid_
 The grid.
using Scalar = typename Grid_::Scalar
 The scalar type.
using SpaceType = typename Grid_::SpaceType
 The whole state space.
using CellsType = typename Grid_::CellsType
 The discrete space of cells.
using RestSpace = typename Grid_::RestSpace
 The rest's space, in order.
using PinnedSpace = typename Grid_::PinnedSpace
 The fixed block's space.
using CovarianceType = Covariance_
 SharedCovariance or PerPointCovariance.
using ConditionalType = Params<Component_>
 A cell's distribution over the rest: a Gaussian, or a hybrid of Gaussians.
using WeightArrayType = Eigen::Array<Scalar, Eigen::Dynamic, 1>
 One entry per live cell.
using LogWeightsType = Eigen::Map<WeightArrayType const>
 The live cells' log-probabilities.
using allocator_type = typename Grid_::allocator_type
 The grid's allocator.
using DensityType = GridGaussian<Grid_, Covariance_, Component_>
 The view toDensity() returns.

Public Member Functions

 GridGaussianParams (Grid_ grid, ConditionalType const &conditional, Covariance_={})
 Every cell of grid alive and equally probable, each with conditional as its Gaussian over the rest of the state.
allocator_type get_allocator () const
Grid_ const & grid () const
Eigen::Index size () const
Eigen::Index cell (Eigen::Index i) const
std::span< Eigen::Index const > cells () const
std::optional< Eigen::Index > find (Eigen::Index cell) const
auto center (Eigen::Index i) const
LogWeightsType logWeights () const
Scalar logWeight (Eigen::Index i) const
Eigen::Index mostProbable () const
CategoricalParams< CellsType, Scalar > toCategorical () const
template<typename P>
auto marginal () const
std::expected< void, WeightError > setWeights (CategoricalParams< CellsType, Scalar > const &weights)
 Replaces the live cells' weights with those of weights, normalized over the live cells, as for a prior that isn't uniform.
decltype(auto) conditional (Eigen::Index i) const
auto modes () const
Moments< RestSpace, Scalar >::MatrixType const & sharedCovariance () const
std::expected< void, NumericError > factorize () const
 Factorizes each live cell's Gaussian, the one they share once, or checks each cell's hybrid, so that the density's collapse reads a distribution; the cells' weights always define one.
std::expected< DensityType, NumericError > toDensity () const &
 Checks the cells (factorize()) and views the state.
void toDensity () const &&=delete
 A density of a temporary would outlive it.
Scalar pruneBelow (Scalar logThreshold)
 Removes every live cell whose log-probability is below logThreshold, and renormalizes; the most probable cell is always kept, the first of them if several are.
Scalar pruneTail (Scalar logFraction)
 Removes the least probable live cells, as many as can be while their combined probability stays below \( e^{\mathrm{logFraction}} \), and renormalizes.
Scalar pruneToSize (Eigen::Index maxSize)
 Removes the least probable live cells until at most maxSize, at least one, remain, and renormalizes.
void subdivide (Eigen::Index factor)
 Splits every live cell into factor cells along each axis (see PointGrid::subdivided()), each with an equal share of its probability and a copy of its Gaussian.

Static Public Attributes

static constexpr bool IsParams = true
 parameters, which views check

Friends

template<typename, typename, typename, typename, typename>
class RbPointMassFilter
 The filter reweights and replaces the Gaussians.

Detailed Description

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
class Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >

The parameters of a Rao-Blackwellized point-mass filter's state: the cells of a grid still alive, their probabilities, and for each a Gaussian, or a hybrid of Gaussians, over the rest of the state.

The density is \( p(x) = \sum_c P(c) \, \delta(x_p - p_c) \, \mathcal{N}(x_r; \mu_c, \Sigma_c) \) over the live cells \( c \), where \( p_c \) is the cell's center (widened by its covariance about the center, if the grid has one). With Component_ a HybridGaussian over the rest, each cell holds an IMM's state instead, \( p(x) = \sum_c P(c) \, \delta(x_p - p_c) \sum_m P(m \mid c) \, \mathcal{N}(x_r; \mu_{cm}, \Sigma_{cm}) \), whose modes() sums the cells' mode probabilities. Only cells of nonzero probability are stored, in increasing order of their flat index, so a cell is addressed two ways: by its position i among the live cells (conditional(i), center(i), logWeight(i)), and by its flat index in the grid's cells (cell(i), find()). A cell whose probability becomes zero, by a gate, by pruning, or by setWeights(), is removed for good, since nothing moves probability between cells.

With Covariance_ SharedCovariance, every cell has the same covariance; with PerPointCovariance, each has its own (see RbPointMassFilter). A cell that holds a hybrid has PerPointCovariance, since mixing its modes gives each cell covariances of its own.

Upkeep (see Upkeep) keeps the number of live cells in bounds: pruneBelow(), pruneTail(), and pruneToSize() remove the improbable cells, and on a regular grid with at most one cell covariance, subdivide() splits every live cell.

The live cells, their probabilities, and their Gaussians come from the grid's allocator (see Allocation), and removing cells reuses that storage.

filter.state().size(); // live cells
filter.state().marginal<GridAxis<Position, 0>>(); // CategoricalParams over the first axis
filter.state().toDensity()->collapsed(); // the whole state as one GaussianParams
upkeep::pruneBelow(1e-9)(filter.state());
upkeep::whenSize(std::less{}, 64, upkeep::subdivide(2))(filter.state());
constexpr Subdivide subdivide(std::ptrdiff_t factor=2)
Definition Upkeep.h:1071
constexpr PruneBelow< internal::DeducedScalar< Value > > pruneBelow(Value probability)
Definition Upkeep.h:954
WhenSize< Compare, Actions... > whenSize(Compare compare, std::ptrdiff_t limit, Actions... actions)
Definition Upkeep.h:852
The axis of a regular grid of points (see regularGrid()) along coordinate I of the block Block: a run...
Definition GridGaussian.h:68
Template Parameters
Grid_the grid (see PointGrid)
Covariance_SharedCovariance or PerPointCovariance
Component_each cell's distribution over the grid's RestSpace: a Gaussian, by default, or a HybridGaussian

Member Function Documentation

◆ cell()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
Eigen::Index Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::cell ( Eigen::Index i) const
inlinenodiscard
Returns
the flat index in the grid's cells of the live cell at position i

◆ cells()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
std::span< Eigen::Index const > Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::cells ( ) const
inlinenodiscard
Returns
the flat index of every live cell, in increasing order

◆ center()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
auto Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::center ( Eigen::Index i) const
inlinenodiscard
Returns
the center of the live cell at position i

◆ conditional()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
decltype(auto) Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::conditional ( Eigen::Index i) const
inlinenodiscard
Returns
the distribution over the rest of the state given the live cell at position i: its Gaussian, or its hybrid

◆ factorize()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
std::expected< void, NumericError > Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::factorize ( ) const
inlinenodiscard

Factorizes each live cell's Gaussian, the one they share once, or checks each cell's hybrid, so that the density's collapse reads a distribution; the cells' weights always define one.

It is const because it writes only the cached factorizations (see Distributions).

Returns
nothing, or the NumericError of the first cell that fails

◆ find()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
std::optional< Eigen::Index > Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::find ( Eigen::Index cell) const
inlinenodiscard
Returns
the position among the live cells of the cell with flat index cell, or nothing if it is dead

◆ get_allocator()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
allocator_type Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::get_allocator ( ) const
inlinenodiscard
Returns
the allocator the live cells come from: the grid's

◆ grid()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
Grid_ const & Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::grid ( ) const
inlinenodiscard
Returns
the grid, with its cells and centers

◆ logWeight()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
Scalar Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::logWeight ( Eigen::Index i) const
inlinenodiscard
Returns
the log-probability of the live cell at position i

◆ logWeights()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
LogWeightsType Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::logWeights ( ) const
inlinenodiscard
Returns
each live cell's log-probability, normalized

◆ marginal()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
template<typename P>
auto Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::marginal ( ) const
inlinenodiscard
Returns
the distribution of the axis of the cells named by the path P (a tag or a TagPath), such as an axis of a regular grid (marginal<GridAxis<Position, 0>>()), summed over the live cells

◆ modes()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
auto Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::modes ( ) const
inlinenodiscard
Returns
the probability of each mode, summed over the live cells, \( P(m) = \sum_c P(c) \, P(m \mid c) \), normalized

◆ mostProbable()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
Eigen::Index Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::mostProbable ( ) const
inlinenodiscard
Returns
the position of the most probable live cell; ties go to the lowest

◆ pruneBelow()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
Scalar Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::pruneBelow ( Scalar logThreshold)
inlinenodiscard

Removes every live cell whose log-probability is below logThreshold, and renormalizes; the most probable cell is always kept, the first of them if several are.

The threshold is absolute: under subdivide(), which shares each cell's probability among its children, a caller who wants the same density cut lowers it by the log of the children per cell. upkeep::pruneBelow() calls it.

Returns
the log of the probability removed, -inf if nothing was
See also
pruneTail(), pruneToSize()

◆ pruneTail()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
Scalar Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::pruneTail ( Scalar logFraction)
inlinenodiscard

Removes the least probable live cells, as many as can be while their combined probability stays below \( e^{\mathrm{logFraction}} \), and renormalizes.

The fraction is below one, so a cell is always kept. Of cells equally probable, those later in order go first. It bounds the probability removed however many cells there are. upkeep::pruneTail() calls it.

Returns
the log of the probability removed, -inf if nothing was
See also
pruneBelow(), pruneToSize()

◆ pruneToSize()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
Scalar Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::pruneToSize ( Eigen::Index maxSize)
inlinenodiscard

Removes the least probable live cells until at most maxSize, at least one, remain, and renormalizes.

Of cells equally probable, those later in order go first. upkeep::pruneToSize() calls it.

Returns
the log of the probability removed, -inf if nothing was
See also
pruneBelow(), pruneTail()

◆ setWeights()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
std::expected< void, WeightError > Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::setWeights ( CategoricalParams< CellsType, Scalar > const & weights)
inlinenodiscard

Replaces the live cells' weights with those of weights, normalized over the live cells, as for a prior that isn't uniform.

Cells it gives weight zero are removed; dead cells stay dead.

Returns
nothing, or the WeightError of weights that give every live cell weight zero, or one a weight that is NaN or \( +\infty \), with the weights as they were, as a filter's state must always define a distribution (decisions.md [update-outcomes])

◆ sharedCovariance()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
Moments< RestSpace, Scalar >::MatrixType const & Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::sharedCovariance ( ) const
inlinenodiscard
Returns
the covariance every cell shares

◆ size()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
Eigen::Index Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::size ( ) const
inlinenodiscard
Returns
the number of live cells

◆ subdivide()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
void Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::subdivide ( Eigen::Index factor)
inline

Splits every live cell into factor cells along each axis (see PointGrid::subdivided()), each with an equal share of its probability and a copy of its Gaussian.

The grid is replaced by the subdivided one, so flat cell indices change.

With the cell covariance \( \mathrm{diag}(s^2 / 12) \) of a cell of width \( s \), the collapsed mean and covariance don't change. Without a cell covariance the cells are point masses, and the children spread over their parent's cell: the mean doesn't change, and the variance along each axis grows by \( \tfrac{s^2}{12} (1 - 1 / k^2) \), \( k \) the factor. For a grid that samples a density at its centers, this brings it closer to that density; where the points mean exactly what they say, don't subdivide.

◆ toCategorical()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
CategoricalParams< CellsType, Scalar > Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::toCategorical ( ) const
inlinenodiscard
Returns
the weights over every cell of the grid, dead ones zero, normalized

◆ toDensity()

template<typename Grid_, typename Covariance_ = SharedCovariance, typename Component_ = Gaussian<typename Grid_::RestSpace, typename Grid_::Scalar>>
std::expected< DensityType, NumericError > Emrys::GridGaussianParams< Grid_, Covariance_, Component_ >::toDensity ( ) const &
inlinenodiscard

Checks the cells (factorize()) and views the state.

Returns
a GridGaussian that checks this object, or the NumericError from factorize()

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