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

How each component of a Mixture descends from the components it had at its last startLineage(): each component's share from each of those parents. More...

#include <EmrysFilter/Distributions/Mixture.h>

Public Types

using Scalar = Scalar_
 the scalar type
using allocator_type = Allocator_
 the allocator the shares come from
using Index = Eigen::Index
 Eigen's index type.

Public Member Functions

 MixtureLineage (Allocator_ const &allocator)
 An empty record, with no mark, whose shares come from allocator.
 MixtureLineage (MixtureLineage const &other)
 Copies the record into storage from other's allocator (see Allocation).
 MixtureLineage (MixtureLineage const &other, Allocator_ const &allocator)
 Copies other into storage from allocator.
 MixtureLineage (MixtureLineage &&other)=default
 Takes other's record.
 MixtureLineage (MixtureLineage &&other, Allocator_ const &allocator)
 Moves other into storage from allocator, taking its storage when the allocators are equal.
MixtureLineage & operator= (MixtureLineage const &other)=default
 Copies other's record into this one's storage.
MixtureLineage & operator= (MixtureLineage &&other)=default
 Takes other's record, as std::vector's move assignment does.
allocator_type get_allocator () const
Index count () const
Index parentCount () const
Index size () const
std::span< Scalar const > logShares (Index i) const
Scalar logShare (Index i, Index parent) const
template<typename Parents, typename Children>
void carry (Eigen::MatrixBase< Parents > const &parents, Eigen::MatrixBase< Children > &children, Scalar orphan=0) const
 Carries a value per parent to the components, as a statistic kept per hypothesis follows them through updates, merges, and prunes: children(i), one per component, becomes the mean of parents over component i's parents, weighted by its shares from them, so a component with one parent takes that parent's value and a merge takes the share-weighted mean of two; a component with no parent gets orphan.

Friends

template<internal::ComponentOrInfoForm, typename>
class MixtureParams
 The mixture keeps its rows.

Detailed Description

template<RealScalar Scalar_, typename Allocator_ = DefaultAllocator>
class Emrys::MixtureLineage< Scalar_, Allocator_ >

How each component of a Mixture descends from the components it had at its last startLineage(): each component's share from each of those parents.

Row i holds component i's log-shares, one per parent, which sum to one: the fraction of its weight that came through each parent, \( P(\text{parent } n \mid \text{component } i) \). MixtureParams::startLineage() gives every component itself as its one parent, and from then on the mixture keeps the rows as its components change: a reweighted, moved, or replaced component keeps its row; a merge takes the weighted sum of the two rows; split() gives each child its parent's row; removal drops rows; and add() and append() give a new component a row of zeros, no parent at all. A filter that splits a component into several updated branches gives each its prior's row. This is the f-graph of Rahmathullah, Svensson, and Svensson (2014): the branches merged into each node and their weights, kept as the normalized share per parent rather than one weight per merged branch, which is what the backward pass of GaussianMixtureHistory reads.

count() counts the mixture's startLineage() calls, so a record of the lineage can say how many marks fell between two records. A copy of a mixture is a new mixture and has no lineage, so a filter's state swapped for a copy shows as a count that went back; a move keeps it. Until the first startLineage() there are no rows, and the mixture does no work to keep them.

The smoother is one reader. carry() is for another: a value kept per component outside the filter, such as each hypothesis's running NIS, which the rows take from the parents to the components through the updates, merges, and prunes between two marks (usage.md, "Checking an estimator").

The rows come from Allocator_, one shared buffer of parentCount() log-shares per component.

Template Parameters
Scalar_scalar type of the shares
Allocator_allocator for the shares (see Allocation)
See also
MixtureParams::lineage(), GaussianMixtureHistory

Member Function Documentation

◆ carry()

template<RealScalar Scalar_, typename Allocator_ = DefaultAllocator>
template<typename Parents, typename Children>
void Emrys::MixtureLineage< Scalar_, Allocator_ >::carry ( Eigen::MatrixBase< Parents > const & parents,
Eigen::MatrixBase< Children > & children,
Scalar orphan = 0 ) const
inline

Carries a value per parent to the components, as a statistic kept per hypothesis follows them through updates, merges, and prunes: children(i), one per component, becomes the mean of parents over component i's parents, weighted by its shares from them, so a component with one parent takes that parent's value and a merge takes the share-weighted mean of two; a component with no parent gets orphan.

parents has parentCount() values and children size(), both sized by the caller.

◆ count()

template<RealScalar Scalar_, typename Allocator_ = DefaultAllocator>
Index Emrys::MixtureLineage< Scalar_, Allocator_ >::count ( ) const
inlinenodiscard
Returns
the number of MixtureParams::startLineage() calls on the mixture since it was made, zero for a mixture with no lineage

◆ get_allocator()

template<RealScalar Scalar_, typename Allocator_ = DefaultAllocator>
allocator_type Emrys::MixtureLineage< Scalar_, Allocator_ >::get_allocator ( ) const
inlinenodiscard
Returns
the allocator the shares come from

◆ logShare()

template<RealScalar Scalar_, typename Allocator_ = DefaultAllocator>
Scalar Emrys::MixtureLineage< Scalar_, Allocator_ >::logShare ( Index i,
Index parent ) const
inlinenodiscard
Returns
component i's log-share from parent parent

◆ logShares()

template<RealScalar Scalar_, typename Allocator_ = DefaultAllocator>
std::span< Scalar const > Emrys::MixtureLineage< Scalar_, Allocator_ >::logShares ( Index i) const
inlinenodiscard
Returns
component i's log-share from each parent, \( -\infty \) for none

◆ parentCount()

template<RealScalar Scalar_, typename Allocator_ = DefaultAllocator>
Index Emrys::MixtureLineage< Scalar_, Allocator_ >::parentCount ( ) const
inlinenodiscard
Returns
the number of components the mixture had at its last startLineage(), the parents

◆ size()

template<RealScalar Scalar_, typename Allocator_ = DefaultAllocator>
Index Emrys::MixtureLineage< Scalar_, Allocator_ >::size ( ) const
inlinenodiscard
Returns
the number of components with a row: the mixture's size(), or zero with no lineage

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