EmrysFilter 0.1.0
State estimation utilities in C++23 using Eigen
Loading...
Searching...
No Matches
Emrys::Recursion Concept Reference

A recursion: a filter without its state, acting in place on a state passed in (decisions.md [filters-and-recursions]). More...

#include <EmrysFilter/Filters/Recursion.h>

Concept definition

template<typename R>
concept Recursion = RealScalar<typename R::Scalar> && Space<typename R::SpaceType> && requires(R const & recursion) {
typename R::StateType;
typename R::ModelType;
typename R::MethodType;
{ R::Reentrant } -> std::convertible_to<bool>;
{ recursion.model() } -> std::same_as<typename R::ModelType const &>;
{ recursion.method() } -> std::same_as<typename R::MethodType const &>;
}
A type usable as the scalar of a distribution: a real number type such as float, double,...
Definition Math.h:80
A recursion: a filter without its state, acting in place on a state passed in (decisions....
Definition Recursion.h:73
A type usable as the space of a distribution.
Definition Space.h:186

Detailed Description

A recursion: a filter without its state, acting in place on a state passed in (decisions.md [filters-and-recursions]).

A filter holds a state and a recursion: the process model, the prediction method, and any scratch its steps need. KalmanRecursion runs the Kalman filter's steps over one component and ImmRecursion the interacting multiple model's over a Hybrid; KalmanFilter and MixtureFilter take theirs as their last template parameter, defaulting to the one the component names, and deduce it from a recursion passed to the constructor, MixtureFilter{recursion, mixture}. So a recursion of the user's own, a method the library doesn't take (decisions.md [user-extension-points]), runs over one state or over each component of a mixture with nothing of the library's changed; usage.md, "Writing a recursion", shows one that wraps a KalmanRecursion.

The concept checks what it can without a measurement: the type members Scalar, a RealScalar; SpaceType, a Space; StateType, the parameters the steps act on (a KalmanFilter's or a mixture's component, Params of the filter's component); ModelType and MethodType, the filter's model and method; static constexpr bool Reentrant, whether steps on different states may run at once, which is false for a recursion with scratch, and which a MixtureFilter reads to refuse an execution policy other than Sequential; and model() and method(), returning the two by constant reference. The rest of the contract is what the filters call, each instantiated only where it is used:

  • predict(state, dt, inputs...), or predict(state, inputs...) for a fixed-step model (see FixedStepModel), moving state forward in place and returning nothing, or a std::expected<void, E> that is empty when the state could not take the step.
  • template <MeasurementModel M> using UpdateType, the std::expected<ResultType<M>, NumericError> (GaussianError and WeightError are its names) that update(state, measurement, policy) returns, and template <MeasurementModel M> using ResultType, its value: a type with a bool accepted and the observation's log-likelihood under the prior state as logLikelihood(), by which a mixture reweights the component, as every filter's result has them (decisions.md [update-outcomes]). An update that returns accepted false, because the policy rejected the measurement or the model gives it no density, has not written state, so that no filter copies its state to undo one; an update that returns an error leaves state valid. The policy is any callable the filter was given, wrapped so that its type is the filter's: run it on the branches by reduceToOne(), which returns the state it keeps, or nothing (see ReductionPolicy).
  • update(state, measurement, policy, result), the same update into a ResultType<M> whose storage is reused, returning std::expected<void, GaussianError>. A MixtureFilter keeps one result per component and refills them; a result constructible from the filter's allocator is made empty with it and filled this way, and any other is moved from update(state, measurement, policy) into its slot.
  • predictJoint(state, dt, inputs...), or without dt, returning the step as a PredictedJoint for a smoother's history, only where predictJoint() is called on the filter.

A MixtureFilter runs a Gaussian component's update through the measurement's branches rather than the recursion when the policy may keep several of them, adding them to the filter's output as Keep does, so a recursion over Gaussians decides the update only under a policy that returns the component it keeps, such as Collapse or Select, or a Gate over one.

See also
RecursionOver, KalmanRecursion, ImmRecursion, KalmanFilter, MixtureFilter