EmrysFilter 0.1.0
State estimation utilities in C++23 using Eigen
Loading...
Searching...
No Matches
Emrys::HiddenMarkovFilter< Space_, Chain_, Scalar_, Upkeep_ > Class Template Reference

A hidden Markov model filter: a CategoricalParams state, the chain that moves it, and the log-evidence of the measurements so far. More...

#include <EmrysFilter/Filters/HiddenMarkovFilter.h>

Inheritance diagram for Emrys::HiddenMarkovFilter< Space_, Chain_, Scalar_, Upkeep_ >:

Public Types

using Scalar = Scalar_
 the scalar type of the probabilities
using SpaceType = Space_
 the discrete space
using ChainType = Chain_
 the chain
using StateType = CategoricalParams<Space_, Scalar_>
 the state the filter owns

Public Member Functions

 HiddenMarkovFilter (Chain_ chain, StateType state, std::type_identity_t< Upkeep_ > upkeep={})
 The filter moved by chain, starting from state, with upkeep upkeep, which maintain() runs.
 HiddenMarkovFilter (Chain_ chain)
 The filter moved by chain, starting from the uniform distribution over its space.
StateType const & state () const
StateType & state ()
void setState (StateType state)
 Replaces the state estimate with one on the chain's space, as the constructor's must be, leaving the log-evidence as it is.
Chain_ const & chain () const
Chain_ & chain ()
Scalar logEvidence () const
void resetLogEvidence ()
 Sets the log-evidence back to zero, to start a new record from the current state.
void predict ()
 Moves the state one step of a MarkovChain: \( p' = p\, \Pi \).
void predict (TimeStep< Scalar > auto const &dt)
 Moves the state over an interval of dt, any TimeStep (see Time steps), of a ContinuousTimeMarkovChain: \( p' = p\, e^{Q \Delta t} \).
std::expected< Scalar, WeightError > predict (TimeStep< Scalar > auto const &dt, ArrivalInterval< Space_, Scalar_ > const &interval)
 Moves the state over an interval of dt of a ContinuousTimeMarkovChain while observing interval of a Markov-modulated Poisson process, and adds its log-likelihood to the log-evidence (see ArrivalInterval).
CategoricalPredictedJoint< Space_, Scalar_ > predictJoint ()
 Moves the state one step of a MarkovChain, as predict(), and returns the step's joint for a CategoricalHistory.
CategoricalPredictedJoint< Space_, Scalar_ > predictJoint (TimeStep< Scalar > auto const &dt)
 Moves the state over an interval of dt of a ContinuousTimeMarkovChain, as predict(dt), and returns the step's joint for a CategoricalHistory.
std::expected< CategoricalPredictedJoint< Space_, Scalar_ >, WeightError > predictJoint (TimeStep< Scalar > auto const &dt, ArrivalInterval< Space_, Scalar_ > const &interval)
 Moves the state over an interval of dt while observing interval, as predict(dt, interval), and returns the step's joint for a CategoricalHistory.
template<EmissionModel< Space_ > E>
std::expected< HiddenMarkovFilterUpdate< Scalar_ >, WeightError > update (E const &emission)
 Updates the state by emission, by Bayes' rule, in place, and adds the measurement's log-evidence to the total.

Detailed Description

template<DiscreteSpace Space_, typename Chain_ = MarkovChain<Space_>, RealScalar Scalar_ = double, typename Upkeep_ = upkeep::None>
class Emrys::HiddenMarkovFilter< Space_, Chain_, Scalar_, Upkeep_ >

A hidden Markov model filter: a CategoricalParams state, the chain that moves it, and the log-evidence of the measurements so far.

The forward recursion of a hidden Markov model (Rabiner (1989), §III-A), kept normalized at every update as that paper's §V-A scales it, with the log of each step's normalizer summed into logEvidence(), which is \( \log p(z_{1:k}) \), the quantity for comparing models. The weights themselves are logs, so a long run of unlikely measurements underflows neither [discrete-spaces]. A state given by the user need not be normalized; an update checks it, and fails with a WeightError if its weights fail to define a distribution. An update conditions the state where it is, and a measurement no value explains is rejected and leaves it as it was [update-outcomes].

With a MarkovChain, predict() takes one step of the chain. With a ContinuousTimeMarkovChain, predict(dt) moves the state over an interval exactly, and predict(dt, interval) does so while observing an ArrivalInterval, which makes the filter the Markov-modulated Poisson process filter. update() takes any EmissionModel.

filter.predict();
auto const updated = filter.update(table.observe(Activity::index<Walk>())); // or a WeightError
filter.state().toDensity()->probability<Rainy>();
filter.logEvidence();
The parameters of a probability distribution over a discrete space: one weight per value.
Definition Categorical.h:257
HiddenMarkovFilter(Chain_ chain, StateType state, std::type_identity_t< Upkeep_ > upkeep={})
The filter moved by chain, starting from state, with upkeep upkeep, which maintain() runs.
Definition HiddenMarkovFilter.h:153
static MarkovChain persistent(Scalar stay, Space_ space={})
Definition Categorical.h:934
Template Parameters
Space_the discrete space (see Discrete spaces)
Chain_MarkovChain or ContinuousTimeMarkovChain on the space
Scalar_scalar type of the probabilities, double by default
Upkeep_the upkeep maintain() runs on the state (see Upkeep), upkeep::None unless given one; the library has no action for a categorical state, so it is the caller's own
See also
CategoricalParams, EmissionModel, Filters

Member Function Documentation

◆ chain() [1/2]

template<DiscreteSpace Space_, typename Chain_ = MarkovChain<Space_>, RealScalar Scalar_ = double, typename Upkeep_ = upkeep::None>
Chain_ & Emrys::HiddenMarkovFilter< Space_, Chain_, Scalar_, Upkeep_ >::chain ( )
inlinenodiscard
Returns
the chain, to change between steps

◆ chain() [2/2]

template<DiscreteSpace Space_, typename Chain_ = MarkovChain<Space_>, RealScalar Scalar_ = double, typename Upkeep_ = upkeep::None>
Chain_ const & Emrys::HiddenMarkovFilter< Space_, Chain_, Scalar_, Upkeep_ >::chain ( ) const
inlinenodiscard
Returns
the chain

◆ logEvidence()

template<DiscreteSpace Space_, typename Chain_ = MarkovChain<Space_>, RealScalar Scalar_ = double, typename Upkeep_ = upkeep::None>
Scalar Emrys::HiddenMarkovFilter< Space_, Chain_, Scalar_, Upkeep_ >::logEvidence ( ) const
inlinenodiscard
Returns
the log-evidence \( \log p(z_{1:k}) \) of every measurement since construction or the last resetLogEvidence(): the sum of each update's and each observed interval's

◆ predict()

template<DiscreteSpace Space_, typename Chain_ = MarkovChain<Space_>, RealScalar Scalar_ = double, typename Upkeep_ = upkeep::None>
std::expected< Scalar, WeightError > Emrys::HiddenMarkovFilter< Space_, Chain_, Scalar_, Upkeep_ >::predict ( TimeStep< Scalar > auto const & dt,
ArrivalInterval< Space_, Scalar_ > const & interval )
inlinenodiscard

Moves the state over an interval of dt of a ContinuousTimeMarkovChain while observing interval of a Markov-modulated Poisson process, and adds its log-likelihood to the log-evidence (see ArrivalInterval).

Returns
the interval's log-likelihood, or a WeightError if the observation is impossible under the state, which is then unchanged

◆ predictJoint()

template<DiscreteSpace Space_, typename Chain_ = MarkovChain<Space_>, RealScalar Scalar_ = double, typename Upkeep_ = upkeep::None>
std::expected< CategoricalPredictedJoint< Space_, Scalar_ >, WeightError > Emrys::HiddenMarkovFilter< Space_, Chain_, Scalar_, Upkeep_ >::predictJoint ( TimeStep< Scalar > auto const & dt,
ArrivalInterval< Space_, Scalar_ > const & interval )
inlinenodiscard

Moves the state over an interval of dt while observing interval, as predict(dt, interval), and returns the step's joint for a CategoricalHistory.

Returns
the joint, or a WeightError if the observation is impossible under the state, which is then unchanged

◆ state() [1/2]

template<DiscreteSpace Space_, typename Chain_ = MarkovChain<Space_>, RealScalar Scalar_ = double, typename Upkeep_ = upkeep::None>
StateType & Emrys::HiddenMarkovFilter< Space_, Chain_, Scalar_, Upkeep_ >::state ( )
inlinenodiscard
Returns
the state estimate, to change where it is between steps, as when setting its weights. It must stay on the chain's space; setState() replaces it with another, and checks it. The log-evidence is left as it is.

◆ state() [2/2]

template<DiscreteSpace Space_, typename Chain_ = MarkovChain<Space_>, RealScalar Scalar_ = double, typename Upkeep_ = upkeep::None>
StateType const & Emrys::HiddenMarkovFilter< Space_, Chain_, Scalar_, Upkeep_ >::state ( ) const
inlinenodiscard
Returns
the state estimate

◆ update()

template<DiscreteSpace Space_, typename Chain_ = MarkovChain<Space_>, RealScalar Scalar_ = double, typename Upkeep_ = upkeep::None>
template<EmissionModel< Space_ > E>
std::expected< HiddenMarkovFilterUpdate< Scalar_ >, WeightError > Emrys::HiddenMarkovFilter< Space_, Chain_, Scalar_, Upkeep_ >::update ( E const & emission)
inlinenodiscard

Updates the state by emission, by Bayes' rule, in place, and adds the measurement's log-evidence to the total.

A measurement impossible under the state, to which every value with a nonzero probability gives likelihood zero, is rejected (decisions.md [update-outcomes]): the state is unchanged, the result's log-likelihood is \( -\infty \), and so is logEvidence() from then until resetLogEvidence(), since the measurements so far have probability zero under the model.

Returns
the log-evidence \( \log p(z_k \mid z_{1:k-1}) \) as the result's logLikelihood(), and whether the measurement was accepted (see HiddenMarkovFilterUpdate); or the WeightError of a state whose weights fail to define a distribution, or of a log-likelihood that is NaN or \( +\infty \), with the state and the log-evidence unchanged

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