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

A Markov chain on a discrete space: the probability of moving from each value to each value in one step. More...

#include <EmrysFilter/Distributions/Categorical.h>

Public Types

using Scalar = Scalar_
 the scalar type of the probabilities
using SpaceType = Space_
 the discrete space
using MatrixType
 The transition matrix's type: a row per value moved from, a column per value moved to.

Public Member Functions

 MarkovChain (Space_ space={})
 The chain that never moves.
template<MatrixExpression Transitions>
 MarkovChain (Space_ space, Transitions &&transitions)
 The chain on space with transition matrix transitions: nonnegative, with each row summing to one.
template<MatrixExpression Transitions>
requires FixedSizeSpace<Space_>
 MarkovChain (Transitions &&transitions)
 The chain on a FixedSizeSpace, named as the template argument, with transition matrix transitions: MarkovChain<Maneuver>{matrix} (decisions.md [space-storage]).
template<DiscreteSpace... Axes>
requires ( internal::IsDiscreteProduct<Space_> && sizeof...(Axes) == std::tuple_size_v<internal::DiscreteProductAxes<Space_>> )
 MarkovChain (Space_ space, MarkovChain< Axes, Scalar_ > const &... chains)
 The chain on the DiscreteProduct space whose axes move independently, each by its own chain in chains, one per axis in order.
template<DiscreteSpace... Axes>
requires ( FixedSizeSpace<Space_> && internal::IsDiscreteProduct<Space_> && sizeof...(Axes) == std::tuple_size_v
<internal::DiscreteProductAxes<Space_>> )
 MarkovChain (MarkovChain< Axes, Scalar_ > const &... chains)
 The chain on a DiscreteProduct that is a FixedSizeSpace, named as the template argument, whose axes move independently by chains: MarkovChain<Mode>{maneuver, sensor}.
Space_ const & space () const
MatrixType const & matrix () const
Scalar transition (Eigen::Index from, Eigen::Index to) const
CategoricalParams< Space_, Scalar_ > next (Eigen::Index from) const

Static Public Member Functions

static MarkovChain persistent (Scalar stay, Space_ space={})
static MarkovChain memoryless (Categorical< Space_, Scalar_ > const &next)
template<typename DwellTimes, typename ExitWeights>
static MarkovChain fromDwellTimes (Eigen::MatrixBase< DwellTimes > const &dwellTimes, Eigen::MatrixBase< ExitWeights > const &exitWeights, Space_ space={})
template<typename DwellTimes>
static MarkovChain fromDwellTimes (Eigen::MatrixBase< DwellTimes > const &dwellTimes, Space_ space={})

Static Public Attributes

static constexpr int CardinalityAtCompileTime = Space_::Cardinality
 the number of values, or Eigen::Dynamic
static constexpr int MaxCardinalityAtCompileTime = Space_::MaxCardinality
 a bound on it, or Eigen::Dynamic

Detailed Description

template<DiscreteSpace Space_, RealScalar Scalar_ = double>
class Emrys::MarkovChain< Space_, Scalar_ >

A Markov chain on a discrete space: the probability of moving from each value to each value in one step.

A time-homogeneous Markov chain on a finite set. The transition matrix \( \Pi \), a right stochastic matrix, has a row per value moved from and a column per value moved to, so \( \Pi_{ij} = P(j \mid i) \) and each row sums to one. predict() moves a Categorical one step: \( p'_j = \sum_i p_i \Pi_{ij} \).

A chain on a DiscreteProduct can be built from independent chains on its axes, whose matrix is their Kronecker product, as a maneuver regime and a sensor's outlier state switch independently:

auto const mode = MarkovChain<Mode>{maneuver, sensor};
MarkovChain(Space_ space={})
The chain that never moves.
Definition Categorical.h:847
static MarkovChain persistent(Scalar stay, Space_ space={})
Definition Categorical.h:934

A chain is often known by how long it stays at each value and where it goes when it leaves. fromDwellTimes() builds it from both, and stationary() gives the distribution it settles into, the prior for a mode that has run long before the first measurement:

// a cruise lasts 30 steps, a turn 8, a dive 4; a cruise ends in a turn twice as often as in a dive
auto const exits = Eigen::Matrix3d{{0, 2, 1}, {1, 0, 0}, {1, 0, 0}};
auto const chain = MarkovChain<Flight>::fromDwellTimes(Eigen::Vector3d{30, 8, 4}, exits);
auto const prior = stationary(chain); // 9/11, 8/55, 2/55, or a ChainError
static MarkovChain fromDwellTimes(Eigen::MatrixBase< DwellTimes > const &dwellTimes, Eigen::MatrixBase< ExitWeights > const &exitWeights, Space_ space={})
Definition Categorical.h:973
std::expected< CategoricalParams< Space, Scalar >, ChainError > stationary(MarkovChain< Space, Scalar > const &chain)
Definition Categorical.h:1069
Template Parameters
Space_the discrete space (see Discrete spaces)
Scalar_scalar type of the probabilities, double by default

Member Typedef Documentation

◆ MatrixType

template<DiscreteSpace Space_, RealScalar Scalar_ = double>
using Emrys::MarkovChain< Space_, Scalar_ >::MatrixType
Initial value:
Eigen::Matrix<
Scalar_,
Eigen::RowMajor,
static constexpr int CardinalityAtCompileTime
the number of values, or Eigen::Dynamic
Definition Categorical.h:834
static constexpr int MaxCardinalityAtCompileTime
a bound on it, or Eigen::Dynamic
Definition Categorical.h:835

The transition matrix's type: a row per value moved from, a column per value moved to.

Constructor & Destructor Documentation

◆ MarkovChain()

template<DiscreteSpace Space_, RealScalar Scalar_ = double>
template<DiscreteSpace... Axes>
requires ( internal::IsDiscreteProduct<Space_> && sizeof...(Axes) == std::tuple_size_v<internal::DiscreteProductAxes<Space_>> )
Emrys::MarkovChain< Space_, Scalar_ >::MarkovChain ( Space_ space,
MarkovChain< Axes, Scalar_ > const &... chains )
inline

The chain on the DiscreteProduct space whose axes move independently, each by its own chain in chains, one per axis in order.

Its matrix is their Kronecker product.

Member Function Documentation

◆ fromDwellTimes() [1/2]

template<DiscreteSpace Space_, RealScalar Scalar_ = double>
template<typename DwellTimes, typename ExitWeights>
MarkovChain Emrys::MarkovChain< Space_, Scalar_ >::fromDwellTimes ( Eigen::MatrixBase< DwellTimes > const & dwellTimes,
Eigen::MatrixBase< ExitWeights > const & exitWeights,
Space_ space = {} )
inlinestaticnodiscard
Returns
the chain on space that stays at value \( i \) for a mean of \( \tau_i \) steps, dwellTimes, and on leaving moves to each other value \( j \) in proportion to \( w_{ij} \), exitWeights: \( \Pi_{ii} = 1 - 1/\tau_i \) and \( \Pi_{ij} = w_{ij} / (\tau_i \sum_k w_{ik}) \).

The number of steps at a value, counting the step that reached it, is geometric with mean \( 1 / (1 - \Pi_{ii}) \), so each \( \tau_i \) is at least one, and an infinite one never leaves. The exit weights are nonnegative, need not sum to one, and are zero on the diagonal; a value that is left needs one that isn't zero. A dwell time in seconds with a fixed step is ContinuousTimeMarkovChain::fromDwellTimes() and its transition() over the step, which is exact where \( 1 - \Delta t / \tau_i \) is not.

◆ fromDwellTimes() [2/2]

template<DiscreteSpace Space_, RealScalar Scalar_ = double>
template<typename DwellTimes>
MarkovChain Emrys::MarkovChain< Space_, Scalar_ >::fromDwellTimes ( Eigen::MatrixBase< DwellTimes > const & dwellTimes,
Space_ space = {} )
inlinestaticnodiscard
Returns
the chain on space that stays at value \( i \) for a mean of \( \tau_i \) steps, dwellTimes, and on leaving moves to any other value with equal probability: the other fromDwellTimes() with every exit weight one

◆ matrix()

template<DiscreteSpace Space_, RealScalar Scalar_ = double>
MatrixType const & Emrys::MarkovChain< Space_, Scalar_ >::matrix ( ) const
inlinenodiscard
Returns
the transition matrix \( \Pi \), with \( \Pi_{ij} = P(j \mid i) \)

◆ memoryless()

template<DiscreteSpace Space_, RealScalar Scalar_ = double>
MarkovChain Emrys::MarkovChain< Space_, Scalar_ >::memoryless ( Categorical< Space_, Scalar_ > const & next)
inlinestaticnodiscard
Returns
the chain that moves to each value with the probabilities of next, wherever it starts: every row is the same, so the value at each step is independent of the last

◆ next()

template<DiscreteSpace Space_, RealScalar Scalar_ = double>
CategoricalParams< Space_, Scalar_ > Emrys::MarkovChain< Space_, Scalar_ >::next ( Eigen::Index from) const
inlinenodiscard
Returns
the distribution of the value one step after the value from: row from of the transition matrix, as parameters whose log-weights are its log-probabilities. simulate() draws from it without building it.

◆ persistent()

template<DiscreteSpace Space_, RealScalar Scalar_ = double>
MarkovChain Emrys::MarkovChain< Space_, Scalar_ >::persistent ( Scalar stay,
Space_ space = {} )
inlinestaticnodiscard
Returns
the chain on space that stays at its value with probability stay and otherwise moves to any other value with equal probability

◆ space()

template<DiscreteSpace Space_, RealScalar Scalar_ = double>
Space_ const & Emrys::MarkovChain< Space_, Scalar_ >::space ( ) const
inlinenodiscard
Returns
the discrete space

◆ transition()

template<DiscreteSpace Space_, RealScalar Scalar_ = double>
Scalar Emrys::MarkovChain< Space_, Scalar_ >::transition ( Eigen::Index from,
Eigen::Index to ) const
inlinenodiscard
Returns
the probability of moving from the value from to the value to in one step

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