EmrysFilter 0.1.0
State estimation utilities in C++23 using Eigen
Loading...
Searching...
No Matches
Models

The fourth layer (decisions.md [layered-headers]): how a distribution moves through a function and what a filter is given to work with. More...

Topics

 Transforms
 transform() pushes independent uncertain inputs through a function \( y = f(x) \boxplus v \) and returns the distribution of \( y \) as a Gaussian (decisions.md [transform-policies]).

Namespaces

namespace  Emrys::jacobians
 The marks of the Jacobians a batched function writes beside its values (decisions.md [batched-functions], [policy-factories]): perColumn() and shared(), given as batched(f, mark).

Concepts

concept  Emrys::JacobianMark
 Whether T is a mark of the Jacobians a batched function writes, made by a factory in Emrys::jacobians (decisions.md [batched-functions]).
concept  Emrys::EmissionModel
 A measurement of a value in the discrete space Space: one log-likelihood per value.
concept  Emrys::MeasurementModel
 A measurement model: what measurementModel() returns, or a composition of such models (decisions.md [model-policies]).
concept  Emrys::Measurement
 A measurement: an observed value with its model and the call's inputs, and the method a Kalman update pushes the state through, as observe() makes it; what update() and every filter's update() take (decisions.md [templated-measurements]).
concept  Emrys::ProcessModel
 A process model: what processModel() returns, a built-in model, or a composition of process models (decisions.md [model-policies]).

Classes

struct  Emrys::jacobians::PerColumn
 The mark that a batched function writes one Jacobian per column, by block of its input: Y.jacobian<Name>(j), made by perColumn(). More...
struct  Emrys::jacobians::Shared
 The mark that a batched function writes one Jacobian for every column, by block of its input: Y.jacobian<Name>(), for a function linear in its input, made by shared(). More...
struct  Emrys::Batched< F, Mark >
 A function that takes every point at once, as batched() marks it (decisions.md [batched-functions]): it receives the points as the columns of a matrix X and writes into one output Y, a BatchedOutput the library provides, last. More...
class  Emrys::BatchedOutput< In, Out, Scalar_, Mark >
 The output of a batched function (decisions.md [batched-functions]): its values, a column per point, and the Jacobians the library uses, by block of the function's input, in storage the library provides and sizes once before the call. More...
class  Emrys::PosteriorCramerRaoBound< Space_, Scalar_ >
 The posterior Cramér-Rao bound along true trajectories: the Fisher information \( J_k \) of the state, whose inverse bounds the mean squared error of any estimator of \( x_k \). More...
struct  Emrys::CategoricalUpdate< Space, Scalar >
 The result of updating a CategoricalParams by an emission model: the posterior, whose weights sum to one, and the log-evidence of the measurement. More...
class  Emrys::EmissionTable< Space_, ObservationSpace_, Scalar_ >
 An emission table: the probability of each observed value given each value of the state. More...
class  Emrys::DensityEmission< Observation, DistributionOf >
 The emission model of an observation drawn from a distribution chosen by the value: the log-density of the observation under the value's distribution. More...
class  Emrys::PoissonEmission< Space, Scalar_ >
 The emission model of a count of events over an interval, from a Poisson process whose rate is a function of the value. More...
class  Emrys::ExponentialEmission< Space, Scalar_ >
 The emission model of the time from one event to the next, from a Poisson process whose rate is a function of the value. More...
class  Emrys::ArrivalInterval< Space, Scalar_ >
 The observation of a Markov-modulated Poisson process over an interval: no event inside it, and an event at its end unless it closes the record. More...
struct  Emrys::GivenBlock< Space, P, Value >
 A block of a state given from outside the Gaussian being updated, as given() makes it, for update(prior, measurement, given): the block named by the path P of a state in Space, given as Value. More...
struct  Emrys::CountFrom< Path, MeasurementSpace >
 The measurement space function of a model whose measurement has a block of MeasurementSpace per repetition of the state's block Path, given to outputSpace() (decisions.md [measurement-space-functions]). More...
class  Emrys::MeasurementFunction< F, Policies >
 A measurement model: a function \( h \) of its input, with the policies that say what it reads, what it writes, and what it is affine in, and its noise (decisions.md [model-policies]). More...
class  Emrys::Columns< Placed >
 The matrix \( H \) of a linear measurement model by its columns: a matrix per block of the state read, each placed by tag path with on() or onEach() (decisions.md [linear-sensors]). More...
class  Emrys::Observed< Method, Model, Observation, Args >
 An observation of a measurement model: the observed value, the model, the method that pushes the state through it, and the inputs of the call, as observe() makes it (decisions.md [templated-measurements], [method-per-measurement], [model-policies]). More...
struct  Emrys::UpdateBranch< Space, MeasurementSpace, Scalar >
 One outcome of an update: a posterior, how probable it is, and its innovation, from which the observation's likelihood under it and its NIS follow (decisions.md [innovation-statistics]). More...
struct  Emrys::MeasurementUpdate< Space, MeasurementSpace, Count, Scalar_, Allocator >
 The result of update(): weighted branches, one per noise component, and the observation's log-likelihood. More...
struct  Emrys::FilterBranch< MeasurementSpace, Scalar >
 One branch of a filter's update (see FilterUpdate): its weight, its innovation, and its labels, without the posterior, which the filter reduced into its state (decisions.md [innovation-statistics]). More...
struct  Emrys::FilterUpdate< MeasurementSpace, Count, Scalar_, Allocator >
 What a filter's update did: the branches of the update before reduction, with their weights and innovations but not their posteriors (decisions.md [innovation-statistics]), and whether the reduction policy accepted the measurement. More...
struct  Emrys::ReusableFilterUpdate< Space, MeasurementSpace, Scalar, Allocator >
 A FilterUpdate of a run-time number of branches that keeps the MeasurementUpdate it was last filled from, posteriors included, as the scratch of its next fill. More...
struct  Emrys::Reads< Items >
 What a model reads, as reads() declares it: the items, each a path into the state or the tag of an input of the call, under a name (decisions.md [model-policies]). More...
struct  Emrys::Writes< Paths >
 What a model writes, as writes() declares it: the blocks its function's result fills (decisions.md [model-policies]). More...
struct  Emrys::AffineIn< Names >
 The input names a model's function is affine in, given the rest, as affineIn() declares them (decisions.md [model-policies], [affine-coordinates]): a sigma-point method factors those coordinates out and spreads its points over the others alone. More...
class  Emrys::AdditiveNoise< Parts >
 Noise added to a model's output, \( z = h(x) \boxplus v \), as additiveNoise() declares it (decisions.md [additive-noise], [model-policies]): the function is transformed once, and the noise only widens and shifts the result. More...
class  Emrys::ModeNoise< Axis, Part >
 Additive mixture noise whose components are the values of a mode axis, as additiveNoise(mixture).byMode<Axis>() declares it (decisions.md [imm]): the Markov outlier model, in which a sensor's outlier state is a mode of the target that persists as the mode chain says. More...
class  Emrys::ContinuousNoise< Parts >
 A process model's white-noise spectral density, as continuousNoise() declares it, placed by tag path on blocks of the output and discretized over the step by the model (decisions.md [continuous-time-noise], [model-policies]): \( Q_c \, \Delta t \) on each block's differences. More...
struct  Emrys::LogLikelihood< G >
 A measurement model's own \( \log p(z \mid x) \) at a state point, as logLikelihood() declares it, for the filters that weight points (decisions.md [likelihood-measurements], [model-policies]): a function g(in, x, z) of the model's input space instance, its input vector, and the observation. More...
struct  Emrys::Sample< G >
 A draw of the observation that a measurement model known by its likelihood alone makes of a state, as sample() declares it, for simulate() (decisions.md [likelihood-measurements], [model-policies]): a function g(in, x, rng) of the model's input space instance, its input vector, and the caller's generator, returning the observation. More...
struct  Emrys::OutputSpace< X >
 A model's output space given by its instance, or computed from the state's space, as outputSpace() declares it (decisions.md [measurement-space-functions], [model-policies]): for an output with a resizable block, whose size the type does not fix. More...
struct  Emrys::Sure< S, Vector >
 A sure input of predict() or observe(): a known value in the tagged space S, as sure() marks it (decisions.md [prediction-inputs], [tag-addressing]). More...
struct  Emrys::Consider< Paths >
 The blocks of the state that a Kalman update considers rather than estimates, as consider() names them (decisions.md [consider-states]): the Schmidt-Kalman update of Schmidt (1966). More...
class  Emrys::ProcessFunction< F, Policies >
 A process model: a function \( f \) of its input and the step, with the policies that say what it reads, what it writes, and what it is affine in, and its noise (decisions.md [model-policies], [continuous-time-noise]). More...
class  Emrys::RandomWalk< Path, Scalar_ >
 A model driven by white noise alone: \( x' = x \), with noise \( Q_c \, \Delta t \) on its differences. More...
class  Emrys::Kinematic< Scalar_, Paths >
 A chain of two or more derivatives whose last one is driven by white noise: constant velocity and constant acceleration. More...
struct  Emrys::TimeConstant< Scalar >
 The time constant \( \tau \) of an OrnsteinUhlenbeck model, named so that it cannot be given in the place of its variance. More...
struct  Emrys::StationaryVariance< Scalar >
 The stationary variance \( \sigma^2 \) of an OrnsteinUhlenbeck model, named so that it cannot be given in the place of its time constant. More...
class  Emrys::OrnsteinUhlenbeck< Path, Scalar_ >
 A zero-mean Ornstein-Uhlenbeck (first-order Gauss-Markov) process on each coordinate of the block named by Path, such as a slowly varying sensor bias. More...
class  Emrys::Constant< Path >
 The block named by Path does not change, and has no process noise, such as a fixed calibration parameter. More...
class  Emrys::Composition< Models >
 Process models side by side, as compose() puts them (decisions.md [model-policies], [model-placement]): one model whose reads are the union of the parts', gathered once, whose writes are the parts' together, which must write every block of the state once, whose noise is block-diagonal, and whose affine set is the names every part reading them declares affine. More...
struct  Emrys::NoProcessModel
 The process model of a state with nothing to move: what a PointMassFilter, whose grid covers the whole state, holds in place of one. More...
struct  Emrys::PredictedJoint< Space_, Scalar_ >
 One prediction step as a joint: the Gaussian the step started from, the Gaussian it predicted, and the cross-covariance between them. More...
struct  Emrys::ModelsMethod
 What a filter with a fixed-step model takes in place of a prediction method: nothing, since the model carries its own. More...
class  Emrys::UnboundFixedStep< Model_, Method_, Time_ >
 A process model taken over one fixed time step, not yet bound to a state space: what fixedStep() returns. More...
class  Emrys::FixedStepModel< Space_, Model_, Method_, Scalar_ >
 A process model over one fixed time step, with the work that depends only on the step done once. More...
class  Emrys::ModelWithMethod< Model_, Method_ >
 A process model and the prediction method that one mode of a SwitchingModel predicts it by, in place of the filter's [switching-models]. More...
class  Emrys::SwitchingModel< ModeSpace_, Scalar_, Path_, Models >
 A process model that switches between modes: a Markov chain on a discrete mode space, and the process model each mode follows [switching-models]. More...
class  Emrys::SwitchingMeasurement< Path_, Measurements >
 A measurement that switches between modes: one Measurement per value of a mode axis, so that a filter over a Hybrid updates each mode by the measurement that its value in that axis names [imm]. More...

Typedefs

template<DiscreteSpace Space, typename Scalar>
using Emrys::EmissionBuffer = Eigen::Ref<Eigen::Array<Scalar, Space::Cardinality, 1>>
 The buffer an emission model writes its log-likelihoods into: one coefficient per value of the discrete space Space, with as many rows at compile time as Space has values, so that a model over a space of fixed cardinality writes a fixed-size array.
template<typename Position, typename Velocity, RealScalar Scalar = double>
using Emrys::ConstantVelocity = Kinematic<Scalar, Position, Velocity>
 Constant velocity (white-noise acceleration): position moves by velocity times \( \Delta t \).
template<typename Position, typename Velocity, typename Acceleration, RealScalar Scalar = double>
using Emrys::ConstantAcceleration = Kinematic<Scalar, Position, Velocity, Acceleration>
 Constant acceleration (white-noise jerk).
template<typename Model>
using Emrys::DefaultMethodFor = typename internal::DefaultMethodOf<Model>::type
 The prediction method of a filter with process model Model, unless it is given one: Linearized, a FixedStepModel's own, or, for a SwitchingModel of fixed-step models, which each carry their own, ModelsMethod.
template<typename Model, typename Method>
using Emrys::MethodFor = std::conditional_t<isFixedStep<Model>, ModelsMethod, Method>
 The type of a filter constructor's method argument: Method, or ModelsMethod for a fixed-step Model, so that a fixed-step filter can't be given a method.

Functions

constexpr PerColumn Emrys::jacobians::perColumn ()
constexpr Shared Emrys::jacobians::shared ()
template<typename F>
requires (!internal::isBatched<std::remove_cvref_t<F>> && !MatrixExpression<F>)
Batched< std::remove_cvref_t< F > > Emrys::batched (F &&function)
template<typename F, JacobianMark Mark>
requires (!internal::isBatched<std::remove_cvref_t<F>> && !MatrixExpression<F>)
Batched< std::remove_cvref_t< F >, std::remove_cvref_t< Mark > > Emrys::batched (F &&function, Mark)
template<typename Scalar, typename Space, EmissionModel< Space > E>
std::expected< CategoricalUpdate< Space, Scalar >, WeightError > Emrys::update (CategoricalParams< Space, Scalar > const &prior, E const &emission)
template<typename Scalar, typename Space>
std::expected< CategoricalUpdate< Space, Scalar >, WeightError > Emrys::predict (CategoricalParams< Space, Scalar > const &prior, ContinuousTimeMarkovChain< Space, Scalar > const &chain, TimeStep< Scalar > auto const &dt, ArrivalInterval< Space, Scalar > const &interval)
template<internal::WeighsPoints M, typename Space, typename Derived>
Eigen::Array< typename Derived::Scalar, Eigen::Dynamic, 1 > Emrys::logLikelihoods (M const &measurement, Space const &space, Eigen::MatrixBase< Derived > const &states)
template<ExecutionPolicy P, internal::WeighsPoints M, typename Space, typename Derived>
Eigen::Array< typename Derived::Scalar, Eigen::Dynamic, 1 > Emrys::logLikelihoods (P &&policy, M const &measurement, Space const &space, Eigen::MatrixBase< Derived > const &states)
 logLikelihoods() under policy, a for-each over the columns (see Execution policies).
template<internal::WeighsPoints M, typename Space, typename Derived>
Derived::Scalar Emrys::logLikelihood (M const &measurement, Space const &space, Eigen::MatrixBase< Derived > const &x)
template<FixedSizeSpace S, internal::WeighsPoints M, typename Derived>
requires Space<S>
Eigen::Array< typename Derived::Scalar, Eigen::Dynamic, 1 > Emrys::logLikelihoods (M const &measurement, Eigen::MatrixBase< Derived > const &states)
 logLikelihoods() in the fixed-size state space S, given as a template argument: logLikelihoods<State>(measurement, states).
template<FixedSizeSpace S, ExecutionPolicy P, internal::WeighsPoints M, typename Derived>
requires Space<S>
Eigen::Array< typename Derived::Scalar, Eigen::Dynamic, 1 > Emrys::logLikelihoods (P &&policy, M const &measurement, Eigen::MatrixBase< Derived > const &states)
 logLikelihoods() under policy in the fixed-size state space S, given as a template argument: logLikelihoods<State>(policy, measurement, states).
template<FixedSizeSpace S, internal::WeighsPoints M, typename Derived>
requires Space<S>
Derived::Scalar Emrys::logLikelihood (M const &measurement, Eigen::MatrixBase< Derived > const &x)
 logLikelihood() in the fixed-size state space S, given as a template argument: logLikelihood<State>(measurement, x).
template<UncertainInput Prior, Measurement M>
auto Emrys::update (Prior const &prior, M const &measurement)
template<UncertainInput Prior, Measurement M, typename Reference>
auto Emrys::update (Prior const &prior, M const &measurement, LinearizedAbout< Reference > const &about)
template<typename P, typename Space, typename Value>
GivenBlock< Space, P, Value > Emrys::given (Space const &space, Value const &value)
template<typename P, typename Space, typename Value>
void Emrys::given (Space const &space, Value const &&value)=delete
 given() of a temporary value is deleted: the mark refers to the value, which would be gone at the end of the full expression, so a mark kept in a variable would dangle.
template<UncertainInput Prior, Measurement M, typename Space, typename P, typename Value>
auto Emrys::update (Prior const &prior, M const &measurement, GivenBlock< Space, P, Value > const &pinned)
template<typename F, typename... Policies>
requires (!MatrixExpression<F> && !internal::ModelPolicy<F> && !internal::isColumns<std::remove_cvref_t<F>>)
auto Emrys::measurementModel (F &&function, Policies &&... policies)
template<MatrixExpression Matrix, typename... Policies>
auto Emrys::measurementModel (Matrix &&matrix, Policies &&... policies)
template<typename... Placed, typename... Policies>
auto Emrys::measurementModel (Columns< Placed... > columns, Policies &&... policies)
template<internal::ModelPolicy... Policies>
auto Emrys::measurementModel (Policies &&... policies)
template<TransformMethod Method, typename M, MatrixExpression Z, typename... Args>
requires MeasurementModel<std::unwrap_ref_decay_t<M>>
auto Emrys::observe (Method method, M &&model, Z &&observation, Args &&... args)
template<typename M, MatrixExpression Z, typename... Args>
requires MeasurementModel<std::unwrap_ref_decay_t<M>>
auto Emrys::observe (M &&model, Z &&observation, Args &&... args)
template<typename Path, ProcessModel Model, typename... Renames>
auto Emrys::on (Model const &model, Renames const &...)
template<typename Path, ProcessModel Model, typename... Renames>
auto Emrys::onEach (Model const &model, Renames const &...)
template<MeasurementModel... Models>
requires (sizeof...(Models) > 0)
auto Emrys::compose (Models &&... models)
template<typename... Items>
auto Emrys::reads (Items const &...)
template<PathValue... Paths>
auto Emrys::writes (Paths const &...)
template<PathValue... Names>
auto Emrys::affineIn (Names const &...)
template<typename... Parts>
AdditiveNoise< typename internal::HeldOf< std::unwrap_ref_decay_t< Parts > >::type... > Emrys::additiveNoise (Parts &&... parts)
template<typename... Parts>
ContinuousNoise< std::remove_cvref_t< Parts >... > Emrys::continuousNoise (Parts &&... parts)
template<typename G>
requires (!MatrixExpression<G> && !Space<std::remove_cvref_t<G>>)
LogLikelihood< std::remove_cvref_t< G > > Emrys::logLikelihood (G &&function)
template<typename G>
requires (!MatrixExpression<G> && !Space<std::remove_cvref_t<G>>)
Sample< std::remove_cvref_t< G > > Emrys::sample (G &&function)
template<typename X>
requires (!MatrixExpression<X>)
OutputSpace< std::remove_cvref_t< X > > Emrys::outputSpace (X &&x)
template<FixedSizeSpace S, MatrixExpression V>
requires Space<S>
auto Emrys::sure (V &&value)
template<Space S, MatrixExpression V>
auto Emrys::sure (S space, V &&value)
template<PathValue... Paths>
constexpr Consider< internal::PathOf< Paths >... > Emrys::consider (Paths const &...)
template<typename F, typename... Policies>
requires (!MatrixExpression<F> && !internal::ModelPolicy<F>)
auto Emrys::processModel (F &&function, Policies &&... policies)
template<MatrixExpression Matrix, typename... Policies>
auto Emrys::processModel (Matrix &&matrix, Policies &&... policies)
template<Space Space_, typename Derived, ProcessModel Model, typename... Args>
Moments< Space_, typenameDerived::Scalar >::VectorType Emrys::propagate (Space_ const &space, Eigen::MatrixBase< Derived > const &x, Model const &model, TimeStep< typename Derived::Scalar > auto const &dt, Args const &... args)
template<typename Method, UncertainInput Prior, ProcessModel Model, typename... Args>
GaussianParams< typename Prior::SpaceType, typename Prior::Scalar > Emrys::predict (Method const &method, Prior const &prior, Model const &model, TimeStep< typename Prior::Scalar > auto const &time, Args const &... args)
template<typename Method, UncertainInput Prior, ProcessModel Model, typename... Args>
PredictedJoint< typename Prior::SpaceType, typename Prior::Scalar > Emrys::predictJoint (Method const &method, Prior const &prior, Model const &model, TimeStep< typename Prior::Scalar > auto const &time, Args const &... args)
template<ProcessModel Model, typename Time, typename Method = methods::Linearized>
requires TimeStep<Time, double>
UnboundFixedStep< Model, Method, Time > Emrys::fixedStep (Model model, Time dt, Method method={})
template<UncertainInput Prior, typename Space_, typename Model_, typename Method_, typename Scalar_, typename... Args>
GaussianParams< typename Prior::SpaceType, typename Prior::Scalar > Emrys::predict (Prior const &prior, FixedStepModel< Space_, Model_, Method_, Scalar_ > const &model, Args const &... args)
template<UncertainInput Prior, typename Space_, typename Model_, typename Method_, typename Scalar_, typename... Args>
PredictedJoint< typename Prior::SpaceType, typename Prior::Scalar > Emrys::predictJoint (Prior const &prior, FixedStepModel< Space_, Model_, Method_, Scalar_ > const &model, Args const &... args)
template<UncertainInput Prior, typename Model_, typename Method_, typename Time_, typename... Args>
GaussianParams< typename Prior::SpaceType, typename Prior::Scalar > Emrys::predict (Prior const &prior, UnboundFixedStep< Model_, Method_, Time_ > const &step, Args const &... args)
template<UncertainInput Prior, typename Model_, typename Method_, typename Time_, typename... Args>
PredictedJoint< typename Prior::SpaceType, typename Prior::Scalar > Emrys::predictJoint (Prior const &prior, UnboundFixedStep< Model_, Method_, Time_ > const &step, Args const &... args)
template<Space Space_, typename Derived, ProcessModel Model, std::uniform_random_bit_generator G, typename... Args>
Moments< Space_, typenameDerived::Scalar >::VectorType Emrys::simulate (Space_ const &space, Eigen::MatrixBase< Derived > const &x, Model const &model, G &rng, TimeStep< typename Derived::Scalar > auto const &dt, Args const &... args)
template<Space Space_, typename Derived, typename Model, std::uniform_random_bit_generator G, typename... Args>
requires isFixedStep<Model>
Moments< Space_, typenameDerived::Scalar >::VectorType Emrys::simulate (Space_ const &space, Eigen::MatrixBase< Derived > const &x, Model const &model, G &rng, Args const &... args)
template<Space Space_, typename Derived, typename Step, std::uniform_random_bit_generator G, typename... Args>
requires isUnboundStep<Step>
Moments< Space_, typenameDerived::Scalar >::VectorType Emrys::simulate (Space_ const &space, Eigen::MatrixBase< Derived > const &x, Step const &step, G &rng, Args const &... args)
template<Space Space_, typename Derived, MeasurementModel M, std::uniform_random_bit_generator G, typename... Args>
auto Emrys::simulate (Space_ const &space, Eigen::MatrixBase< Derived > const &x, M const &model, G &rng, Args const &... args)
template<FixedSizeSpace Space_, typename Derived, typename Model, std::uniform_random_bit_generator G, typename... Inputs>
requires (Space<Space_> && !isFixedStep<Model> && !isUnboundStep<Model>)
Moments< Space_, typenameDerived::Scalar >::VectorType Emrys::simulate (Eigen::MatrixBase< Derived > const &x, Model const &model, G &rng, TimeStep< typename Derived::Scalar > auto const &dt, Inputs const &... inputs)
template<FixedSizeSpace Space_, typename Derived, typename Model, std::uniform_random_bit_generator G, typename... Inputs>
requires (Space<Space_> && (isFixedStep<Model> || isUnboundStep<Model>))
Moments< Space_, typenameDerived::Scalar >::VectorType Emrys::simulate (Eigen::MatrixBase< Derived > const &x, Model const &model, G &rng, Inputs const &... inputs)
template<FixedSizeSpace Space_, typename Derived, MeasurementModel M, std::uniform_random_bit_generator G, typename... Args>
requires Space<Space_>
auto Emrys::simulate (Eigen::MatrixBase< Derived > const &x, M const &model, G &rng, Args const &... args)
template<typename Space, typename Scalar, std::uniform_random_bit_generator G>
Eigen::Index Emrys::simulate (Eigen::Index from, MarkovChain< Space, Scalar > const &chain, G &rng)
template<typename Space, typename Scalar, std::uniform_random_bit_generator G>
Eigen::Index Emrys::simulate (Eigen::Index from, ContinuousTimeMarkovChain< Space, Scalar > const &chain, G &rng, TimeStep< Scalar > auto const &dt)
template<typename Model, TransformMethod Method>
ModelWithMethod< Model, Method > Emrys::withMethod (Model model, Method method)
template<typename P, typename ModeSpace, typename Scalar, typename... Models>
SwitchingModel< ModeSpace, Scalar, P, Models... > Emrys::switchingModel (MarkovChain< ModeSpace, Scalar > chain, Models... models)
template<typename P, Measurement... Measurements>
SwitchingMeasurement< P, Measurements... > Emrys::switchingMeasurement (Measurements... measurements)

Variables

template<typename Model>
constexpr bool Emrys::isFixedStep = false
 Whether Model is a FixedStepModel, whose predictions take no time step.
template<typename Space_, typename Model_, typename Method_, typename Scalar_>
constexpr bool Emrys::isFixedStep< FixedStepModel< Space_, Model_, Method_, Scalar_ > > {true}
 A FixedStepModel is one.
template<typename Model>
constexpr bool Emrys::isUnboundStep = false
 Whether Model is a fixed step not yet bound to a state space: an UnboundFixedStep, which fixedStep() returns and a filter binds to its state's space.
template<typename Model_, typename Method_, typename Time_>
constexpr bool Emrys::isUnboundStep< UnboundFixedStep< Model_, Method_, Time_ > > {true}
 An UnboundFixedStep is one.
template<typename ModeSpace_, typename Scalar_, typename Path_, typename... Models>
constexpr bool Emrys::isFixedStep< SwitchingModel< ModeSpace_, Scalar_, Path_, Models... > > {(isFixedStep<Models> && ...)}
 A SwitchingModel whose process models are all FixedStepModel is fixed-step too.

Detailed Description

The fourth layer (decisions.md [layered-headers]): how a distribution moves through a function and what a filter is given to work with.

A model's noise is parameters, which a step reads through their density (Parameters and densities). Transform.h propagates a distribution with the methods of Methods.h, over the arguments of TransformArgs.h, into the results of Linearization.h, which Condition.h conditions on an observation; ProcessModel.h and Measurement.h, with the measurement models of MeasurementModel.h, the policies of Policies.h, and the placements and compositions of Placement.h, are the models [model-policies], [model-placement], [affine-coordinates], [templated-measurements], [method-per-measurement], [additive-noise], [sensors], [continuous-time-noise], [weighted-branches], and [prediction-inputs]; SwitchingModel.h adds a mode chain [switching-models], [imm]; Emission.h measures a discrete state [emissions]; Reduction.h and Consistency.h reduce an update's branches and test them [weighted-branches], [reduction-policies], [composed-features], and Simulation.h draws the true states that Consistency.h's nees() tests a filter against, and CramerRao.h's posterior Cramér-Rao bound bounds its error along them [cramer-rao-bound]; FormSteps.h holds the steps of the square-root and information forms of the Gaussian [gaussian-forms]; and Batched.h marks a function that takes every point at once [batched-functions].

A process model moves the whole state forward in time; a measurement model relates part of the state to an observation. They are separate kinds of object: a filter owns its process model, and a measurement arrives carrying its own model and noise.

Both kinds of model are functions with reads and writes (decisions.md [model-policies]): a function f(in, out, x[, dt]), f(in, x[, dt]), or f(x[, dt]) over Eigen vectors, and policies given as calls in any order. A model without reads() and writes() reads and writes the whole state (decisions.md [whole-state-models]), so the textbook Kalman filter on Linear<4> is processModel(F, additiveNoise(q)) and measurementModel(H, additiveNoise(r)). A process model is processModel(), a built-in model, or compose() of process models; a measurement model is measurementModel(). The built-in process models, RandomWalk, Constant, ConstantVelocity and ConstantAcceleration (Kinematic), and OrnsteinUhlenbeck, take their tags as template arguments and the scalar of their parameters last, double by default:

struct Position : Linear<2> {};
struct Velocity : Linear<2> {};
struct Acceleration : Linear<2> {};
struct Bias : Linear<1> {};
using State = Composite<Position, Velocity, Acceleration, Bias>;
auto const model = compose(ConstantAcceleration<Position, Velocity, Acceleration>{0.1},
OrnsteinUhlenbeck<Bias>{TimeConstant{60.0}, StationaryVariance{0.25}});
auto const predicted = predict(methods::linearized(), state, model, dt);
CategoricalParams< Space, Scalar > predict(CategoricalParams< Space, Scalar > const &prior, MarkovChain< Space, Scalar > const &chain)
Definition Categorical.h:1049
auto compose(Models &&... models)
Definition Placement.h:1243

A model of the user's own reads the blocks it names with block<Name>(in, x), writes the blocks it names into a vector in out, and names the inputs of the call it reads by tag; the call gives each as an uncertain input, a Gaussian over the tag's space whose uncertainty goes through the dynamics, or as sure<Tag>(value), a value known exactly:

// Velocity driven by a measured specific force plus known gravity, rather than modeled.
struct SpecificForce : Linear<2> {};
struct Gravity : Linear<2> {};
auto const driven = processModel(
[]<typename T>(auto const & in, auto const & out, auto const & x, double dt) {
auto y = zeros<T>(out);
auto const a = block<SpecificForce>(in, x) + block<Gravity>(in, x);
block<Position>(out, y) = block<Position>(in, x) + dt * block<Velocity>(in, x) + (dt * dt / 2) * a;
block<Velocity>(out, y) = block<Velocity>(in, x) + dt * a;
return y;
},
reads(path<Position>, path<Velocity>, path<SpecificForce>, path<Gravity>),
writes(path<Position>, path<Velocity>));
auto const predicted = predict(methods::unscented(), state, compose(driven, RandomWalk<Bias>{1e-8}), dt,
accelerometer, sure<Gravity>(g));
auto writes(Paths const &...)
Definition Policies.h:262
auto reads(Items const &...)
Definition Policies.h:196
auto processModel(F &&function, Policies &&... policies)
Definition ProcessModel.h:702

The built-in models take continuous-time parameters and discretize them exactly over the step dt, as Bar-Shalom, Li, and Kirubarajan (2001) discretize the continuous-time kinematic models; a model of the user's own gives continuousNoise(), a spectral density over the blocks it writes that the step discretizes as \( Q_c \, \Delta t \), or additiveNoise(), a fixed \( Q \), or neither where its noise comes through an input. The models of a composition must write every coordinate of the state exactly once, so a coordinate that does not move still needs a Constant or RandomWalk model; the check is at compile time where the space is fixed-size. The composition's noise is block-diagonal.

dt reaches a model's function in the filter's scalar, converted once from whatever TimeStep the caller passed (see Time steps), so a float filter's models compute in float. It is in the unit of the models' continuous-time parameters, seconds when it was a std::chrono duration. The function is generic in the scalar of x, which the Linearized method differentiates automatically, or returns its Jacobian with its value (withJacobian(), [returned-jacobians]), as the built-in models do, so that Linearized predicts them with no differentiation.

A model reads its blocks by name wherever they sit in the state, so one model serves every place that has them: on<Ownship>(vehicle) places a model on a block, prefixing every path into the state it reads and writes, onEach<Fleet>(vehicle) places one copy on every repetition of a repeated block, and compose() of measurement models measures their blocks side by side (Placement.h). A model that names the inputs it is affine in with affineIn() has them carried exactly by every sigma-point method, which spreads its points over the rest [affine-coordinates].

A measurement model takes one of three forms, from the convenient to the general: a model built once, a function with a fixed output space or one computed from the state's, such as CountFrom, or a matrix, or Columns that repeat with a block, which serves every count of the state's blocks; a model built per measurement, its function, space, and noise computed from that measurement's own data, such as the receivers that heard a signal or noise whose variances follow each reading's signal-to-noise ratio; and a model known only by its likelihood, measurementModel(reads(...), logLikelihood(g)), for the filters that weight points [likelihood-measurements]. observe() makes a measurement of it, and update() transforms only the blocks the model reads and corrects the rest of the state through their cross-covariance, which is exact under a Gaussian prior; it returns a branch per component of the additive noise, each with its Innovation [weighted-branches], [innovation-statistics]. The filters that weight points take \( \log p(z \mid x) \) from the same measurement, by logLikelihoods() (Likelihood.h).

A function that costs more per call than per point, such as one that looks up a table, holds a lock, or calls into another runtime or a device, can take every point at once: batched(f) marks it as taking the points as the columns of a matrix X and writing their values into the output Y the library provides, h(in, out, X, Y), or for a process model f(in, out, X, dt, Y), with Y.values() a column per point (Batched.h, [batched-functions]). Column \( j \) of what it writes depends only on column \( j \) of X. The library calls it once per particle set or chunk and once per sigma-point set, and through on(), compose(), and onEach() as through the model itself. A method that needs its Jacobian takes it from the function, marked batched(f, jacobians::perColumn()) or batched(f, jacobians::shared()) and writing Y.jacobian<Name>(j) for the blocks Y.wantsJacobian<Name>() names, or differentiates it in dual numbers, for which the function takes X as auto const &:

// The terrain's height below the aircraft, looked up for every particle in one pass.
auto const elevation = measurementModel(
batched([&terrain](auto const & in, auto const &, auto const & X, auto & Y) {
auto const position = block<Position>(in, X);
for (Eigen::Index j = 0; j < X.cols(); ++j)
Y.values()(0, j) = terrain.height(position.col(j));
}),
reads(path<Position>), additiveNoise(elevationNoise));

The program examples/terrain_lookup.cpp filters such a measurement with a particle filter.

Read Filters next.

Typedef Documentation

◆ DefaultMethodFor

template<typename Model>
using Emrys::DefaultMethodFor = typename internal::DefaultMethodOf<Model>::type

The prediction method of a filter with process model Model, unless it is given one: Linearized, a FixedStepModel's own, or, for a SwitchingModel of fixed-step models, which each carry their own, ModelsMethod.

The filters default their method parameter to it, so their deduction guides need no form of their own for a fixed-step model, and a filter's type is spelled with it (KalmanFilter<Gaussian<State>, Model, DefaultMethodFor<Model>>).

◆ MethodFor

template<typename Model, typename Method>
using Emrys::MethodFor = std::conditional_t<isFixedStep<Model>, ModelsMethod, Method>

The type of a filter constructor's method argument: Method, or ModelsMethod for a fixed-step Model, so that a fixed-step filter can't be given a method.

One constructor serves both kinds of model, so the deduction guides, through the abbreviation aliases too, have one implicit candidate to rank against.

Function Documentation

◆ additiveNoise()

template<typename... Parts>
AdditiveNoise< typename internal::HeldOf< std::unwrap_ref_decay_t< Parts > >::type... > Emrys::additiveNoise ( Parts &&... parts)
nodiscard
Returns
the additiveNoise() policy of parts (see AdditiveNoise): one covariance, zero-mean noise, or one distribution, either held by copy, or for std::cref(noise) by reference to one that must outlive the model, or parts placed by tag path with on<Path>() and onEach<Path>()
additiveNoise(R) // zero-mean, R over the output's differences
additiveNoise(std::cref(mixture))
A Gaussian distribution: a mean and covariance in a space.
Definition Gaussian.h:259
auto on(Model const &model, Renames const &...)
Definition Placement.h:1067
AdditiveNoise< typename internal::HeldOf< std::unwrap_ref_decay_t< Parts > >::type... > additiveNoise(Parts &&... parts)
Definition Policies.h:523
auto onEach(Model const &model, Renames const &...)
Definition Placement.h:1138
Dimension_ plain coordinates, or a resizable run of at most MaxDimension_ of them if Dimension_ is Ei...
Definition Coordinates.h:87

◆ affineIn()

template<PathValue... Names>
auto Emrys::affineIn ( Names const & ...)
nodiscard
Returns
the affineIn() policy of names, each the one tag an item of reads() is read under, as a path value of one tag

◆ batched() [1/2]

template<typename F>
requires (!internal::isBatched<std::remove_cvref_t<F>> && !MatrixExpression<F>)
Batched< std::remove_cvref_t< F > > Emrys::batched ( F && function)
nodiscard
Returns
function marked as taking every point at once, with no Jacobian (see Batched): a measurement model's h(in, out, X, Y), a process model's f(in, out, X, dt, Y), or a log-likelihood's g(in, X, z, Y), which writes one log-likelihood per column. Column \( j \) of what it writes depends only on column \( j \) of X, which is the user's contract. A method that needs a Jacobian differentiates the function in the autodiff scalar.
auto const range = Emrys::logLikelihood(Emrys::batched([](auto const & in, auto const & X, auto const & z, auto & Y)
{ Y.values() = -0.5 * (block<Position>(in, X).colwise().norm().array() - z(0)).square().matrix() / variance;
}));
Derived::Scalar logLikelihood(M const &measurement, Space const &space, Eigen::MatrixBase< Derived > const &x)
Definition Likelihood.h:433
Batched< std::remove_cvref_t< F > > batched(F &&function)
Definition Batched.h:248
auto block(Space auto const &space, X &&x)
Definition TagPath.h:979

◆ batched() [2/2]

template<typename F, JacobianMark Mark>
requires (!internal::isBatched<std::remove_cvref_t<F>> && !MatrixExpression<F>)
Batched< std::remove_cvref_t< F >, std::remove_cvref_t< Mark > > Emrys::batched ( F && function,
Mark  )
nodiscard
Returns
function marked as taking every point at once and writing the Jacobians mark says, jacobians::perColumn() or jacobians::shared() (see Batched)

◆ compose()

template<MeasurementModel... Models>
requires (sizeof...(Models) > 0)
auto Emrys::compose ( Models &&... models)
nodiscard
Returns
the measurement model of models side by side (decisions.md [model-placement]): its reads are the union of theirs, gathered once, its output the blocks they write together, which must be distinct, its noise their noise on their blocks, and its log-likelihood, where every one has its own, their sum. Each must name its output with writes().
auto const radar = compose(range, bearing); // measures Composite<Range, Bearing>

◆ consider()

template<PathValue... Paths>
Consider< internal::PathOf< Paths >... > Emrys::consider ( Paths const & ...)
nodiscardconstexpr
Returns
the blocks named by paths, each a path value such as path<GyroBias>, as the argument of observe() that considers them rather than estimating them: observe(methods::linearized(), model, z, consider(path<GyroBias>)) (decisions.md [consider-states]). Each path names a block of the state, which need not be one the model reads, and no block lies in another.

◆ continuousNoise()

template<typename... Parts>
ContinuousNoise< std::remove_cvref_t< Parts >... > Emrys::continuousNoise ( Parts &&... parts)
nodiscard
Returns
the continuousNoise() policy of parts (see ContinuousNoise): spectral densities placed by tag path, continuousNoise(on<Velocity>(q)), or one for the whole output

◆ fixedStep()

template<ProcessModel Model, typename Time, typename Method = methods::Linearized>
requires TimeStep<Time, double>
UnboundFixedStep< Model, Method, Time > Emrys::fixedStep ( Model model,
Time dt,
Method method = {} )
nodiscard
Returns
model taken over the step dt, predicting by method: the UnboundFixedStep that a filter binds to its state's space, KalmanFilter{fixedStep(model, dt), initial}, as the FixedStepModel over that space and the state's scalar.

◆ given() [1/2]

template<typename P, typename Space, typename Value>
void Emrys::given ( Space const & space,
Value const && value )
delete

given() of a temporary value is deleted: the mark refers to the value, which would be gone at the end of the full expression, so a mark kept in a variable would dangle.

Store the value first.

◆ given() [2/2]

template<typename P, typename Space, typename Value>
GivenBlock< Space, P, Value > Emrys::given ( Space const & space,
Value const & value )
nodiscard
Returns
the block named by the path P (a tag or a TagPath) of a state in space, given as value from outside the Gaussian being updated, for update(prior, measurement, given): a vector when the block is known exactly, or an uncertain input such as a Gaussian, independent of the rest of the state. The mark copies the space and refers to value, so it is valid while value is; a temporary value is rejected.

◆ logLikelihood() [1/2]

template<typename G>
requires (!MatrixExpression<G> && !Space<std::remove_cvref_t<G>>)
LogLikelihood< std::remove_cvref_t< G > > Emrys::logLikelihood ( G && function)
nodiscard
Returns
the logLikelihood() policy of function, g(in, x, z) (see LogLikelihood): what a particle or grid filter weights by when the model's noise is not additive, or is not Gaussian

◆ logLikelihood() [2/2]

template<internal::WeighsPoints M, typename Space, typename Derived>
Derived::Scalar Emrys::logLikelihood ( M const & measurement,
Space const & space,
Eigen::MatrixBase< Derived > const & x )
nodiscard
Returns
\( \log p(z \mid x) \) for measurement at the state point x, a column vector in space, as logLikelihoods() computes it.

◆ logLikelihoods() [1/2]

template<internal::WeighsPoints M, typename Space, typename Derived>
Eigen::Array< typename Derived::Scalar, Eigen::Dynamic, 1 > Emrys::logLikelihoods ( M const & measurement,
Space const & space,
Eigen::MatrixBase< Derived > const & states )
nodiscard
Returns
\( \log p(z \mid x_j) \) for measurement at each column \( x_j \) of states in space, for filters that weight state points, such as particle and grid filters.

measurement is an observation of a measurement model (see observe()), with or without a method. Its model's own logLikelihood(g) if it has one, whatever its noise says (decisions.md [likelihood-measurements]); otherwise the log-density of its additive noise at the residual \( z \boxminus h(x_j) \), formed in the measurement space, since the residual at the true state is the noise. An uncertain input of the call that passes through the function widens that density by its covariance carried through the function's Jacobian at the point, which is exact where the model names the input in affineIn(); otherwise the model must supply its own likelihood, and the compile error says so. The noise must factorize; it is factorized once for all the columns where no input widens it. Where the Jacobian at a column is not finite, as for a range at the sensor's position, the widening is not defined, and that column's log-likelihood is NaN, as it is where the function's value is not finite; a ParticleFilter's update refuses a NaN.

This is the likelihood \( p(z_k \mid x_k^i) \) that weights the particles of Arulampalam et al. (2002), equation (48), and the cells of a point-mass filter.

See also
logLikelihood()

◆ logLikelihoods() [2/2]

template<ExecutionPolicy P, internal::WeighsPoints M, typename Space, typename Derived>
Eigen::Array< typename Derived::Scalar, Eigen::Dynamic, 1 > Emrys::logLikelihoods ( P && policy,
M const & measurement,
Space const & space,
Eigen::MatrixBase< Derived > const & states )
nodiscard

logLikelihoods() under policy, a for-each over the columns (see Execution policies).

A model's own logLikelihood(g) and its function then run for several columns at once, so they must not write shared state.

◆ measurementModel() [1/4]

template<typename... Placed, typename... Policies>
auto Emrys::measurementModel ( Columns< Placed... > columns,
Policies &&... policies )
nodiscard
Returns
the linear measurement model with \( H \) given by columns, a matrix per block read in the order given, which is what the model reads, so it takes no reads() (decisions.md [linear-sensors]). If the columns repeat, with onEach(), and no outputSpace() is given, the measurement space is a Repeated block of Linear coordinates with the block's count at each update.

◆ measurementModel() [2/4]

template<typename F, typename... Policies>
requires (!MatrixExpression<F> && !internal::ModelPolicy<F> && !internal::isColumns<std::remove_cvref_t<F>>)
auto Emrys::measurementModel ( F && function,
Policies &&... policies )
nodiscard
Returns
the measurement model whose function is function, with policies, each a call such as reads(), writes(), affineIn(), additiveNoise(), logLikelihood(), or outputSpace(), in any order and each at most once (decisions.md [model-policies]). The function takes h(x), h(in, x), or h(in, out, x), told apart by the count of its arguments. A model reads what reads() names; a model without reads() reads the whole state of the filter it is given to, its input space the state's (decisions.md [whole-state-models]), and is not composed or placed. The output space is outputSpace()'s, else the Composite of writes(), else the space of the one unplaced additive noise, else a Linear sized by what the function returns (decisions.md [sensors]).
// A position fix on a Linear<4> state of position and velocity, as a whole-state model.
auto const fix = measurementModel([](auto const & x) { return x.template head<2>().eval(); },
auto measurementModel(F &&function, Policies &&... policies)
Definition MeasurementModel.h:913
auto const range = measurementModel(
[]<typename T>(auto const & in, auto const & out, auto const & x) {
auto const d = minus<Position>(block<Position>(in, x), block<SensorPosition>(in, x));
return T{(1 + block<ScaleNoise>(in, x)(0)) * d.norm()};
},
auto affineIn(Names const &...)
Definition Policies.h:288
auto minus(S const &space, Eigen::MatrixBase< ADerived > const &a, Eigen::MatrixBase< BDerived > const &b)
Definition Space.h:715
constexpr TagPath< Tags... > path
The path TagPath<Tags...> as a value, for a call that takes its paths as arguments rather than as tem...
Definition TagPath.h:372

◆ measurementModel() [3/4]

template<MatrixExpression Matrix, typename... Policies>
auto Emrys::measurementModel ( Matrix && matrix,
Policies &&... policies )
nodiscard
Returns
the linear measurement model \( z = H x \boxplus v \) of the matrix matrix over the blocks that reads() names, stacked in that order as \( x \), or over the whole state without reads() (decisions.md [linear-sensors], [whole-state-models]), with policies as measurementModel(function, policies...) takes them. The blocks must add their values, as Linear and Periodic ones do, and the model's update is the Kalman filter's exact step, with nothing differentiated.
auto const gps = measurementModel(Eigen::Matrix2d::Identity(), reads(path<Position>), additiveNoise(r));
auto const fix = measurementModel(H, additiveNoise(R)); // H is 2 by 4, R 2 by 2

◆ measurementModel() [4/4]

template<internal::ModelPolicy... Policies>
auto Emrys::measurementModel ( Policies &&... policies)
nodiscard
Returns
the measurement model known by its likelihood alone, measurementModel(reads(...), logLikelihood(g)), for the filters that weight points (decisions.md [likelihood-measurements]): it has no function, so no Kalman update, and its error distribution, such as a quantization convolved with Gaussian noise, is in the likelihood alone. Given sample(g) too, a draw of the observation at a state, simulate() draws its observations.

◆ observe() [1/2]

template<typename M, MatrixExpression Z, typename... Args>
requires MeasurementModel<std::unwrap_ref_decay_t<M>>
auto Emrys::observe ( M && model,
Z && observation,
Args &&... args )
nodiscard
Returns
the Measurement of observation by model with the call's args, as observe(method, model, observation, args...) makes it, with no method given. A model given its matrix, measurementModel(H, noise), is linear, and its measurement is pushed through by Linearized, which is exact for it, so a linear Kalman filter names no method. Any other model's measurement has no method, for the filters that weight points by the likelihood, which push no Gaussian through the model, and a Kalman update refuses it at compile time (decisions.md [linear-sensors]).
filter.update(observe(fix, z)); // fix = measurementModel(H, additiveNoise(R))
particles.update(observe(range, z));
auto observe(Method method, M &&model, Z &&observation, Args &&... args)
Definition MeasurementModel.h:1399

◆ observe() [2/2]

template<TransformMethod Method, typename M, MatrixExpression Z, typename... Args>
requires MeasurementModel<std::unwrap_ref_decay_t<M>>
auto Emrys::observe ( Method method,
M && model,
Z && observation,
Args &&... args )
nodiscard
Returns
the Measurement of observation, a value in the measurement space, by model, pushed through by method, with the call's args after it in any order: an uncertain input over a tagged space for each item of the model's reads() that the state lacks, or sure<Tag>(value) for one known exactly; a covariance update form (updates::joseph()); and a repair of an innovation covariance that is not positive definite (roots::ridge()). The model is held by copy, or for std::cref(model) by reference to one that outlives the measurement (decisions.md [method-per-measurement], [model-policies]).
filter.update(observe(methods::unscented(), range, z, GaussianParams<ScaleNoise>{zero, s}));
filter.update(observe(methods::linearized(), std::cref(gps), fix, updates::joseph()));
constexpr Linearized linearized()
Definition Methods.h:333
constexpr Joseph joseph()
Definition Condition.h:132
constexpr Unscented< Alpha, Beta, Kappa > unscented()
Definition Methods.h:389

◆ on()

template<typename Path, ProcessModel Model, typename... Renames>
auto Emrys::on ( Model const & model,
Renames const & ... )
nodiscard
Returns
the process model model placed on the block of the state that Path (a tag or a TagPath) names (decisions.md [model-placement]): every path into the state it reads and writes is prefixed by Path, and its function is untouched. An input of the call keeps its tag, so two placements of one model share it, unless renames rename it, each on<Name>(path<Tag>), which gives the input Tag the name Name.
auto const pair = compose(on<Ownship>(vehicle), on<Target>(vehicle, on<TargetForce>(path<SpecificForce>)));

◆ onEach()

template<typename Path, ProcessModel Model, typename... Renames>
auto Emrys::onEach ( Model const & model,
Renames const & ... )
nodiscard
Returns
the process model model placed on every repetition of the repeated block of the state that Path (a tag or a TagPath) names, as many as the state has (decisions.md [model-placement]): each repetition moves by the model on its own blocks, with its own noise. An input renamed by renames to a Repeated tag, on<Forces>(path<SpecificForce>) with struct Forces : Repeated<SpecificForce, N>, is one argument with a value per repetition; any other input is shared by every repetition.
auto const fleet = compose(on<Ownship>(vehicle), onEach<Targets>(vehicle, on<TargetForces>(path<SpecificForce>)));

◆ outputSpace()

template<typename X>
requires (!MatrixExpression<X>)
OutputSpace< std::remove_cvref_t< X > > Emrys::outputSpace ( X && x)
nodiscard
Returns
the outputSpace() policy of x (see OutputSpace): the output space instance, or a function of the state's space instance that computes it, such as CountFrom

◆ perColumn()

PerColumn Emrys::jacobians::perColumn ( )
nodiscardconstexpr
Returns
the mark that a batched function writes one Jacobian per column (see PerColumn)

◆ predict() [1/4]

template<typename Scalar, typename Space>
std::expected< CategoricalUpdate< Space, Scalar >, WeightError > Emrys::predict ( CategoricalParams< Space, Scalar > const & prior,
ContinuousTimeMarkovChain< Space, Scalar > const & chain,
TimeStep< Scalar > auto const & dt,
ArrivalInterval< Space, Scalar > const & interval )
nodiscard
Returns
prior moved over an interval of dt by chain while observing interval: the normalized \( p\, e^{(Q - \Lambda) \Delta t} \Lambda \) (without \( \Lambda \) if the interval ends without an event) and the log of its total, the interval's log-likelihood; or a WeightError if the observation is impossible under prior

The exponential is taken of \( Q - \Lambda + \lambda_{\min} I \), whose entries stay of order one for the slowest value however long the interval, and \( \lambda_{\min} \Delta t \) is subtracted from the log-likelihood.

◆ predict() [2/4]

template<typename Method, UncertainInput Prior, ProcessModel Model, typename... Args>
GaussianParams< typename Prior::SpaceType, typename Prior::Scalar > Emrys::predict ( Method const & method,
Prior const & prior,
Model const & model,
TimeStep< typename Prior::Scalar > auto const & time,
Args const &... args )
nodiscard
Returns
prior moved forward by dt through model, computed by method (Linearized or a sigma-point method; Linearized is exact for the built-in models), with the process noise added: \( P' = F P F^T + \sum_i G_i \Sigma_i G_i^T + Q \) in the linear case, with \( G_i \) the Jacobian in uncertain input \( i \).

args are the call's inputs, in any order, each matched to an item of the model's reads() that the state lacks by its tag (decisions.md [prediction-inputs], [model-policies]): an uncertain input (see UncertainInput) over a tagged space, such as an inertial measurement with its noise, whose uncertainty is carried through the dynamics; or sure<Tag>(value) for one known exactly, such as a control. An item the state lacks must be given, and an argument the model does not read is refused, both at compile time. A sigma-point method spreads its points over the coordinates the model's affineIn() does not name, and carries the ones it names, of linear blocks and uncertain inputs, exactly by their Gaussian given the rest (decisions.md [affine-coordinates]).

dt is any TimeStep, converted once to the prior's scalar, which is what the model's function receives (see Time steps).

Under the Linearized method with no uncertain inputs, a model whose function returns its Jacobian [returned-jacobians], as the built-in models do, moves the covariance by that Jacobian at the mean, \( F P F^T + Q \), with no differentiation.

A linearizedAbout() reference first among args linearizes the step about it rather than at the prior (decisions.md [linearization-reference]): the step's Jacobian \( F \) and value at the reference's point, or its statistical linearization over the reference's distribution, are carried to the prior's chart, and the prediction is \( v \), the affine model's value at the prior mean, with covariance \( F P F^T + \Omega + Q \). A model that gives its Jacobian gives it at the reference.

The prediction step of Kalman (1960), with the transform standing in for the transition matrix where the dynamics are not affine (Särkkä (2013), §4.3, §5.2, and §5.5 for the three methods).

See also
Models, transform(), FixedStepModel, linearizedAbout()

◆ predict() [3/4]

template<UncertainInput Prior, typename Space_, typename Model_, typename Method_, typename Scalar_, typename... Args>
GaussianParams< typename Prior::SpaceType, typename Prior::Scalar > Emrys::predict ( Prior const & prior,
FixedStepModel< Space_, Model_, Method_, Scalar_ > const & model,
Args const &... args )
nodiscard
Returns
prior moved forward by model's step, by its method, with its process noise added, as predict(method, prior, model, dt, args...) would.

Under a cached transition (FixedStepModel::CachesTransition) and with no arguments, the mean is the propagated mean and the covariance \( F P F^T + Q \), with no transform. Otherwise it goes as predict() goes, with the cached \( Q \): by the function's Jacobian at the mean where it returns one and no input is uncertain, and through the transform where an uncertain input needs its own Jacobian.

See also
FixedStepModel, Models

◆ predict() [4/4]

template<UncertainInput Prior, typename Model_, typename Method_, typename Time_, typename... Args>
GaussianParams< typename Prior::SpaceType, typename Prior::Scalar > Emrys::predict ( Prior const & prior,
UnboundFixedStep< Model_, Method_, Time_ > const & step,
Args const &... args )
nodiscard
Returns
predict(prior, model, args...) over the FixedStepModel that step, fixedStep()'s result, makes over prior's space and scalar, as a filter given it binds it: predict(prior, fixedStep(model, dt)). The model is made on every call, so its \( Q \) is computed each time; to predict over the step again and again, keep a FixedStepModel or give the step to a filter.
See also
fixedStep(), FixedStepModel, Models

◆ predictJoint() [1/3]

template<typename Method, UncertainInput Prior, ProcessModel Model, typename... Args>
PredictedJoint< typename Prior::SpaceType, typename Prior::Scalar > Emrys::predictJoint ( Method const & method,
Prior const & prior,
Model const & model,
TimeStep< typename Prior::Scalar > auto const & time,
Args const &... args )
nodiscard
Returns
predict(method, prior, model, dt, args...) as a PredictedJoint: prior, the prediction, and their cross-covariance \( C_k \), which transform() gives with prior marked by withCross(), for every method. The process noise and any uncertain inputs are independent of prior, so they add to the prediction's covariance and not to \( C_k \).

The forward half of the Gaussian smoother of Särkkä (2013), chapter 10, which writes the Rauch-Tung-Striebel gain in terms of this cross-covariance so that it needs no Jacobian (see smoothStep()).

See also
PredictedJoint, Models

◆ predictJoint() [2/3]

template<UncertainInput Prior, typename Space_, typename Model_, typename Method_, typename Scalar_, typename... Args>
PredictedJoint< typename Prior::SpaceType, typename Prior::Scalar > Emrys::predictJoint ( Prior const & prior,
FixedStepModel< Space_, Model_, Method_, Scalar_ > const & model,
Args const &... args )
nodiscard
Returns
predict(prior, model, args...) as a PredictedJoint, as predictJoint(method, prior, model, dt, args...) gives one. Under a cached transition and with no arguments, \( C_k = P F^T \), which the prediction computes on the way to \( F P F^T \).
See also
FixedStepModel, PredictedJoint, Models

◆ predictJoint() [3/3]

template<UncertainInput Prior, typename Model_, typename Method_, typename Time_, typename... Args>
PredictedJoint< typename Prior::SpaceType, typename Prior::Scalar > Emrys::predictJoint ( Prior const & prior,
UnboundFixedStep< Model_, Method_, Time_ > const & step,
Args const &... args )
nodiscard
Returns
predictJoint(prior, model, args...) over the FixedStepModel that step, fixedStep()'s result, makes over prior's space and scalar, as predict(prior, step, args...) binds it.
See also
fixedStep(), FixedStepModel, PredictedJoint, Models

◆ processModel() [1/2]

template<typename F, typename... Policies>
requires (!MatrixExpression<F> && !internal::ModelPolicy<F>)
auto Emrys::processModel ( F && function,
Policies &&... policies )
nodiscard
Returns
the process model whose function is function, f(in, out, x, dt), f(in, x, dt), or f(x, dt), told apart by the count of its arguments, with policies, each a call such as reads(), writes(), affineIn(), continuousNoise(), or additiveNoise(), in any order and each at most once (decisions.md [model-policies]). A model reads what reads() names and writes the blocks of the state that writes() names; a model with neither reads and writes the whole state of the filter it is given to, its noise over the whole state, and takes no inputs of the call, nor is it composed or placed (decisions.md [whole-state-models]). A model with no noise policy adds no noise, as one driven by a measured input does.
// Constant velocity on a Linear<4> state of position and velocity, as a whole-state model.
auto const cv = processModel(
[](auto const & x, double dt) {
auto y = x.eval();
y.template head<2>() += dt * x.template tail<2>();
return y;
},
ContinuousNoise< std::remove_cvref_t< Parts >... > continuousNoise(Parts &&... parts)
Definition Policies.h:582
auto const kinematics = processModel(
[]<typename T>(auto const & in, auto const & out, auto const & x, double dt) {
auto const v = block<Velocity>(in, x);
auto y = zeros<T>(out);
block<Position>(out, y) = block<Position>(in, x) + dt * v + (dt * dt / 2) * a;
block<Velocity>(out, y) = v + dt * a;
return y;
},
auto less(S const &space, Eigen::MatrixBase< XDerived > const &x, Eigen::MatrixBase< DDerived > const &d)
Definition Space.h:767
ValueVector< S, Scalar > zeros(S const &space)
Definition TagPath.h:1092

◆ processModel() [2/2]

template<MatrixExpression Matrix, typename... Policies>
auto Emrys::processModel ( Matrix && matrix,
Policies &&... policies )
nodiscard
Returns
the linear whole-state process model \( x_{k+1} = F x_k \) of the matrix matrix over the state's coordinates, with policies, its noise (decisions.md [whole-state-models]): its function returns \( F x \) with \( F \) as its Jacobian, so every method predicts it exactly, as the matrix measurement model updates exactly. The state's coordinates must add their values, as a Linear state's do, and \( F \) is the same over every step; a model whose matrix depends on the step is a function.
auto const cv = processModel(F, additiveNoise(Q)); // F and Q are 4 by 4

◆ propagate()

template<Space Space_, typename Derived, ProcessModel Model, typename... Args>
Moments< Space_, typenameDerived::Scalar >::VectorType Emrys::propagate ( Space_ const & space,
Eigen::MatrixBase< Derived > const & x,
Model const & model,
TimeStep< typename Derived::Scalar > auto const & dt,
Args const &... args )
nodiscard
Returns
the state x in space moved forward by dt through the process model model with the call's args, each a sure input or an uncertain one read at its mean, before process noise: the function at the blocks read, written into the state by block. Not normalized. What a simulation or a test reads of a model's step.

◆ reads()

template<typename... Items>
auto Emrys::reads ( Items const & ...)
nodiscard
Returns
the reads() policy of items: each a path value, path<Tags...> or a tag's value, read under its last tag, or on<Name>(path), read under Name. Two items that would share a name are refused, with a message that points at on<Name>().

◆ sample()

template<typename G>
requires (!MatrixExpression<G> && !Space<std::remove_cvref_t<G>>)
Sample< std::remove_cvref_t< G > > Emrys::sample ( G && function)
nodiscard
Returns
the sample() policy of function, g(in, x, rng) (see Sample): what simulate() draws an observation by for a model known by its likelihood alone, whose logLikelihood() it must agree with

◆ shared()

Shared Emrys::jacobians::shared ( )
nodiscardconstexpr
Returns
the mark that a batched function writes one Jacobian for every column, which is the user's contract that the function is linear in its input (see Shared)

◆ simulate() [1/9]

template<typename Space, typename Scalar, std::uniform_random_bit_generator G>
Eigen::Index Emrys::simulate ( Eigen::Index from,
ContinuousTimeMarkovChain< Space, Scalar > const & chain,
G & rng,
TimeStep< Scalar > auto const & dt )
nodiscard
Returns
a draw of the value an interval of dt, any TimeStep, after the value from under the continuous-time chain chain: simulate() of its transition() over dt, which computes the matrix exponential at each call.

◆ simulate() [2/9]

template<typename Space, typename Scalar, std::uniform_random_bit_generator G>
Eigen::Index Emrys::simulate ( Eigen::Index from,
MarkovChain< Space, Scalar > const & chain,
G & rng )
nodiscard
Returns
a draw of the value one step of chain after the value from, as a flat index: a draw from chain.next(from), the true mode's next value in a simulation of a switching or hidden Markov model, as simulate() of a process model draws the true state's.
mode = simulate(mode, switching.chain(), rng);
Moments< Space_, typenameDerived::Scalar >::VectorType simulate(Space_ const &space, Eigen::MatrixBase< Derived > const &x, Model const &model, G &rng, TimeStep< typename Derived::Scalar > auto const &dt, Args const &... args)
Definition Simulation.h:130

It makes one uniform draw against the running sum of the row, as drawSample() of a Categorical does, and allocates nothing.

◆ simulate() [3/9]

template<FixedSizeSpace Space_, typename Derived, MeasurementModel M, std::uniform_random_bit_generator G, typename... Args>
requires Space<Space_>
auto Emrys::simulate ( Eigen::MatrixBase< Derived > const & x,
M const & model,
G & rng,
Args const &... args )
nodiscard
Returns
simulate(space, x, model, rng, args...) in the fixed-size space Space_, given as a template argument: simulate<State>(truth, gps, rng).

◆ simulate() [4/9]

template<FixedSizeSpace Space_, typename Derived, typename Model, std::uniform_random_bit_generator G, typename... Inputs>
requires (Space<Space_> && (isFixedStep<Model> || isUnboundStep<Model>))
Moments< Space_, typenameDerived::Scalar >::VectorType Emrys::simulate ( Eigen::MatrixBase< Derived > const & x,
Model const & model,
G & rng,
Inputs const &... inputs )
nodiscard
Returns
simulate(space, x, model, rng, inputs...) for the fixed-step model model, or fixedStep()'s result, in the fixed-size space Space_, given as a template argument: simulate<State>(truth, model, rng).

◆ simulate() [5/9]

template<FixedSizeSpace Space_, typename Derived, typename Model, std::uniform_random_bit_generator G, typename... Inputs>
requires (Space<Space_> && !isFixedStep<Model> && !isUnboundStep<Model>)
Moments< Space_, typenameDerived::Scalar >::VectorType Emrys::simulate ( Eigen::MatrixBase< Derived > const & x,
Model const & model,
G & rng,
TimeStep< typename Derived::Scalar > auto const & dt,
Inputs const &... inputs )
nodiscard
Returns
simulate(space, x, model, rng, dt, inputs...) in the fixed-size space Space_, given as a template argument: simulate<State>(truth, model, rng, dt).

◆ simulate() [6/9]

template<Space Space_, typename Derived, MeasurementModel M, std::uniform_random_bit_generator G, typename... Args>
auto Emrys::simulate ( Space_ const & space,
Eigen::MatrixBase< Derived > const & x,
M const & model,
G & rng,
Args const &... args )
nodiscard
Returns
a draw of the measurement that model makes of the true state x in space, with the call's args as observe() takes them after the observation: \( h(x, v) \boxplus w \), formed in the measurement space, for each uncertain input \( v \) drawn from its distribution and \( w \) drawn from the model's additive noise, a value in the measurement space that observe() turns into the measurement a filter takes.

This is the measurement model that a filter given model assumes, so a filter run on its draws from simulate()'s true states should pass NeesMonitor's and NisMonitor's tests. Each distribution is drawn by drawSample() of its density, the inputs in the order the model reads them and the noise last, in a fixed order from rng, so a seed fixes the run. A model known by its likelihood alone has no function, and is drawn by its sample(g), g(in, x, rng), after the inputs; without one it fails to compile.

auto const gps = measurementModel(Eigen::Matrix2d::Identity(), reads(path<Position>), additiveNoise(noise));
filter.update(observe(methods::linearized(), gps, simulate(space, truth, gps, rng)));
See also
observe(), NeesMonitor

◆ simulate() [7/9]

template<Space Space_, typename Derived, typename Model, std::uniform_random_bit_generator G, typename... Args>
requires isFixedStep<Model>
Moments< Space_, typenameDerived::Scalar >::VectorType Emrys::simulate ( Space_ const & space,
Eigen::MatrixBase< Derived > const & x,
Model const & model,
G & rng,
Args const &... args )
nodiscard
Returns
a draw of the true state one step of the fixed-step model model after the true state x in space, with the call's args: simulate(space, x, model, rng, dt, args...) over the model's step, with its cached process noise.

◆ simulate() [8/9]

template<Space Space_, typename Derived, ProcessModel Model, std::uniform_random_bit_generator G, typename... Args>
Moments< Space_, typenameDerived::Scalar >::VectorType Emrys::simulate ( Space_ const & space,
Eigen::MatrixBase< Derived > const & x,
Model const & model,
G & rng,
TimeStep< typename Derived::Scalar > auto const & dt,
Args const &... args )
nodiscard
Returns
a draw of the true state a time step dt after the true state x in space, under the process model model with the call's args: \( f(x) \boxplus w \), where \( f \) is the model's step and \( w \sim \mathcal{N}(0, Q) \) its process noise over dt.

This is the discrete-time model that a filter over model assumes, the one whose noise the blocks discretize as Bar-Shalom, Li, and Kirubarajan (2001) describe, so a filter run on its draws, with measurements drawn from the true states, should pass NeesMonitor's and NisMonitor's tests. simulate(space, x, model, rng) with a measurement model draws those measurements.

auto rng = std::mt19937_64{42};
auto truth = Eigen::Vector4d{0, 0, 1, 0};
for (int k = 0; k < steps; ++k)
{
truth = simulate(space, truth, model, rng, 0.1);
filter.predict(0.1);
filter.update(observe(methods::linearized(), gps, simulate(space, truth, gps, rng)));
}

dt is any TimeStep, converted to the state's scalar (see Time steps), which must be a standard floating-point type. args are the call's inputs as predict() takes them: a sure input, such as a control, reaches the model as it is, and an uncertain one is drawn from its distribution, the inputs in the order the model reads them and the process noise last, so that a seed fixes the run within one standard library: the standard normals come from std::normal_distribution, whose algorithm the standard leaves to the implementation, so one seed draws another run under libstdc++ than under MSVC's library (decisions.md [random-draws]). A filter's uncertain input is the noisy measurement of a true one, so give the simulation the true value as sure<Tag>(value).

See also
NeesMonitor, FixedStepModel

◆ simulate() [9/9]

template<Space Space_, typename Derived, typename Step, std::uniform_random_bit_generator G, typename... Args>
requires isUnboundStep<Step>
Moments< Space_, typenameDerived::Scalar >::VectorType Emrys::simulate ( Space_ const & space,
Eigen::MatrixBase< Derived > const & x,
Step const & step,
G & rng,
Args const &... args )
nodiscard
Returns
a draw of the true state one step of step, made by fixedStep(model, dt), after the true state x in space, with the call's args: simulate(space, x, model, rng, dt, args...).

◆ sure() [1/2]

template<Space S, MatrixExpression V>
auto Emrys::sure ( S space,
V && value )
nodiscard
Returns
value as the sure input in space, a tagged space instance, for a resizable space, whose size is checked against the instance

◆ sure() [2/2]

template<FixedSizeSpace S, MatrixExpression V>
requires Space<S>
auto Emrys::sure ( V && value)
nodiscard
Returns
value, a vector, as the sure input in the fixed-size tagged space S: sure<Gravity>(g). Its size is checked against the space, at compile time where the vector's is fixed.

◆ switchingMeasurement()

template<typename P, Measurement... Measurements>
SwitchingMeasurement< P, Measurements... > Emrys::switchingMeasurement ( Measurements... measurements)
nodiscard
Returns
a SwitchingMeasurement in which the mode's value in the axis named by the path P (a tag or a TagPath) selects the measurement: measurements has one per value of that axis, in order. filter.update(switchingMeasurement<Sensor>(nominal, biased)) updates the modes of an ImmFilter over DiscreteProduct<Maneuver, Sensor> whose Sensor value is the first by nominal, and the others by biased.

◆ switchingModel()

template<typename P, typename ModeSpace, typename Scalar, typename... Models>
SwitchingModel< ModeSpace, Scalar, P, Models... > Emrys::switchingModel ( MarkovChain< ModeSpace, Scalar > chain,
Models... models )
nodiscard
Returns
a SwitchingModel on the modes of chain in which the mode's value in the axis named by the path P (a tag or a TagPath) selects the process model: models has one per value of that axis, in order. switchingModel<Maneuver>(chain, cruise, turn) on a mode space DiscreteProduct<Maneuver, Sensor> gives both sensor states of a maneuver the same dynamics.

◆ update() [1/4]

template<typename Scalar, typename Space, EmissionModel< Space > E>
std::expected< CategoricalUpdate< Space, Scalar >, WeightError > Emrys::update ( CategoricalParams< Space, Scalar > const & prior,
E const & emission )
nodiscard
Returns
prior updated by emission, by Bayes' rule: the posterior \( p_v\, p(z \mid v) / p(z) \) and the log-evidence \( \log p(z) \), as a Gaussian update returns its log-likelihood; or a WeightError if the measurement is impossible under prior, or the weights of prior fail to define a distribution

◆ update() [2/4]

template<UncertainInput Prior, Measurement M>
auto Emrys::update ( Prior const & prior,
M const & measurement )
nodiscard
Returns
prior conditioned on measurement, as weighted branches (see MeasurementUpdate).

Only the blocks the measurement's model reads, \( S \), go through its transform. The full state is then corrected through the cross-covariance

\[ \Sigma_{xy} = P_{xS} \, P_{SS}^{-1} \, \Sigma_{Sy}, \]

which is exact under a Gaussian prior: \( E[x \mid S] \) is affine in \( S \), and the remainder is independent of \( S \) and so of \( h(S) \). A linear method's \( P_{SS}^{-1} \Sigma_{Sy} \) is its Jacobian, and a sigma-point method's \( R^{-T} \Psi \), a solve with the root \( R \) that spread its points (decisions.md [linearization-forms]), whose least-norm solution keeps a block known exactly fine.

The innovation covariance must be positive definite, since each branch's gain and likelihood come from its Cholesky factor (decisions.md [innovation-cholesky]). Measurement noise that is positive definite makes it so; a measurement with no noise of a quantity the prior knows exactly does not, and neither can rounding or an unscented transform with a negative center weight. Such an update returns GaussianError::NotPositiveDefinite, whichever branch it was in. A constraint that a measurement with no noise would impose is better kept by a space (see Spaces) or a small positive noise.

The measurement \( \hat z \) is predicted in the measurement space, and the residual of the observation from it, \( z \boxminus \hat z \), is formed there, so a bearing wraps and a rotation's residual is its rotation vector. With additive noise, the measurement function is transformed once, whatever the number of noise components. Component \( k \), with weight \( w_k \), mean \( \mu_k \), and covariance \( R_k \), predicts the measurement \( \hat z \boxplus \mu_k \) with covariance \( \Sigma_{zz} + R_k \), and its branch is the Kalman update (see update()) by the observation. Its weight is \( w_k \, p(z \mid k) / p(z) \). An uncertain input of the call goes through the function with the blocks read, and widens \( \Sigma_{zz} \).

The covariance is updated in the form the measurement was given (see observe()), updates::Standard by default. updates::Joseph linearizes the measurement before additive noise once (see statisticalLinearization()), and each component adds its own \( R_k \) to the linearization error, so a precise measurement's noise is never recovered by subtraction.

The branches are the hypotheses of a Gaussian-sum update (Bar-Shalom, Li, and Kirubarajan (2001)); with one inlier and one outlier component and the Collapse policy, the result is the probabilistic data association update of Bar-Shalom and Tse (1975).

Returns
the branches, or GaussianError::NotPositiveDefinite
See also
observe(), Measurement, Models

◆ update() [3/4]

template<UncertainInput Prior, Measurement M, typename Space, typename P, typename Value>
auto Emrys::update ( Prior const & prior,
M const & measurement,
GivenBlock< Space, P, Value > const & pinned )
nodiscard
Returns
prior, a Gaussian over the rest of a state, conditioned on measurement, with the block that pinned names given separately: weighted branches over the rest, or the error, as update(prior, measurement) returns them.

The measurement's model reads blocks of the whole state by tag path as usual; the given block comes from pinned, and the others from prior, whose space is the rest of the state in order. A given value is known exactly, as a grid point or a particle is. A given Gaussian is an independent uncertain input: its uncertainty widens the predicted measurement, but it is not conditioned on the measurement, so a later update treats it as independent again. This is the update of a Rao-Blackwellized filter's conditional Gaussian given its point.

// prior over Composite<Velocity, Bias>, given Position of Composite<Position, Velocity, Bias>
auto const updated = update(prior, observe(methods::unscented(), rangePlusBias, z), given<Position>(State{},
cellCenter));
GivenBlock< Space, P, Value > given(Space const &space, Value const &value)
Definition Measurement.h:917
std::expected< CategoricalUpdate< Space, Scalar >, WeightError > update(CategoricalParams< Space, Scalar > const &prior, E const &emission)
Definition Emission.h:97
See also
given(), RbPointMassFilter

◆ update() [4/4]

template<UncertainInput Prior, Measurement M, typename Reference>
auto Emrys::update ( Prior const & prior,
M const & measurement,
LinearizedAbout< Reference > const & about )
nodiscard
Returns
prior conditioned on measurement, as update(prior, measurement) does, with the measurement linearized about about rather than at the prior (decisions.md [linearization-reference]): by Linearized at the reference's point, or by a sigma-point method over its distribution, with the Jacobian carried to the prior's chart and the predicted measurement moved back along it to the prior mean, and the Kalman update of the prior under that linearization. About the prior's own mean, Linearized gives update(prior, measurement) to rounding; about the posterior of an update, it is the next iteration of an Iterated one.

Every noise component branches from the one linearization. An Iterated measurement, which chooses its own points, refuses a reference at compile time, as does a sigma-point method given a point.

Returns
the branches, or GaussianError::NotPositiveDefinite
See also
linearizedAbout(), Models

◆ withMethod()

template<typename Model, TransformMethod Method>
ModelWithMethod< Model, Method > Emrys::withMethod ( Model model,
Method method )
nodiscard
Returns
model, which a mode of a SwitchingModel predicts by method in place of the filter's method: SwitchingModel{chain, cruise, withMethod(turn, methods::unscented())} [switching-models]. A fixed-step model takes its method from fixedStep() instead.

◆ writes()

template<PathValue... Paths>
auto Emrys::writes ( Paths const & ...)
nodiscard
Returns
the writes() policy of paths, each a path value, distinct