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

Reduction policy that rejects branches by a chi-squared test on their normalized innovation squared, then reduces the rest with Inner. More...

#include <EmrysFilter/Models/Reduction.h>

Public Types

using Scalar = Scalar_
 The type of the probability or threshold it holds.

Public Member Functions

 Gate (Scalar probability, Inner inner={})
 Passes branches whose NIS is within the probability chi-squared quantile.
 Gate (NisThreshold< Scalar > threshold, Inner inner={})
 Passes branches whose NIS is at most threshold.
template<RealScalar Result = Scalar>
Result threshold (Eigen::Index dimension) const
Inner const & inner () const
template<typename Branches, typename Out>
requires internal::BranchRange<Branches> && internal::ReducesInto<Inner, Branches, Out> && internal::ReducesInto<Inner,
internal::PassingBranches<Branches>, Out>
void operator() (Branches &&branches, Out &out) const
 Reduces the branches of branches that pass the gate into out by Inner, or adds nothing when none pass.

Static Public Attributes

static constexpr std::size_t InlinePassing = 32
 The most branches of a run-time number whose passing indices a gate holds on the stack.

Detailed Description

template<typename Inner = Collapse, RealScalar Scalar_ = double>
class Emrys::reductions::Gate< Inner, Scalar_ >

Reduction policy that rejects branches by a chi-squared test on their normalized innovation squared, then reduces the rest with Inner.

A branch passes when its NIS (see UpdateBranch) is at most the threshold: the probability quantile of the chi-squared distribution with the innovation's dimension as its degrees of freedom, or a NisThreshold given directly. The passing branches, with their weights as they were, go to Inner (Collapse by default), and what Inner keeps stands for them alone: a filter of several components, modes, or points weights it by the passing branches' likelihood, \( \sum_{k \text{ passes}} w_k \, p(z \mid k) \), not the whole update's (see ReductionPolicy). When none pass, the measurement is rejected and the state keeps its prior.

This is an absolute test of each branch against its own innovation covariance, and needs no outlier model. It composes with mixture noise, which compares branches with each other: reductions::gate(0.997, reductions::select()) gates each noise component, then keeps the most probable.

The validation gate of Bar-Shalom, Li, and Kirubarajan (2001), as given in Bar-Shalom and Tse (1975), ยง4, equations (4.3) to (4.5), applied to an update's branches.

Scalar_ is the type of the probability or threshold it holds, deduced from the one given (reductions::gate(0.997f) holds a float). The quantile is computed in the update's scalar, so a float filter's gate does no double arithmetic, and one given a float holds no double either.

A gate given a probability computes its quantile on every update, an iteration that costs many times a small Kalman update, and the gate keeps no result between calls. Where the innovation's dimension is known and the filter runs at a high rate, compute the threshold once and give it as a NisThreshold, which costs a comparison per branch:

auto const tested = filter.update(fix(z), gate);
Scalar chiSquaredQuantile(std::type_identity_t< Scalar > const &probability, std::type_identity_t< Scalar > const &dof)
Definition ChiSquared.h:148
Gate< Inner, internal::DeducedScalar< Value > > gate(Value probability, Inner inner={})
Definition Reduction.h:582
A Gate's threshold given directly as a normalized innovation squared, rather than as a probability,...
Definition Reduction.h:386
See also
Collapse, Select, chiSquaredQuantile()

Member Function Documentation

◆ inner()

template<typename Inner = Collapse, RealScalar Scalar_ = double>
Inner const & Emrys::reductions::Gate< Inner, Scalar_ >::inner ( ) const
inlinenodiscard
Returns
the reduction policy for the branches that pass

◆ operator()()

template<typename Inner = Collapse, RealScalar Scalar_ = double>
template<typename Branches, typename Out>
requires internal::BranchRange<Branches> && internal::ReducesInto<Inner, Branches, Out> && internal::ReducesInto<Inner,
internal::PassingBranches<Branches>, Out>
void Emrys::reductions::Gate< Inner, Scalar_ >::operator() ( Branches && branches,
Out & out ) const
inline

Reduces the branches of branches that pass the gate into out by Inner, or adds nothing when none pass.

When some but not all pass, Inner reads them through their indices, held in an array on the stack for an array of branches or a run-time number of up to InlinePassing, and otherwise in a buffer from the branches' allocator, the one case that allocates; posteriors are moved out of branches given as an rvalue.

◆ threshold()

template<typename Inner = Collapse, RealScalar Scalar_ = double>
template<RealScalar Result = Scalar>
Result Emrys::reductions::Gate< Inner, Scalar_ >::threshold ( Eigen::Index dimension) const
inlinenodiscard
Returns
the NIS threshold for an innovation with dimension coordinates, computed in Result: the gate's own scalar unless named, and the update's when operator() asks

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