36template <DiscreteSpace Space_, RealScalar Scalar_>
39template <DiscreteSpace Space_, RealScalar Scalar_>
61template <
typename Scalar,
typename Matrix,
typename DwellTimes,
typename ExitWeights>
63dwellGenerator(Eigen::MatrixBase<DwellTimes>
const & dwellTimes, Eigen::MatrixBase<ExitWeights>
const & exitWeights)
65 Eigen::Index
const n = exitWeights.rows();
67 dwellTimes.size() == n && exitWeights.cols() == n &&
"give a dwell time and a row of exit weights per value"
69 auto generator = Matrix{};
70 generator.resize(n, n);
71 for (Eigen::Index i = 0; i < n; ++i)
73 Scalar
const dwell = Scalar(dwellTimes(i));
74 EMRYS_FILTER_ASSERT(dwell > Scalar(0) &&
"a dwell time must be positive");
75 EMRYS_FILTER_ASSERT(exitWeights(i, i) == 0 &&
"a value's weight of exiting to itself must be zero");
76 EMRYS_FILTER_ASSERT((exitWeights.row(i).array() >= 0).all() &&
"exit weights must be nonnegative");
77 Scalar
const leave = Scalar(1) / dwell;
78 Scalar
const total = Scalar(exitWeights.row(i).sum());
80 (leave == Scalar(0) || total > Scalar(0)) &&
"a value that is left needs a value to exit to"
82 if (leave == Scalar(0))
84 generator.row(i).setZero();
88 generator.row(i) = exitWeights.row(i).template cast<Scalar>() * Scalar(leave / total);
90 generator(i, i) = -leave;
108template <
typename Scalar,
typename Array,
typename Matrix>
109[[nodiscard]] std::expected<Array, ChainError>
110stationaryProbabilities(Matrix kernel)
112 Eigen::Index
const n = kernel.rows();
113 EMRYS_FILTER_ASSERT(n > 0 &&
"a chain has at least one value");
114 for (Eigen::Index k = n - 1; k > 0; --k)
118 Scalar
const leave = kernel.row(k).head(k).sum();
119 if (!(leave > Scalar(0)))
123 kernel.col(k).head(k) /= leave;
124 kernel.topLeftCorner(k, k).noalias() += kernel.col(k).head(k) * kernel.row(k).head(k);
126 Array probabilities = Array::Zero(n);
127 probabilities(0) = Scalar(1);
128 for (Eigen::Index k = 1; k < n; ++k)
130 Scalar
const flow = probabilities.head(k).matrix().dot(kernel.col(k).head(k));
131 if (!(flow > Scalar(0)))
135 probabilities(k) = flow;
137 probabilities /= probabilities.sum();
138 return probabilities;
146template <
typename P,
typename Scalar, DiscreteSpace Space,
typename Values>
148categoricalMarginal(Space
const & space, Values
const & logValues)
150 auto const [stride, axis] = locateAxisByPath<P>(space);
151 using Axis = std::remove_cvref_t<
decltype(*axis)>;
153 Eigen::Index
const count = axis->cardinality();
156 AxisArray maxima = AxisArray::Constant(count, -Eigen::NumTraits<Scalar>::infinity());
157 AxisArray sums = AxisArray::Zero(count);
158 for (Eigen::Index v = 0; v < logValues.size(); ++v)
160 Eigen::Index
const i = (v / stride) % count;
161 Scalar
const x = logValues(v);
162 if (x == -Eigen::NumTraits<Scalar>::infinity())
168 sums(i) += Eigen::numext::exp(x - maxima(i));
172 sums(i) = sums(i) * Eigen::numext::exp(maxima(i) - x) + Scalar(1);
176 for (Eigen::Index i = 0; i < count; ++i)
179 sums(i) == Scalar(0) ? -Eigen::NumTraits<Scalar>::infinity() : maxima(i) + Eigen::numext::log(sums(i));
181 return CategoricalParams<Axis, Scalar>{*axis, maxima};
188template <
typename Scalar, DiscreteSpace Rest,
typename Values>
189[[nodiscard]] CategoricalParams<Rest, Scalar>
190categoricalConditional(Rest rest, ValueLocation
const & location, Values
const & logValues)
193 auto selected = RestArray{};
194 selected.resize(rest.cardinality());
195 Eigen::Index next = 0;
196 for (Eigen::Index v = 0; v < logValues.size(); ++v)
198 if (location.matches(v))
200 selected(next++) = logValues(v);
203 EMRYS_FILTER_ASSERT(next == selected.size());
204 return CategoricalParams<Rest, Scalar>{std::move(rest), selected};
212template <
typename Scalar,
typename Array,
typename Kernel>
214movedLogWeights(Array
const & logWeights, Kernel
const & kernel)
217 Scalar
const largest = logWeights.maxCoeff();
218 Scalar
const shift =
isFinite(largest) ? largest : Scalar(0);
219 Array
const weights = (logWeights - shift).exp();
220 Array moved = multiply(kernel.transpose(), weights.matrix()).array();
221 return moved.log() + shift;
255template <DiscreteSpace Space_, RealScalar Scalar_ =
double>
269 Eigen::Array<Scalar_, CardinalityAtCompileTime, 1, Eigen::ColMajor, MaxCardinalityAtCompileTime, 1>;
273 : m_space{std::move(
space)}
280 template <
typename Derived>
282 : m_space{std::move(
space)}
285 EMRYS_FILTER_ASSERT(m_logWeights.size() == m_space.cardinality() &&
"give one log-weight per value");
292 template <
typename Derived>
302 template <
typename Derived>
315 template <
typename... Weights>
317 && (std::convertible_to<Weights, Scalar_> && ...)
324 ((array(i++) = Scalar_(weights)), ...);
329 [[nodiscard]] Space_
const &
336 [[nodiscard]] Eigen::Index
339 return m_logWeights.size();
353 EMRYS_FILTER_ASSERT(value >= 0 && value <
cardinality() &&
"the value is out of range");
354 return m_logWeights(value);
360 [[nodiscard]] std::expected<Scalar, WeightError>
363 return internal::logTotalWeight<Scalar>(m_logWeights);
367 template <
typename Derived>
372 m_stamp.touchValues();
373 m_logWeights =
logWeights.derived().array().template cast<Scalar>();
377 template <
typename Derived>
381 setLogWeights(weights.derived().array().template cast<Scalar>().log());
388 EMRYS_FILTER_ASSERT(value >= 0 && value <
cardinality() &&
"the value is out of range");
389 m_stamp.touchValues();
403 template <
typename... Values>
404 requires(
sizeof...(Values) > 0)
414 template <
typename... Values>
415 requires(
sizeof...(Values) > 0)
426 template <
typename Derived>
431 m_stamp.touchValues();
432 m_logWeights +=
logLikelihoods.derived().array().template cast<Scalar>();
442 template <
typename Derived>
443 [[nodiscard]] std::expected<Scalar, WeightError>
450 return std::unexpected{prior.error()};
453 auto const total = internal::logTotalWeight<Scalar>(posterior);
456 return std::unexpected{total.error()};
458 m_stamp.touchValues();
459 m_logWeights = posterior - *total;
460 return *total - *prior;
466 [[nodiscard]] std::expected<void, WeightError>
472 return std::unexpected{total.error()};
474 m_stamp.touchValues();
475 m_logWeights -= *total;
482 template <
typename P>
486 return internal::categoricalMarginal<P, Scalar>(m_space, m_logWeights);
493 template <
typename P>
497 auto const [stride, axis] = internal::locateAxisByPath<P>(m_space);
498 EMRYS_FILTER_ASSERT(value >= 0 && value < axis->
cardinality() &&
"the value is out of range");
499 return internal::categoricalConditional<Scalar>(
500 internal::complementAxes<P>(m_space),
501 internal::ValueLocation{stride, axis->cardinality(), value},
510 template <
typename Value>
514 return internal::categoricalConditional<Scalar>(
515 internal::complementAxes<internal::ValueAxisPath<Value, Space_>>(m_space),
516 internal::locateValuePath<Value>(m_space),
524 [[nodiscard]] std::expected<DensityType, WeightError>
530 return std::unexpected{total.error()};
532 return DensityType{*
this, *total};
545 friend class internal::ValuesCheck;
549 internal::Stamp m_stamp;
566template <
typename Space,
typename Scalar>
599template <DiscreteSpace Space_, RealScalar Scalar_ =
double>
615 [[nodiscard]] Space_
const &
618 return source().space();
622 [[nodiscard]] Eigen::Index
625 return source().cardinality();
634 return source().m_logWeights - m_logTotal;
650 return source().logWeight(value) - m_logTotal;
664 template <
typename... Values>
665 requires(
sizeof...(Values) > 0)
670 auto const locations = std::array<internal::ValueLocation,
sizeof...(Values)>{
671 internal::locateValuePath<Values>(params.m_space)...
674 for (Eigen::Index v = 0; v < params.
cardinality(); ++v)
677 for (
auto const & location : locations)
679 matches = matches && location.matches(v);
683 total.add(params.m_logWeights(v));
686 return total.
value() - m_logTotal;
691 template <
typename... Values>
692 requires(
sizeof...(Values) > 0)
711 ArrayType const & logWeights = source().m_logWeights;
713 for (Eigen::Index v = 0; v < logWeights.size(); ++v)
715 if (logWeights(v) != -Eigen::NumTraits<Scalar>::infinity())
721 return Eigen::numext::maxi(result,
Scalar(0));
725 [[nodiscard]] Eigen::Index
728 ArrayType const & logWeights = source().m_logWeights;
729 Eigen::Index best = 0;
730 for (Eigen::Index v = 1; v < logWeights.size(); ++v)
732 if (logWeights(v) > logWeights(best))
743 template <
typename P>
753 template <
typename P>
763 template <
typename Value>
777 Categorical(ParamsType
const & source, Scalar logTotal)
779 , m_logTotal{logTotal}
783 [[nodiscard]] ParamsType
const &
786 return m_check.get();
789 internal::ValuesCheck<ParamsType> m_check;
827template <DiscreteSpace Space_, RealScalar Scalar_ =
double>
848 : m_space{std::move(space)}
849 , m_transitions{MatrixType::Identity(m_space.cardinality(), m_space.cardinality())}
855 template <MatrixExpression Transitions>
857 : m_space{std::move(
space)}
858 , m_transitions{internal::castScalar<
Scalar>(std::forward<Transitions>(transitions))}
861 m_transitions.rows() == m_space.cardinality() && m_transitions.cols() == m_space.cardinality()
862 &&
"the transition matrix has a row and a column per value"
865 (m_transitions.array() >=
Scalar(0)).all() &&
"transition probabilities must be nonnegative"
868 ((m_transitions.rowwise().sum().array() -
Scalar(1)).abs() <= Eigen::NumTraits<Scalar>::dummy_precision())
870 &&
"each row of the transition matrix must sum to one"
877 template <MatrixExpression Transitions>
880 :
MarkovChain{Space_{}, std::forward<Transitions>(transitions)}
888 internal::IsDiscreteProduct<Space_>
889 &&
sizeof...(Axes) == std::tuple_size_v<internal::DiscreteProductAxes<Space_>>
892 : m_space{std::move(
space)}
895 std::is_same_v<std::tuple<
Axes...>, internal::DiscreteProductAxes<Space_>>,
896 "give one chain per axis of the product, in order"
898 Eigen::Index
const n = m_space.cardinality();
899 m_transitions = MatrixType::Ones(n, n);
900 Eigen::Index stride = n;
903 Eigen::Index
const count = chains.
space().cardinality();
905 for (Eigen::Index i = 0; i < n; ++i)
907 for (Eigen::Index j = 0; j < n; ++j)
909 m_transitions(i, j) *= chains.
matrix()((i / stride) % count, (j / stride) % count);
915 EMRYS_FILTER_ASSERT(stride == 1 &&
"each chain must have its axis's cardinality");
924 &&
sizeof...(Axes) == std::tuple_size_v<internal::DiscreteProductAxes<Space_>>
933 [[nodiscard]]
static MarkovChain
936 EMRYS_FILTER_ASSERT(stay >= Scalar(0) && stay <= Scalar(1) &&
"the probability must be in [0, 1]");
937 Eigen::Index
const n = space.cardinality();
941 result.m_transitions.setConstant((Scalar(1) - stay) / Scalar(n - 1));
942 result.m_transitions.diagonal().setConstant(stay);
950 [[nodiscard]]
static MarkovChain
971 template <
typename DwellTimes,
typename ExitWeights>
974 Eigen::MatrixBase<DwellTimes>
const & dwellTimes,
975 Eigen::MatrixBase<ExitWeights>
const & exitWeights,
979 EMRYS_FILTER_ASSERT((dwellTimes.array() >= 1).all() &&
"a dwell time is at least one step");
980 MatrixType transitions = internal::dwellGenerator<Scalar, MatrixType>(dwellTimes, exitWeights);
981 transitions.diagonal().array() += Scalar(1);
982 EMRYS_FILTER_ASSERT(transitions.rows() == space.cardinality() &&
"give a dwell time per value");
983 return MarkovChain{std::move(space), std::move(transitions)};
990 template <
typename DwellTimes>
991 [[nodiscard]]
static MarkovChain
994 Eigen::Index
const n = space.cardinality();
995 return fromDwellTimes(dwellTimes, MatrixType::Ones(n, n) - MatrixType::Identity(n, n), std::move(space));
999 [[nodiscard]] Space_
const &
1006 [[nodiscard]] MatrixType
const &
1009 return m_transitions;
1013 [[nodiscard]] Scalar
1016 return m_transitions(from, to);
1026 EMRYS_FILTER_ASSERT(from >= 0 && from < m_space.cardinality() &&
"the value is not in the chain's space");
1033 MatrixType m_transitions;
1037template <DiscreteSpace Space, MatrixExpression Transitions>
1038MarkovChain(Space, Transitions &&) -> MarkovChain<Space, typename std::remove_cvref_t<Transitions>::Scalar>;
1047template <
typename Scalar,
typename Space>
1048[[nodiscard]] CategoricalParams<Space, Scalar>
1051 EMRYS_FILTER_ASSERT(prior.
space() == chain.
space() &&
"the chain is on a different space");
1067template <
typename Scalar,
typename Space>
1068[[nodiscard]] std::expected<CategoricalParams<Space, Scalar>,
ChainError>
1072 std::expected<ArrayType, ChainError>
const probabilities =
1073 internal::stationaryProbabilities<Scalar, ArrayType>(chain.
matrix());
1076 return std::unexpected{probabilities.error()};
1085template <
typename Scalar,
typename Space, std::uniform_random_bit_generator G>
1086[[nodiscard]] std::vector<Eigen::Index>
1089 static_assert(std::floating_point<Scalar>,
"sampling requires a standard floating-point scalar");
1090 EMRYS_FILTER_ASSERT(n >= 0);
1093 std::discrete_distribution<Eigen::Index>{probabilities.data(), probabilities.data() + probabilities.size()};
1094 std::size_t
const count = std::size_t(n);
1095 auto samples = std::vector<Eigen::Index>(count);
1096 for (
auto &
sample : samples)
1109template <
typename Scalar,
typename Space, std::uniform_random_bit_generator G>
1110[[nodiscard]] Eigen::Index
1114 return internal::drawIndex<Scalar>(
1115 probabilities.size(),
1116 [&](Eigen::Index i) {
1117 return probabilities(i);
1125#ifndef EMRYS_FILTER_NO_IO
1134template <
typename Space_,
typename Scalar_>
1136describe(std::ostream & stream, Categorical<Space_, Scalar_>
const & categorical, Indent indent)
1139 stream << indent <<
"categorical over ";
1140 printCount(stream, probabilities.size(),
"value");
1142 printRow(stream, indent.deeper(),
"probabilities", probabilities);
1148template <
typename Space_,
typename Scalar_>
1150describe(std::ostream & stream, CategoricalParams<Space_, Scalar_>
const & params, Indent indent)
1152 if (
auto const density = params.toDensity())
1154 describe(stream, *density, indent);
1157 stream << indent <<
"categorical over ";
1158 printCount(stream, params.cardinality(),
"value");
1159 stream <<
", whose weights are not normalizable\n";
1160 printRow(stream, indent.deeper(),
"log-weights", params.logWeights());
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,...
Products of fixed-size matrices by Eigen's fixed-size product at every size: multiply() is by Eigen'...
Params and Density: the traits that pair a distribution's parameters with its density,...
Printing: operator<< and std::formatter for every distribution, every filter (which prints its name a...
The Space concept and what every continuous space shares (decisions.md [sizes-and-dimensions]): the t...
What parameters and their views share (decisions.md [view-stamp], [params-and-density]): Stamp,...
Log-weights: the WeightError a normalization can fail with (NumericError.h), and the streaming log-su...
The parameters of a probability distribution over a discrete space: one weight per value.
Definition Categorical.h:257
CategoricalParams(Space_ space={})
The uniform distribution over space, with log-weights that are its log-probabilities.
Definition Categorical.h:272
auto conditional() const
Definition Categorical.h:512
static constexpr bool IsParams
Definition Categorical.h:265
Space_ SpaceType
the discrete space
Definition Categorical.h:261
void setLogWeights(Eigen::DenseBase< Derived > const &logWeights)
Sets the log-weights to logWeights, one per value.
Definition Categorical.h:369
auto marginal() const
Definition Categorical.h:484
void setWeight(Eigen::Index value, Scalar weight)
Sets the weight of the value with flat index value to weight.
Definition Categorical.h:395
std::expected< Scalar, WeightError > update(Eigen::DenseBase< Derived > const &logLikelihoods)
Bayes' rule: multiplies each value's probability by its likelihood , with logLikelihoods one per val...
Definition Categorical.h:444
static constexpr int MaxCardinalityAtCompileTime
Definition Categorical.h:264
void setWeights(Eigen::DenseBase< Derived > const &weights)
Sets the weights to weights, one per value, which need not sum to one.
Definition Categorical.h:379
void toDensity() const &&=delete
A density of a temporary would outlive it.
ArrayType const & logWeights() const
Definition Categorical.h:344
void reweight(Eigen::DenseBase< Derived > const &logLikelihoods)
Multiplies each value's weight by its likelihood , with logLikelihoods one per value,...
Definition Categorical.h:428
std::expected< DensityType, WeightError > toDensity() const &
Definition Categorical.h:525
Space_ const & space() const
Definition Categorical.h:330
static CategoricalParams fromWeights(Space_ space, Eigen::DenseBase< Derived > const &weights)
Definition Categorical.h:294
CategoricalParams(Space_ space, Eigen::DenseBase< Derived > const &logWeights)
The distribution over space whose probabilities are proportional to , with logWeights ,...
Definition Categorical.h:281
static constexpr int CardinalityAtCompileTime
Definition Categorical.h:263
auto conditional(Eigen::Index value) const
Definition Categorical.h:495
Categorical< Space_, Scalar_ > DensityType
the view toDensity() returns
Definition Categorical.h:262
void setLogWeight(Scalar logWeight)
Sets the log-weight of the value with the named values Values, one per axis (see valueOf()),...
Definition Categorical.h:406
static CategoricalParams fromWeights(Weights... weights)
Definition Categorical.h:319
Eigen::Index cardinality() const
Definition Categorical.h:337
void setWeight(Scalar weight)
Sets the weight of the value with the named values Values, one per axis (see valueOf()),...
Definition Categorical.h:417
static CategoricalParams fromWeights(Eigen::DenseBase< Derived > const &weights)
Definition Categorical.h:305
std::expected< void, WeightError > normalize()
Shifts the log-weights so that the weights sum to one, or returns the WeightError that stops it,...
Definition Categorical.h:467
Scalar logWeight(Eigen::Index value) const
Definition Categorical.h:351
std::expected< Scalar, WeightError > logTotalWeight() const
Definition Categorical.h:361
Scalar_ Scalar
the scalar type of the weights
Definition Categorical.h:260
void setLogWeight(Eigen::Index value, Scalar logWeight)
Sets the log-weight of the value with flat index value to logWeight.
Definition Categorical.h:386
Eigen::Array< Scalar_, CardinalityAtCompileTime, 1, Eigen::ColMajor, MaxCardinalityAtCompileTime, 1 > ArrayType
One entry per value, in flat-index order.
Definition Categorical.h:268
The probabilities of a CategoricalParams whose weights define a distribution: a read-only view.
Definition Categorical.h:601
auto conditional() const
Definition Categorical.h:765
auto logProbabilities() const
Definition Categorical.h:632
Space_ const & space() const
Definition Categorical.h:616
Space_ SpaceType
Definition Categorical.h:606
typename ParamsType::ArrayType ArrayType
Definition Categorical.h:607
Scalar entropy() const
Definition Categorical.h:709
auto marginal() const
Definition Categorical.h:745
static constexpr int MaxCardinalityAtCompileTime
Definition Categorical.h:610
CategoricalParams< Space_, Scalar_ > ParamsType
Definition Categorical.h:604
static constexpr bool IsParams
Definition Categorical.h:612
Eigen::Index mostProbable() const
Definition Categorical.h:726
auto probabilities() const
Definition Categorical.h:641
Scalar_ Scalar
Definition Categorical.h:605
Scalar logProbability() const
Definition Categorical.h:667
auto conditional(Eigen::Index value) const
Definition Categorical.h:755
Eigen::Index cardinality() const
Definition Categorical.h:623
Scalar logProbability(Eigen::Index value) const
Definition Categorical.h:648
static constexpr int CardinalityAtCompileTime
Definition Categorical.h:608
Scalar probability() const
Definition Categorical.h:694
Scalar probability(Eigen::Index value) const
Definition Categorical.h:655
The block named by Path does not change, and has no process noise, such as a fixed calibration parame...
Definition ProcessModel.h:1274
Streaming log-sum-exp: accumulates without overflow.
Definition Weights.h:46
Scalar value() const
Definition Weights.h:133
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
Space_ SpaceType
the discrete space
Definition Categorical.h:833
static constexpr int CardinalityAtCompileTime
Definition Categorical.h:834
MarkovChain(Space_ space={})
The chain that never moves.
Definition Categorical.h:847
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...
Definition Categorical.h:891
Scalar transition(Eigen::Index from, Eigen::Index to) const
Definition Categorical.h:1014
CategoricalParams< Space_, Scalar_ > next(Eigen::Index from) const
Definition Categorical.h:1024
static MarkovChain persistent(Scalar stay, Space_ space={})
Definition Categorical.h:934
Space_ const & space() const
Definition Categorical.h:1000
MarkovChain(Space_ space, Transitions &&transitions)
The chain on space with transition matrix transitions: nonnegative, with each row summing to one.
Definition Categorical.h:856
Scalar_ Scalar
the scalar type of the probabilities
Definition Categorical.h:832
MarkovChain(MarkovChain< Axes, Scalar_ > const &... chains)
The chain on a DiscreteProduct that is a FixedSizeSpace, named as the template argument,...
Definition Categorical.h:926
MarkovChain(Transitions &&transitions)
The chain on a FixedSizeSpace, named as the template argument, with transition matrix transitions: Ma...
Definition Categorical.h:879
static MarkovChain fromDwellTimes(Eigen::MatrixBase< DwellTimes > const &dwellTimes, Eigen::MatrixBase< ExitWeights > const &exitWeights, Space_ space={})
Definition Categorical.h:973
MatrixType const & matrix() const
Definition Categorical.h:1007
static constexpr int MaxCardinalityAtCompileTime
Definition Categorical.h:835
static MarkovChain fromDwellTimes(Eigen::MatrixBase< DwellTimes > const &dwellTimes, Space_ space={})
Definition Categorical.h:992
static MarkovChain memoryless(Categorical< Space_, Scalar_ > const &next)
Definition Categorical.h:951
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 type usable as the space of a distribution.
Definition Space.h:186
#define EMRYS_FILTER_NO_UNIQUE_ADDRESS
Assertion used for programmer errors (misuse of the API).
Definition Macros.h:38
bool isFinite(T const &x)
Definition Math.h:305
constexpr Eigen::Index valueOf(S const &space, AxisIndex< Paths, N > const &... indices)
Definition Discrete.h:1112
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
Eigen::Index drawSample(Categorical< Space, Scalar > const &distribution, G &rng)
Definition Categorical.h:1111
std::vector< Eigen::Index > drawSamples(Categorical< Space, Scalar > const &distribution, Eigen::Index n, G &rng)
Definition Categorical.h:1087
ChainError
Reasons a Markov chain has no single stationary distribution.
Definition Categorical.h:48
@ Reducible
some value can't be reached from some other, so the chain is not irreducible
Definition Categorical.h:49
Eigen::Array< typename Derived::Scalar, Eigen::Dynamic, 1 > logLikelihoods(M const &measurement, Space const &space, Eigen::MatrixBase< Derived > const &states)
Definition Likelihood.h:408
Sample< std::remove_cvref_t< G > > sample(G &&function)
Definition Policies.h:665