16#include <unsupported/Eigen/MatrixFunctions>
59template <DiscreteSpace Space_, RealScalar Scalar_ =
double>
74 : m_space{std::move(
space)}
75 , m_generator{
MatrixType::Zero(m_space.cardinality(), m_space.cardinality())}
81 template <MatrixExpression Generator>
83 : m_space{std::move(
space)}
84 , m_generator{internal::castScalar<
Scalar>(std::forward<Generator>(
generator))}
87 m_generator.rows() == m_space.cardinality() && m_generator.cols() == m_space.cardinality()
88 &&
"the generator has a row and a column per value"
90 [[maybe_unused]]
Scalar scale = 0;
91 for (Eigen::Index i = 0; i < m_generator.rows(); ++i)
93 for (Eigen::Index j = 0; j < m_generator.cols(); ++j)
95 EMRYS_FILTER_ASSERT((i == j || m_generator(i, j) >=
Scalar(0)) &&
"rates must be nonnegative");
97 scale = Eigen::numext::maxi(scale,
Scalar(-m_generator(i, i)));
100 (m_generator.rowwise().sum().array().abs()
101 <= Eigen::NumTraits<Scalar>::dummy_precision() * Eigen::numext::maxi(scale,
Scalar(1)))
103 &&
"each row of the generator must sum to zero"
110 template <MatrixExpression Generator>
122 &&
sizeof...(Axes) == std::tuple_size_v<internal::DiscreteProductAxes<Space_>>
133 internal::IsDiscreteProduct<Space_>
134 &&
sizeof...(Axes) == std::tuple_size_v<internal::DiscreteProductAxes<Space_>>
137 : m_space{std::move(
space)}
140 std::is_same_v<std::tuple<
Axes...>, internal::DiscreteProductAxes<Space_>>,
141 "give one chain per axis of the product, in order"
143 Eigen::Index
const n = m_space.cardinality();
144 m_generator = MatrixType::Zero(n, n);
145 Eigen::Index stride = n;
148 Eigen::Index
const count = chains.
space().cardinality();
152 for (Eigen::Index i = 0; i < n; ++i)
154 Eigen::Index
const from = (i / stride) % count;
155 Eigen::Index
const base = i - from * stride;
156 for (Eigen::Index to = 0; to < count; ++to)
158 m_generator(i, base + to * stride) += chains.
generator()(from, to);
164 EMRYS_FILTER_ASSERT(stride == 1 &&
"each chain must have its axis's cardinality");
173 EMRYS_FILTER_ASSERT(
rate >=
Scalar(0) &&
"the rate must be nonnegative");
174 Eigen::Index
const n =
space.cardinality();
178 result.m_generator.setConstant(
rate /
Scalar(n - 1));
179 result.m_generator.diagonal().setConstant(-
rate);
199 template <
typename DwellTimes,
typename ExitWeights>
202 Eigen::MatrixBase<DwellTimes>
const & dwellTimes,
203 Eigen::MatrixBase<ExitWeights>
const & exitWeights,
207 Eigen::Index
const n =
space.cardinality();
208 MatrixType generator = internal::dwellGenerator<Scalar, MatrixType>(dwellTimes, exitWeights);
209 EMRYS_FILTER_ASSERT(
generator.rows() == n &&
"give a dwell time per value");
217 template <
typename DwellTimes>
221 Eigen::Index
const n =
space.cardinality();
222 return fromDwellTimes(dwellTimes, MatrixType::Ones(n, n) - MatrixType::Identity(n, n), std::move(
space));
226 [[nodiscard]] Space_
const &
243 rate(Eigen::Index from, Eigen::Index to)
const
245 return m_generator(from, to);
254 Scalar const dt = internal::toScalarTime<Scalar_>(time);
259 transitions = transitions.cwiseMax(
Scalar(0));
260 transitions.array().colwise() /= transitions.rowwise().sum().array();
271template <DiscreteSpace Space, MatrixExpression Generator>
273 -> ContinuousTimeMarkovChain<Space, typename std::remove_cvref_t<Generator>::Scalar>;
280template <
typename Scalar,
typename Space>
281[[nodiscard]] CategoricalParams<Space, Scalar>
300template <
typename Scalar,
typename Space>
301[[nodiscard]] std::expected<CategoricalParams<Space, Scalar>,
ChainError>
305 std::expected<ArrayType, ChainError>
const probabilities =
306 internal::stationaryProbabilities<Scalar, ArrayType>(chain.
generator());
309 return std::unexpected{probabilities.error()};
The distribution over a discrete space (decisions.md [discrete-spaces], [params-and-density]): Catego...
Discrete spaces (decisions.md [discrete-spaces]): the DiscreteSpace concept; Finite,...
How a function that stores a matrix argument takes it (decisions.md [forwarded-matrices]): the concep...
The macros every header includes first.
Mathematical constants and scalar functions that work in every scalar type the library accepts,...
The Space concept and what every continuous space shares (decisions.md [sizes-and-dimensions]): the t...
Time steps (decisions.md [time-steps]): TimeTraits, which converts a time type to a scalar,...
The parameters of a probability distribution over a discrete space: one weight per value.
Definition Categorical.h:257
Eigen::Array< Scalar_, CardinalityAtCompileTime, 1, Eigen::ColMajor, MaxCardinalityAtCompileTime, 1 > ArrayType
One entry per value, in flat-index order.
Definition Categorical.h:268
A continuous-time Markov chain on a discrete space: the rate of moving from each value to each other ...
Definition ContinuousTimeMarkovChain.h:61
Scalar rate(Eigen::Index from, Eigen::Index to) const
Definition ContinuousTimeMarkovChain.h:243
ContinuousTimeMarkovChain(Space_ space, ContinuousTimeMarkovChain< Axes, Scalar_ > const &... chains)
The chain on the DiscreteProduct space whose axes move independently, each by its own chain in chains...
Definition ContinuousTimeMarkovChain.h:136
static ContinuousTimeMarkovChain fromDwellTimes(Eigen::MatrixBase< DwellTimes > const &dwellTimes, Space_ space={})
Definition ContinuousTimeMarkovChain.h:219
ContinuousTimeMarkovChain(Space_ space, Generator &&generator)
The chain on space with generator generator: nonnegative off the diagonal, with each row summing to z...
Definition ContinuousTimeMarkovChain.h:82
MarkovChain< Space_, Scalar_ > transition(TimeStep< Scalar_ > auto const &time) const
Definition ContinuousTimeMarkovChain.h:252
ContinuousTimeMarkovChain(Space_ space={})
The chain that never moves: every rate zero.
Definition ContinuousTimeMarkovChain.h:73
Space_ const & space() const
Definition ContinuousTimeMarkovChain.h:227
static ContinuousTimeMarkovChain persistent(Scalar rate, Space_ space={})
Definition ContinuousTimeMarkovChain.h:171
static constexpr int MaxCardinalityAtCompileTime
a bound on it, or Eigen::Dynamic
Definition ContinuousTimeMarkovChain.h:67
MatrixType const & generator() const
Definition ContinuousTimeMarkovChain.h:234
static constexpr int CardinalityAtCompileTime
the number of values, or Eigen::Dynamic
Definition ContinuousTimeMarkovChain.h:66
Space_ SpaceType
the discrete space
Definition ContinuousTimeMarkovChain.h:65
ContinuousTimeMarkovChain(ContinuousTimeMarkovChain< Axes, Scalar_ > const &... chains)
The chain on a DiscreteProduct that is a FixedSizeSpace, named as the template argument,...
Definition ContinuousTimeMarkovChain.h:124
static ContinuousTimeMarkovChain fromDwellTimes(Eigen::MatrixBase< DwellTimes > const &dwellTimes, Eigen::MatrixBase< ExitWeights > const &exitWeights, Space_ space={})
Definition ContinuousTimeMarkovChain.h:201
ContinuousTimeMarkovChain(Generator &&generator)
The chain on a FixedSizeSpace, named as the template argument, with generator generator: ContinuousTi...
Definition ContinuousTimeMarkovChain.h:112
Scalar_ Scalar
the scalar type of the rates
Definition ContinuousTimeMarkovChain.h:64
typename MarkovChain< Space_, Scalar_ >::MatrixType MatrixType
The generator's type, the same as a MarkovChain's transition matrix.
Definition ContinuousTimeMarkovChain.h:70
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
Axes: a way of taking a root of a covariance , , whose columns carry a sigma-point rule's unit point...
Definition Roots.h:300
A type usable as a discrete space: a finite set of values.
Definition Discrete.h:72
A space whose instance holds nothing, so that S{} is the only one there is: a space of fixed size,...
Definition Space.h:217
A step of time that converts to Scalar: Scalar itself, or any type with a TimeTraits,...
Definition Time.h:128
CategoricalParams< Space, Scalar > predict(CategoricalParams< Space, Scalar > const &prior, MarkovChain< Space, Scalar > const &chain)
Definition Categorical.h:1049
std::expected< CategoricalParams< Space, Scalar >, ChainError > stationary(MarkovChain< Space, Scalar > const &chain)
Definition Categorical.h:1069
ChainError
Reasons a Markov chain has no single stationary distribution.
Definition Categorical.h:48