37template <
typename Space_,
typename Vector,
typename Noise,
typename G>
39drawProcessNoise(Space_
const & space, Vector
const & moved, Eigen::MatrixBase<Noise>
const & noise, G & rng)
41 using Scalar =
typename Vector::Scalar;
44 fillStandardNormal(z, rng);
45 auto const factor = defaultRoot(noise);
46 return Emrys::plus(space, moved, Difference{multiply(factor, z)});
53template <
typename Distribution,
typename G>
55drawMeasurementNoise(Distribution
const & distribution, G & rng)
57 if constexpr (
requires { distribution.toDensity(); })
59 auto const density = distribution.toDensity();
60 EMRYS_FILTER_ASSERT(density &&
"the measurement's noise must factorize");
73template <
typename R,
typename Derived,
typename Scalar,
typename G>
75drawStep(R
const & resolved, Eigen::MatrixBase<Derived>
const & x, Scalar step, G & rng)
78 auto const draws = std::apply(
79 [&](
auto const &... inputs) {
80 return std::tuple{drawMeasurementNoise(inputOf(inputs), rng)...};
85 [&](
auto const &... drawn) {
86 return Vector{valueOf(resolved.propagate(x.derived(), step, drawn...))};
128template <
Space Space_,
typename Derived,
ProcessModel Model, std::uniform_random_bit_generator G,
typename... Args>
131 Space_
const & space,
132 Eigen::MatrixBase<Derived>
const & x,
139 using Scalar =
typename Derived::Scalar;
140 EMRYS_FILTER_ASSERT(x.size() ==
valueDimension(space) &&
"the state does not fit the space");
141 internal::assertPartitions(model, space);
142 Scalar
const step = internal::toScalarTime<Scalar>(dt);
143 auto const call = internal::modelWith(std::cref(model), args...);
144 auto const resolved = internal::resolveProcess(call, space);
145 return internal::drawProcessNoise(
147 internal::drawStep(resolved, x, step, rng),
148 resolved.template noise<Scalar>(step),
158template <Space Space_,
typename Derived,
typename Model, std::uniform_random_bit_generator G,
typename... Args>
161simulate(Space_
const & space, Eigen::MatrixBase<Derived>
const & x, Model
const & model, G & rng, Args
const &... args)
163 using Scalar =
typename Derived::Scalar;
164 EMRYS_FILTER_ASSERT(x.size() ==
valueDimension(space) &&
"the state does not fit the space");
165 internal::assertPartitions(model, space,
"the model must fit the state space");
166 auto const call = internal::modelWith(std::cref(model.model()), args...);
167 auto const resolved = internal::resolveProcess(call, space);
168 return internal::drawProcessNoise(
170 internal::drawStep(resolved, x, Scalar(model.timeStep()), rng),
171 model.noise().template cast<Scalar>(),
180template <Space Space_,
typename Derived,
typename Step, std::uniform_random_bit_generator G,
typename... Args>
183simulate(Space_
const & space, Eigen::MatrixBase<Derived>
const & x, Step
const & step, G & rng, Args
const &... args)
185 return simulate(space, x, step.model(), rng, step.timeStep(), args...);
209template <Space Space_,
typename Derived, MeasurementModel M, std::uniform_random_bit_generator G,
typename... Args>
211simulate(Space_
const & space, Eigen::MatrixBase<Derived>
const & x, M
const & model, G & rng, Args
const &... args)
213 using Scalar =
typename Derived::Scalar;
214 EMRYS_FILTER_ASSERT(x.size() ==
valueDimension(space) &&
"the state does not fit the space");
215 auto const observed = internal::modelWith(std::cref(model), args...);
216 auto const resolved = internal::resolveMeasurement(observed, space);
217 using R = std::remove_cvref_t<
decltype(resolved)>;
219 R::HasFunction || R::HasSample,
220 "a measurement model known by its likelihood alone has no function to draw a measurement from; give it "
221 "sample(g), a draw of the observation at a state"
225 auto const draws = std::apply(
226 [&](
auto const &... inputs) {
227 return std::tuple{internal::drawMeasurementNoise(inputs, rng)...};
231 if constexpr (!R::HasFunction)
234 [&](
auto const &... drawn) {
235 return resolved.sampleAtState(x, rng, drawn...);
242 auto const & measurementSpace = resolved.space();
244 Vector predicted = std::apply(
245 [&](
auto const &... drawn) {
246 return internal::valueOf(resolved.evaluateAtState(x, drawn...)).eval();
251 if constexpr (R::HasAdditiveNoise)
253 auto const noise = internal::drawMeasurementNoise(resolved.noise().distribution(), rng);
254 return Vector{
Emrys::plus(measurementSpace, predicted, noise.template cast<Scalar>())};
268 FixedSizeSpace Space_,
271 std::uniform_random_bit_generator G,
276 Eigen::MatrixBase<Derived>
const & x,
280 Inputs
const &... inputs
283 return simulate(Space_{}, x, model, rng, dt, inputs...);
292 FixedSizeSpace Space_,
295 std::uniform_random_bit_generator G,
299simulate(Eigen::MatrixBase<Derived>
const & x, Model
const & model, G & rng, Inputs
const &... inputs)
301 return simulate(Space_{}, x, model, rng, inputs...);
309 FixedSizeSpace Space_,
312 std::uniform_random_bit_generator G,
314 requires Space<Space_>
316simulate(Eigen::MatrixBase<Derived>
const & x, M
const & model, G & rng, Args
const &... args)
318 return simulate(Space_{}, x, model, rng, args...);
333template <
typename Space,
typename Scalar, std::uniform_random_bit_generator G>
334[[nodiscard]] Eigen::Index
337 EMRYS_FILTER_ASSERT(from >= 0 && from < chain.
space().cardinality() &&
"the value is not in the chain's space");
338 return internal::drawIndex<Scalar>(
339 chain.
space().cardinality(),
340 [&](Eigen::Index to) {
341 return chain.transition(from, to);
352template <
typename Space,
typename Scalar, std::uniform_random_bit_generator G>
353[[nodiscard]] Eigen::Index
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...
The macros every header includes first.
The update of a Gaussian by a measurement (decisions.md [templated-measurements], [weighted-branches]...
Moments: the mean and covariance that a Gaussian carries and that a mixture or a sample set is moment...
Products of fixed-size matrices by Eigen's fixed-size product at every size: multiply() is by Eigen'...
Process models as functions with reads and writes (decisions.md [model-policies], [continuous-time-no...
Drawing samples: SamplesWithLogDensity and SampleWithLogDensity, the Gaussian draws drawSamples(),...
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,...
Log-weights: the WeightError a normalization can fail with (NumericError.h), and the streaming log-su...
A continuous-time Markov chain on a discrete space: the rate of moving from each value to each other ...
Definition ContinuousTimeMarkovChain.h:61
MarkovChain< Space_, Scalar_ > transition(TimeStep< Scalar_ > auto const &time) const
Definition ContinuousTimeMarkovChain.h:252
A Markov chain on a discrete space: the probability of moving from each value to each value in one st...
Definition Categorical.h:829
Space_ const & space() const
Definition Categorical.h:1000
ValueVector< Space_, Scalar > VectorType
a value, such as the mean
Definition Moments.h:74
A process model: what processModel() returns, a built-in model, or a composition of process models (d...
Definition ProcessModel.h:2010
A type usable as the space of a distribution.
Definition Space.h:186
A step of time that converts to Scalar: Scalar itself, or any type with a TimeTraits,...
Definition Time.h:128
Eigen::Index drawSample(Categorical< Space, Scalar > const &distribution, G &rng)
Definition Categorical.h:1111
constexpr bool isFixedStep
Whether Model is a FixedStepModel, whose predictions take no time step.
Definition ProcessModel.h:2776
Moments< Space_, typenameDerived::Scalar >::VectorType simulate(Space_ const &space, Eigen::MatrixBase< Derived > const &x, Model const &model, G &rng, TimeStep< typename Derived::Scalar > auto const &dt, Args const &... args)
Definition Simulation.h:130
constexpr bool isUnboundStep
Whether Model is a fixed step not yet bound to a state space: an UnboundFixedStep,...
Definition ProcessModel.h:2792
Eigen::Index valueDimension(S const &space)
Definition Space.h:272
auto plus(S const &space, Eigen::MatrixBase< XDerived > const &x, Eigen::MatrixBase< DDerived > const &d)
Definition Space.h:675
ValueVector< DifferenceSpace< S >, Scalar > DifferenceVector
A difference in S as an Eigen column vector of Scalar, the type of minus() and of the offset plus() t...
Definition Space.h:650
Eigen::Index differenceDimension(S const &space)
Definition Space.h:284
void normalizeValues(S const &space, Eigen::MatrixBase< Derived > const &block)
Brings the values in block (rows are space's coordinates, columns samples) into canonical form,...
Definition Space.h:331