EmrysFilter 0.1.0
State estimation utilities in C++23 using Eigen
Loading...
Searching...
No Matches
Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ > Class Template Reference

A mixture filter: a Mixture state, a process model, and the method that predicts through it, each component run by the recursion its type names, or by the one given. More...

#include <EmrysFilter/Filters/MixtureFilter.h>

Inheritance diagram for Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >:
Emrys::GaussianMixtureFilter< Space_, Model_, Method_, Scalar_, Allocator_, Upkeep_ >

Public Types

using Scalar = typename Params<Component_>::Scalar
 the scalar type
using SpaceType = typename Params<Component_>::SpaceType
 the state space
using ModelType = Model_
 the process model
using MethodType = Method_
 the prediction method
using StateType = MixtureParams<Component_, Allocator_>
 the state the filter owns
using ComponentType = Params<Component_>
 one component of the state
using allocator_type = Allocator_
 the state's allocator
using RecursionType = Recursion_
 the steps each component runs (see Recursion)
using JointType = GaussianMixturePredictedJoint<SpaceType, Scalar, Allocator_>
 what predictJoint() returns, for Gaussian components
template<Measurement M>
using ResultType
 What update() with M fills when given a result: one component's update per component, each with the filter's allocator for what in it is sized by a run-time count.
template<Measurement M>
using UpdateType = std::expected<ResultType<M>, NumericError>
 What update() with M returns: the ResultType in a std::expected (decisions.md [innovation-cholesky]).

Public Member Functions

 MixtureFilter (Model_ model, StateType state, MethodFor< Model_, Method_ > method={}, std::type_identity_t< Upkeep_ > upkeep={})
 A filter with process model model, initial state state, prediction method method, which a fixed-step model carries instead, and upkeep upkeep, which maintain() runs.
 MixtureFilter (Model_ model, StateType state, std::type_identity_t< Upkeep_ > upkeep)
 A filter with process model model, initial state state, the default prediction method, and upkeep upkeep, which maintain() runs.
 MixtureFilter (Recursion_ recursion, StateType state, std::type_identity_t< Upkeep_ > upkeep={})
 A filter that runs recursion, the library's or one of the user's own (see Recursion), on each component of the initial state state, which must have at least one, with upkeep upkeep, which maintain() runs.
allocator_type get_allocator () const
StateType const & state () const
StateType & state ()
void setState (StateType state)
 Replaces the state estimate, as when reinitializing, with one that has at least one component and whose space the process model's writes partition, as the constructor's must.
RecursionType const & recursion () const
Model_ const & model () const
Model_ & model ()
Method_ const & method () const
template<typename... Inputs>
requires (!isFixedStep<Model_>)
auto predict (TimeStep< Scalar > auto const &dt, Inputs const &... inputs)
 Moves each component forward by dt, any TimeStep (see Time steps), through the process model, with inputs passed to its blocks as in Emrys::predict().
template<ExecutionPolicy P, typename... Inputs>
requires (!isFixedStep<Model_>)
auto predict (P &&policy, TimeStep< Scalar > auto const &dt, Inputs const &... inputs)
 predict(dt, inputs...) under policy, a for-each over the components, so the result is Sequential's (see Execution policies).
template<typename... Inputs>
requires (isFixedStep<Model_> && !internal::leadsWithPolicy<Inputs...> && !internal::leadsWithSteps<Inputs...>)
auto predict (Inputs const &... inputs)
 Moves each component forward by the fixed-step model's step, with inputs passed as in Emrys::predict().
template<ExecutionPolicy P, typename... Inputs>
requires (isFixedStep<Model_> && !internal::leadsWithSteps<Inputs...>)
auto predict (P &&policy, Inputs const &... inputs)
 predict(inputs...) under policy, as predict(policy, dt, inputs...) runs.
template<typename... Inputs>
requires isFixedStep<Model_>
auto predict (Steps steps, Inputs const &... inputs)
 Moves each component forward by steps of the fixed-step model, as that many calls of predict(inputs...) do, with inputs at every step, returning as predict(inputs...) does.
template<ExecutionPolicy P, typename... Inputs>
requires isFixedStep<Model_>
auto predict (P &&policy, Steps steps, Inputs const &... inputs)
 predict(steps, inputs...) under policy, as that many calls of predict(policy, inputs...) run, stopping at the first that reports an error.
template<typename... Inputs>
requires (!isFixedStep<Model_> && isGaussian<ComponentType>)
JointType predictJoint (TimeStep< Scalar > auto const &dt, Inputs const &... inputs)
 Moves each Gaussian component forward as predict(dt, inputs...) does, and starts the state's lineage over (MixtureParams::startLineage()).
template<typename JointAllocator, typename... Inputs>
requires (!isFixedStep<Model_> && isGaussian<ComponentType>)
void predictJoint (TimeStep< Scalar > auto const &dt, GaussianMixturePredictedJoint< SpaceType, Scalar, JointAllocator > &joint, Inputs const &... inputs)
 As predictJoint(dt, inputs...), but into joint, whose storage is reused: with the same joint at every step, recording allocates nothing once it has been as large.
template<ExecutionPolicy P, typename JointAllocator, typename... Inputs>
requires (!isFixedStep<Model_> && isGaussian<ComponentType>)
void predictJoint (P &&policy, TimeStep< Scalar > auto const &dt, GaussianMixturePredictedJoint< SpaceType, Scalar, JointAllocator > &joint, Inputs const &... inputs)
 predictJoint(dt, joint, inputs...) under policy, a for-each over the components into the joint's slots, so the joint and the state are Sequential's (see Execution policies).
template<typename... Inputs>
requires ( isFixedStep<Model_> && isGaussian<ComponentType> && !internal::leadsWithPolicy<Inputs...> && !internal::leadsWithSteps
<Inputs...> )
JointType predictJoint (Inputs const &... inputs)
 Moves each Gaussian component forward as predict(inputs...) does with a fixed-step model, and starts the state's lineage over.
template<typename JointAllocator, typename... Inputs>
requires (isFixedStep<Model_> && isGaussian<ComponentType>)
void predictJoint (GaussianMixturePredictedJoint< SpaceType, Scalar, JointAllocator > &joint, Inputs const &... inputs)
 As predictJoint(inputs...), but into joint, whose storage is reused.
template<ExecutionPolicy P, typename JointAllocator, typename... Inputs>
requires (isFixedStep<Model_> && isGaussian<ComponentType>)
void predictJoint (P &&policy, GaussianMixturePredictedJoint< SpaceType, Scalar, JointAllocator > &joint, Inputs const &... inputs)
 predictJoint(joint, inputs...) under policy, as predictJoint(policy, dt, joint, inputs...) runs.
template<Measurement M, typename Policy = reductions::Collapse>
requires ( !isGaussian<ComponentType> || MixtureReductionPolicy<Policy, internal::MeasuredUpdate<ComponentType, M>, Component_> )
UpdateType< M > update (M const &measurement, Policy const &policy={})
 Conditions each component on measurement, by the measurement's own method, reduces its branches with policy, a MixtureReductionPolicy over the component (Collapse, Select, Keep, or a Gate), and multiplies the weight of what the policy keeps by \( p(z \mid i) \) times its share among the branches: for a Gate the passing branches' share, so that a branch the gate fails counts as impossible.
template<ExecutionPolicy P, Measurement M, typename Policy = reductions::Collapse>
requires ( !isGaussian<ComponentType> || MixtureReductionPolicy<Policy, internal::MeasuredUpdate<ComponentType, M>, Component_> )
UpdateType< M > update (P &&executionPolicy, M const &measurement, Policy const &policy={})
 update(measurement, policy) under executionPolicy: each component's update is a for-each into slots made first, and the reweighting, the evidence, and the posterior then follow in order, so the result is Sequential's (see Execution policies).
template<Measurement M, typename Policy, typename ResultAllocator>
requires ( !isGaussian<ComponentType> || MixtureReductionPolicy<Policy, internal::MeasuredUpdate<ComponentType, M>, Component_> )
std::expected< void, NumericError > update (M const &measurement, Policy const &policy, MixtureFilterUpdate< typename ResultType< M >::ComponentUpdateType, Scalar, ResultAllocator > &result)
 As update(measurement, policy), but into result, whose storage is reused: with the same result at every step, an update allocates nothing once it has been as large.
template<ExecutionPolicy P, Measurement M, typename Policy, typename ResultAllocator>
requires ( !isGaussian<ComponentType> || MixtureReductionPolicy<Policy, internal::MeasuredUpdate<ComponentType, M>, Component_> )
std::expected< void, NumericError > update (P &&executionPolicy, M const &measurement, Policy const &policy, MixtureFilterUpdate< typename ResultType< M >::ComponentUpdateType, Scalar, ResultAllocator > &result)
 update(measurement, policy, result) under executionPolicy, as update(executionPolicy, measurement, policy) runs.

Detailed Description

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, RecursionOver< Component_ > Recursion_ = internal::RecursionForType<Component_, Model_, Method_, Allocator_>, typename Upkeep_ = upkeep::None>
requires std::same_as<typename Recursion_::ModelType, Model_> && std::same_as<typename Recursion_::MethodType, Method_>
class Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >

A mixture filter: a Mixture state, a process model, and the method that predicts through it, each component run by the recursion its type names, or by the one given.

Each component is predicted and updated as a filter over one of it would be, and an update multiplies each component's weight by the observation's likelihood under it, \( p(z \mid i) \). With Gaussian components (GaussianMixtureFilter) each is a KalmanFilter's step, and a mixture can carry a multimodal state, such as an ambiguity that later measurements resolve, or many narrow components that follow a nonlinear model more closely than one wide one, as uniformComponents() gives over a box where only the box is known (UniformMixture.h). With hybrid components (a Mixture of HybridGaussian) each is an ImmFilter's step, mixed through its switching model and updated per mode, and reweighted by the IMM's likelihood \( \log \sum_m \mu_m \, p(z \mid m) \): a mixture of IMM filters (decisions.md [filters-and-recursions]).

The Gaussian sum filter of Alspach and Sorenson (1972), with the component reduction left to the caller (Upkeep); with hybrid components, its components are mode-matched as the Gaussian mixture filter for jump Markov systems of Pasha, Vo, Tuan, and Ma (2009) carries each target's.

The policy reduces each component's branches, one per measurement-noise component. Collapse (the default), Select, and Gate keep one component per component, so the mixture keeps its size; Keep, for Gaussian components, keeps every branch, so with mixture noise the number of components grows by that factor with each update. Reduce the mixture between steps through state(): pruneBelow(), pruneTail(), pruneToSize(), merge(), or fitMixture(). With Gaussian components, predictJoint() records each step for a GaussianMixtureHistory to smooth, and the state's lineage (MixtureParams::lineage()) follows the components through the updates and reductions between (decisions.md [smoothing]).

Keep gains over Collapse when the components disagree for longer than one update, as about a multimodal state or an outlier too near to tell from an inlier at once. When each fix is plainly one or the other, every component's branches agree on it and Collapse loses little. kullbackLeiblerCollapseBounds() of the state's density says whether its moments describe it (see Divergences), and of a component's branches whether collapsing them would lose much, so a policy of the user's own can keep the branches only where they disagree. A Gate commits: a component it drops is gone, where mixture noise without a gate would only lower its weight, so a bad fix that another component happens to explain removes the right one.

Which single estimate to read from the mixture depends on the question. The moments of the state's density, state().toDensity()->moments(), are the minimum mean-squared-error estimate, and can sit between the modes, where no component is. The most probable component, state()[state().mostProbable()].component, is the estimate a display shows of a multimodal state.

A component whose update the recursion rejects, as a Gate does when no branch passes, is dropped. When every component is rejected, the measurement is rejected and the state keeps its prior, so with one component the filter behaves as the filter over that component. A component whose update fails, as one whose innovation covariance is not positive definite does, fails the whole update, which returns the error. The components are updated in place, so those before the failed one stay updated, with the weights as they were; nothing is copied to undo a failure (decisions.md [innovation-cholesky]). A policy that keeps several branches builds the posterior apart, and its failure leaves the state as it was.

filter.predict(dt);
auto const updated = filter.update(fix); // each component updated and reweighted
auto const kept = filter.update(robustFix, reductions::keep()); // an inlier and an outlier branch per component
auto const pruned = filter.state().pruneToSize(16); // the 16 heaviest components kept
auto bank = MixtureFilter{switchingModel<Maneuver>(chain, cruise, turn), hybrids}; // a mixture of IMMs
bank.predict(dt);
auto const robust = bank.update(robustFix); // noise byMode<Sensor>(): each IMM's Markov outlier axis
The MixtureFilter over a GaussianMixtureParams, the spelling for the common case (decisions....
Definition MixtureFilter.h:1336
auto predict(TimeStep< Scalar > auto const &dt, Inputs const &... inputs)
Moves each component forward by dt, any TimeStep (see Time steps), through the process model,...
Definition MixtureFilter.h:429
MixtureFilter(Model_ model, StateType state, MethodFor< Model_, Method_ > method={}, std::type_identity_t< Upkeep_ > upkeep={})
A filter with process model model, initial state state, prediction method method, which a fixed-step ...
Definition MixtureFilter.h:302
constexpr Keep keep()
Definition Reduction.h:371
Kinematic< Scalar, Position, Velocity > ConstantVelocity
Constant velocity (white-noise acceleration): position moves by velocity times .
Definition ProcessModel.h:1152
SwitchingModel< ModeSpace, Scalar, P, Models... > switchingModel(MarkovChain< ModeSpace, Scalar > chain, Models... models)
Definition SwitchingModel.h:510

The recursion updates the state's components in place. A policy that keeps several branches builds the posterior in a second mixture from the state's allocator, with the state's capacity, exchanged with the state. An update allocates nothing once the mixture has been as large. update(measurement, policy, result) also reuses the result's storage (see Allocation). A recursion with scratch, the IMM's, runs the components in order, so a policy other than Sequential is a compile-time error with hybrid components.

A recursion of the user's own, one that meets Recursion over the component, runs on each component in place of the one the component names: MixtureFilter{recursion, mixture} deduces it as the last argument (decisions.md [user-extension-points]).

Template Parameters
Component_the components' type (see Component): a Gaussian over the state space (see Spaces), or a Hybrid of them
Model_the process model, a ProcessModel or a FixedStepModel, which partition the space, or a SwitchingModel for hybrid components; with a FixedStepModel, predict() takes no time step
Method_the prediction method; a FixedStepModel's own
Allocator_the state's allocator (see Allocation)
Recursion_the recursion each component's steps run (see Recursion): the one the component names unless given one
Upkeep_the upkeep maintain() runs on the state (see Upkeep), upkeep::None unless given one
See also
KalmanFilter, ImmFilter, Recursion, Filters

Member Typedef Documentation

◆ ResultType

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, RecursionOver< Component_ > Recursion_ = internal::RecursionForType<Component_, Model_, Method_, Allocator_>, typename Upkeep_ = upkeep::None>
template<Measurement M>
using Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >::ResultType
Initial value:
internal::RebindUpdateAllocator<typename RecursionType::template UpdateType<M>::value_type, Allocator_>,
Allocator_>
typename Params< Component_ >::Scalar Scalar
the scalar type
Definition ImmFilter.h:326
What a mixture filter's update did: each prior component's update before reduction,...
Definition MixtureFilter.h:71

What update() with M fills when given a result: one component's update per component, each with the filter's allocator for what in it is sized by a run-time count.

Constructor & Destructor Documentation

◆ MixtureFilter() [1/2]

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, RecursionOver< Component_ > Recursion_ = internal::RecursionForType<Component_, Model_, Method_, Allocator_>, typename Upkeep_ = upkeep::None>
Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >::MixtureFilter ( Model_ model,
StateType state,
MethodFor< Model_, Method_ > method = {},
std::type_identity_t< Upkeep_ > upkeep = {} )
inline

A filter with process model model, initial state state, prediction method method, which a fixed-step model carries instead, and upkeep upkeep, which maintain() runs.

state must have at least one component.

◆ MixtureFilter() [2/2]

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, RecursionOver< Component_ > Recursion_ = internal::RecursionForType<Component_, Model_, Method_, Allocator_>, typename Upkeep_ = upkeep::None>
Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >::MixtureFilter ( Recursion_ recursion,
StateType state,
std::type_identity_t< Upkeep_ > upkeep = {} )
inline

A filter that runs recursion, the library's or one of the user's own (see Recursion), on each component of the initial state state, which must have at least one, with upkeep upkeep, which maintain() runs.

A recursion with scratch, as the IMM's, must have been given the components' allocator.

Member Function Documentation

◆ get_allocator()

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, RecursionOver< Component_ > Recursion_ = internal::RecursionForType<Component_, Model_, Method_, Allocator_>, typename Upkeep_ = upkeep::None>
allocator_type Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >::get_allocator ( ) const
inlinenodiscard
Returns
the allocator of the state and its posterior

◆ method()

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, RecursionOver< Component_ > Recursion_ = internal::RecursionForType<Component_, Model_, Method_, Allocator_>, typename Upkeep_ = upkeep::None>
Method_ const & Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >::method ( ) const
inlinenodiscard
Returns
the prediction method

◆ model() [1/2]

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, RecursionOver< Component_ > Recursion_ = internal::RecursionForType<Component_, Model_, Method_, Allocator_>, typename Upkeep_ = upkeep::None>
Model_ & Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >::model ( )
inlinenodiscard
Returns
the process model, to change its parameters

◆ model() [2/2]

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, RecursionOver< Component_ > Recursion_ = internal::RecursionForType<Component_, Model_, Method_, Allocator_>, typename Upkeep_ = upkeep::None>
Model_ const & Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >::model ( ) const
inlinenodiscard
Returns
the process model

◆ predict() [1/3]

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, RecursionOver< Component_ > Recursion_ = internal::RecursionForType<Component_, Model_, Method_, Allocator_>, typename Upkeep_ = upkeep::None>
template<typename... Inputs>
requires (isFixedStep<Model_> && !internal::leadsWithPolicy<Inputs...> && !internal::leadsWithSteps<Inputs...>)
auto Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >::predict ( Inputs const &... inputs)
inlinenodiscard

Moves each component forward by the fixed-step model's step, with inputs passed as in Emrys::predict().

The weights are unchanged.

◆ predict() [2/3]

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, RecursionOver< Component_ > Recursion_ = internal::RecursionForType<Component_, Model_, Method_, Allocator_>, typename Upkeep_ = upkeep::None>
template<ExecutionPolicy P, typename... Inputs>
requires (!isFixedStep<Model_>)
auto Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >::predict ( P && policy,
TimeStep< Scalar > auto const & dt,
Inputs const &... inputs )
inlinenodiscard

predict(dt, inputs...) under policy, a for-each over the components, so the result is Sequential's (see Execution policies).

A mixture of a few components is best left Sequential, and a recursion with scratch, the IMM's, takes nothing else.

◆ predict() [3/3]

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, RecursionOver< Component_ > Recursion_ = internal::RecursionForType<Component_, Model_, Method_, Allocator_>, typename Upkeep_ = upkeep::None>
template<typename... Inputs>
requires (!isFixedStep<Model_>)
auto Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >::predict ( TimeStep< Scalar > auto const & dt,
Inputs const &... inputs )
inlinenodiscard

Moves each component forward by dt, any TimeStep (see Time steps), through the process model, with inputs passed to its blocks as in Emrys::predict().

The weights are unchanged.

Returns
nothing for Gaussians and their hybrids; for square-root forms and their hybrids, a std::expected that is empty when a component could not take the step, as its recursion's predict() reports, a component that could not take it keeps its prior while the others move (decisions.md [gaussian-forms])

◆ predictJoint() [1/2]

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, RecursionOver< Component_ > Recursion_ = internal::RecursionForType<Component_, Model_, Method_, Allocator_>, typename Upkeep_ = upkeep::None>
template<typename... Inputs>
requires ( isFixedStep<Model_> && isGaussian<ComponentType> && !internal::leadsWithPolicy<Inputs...> && !internal::leadsWithSteps
<Inputs...> )
JointType Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >::predictJoint ( Inputs const &... inputs)
inlinenodiscard

Moves each Gaussian component forward as predict(inputs...) does with a fixed-step model, and starts the state's lineage over.

Returns
the step as a GaussianMixturePredictedJoint, as predictJoint(dt, inputs...) does

◆ predictJoint() [2/2]

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, RecursionOver< Component_ > Recursion_ = internal::RecursionForType<Component_, Model_, Method_, Allocator_>, typename Upkeep_ = upkeep::None>
template<typename... Inputs>
requires (!isFixedStep<Model_> && isGaussian<ComponentType>)
JointType Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >::predictJoint ( TimeStep< Scalar > auto const & dt,
Inputs const &... inputs )
inlinenodiscard

Moves each Gaussian component forward as predict(dt, inputs...) does, and starts the state's lineage over (MixtureParams::startLineage()).

Returns
the step as a GaussianMixturePredictedJoint, from the state's allocator, for a GaussianMixtureHistory to record: the weights, each component's PredictedJoint, and the state's lineage before the step

◆ recursion()

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, RecursionOver< Component_ > Recursion_ = internal::RecursionForType<Component_, Model_, Method_, Allocator_>, typename Upkeep_ = upkeep::None>
RecursionType const & Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >::recursion ( ) const
inlinenodiscard
Returns
the recursion: the model, method, and any scratch the components' steps run with

◆ setState()

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, RecursionOver< Component_ > Recursion_ = internal::RecursionForType<Component_, Model_, Method_, Allocator_>, typename Upkeep_ = upkeep::None>
void Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >::setState ( StateType state)
inline

Replaces the state estimate, as when reinitializing, with one that has at least one component and whose space the process model's writes partition, as the constructor's must.

The scratch follows the new state's space, allocator, and capacity. A recursion with scratch is given the new components' allocator through its resetScratch(), as the IMM's is; one without that member must have it already.

◆ state() [1/2]

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, RecursionOver< Component_ > Recursion_ = internal::RecursionForType<Component_, Model_, Method_, Allocator_>, typename Upkeep_ = upkeep::None>
StateType & Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >::state ( )
inlinenodiscard
Returns
the current state estimate, to change where it is between steps: to reduce it with pruneBelow(), pruneTail(), pruneToSize(), or merge(), or to assign it a mixture in the same space, as fitMixture()'s. It must keep its space, its allocator, and at least one component; setState() replaces it with another, and checks it.

◆ state() [2/2]

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, RecursionOver< Component_ > Recursion_ = internal::RecursionForType<Component_, Model_, Method_, Allocator_>, typename Upkeep_ = upkeep::None>
StateType const & Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >::state ( ) const
inlinenodiscard
Returns
the current state estimate

◆ update() [1/3]

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, RecursionOver< Component_ > Recursion_ = internal::RecursionForType<Component_, Model_, Method_, Allocator_>, typename Upkeep_ = upkeep::None>
template<Measurement M, typename Policy, typename ResultAllocator>
requires ( !isGaussian<ComponentType> || MixtureReductionPolicy<Policy, internal::MeasuredUpdate<ComponentType, M>, Component_> )
std::expected< void, NumericError > Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >::update ( M const & measurement,
Policy const & policy,
MixtureFilterUpdate< typename ResultType< M >::ComponentUpdateType, Scalar, ResultAllocator > & result )
inlinenodiscard

As update(measurement, policy), but into result, whose storage is reused: with the same result at every step, an update allocates nothing once it has been as large.

Returns
nothing, or the error update(measurement, policy) would return, with the state unchanged and result unspecified

◆ update() [2/3]

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, RecursionOver< Component_ > Recursion_ = internal::RecursionForType<Component_, Model_, Method_, Allocator_>, typename Upkeep_ = upkeep::None>
template<Measurement M, typename Policy = reductions::Collapse>
requires ( !isGaussian<ComponentType> || MixtureReductionPolicy<Policy, internal::MeasuredUpdate<ComponentType, M>, Component_> )
UpdateType< M > Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >::update ( M const & measurement,
Policy const & policy = {} )
inlinenodiscard

Conditions each component on measurement, by the measurement's own method, reduces its branches with policy, a MixtureReductionPolicy over the component (Collapse, Select, Keep, or a Gate), and multiplies the weight of what the policy keeps by \( p(z \mid i) \) times its share among the branches: for a Gate the passing branches' share, so that a branch the gate fails counts as impossible.

The weights are then normalized, and the observation's log-likelihood counts every branch. Components the recursion rejects are dropped; if it rejects them all, the state is unchanged.

Returns
each component's update before reduction, the observation's log-likelihood under the mixture, and whether the measurement was accepted (see MixtureFilterUpdate), with the components from the state's allocator; or the WeightError of prior weights that cannot be normalized, with the state unchanged; or, if any component's update failed, as one whose innovation covariance is not positive definite does, its error, with the components before it updated and the weights as they were (see the class comment, and decisions.md [innovation-cholesky], [update-outcomes])

◆ update() [3/3]

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, RecursionOver< Component_ > Recursion_ = internal::RecursionForType<Component_, Model_, Method_, Allocator_>, typename Upkeep_ = upkeep::None>
template<ExecutionPolicy P, Measurement M, typename Policy = reductions::Collapse>
requires ( !isGaussian<ComponentType> || MixtureReductionPolicy<Policy, internal::MeasuredUpdate<ComponentType, M>, Component_> )
UpdateType< M > Emrys::MixtureFilter< Component_, Model_, Method_, Allocator_, Recursion_, Upkeep_ >::update ( P && executionPolicy,
M const & measurement,
Policy const & policy = {} )
inlinenodiscard

update(measurement, policy) under executionPolicy: each component's update is a for-each into slots made first, and the reweighting, the evidence, and the posterior then follow in order, so the result is Sequential's (see Execution policies).

The slots allocate.


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