32template <
typename Chain>
33inline constexpr bool IsContinuousTimeChain =
false;
36template <
typename Space,
typename Scalar>
37inline constexpr bool IsContinuousTimeChain<ContinuousTimeMarkovChain<Space, Scalar>> =
true;
56template <DiscreteSpace Space, RealScalar Scalar>
74template <
typename Scalar =
double>
83 return m_logLikelihood;
90 friend struct internal::UpdateAccess;
92 Scalar m_logLikelihood = 0;
134class HiddenMarkovFilter :
public internal::HeldUpkeep<HiddenMarkovFilter<Space_, Chain_, Scalar_, Upkeep_>, Upkeep_>
136 using UpkeepBase = internal::HeldUpkeep<HiddenMarkovFilter, Upkeep_>;
139 std::is_same_v<typename Chain_::SpaceType, Space_> && std::is_same_v<typename Chain_::Scalar, Scalar_>,
140 "the chain must be on the filter's space, in its scalar"
154 : UpkeepBase{std::move(
upkeep)}
155 , m_chain{std::move(
chain)}
156 , m_state{std::move(
state)}
158 EMRYS_FILTER_ASSERT(m_chain.space() == m_state.
space() &&
"the chain is on a different space");
163 : UpkeepBase{Upkeep_{}}
164 , m_chain{std::move(
chain)}
165 , m_state{m_chain.space()}
191 EMRYS_FILTER_ASSERT(m_chain.space() ==
state.space() &&
"the state is on a different space");
192 m_state = std::move(
state);
196 [[nodiscard]] Chain_
const &
203 [[nodiscard]] Chain_ &
215 return m_logEvidence;
222 m_logEvidence =
Scalar(0);
228 requires(!internal::IsContinuousTimeChain<Chain_>)
238 requires internal::IsContinuousTimeChain<Chain_>
250 [[nodiscard]] std::expected<Scalar, WeightError>
252 requires internal::IsContinuousTimeChain<Chain_>
262 requires(!internal::IsContinuousTimeChain<Chain_>)
266 m_state = std::move(predicted);
275 requires internal::IsContinuousTimeChain<Chain_>
277 auto step = m_chain.transition(dt);
280 m_state = std::move(predicted);
290 [[nodiscard]] std::expected<CategoricalPredictedJoint<Space_, Scalar_>,
WeightError>
292 requires internal::IsContinuousTimeChain<Chain_>
294 auto step = internal::arrivalKernel(m_chain, internal::toScalarTime<Scalar>(dt), interval);
295 auto moved = internal::moveByKernel(m_state, step.kernel, step.logScale);
298 return std::unexpected{moved.error()};
302 step.kernel /= Eigen::numext::exp(
Scalar(moved->logEvidence - step.logScale));
305 m_state = std::move(moved->posterior);
306 m_logEvidence += moved->logEvidence;
323 template <EmissionModel<Space_> E>
324 [[nodiscard]] std::expected<HiddenMarkovFilterUpdate<Scalar_>,
WeightError>
327 auto const prior = m_state.logTotalWeight();
330 return std::unexpected{prior.error()};
332 auto const evidence = m_state.update(internal::emissionLogLikelihoods(m_state, emission));
339 return std::unexpected{evidence.error()};
341 internal::UpdateAccess::logLikelihood(result) = -Eigen::NumTraits<Scalar_>::infinity();
342 m_logEvidence = -Eigen::NumTraits<Scalar_>::infinity();
345 internal::UpdateAccess::logLikelihood(result) = *evidence;
347 m_logEvidence += *evidence;
354 [[nodiscard]] std::expected<Scalar, WeightError>
359 return std::unexpected{result.error()};
361 m_state = std::move(result->posterior);
362 m_logEvidence += result->logEvidence;
363 return result->logEvidence;
372template <
typename Chain>
376template <
typename Chain>
379template <
typename Chain,
typename U>
387#ifndef EMRYS_FILTER_NO_IO
396template <
typename Space_,
typename Chain_,
typename Scalar_,
typename Upkeep_>
398describe(std::ostream & stream, HiddenMarkovFilter<Space_, Chain_, Scalar_, Upkeep_>
const & filter, Indent indent)
400 describeFilter(stream,
"hidden Markov filter", filter.state(), indent);
The distribution over a discrete space (decisions.md [discrete-spaces], [params-and-density]): Catego...
The continuous-time chain on a discrete space: ContinuousTimeMarkovChain, built from a generator of r...
Discrete spaces (decisions.md [discrete-spaces]): the DiscreteSpace concept; Finite,...
The measurement of a discrete state: the EmissionModel concept, which fills one log-likelihood per va...
The upkeep a filter holds (decisions.md [upkeep]): internal::HeldUpkeep, the base that gives every fi...
The macros every header includes first.
Mathematical constants and scalar functions that work in every scalar type the library accepts,...
Printing: operator<< and std::formatter for every distribution, every filter (which prints its name a...
The Recursion concept (decisions.md [filters-and-recursions], [user-extension-points]): what a Kalman...
Log-weights: the WeightError a normalization can fail with (NumericError.h), and the streaming log-su...
The observation of a Markov-modulated Poisson process over an interval: no event inside it,...
Definition Emission.h:502
The parameters of a probability distribution over a discrete space: one weight per value.
Definition Categorical.h:257
Space_ const & space() const
Definition Categorical.h:330
What a hidden Markov filter's update did: the measurement's log-evidence under the prior,...
Definition HiddenMarkovFilter.h:76
bool accepted
whether some value with a nonzero probability could explain the measurement
Definition HiddenMarkovFilter.h:86
Scalar logLikelihood() const
Definition HiddenMarkovFilter.h:81
A hidden Markov model filter: a CategoricalParams state, the chain that moves it, and the log-evidenc...
Definition HiddenMarkovFilter.h:135
void setState(StateType state)
Replaces the state estimate with one on the chain's space, as the constructor's must be,...
Definition HiddenMarkovFilter.h:189
CategoricalPredictedJoint< Space_, Scalar_ > predictJoint()
Moves the state one step of a MarkovChain, as predict(), and returns the step's joint for a Categoric...
Definition HiddenMarkovFilter.h:261
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
Chain_ ChainType
the chain
Definition HiddenMarkovFilter.h:147
void predict()
Moves the state one step of a MarkovChain: .
Definition HiddenMarkovFilter.h:227
void resetLogEvidence()
Sets the log-evidence back to zero, to start a new record from the current state.
Definition HiddenMarkovFilter.h:220
CategoricalParams< Space_, Scalar_ > StateType
the state the filter owns
Definition HiddenMarkovFilter.h:148
Space_ SpaceType
the discrete space
Definition HiddenMarkovFilter.h:146
Scalar logEvidence() const
Definition HiddenMarkovFilter.h:213
StateType & state()
Definition HiddenMarkovFilter.h:180
CategoricalPredictedJoint< Space_, Scalar_ > predictJoint(TimeStep< Scalar > auto const &dt)
Moves the state over an interval of dt of a ContinuousTimeMarkovChain, as predict(dt),...
Definition HiddenMarkovFilter.h:274
Chain_ const & chain() const
Definition HiddenMarkovFilter.h:197
StateType const & state() const
Definition HiddenMarkovFilter.h:170
Scalar_ Scalar
the scalar type of the probabilities
Definition HiddenMarkovFilter.h:145
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 M...
Definition HiddenMarkovFilter.h:251
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),...
Definition HiddenMarkovFilter.h:291
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 t...
Definition HiddenMarkovFilter.h:325
void predict(TimeStep< Scalar > auto const &dt)
Moves the state over an interval of dt, any TimeStep (see Time steps), of a ContinuousTimeMarkovChain...
Definition HiddenMarkovFilter.h:237
Chain_ & chain()
Definition HiddenMarkovFilter.h:204
HiddenMarkovFilter(Chain_ chain)
The filter moved by chain, starting from the uniform distribution over its space.
Definition HiddenMarkovFilter.h:162
A Markov chain on a discrete space: the probability of moving from each value to each value in one st...
Definition Categorical.h:829
Eigen::Matrix< Scalar_, CardinalityAtCompileTime, CardinalityAtCompileTime, Eigen::RowMajor, MaxCardinalityAtCompileTime, MaxCardinalityAtCompileTime > MatrixType
The transition matrix's type: a row per value moved from, a column per value moved to.
Definition Categorical.h:838
A type usable as a discrete space: a finite set of values.
Definition Discrete.h:72
A type usable as the scalar of a distribution: a real number type such as float, double,...
Definition Math.h:80
A step of time that converts to Scalar: Scalar itself, or any type with a TimeTraits,...
Definition Time.h:128
NumericError WeightError
Reasons a collection of log-weights cannot be normalized: Empty, ZeroSum, or NonFinite of NumericErro...
Definition NumericError.h:53
@ ZeroSum
every weight is zero (every log-weight is -inf)
Definition NumericError.h:35
CategoricalParams< Space, Scalar > predict(CategoricalParams< Space, Scalar > const &prior, MarkovChain< Space, Scalar > const &chain)
Definition Categorical.h:1049
The upkeep operations, each made by its factory (decisions.md [policy-factories], [upkeep]): the acti...
Definition Upkeep.h:380
One prediction of a HiddenMarkovFilter as a smoother needs it: the distribution the step started from...
Definition HiddenMarkovFilter.h:58
CategoricalParams< Space, Scalar > filtered
Definition HiddenMarkovFilter.h:61
MatrixType transitions
Definition HiddenMarkovFilter.h:63
CategoricalParams< Space, Scalar > predicted
Definition HiddenMarkovFilter.h:62
typename MarkovChain< Space, Scalar >::MatrixType MatrixType
the transitions' type
Definition HiddenMarkovFilter.h:59
The result of updating a CategoricalParams by an emission model: the posterior, whose weights sum to ...
Definition Emission.h:66
The upkeep a filter holds when it is given none: it takes any state, changes nothing,...
Definition Upkeep.h:889