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

The autonomous multiple model (AMM) estimator: a bank of filters, one per mode, each running on its own, and the probability that each mode is the one in force, by Bayes' rule over their measurement likelihoods. More...

#include <EmrysFilter/Filters/AmmFilter.h>

Inheritance diagram for Emrys::AmmFilter< Component_, Model_, Method_, Allocator_, Upkeep_ >:
Emrys::ImmFilter< Component_, Model_, Method_, Allocator_, Upkeep_ >

Public Types

using Base = ImmFilter<Component_, Model_, Method_, Allocator_, Upkeep_>
 the filter this is
Public Types inherited from Emrys::ImmFilter< Component_, Model_, Method_, Allocator_, Upkeep_ >
using RecursionType = ImmRecursion<Component_, Model_, Method_, Allocator_>
 the steps it runs
using Scalar = typename RecursionType::Scalar
 the scalar type
using SpaceType = typename RecursionType::SpaceType
 the state space
using ModelType = Model_
 the process model
using MethodType = Method_
 the prediction method
using ModeSpaceType = typename RecursionType::ModeSpaceType
 the discrete mode space
using StateType = typename RecursionType::StateType
 the state the filter owns
using ComponentType = Params<Component_>
 one component of the state
using allocator_type = Allocator_
 the state's allocator
using JointType = typename RecursionType::JointType
 what predictJoint() returns

Public Member Functions

template<typename... Models>
requires std::constructible_from<Model_, typename Model_::ChainType, Models...>
 AmmFilter (typename Base::StateType state, Models... models)
 A filter with initial state state whose modes follow models, one per mode in flat-index order or one shared by every mode, each predicting by its models' default method.
template<typename... Models>
requires (!isFixedStep<Model_> && std::constructible_from<Model_, typename Model_::ChainType, Models...>)
 AmmFilter (Method_ method, typename Base::StateType state, Models... models)
 As AmmFilter(state, models...), predicting by method.
template<typename... Models>
requires ( !std::same_as<Upkeep_, Emrys::upkeep::None> && std::constructible_from<Model_, typename Model_::ChainType, Models...> )
 AmmFilter (std::type_identity_t< Upkeep_ > upkeep, typename Base::StateType state, Models... models)
 As AmmFilter(state, models...), with upkeep upkeep, which maintain() runs.
template<typename... Models>
requires ( !isFixedStep<Model_> && !std::same_as<Upkeep_, Emrys::upkeep::None> && std::constructible_from<Model_, typename
Model_::ChainType, Models...> )
 AmmFilter (Method_ method, std::type_identity_t< Upkeep_ > upkeep, typename Base::StateType state, Models... models)
 As AmmFilter(method, state, models...), with upkeep upkeep, which maintain() runs.
Public Member Functions inherited from Emrys::ImmFilter< Component_, Model_, Method_, Allocator_, Upkeep_ >
 ImmFilter (Model_ model, StateType state, MethodFor< Model_, Method_ > method={}, std::type_identity_t< Upkeep_ > upkeep={})
 A filter with switching model model, initial state state, prediction method method, and upkeep upkeep, which maintain() runs.
 ImmFilter (Model_ model, StateType state, std::type_identity_t< Upkeep_ > upkeep)
 A filter with switching model model, initial state state, the default prediction method, and upkeep upkeep, which maintain() runs.
allocator_type get_allocator () const
StateType const & state () const
StateType & state ()
void setState (StateType state)
 Replaces the state, as when reinitializing, with one that has the model's modes and whose space every 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)
 Mixes the modes' components through the chain, moves each by dt, any TimeStep (see Time steps), through its mode's process model, with inputs passed as in Emrys::predict(), and moves the mode probabilities one step of the chain.
template<typename... Inputs>
requires (isFixedStep<Model_> && !internal::leadsWithSteps<Inputs...>)
auto predict (Inputs const &... inputs)
 Mixes the modes' components through the chain, moves each by its mode's fixed-step model's step, by that model's method, with inputs passed as in Emrys::predict(), and moves the mode probabilities one step of the chain, returning as predict(dt, inputs...) does.
template<typename... Inputs>
requires isFixedStep<Model_>
auto predict (Steps steps, Inputs const &... inputs)
 Moves the state forward by steps of the fixed-step models, as that many calls of predict(inputs...) do, with inputs at every step: the chain takes a step each time.
template<typename... Inputs>
requires (!isFixedStep<Model_>)
JointType predictJoint (TimeStep< Scalar > auto const &dt, Inputs const &... inputs)
 Moves the state forward as predict(dt, inputs...) does.
template<typename JointAllocator, typename... Inputs>
requires (!isFixedStep<Model_>)
void predictJoint (TimeStep< Scalar > auto const &dt, HybridPredictedJoint< SpaceType, ModeSpaceType, 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 filled.
template<typename... Inputs>
requires (isFixedStep<Model_> && !internal::leadsWithSteps<Inputs...>)
JointType predictJoint (Inputs const &... inputs)
 Moves the state forward as predict(inputs...) does with fixed-step models.
template<typename JointAllocator, typename... Inputs>
requires isFixedStep<Model_>
void predictJoint (HybridPredictedJoint< SpaceType, ModeSpaceType, Scalar, JointAllocator > &joint, Inputs const &... inputs)
 As predictJoint(inputs...), but into joint, whose storage is reused.
template<Measurement M, typename Policy = reductions::Collapse>
auto update (M const &measurement, Policy const &policy={})
 Conditions each mode's component on measurement, by the measurement's own method, reduces its branches with policy (Collapse, Select, or a Gate), and multiplies each mode's probability by \( p(z \mid m) \).
template<Measurement M, typename Policy, typename ModeUpdate, typename ResultAllocator>
std::expected< void, NumericError > update (M const &measurement, Policy const &policy, ImmFilterUpdate< ModeUpdate, 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<typename P, Measurement... Ms, typename Policy = reductions::Collapse>
auto update (SwitchingMeasurement< P, Ms... > const &measurement, Policy const &policy={})
 As update(measurement, policy), but with a measurement per value of the mode axis that measurement names (see SwitchingMeasurement): each mode is updated by the measurement that its value in that axis selects, and its own likelihood \( p(z \mid m) \) reweights it.
template<typename P, Measurement... Ms, typename Policy, typename ModeUpdate, typename ResultAllocator>
std::expected< void, NumericError > update (SwitchingMeasurement< P, Ms... > const &measurement, Policy const &policy, ImmFilterUpdate< ModeUpdate, Scalar, ResultAllocator > &result)
 As update(measurement, policy) with a SwitchingMeasurement, but into result, whose storage is reused.

Detailed Description

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, typename Upkeep_ = upkeep::None>
class Emrys::AmmFilter< Component_, Model_, Method_, Allocator_, Upkeep_ >

The autonomous multiple model (AMM) estimator: a bank of filters, one per mode, each running on its own, and the probability that each mode is the one in force, by Bayes' rule over their measurement likelihoods.

The mode is fixed for all time but unknown, so it is a parameter to identify rather than a state that switches: the ImmFilter with the identity chain, which this class builds from the state's modes and gives its base. The two are one algorithm, with \( \Pi = I \), so every IMM step works here unchanged. Mixing through the identity gives each mode its own component, and the IMM's predict() sees the identity and skips it: each mode's component moves through its own process model as a KalmanFilter's would, and the mode probabilities carry over. update() updates each component and multiplies each mode's probability by \( p(z \mid m) \). The combined estimate is the collapsed() of the state's density.

slow, fast}; // one process model per regime
filter.predict(dt);
auto const updated = filter.update(fix);
upkeep::floorModes(1e-3)(filter.state()); // keep every mode recoverable
filter.state().modes().toDensity()->probability<Fast>();
AmmFilter(typename Base::StateType state, Models... models)
A filter with initial state state whose modes follow models, one per mode in flat-index order or one ...
Definition AmmFilter.h:97
The parameters of a probability distribution over a discrete space: one weight per value.
Definition Categorical.h:257
HybridParams< Gaussian< Space_, Scalar_ >, ModeSpace_, Allocator_ > HybridGaussianParams
The HybridParams of Gaussians in covariance form: the parameters of a HybridGaussian,...
Definition Hybrid.h:754
constexpr FloorModes< internal::DeducedScalar< Value > > floorModes(Value probability)
Definition Upkeep.h:1262

The models are a pack, so the filter's upkeep comes before the state, after the method if one is given, and maintain() runs it:

initial}, slow, fast}; auto const updated = floored.update(fix); (void)floored.maintain();

Its known failure is a mode probability that falls to zero, or so near it that no run of measurements brings it back: the estimator then cannot follow a mode that changes after all, nor recover from a mode that was wrongly ruled out. FloorModes, applied after each update, bounds the probabilities below. The chain stays the base's to change through model(); a chain that is no longer the identity makes the filter the IMM it is built on.

The multiple model estimator that Athans et al. (1977), §V.B–C, credit to Magill (1965): a Kalman filter per model and the probabilities of equation (5.5). Theirs are steady-state filters with constant innovation covariances; here each mode's component is a full filter's, so its likelihood is exact under the mode. Bar-Shalom, Li, andKirubarajan (2001) set it beside the IMM.

Template Parameters
Component_the component given one mode (see Component), a Gaussian over the state space (see Spaces)
Model_a SwitchingModel over the mode space, with the mode space as its own axis: one process model per mode, or one shared
Method_the prediction method of every mode whose model carries none of its own (see withMethod()); ModelsMethod with fixed-step models, which all carry one
Allocator_the state's allocator (see Allocation)
Upkeep_the upkeep maintain() runs on the state (see Upkeep), upkeep::None unless given one, such as FloorModes
See also
ImmFilter, FloorModes, Filters

Constructor & Destructor Documentation

◆ AmmFilter() [1/2]

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, typename Upkeep_ = upkeep::None>
template<typename... Models>
requires (!isFixedStep<Model_> && std::constructible_from<Model_, typename Model_::ChainType, Models...>)
Emrys::AmmFilter< Component_, Model_, Method_, Allocator_, Upkeep_ >::AmmFilter ( Method_ method,
typename Base::StateType state,
Models... models )
inline

As AmmFilter(state, models...), predicting by method.

The method comes first because the models are a pack; fixed-step models carry their own, so there is none to give.

◆ AmmFilter() [2/2]

template<Component Component_, typename Model_, typename Method_ = DefaultMethodFor<Model_>, typename Allocator_ = DefaultAllocator, typename Upkeep_ = upkeep::None>
template<typename... Models>
requires ( !std::same_as<Upkeep_, Emrys::upkeep::None> && std::constructible_from<Model_, typename Model_::ChainType, Models...> )
Emrys::AmmFilter< Component_, Model_, Method_, Allocator_, Upkeep_ >::AmmFilter ( std::type_identity_t< Upkeep_ > upkeep,
typename Base::StateType state,
Models... models )
inline

As AmmFilter(state, models...), with upkeep upkeep, which maintain() runs.

The upkeep comes before the state because the models are a pack.


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