44inline constexpr bool isKalmanState = Component<C> || (GaussianForm<Params<C>> && std::same_as<Density<Params<C>>, C>);
54concept KalmanState =
requires {
requires internal::isKalmanState<C>; };
63template <
typename C,
typename M>
64[[nodiscard]]
consteval auto
67 if constexpr (isOtherGaussianForm<C>)
69 return std::type_identity<decltype(updateInPlace<false>(std::declval<C &>(), std::declval<M const &>()))>{};
74 typename decltype(
Emrys::update(std::declval<C const &>(), std::declval<M const &>()))::value_type;
75 return std::type_identity<std::expected<
76 FilterUpdateWithScratch<
77 typename C::SpaceType,
78 typename Measured::MeasurementSpaceType,
79 Measured::BranchCount,
119template <KalmanState Component_,
typename Model_,
typename Method_ = DefaultMethodFor<Model_>>
123 internal::predictsBy<Model_, Method_>,
124 "a filter with a fixed-step model predicts by the model's method"
126 static_assert(internal::checkPredictionMethod<Method_>());
129 static constexpr bool IsForm = internal::isOtherGaussianForm<Params<Component_>>;
141 template <Measurement M>
142 using UpdateType =
typename decltype(internal::kalmanUpdateType<Params<Component_>, M>())::type;
145 template <Measurement M>
152 : m_model{std::move(
model)}
153 , m_method{internal::predictionMethod(m_model, std::move(
method))}
157 [[nodiscard]] Model_
const &
164 [[nodiscard]] Model_ &
171 [[nodiscard]] Method_
const &
181 return m_model.partitions(space);
192 template <
typename... Inputs>
197 return internal::predictInPlace(m_method, state, m_model, internal::toScalarTime<Scalar>(dt), inputs...);
203 template <
typename... Inputs>
208 return internal::predictInPlace(state, m_model, inputs...);
216 template <
typename... Inputs>
222 state = joint.predicted;
230 template <
typename... Inputs>
236 state = joint.predicted;
252 template <Measurement M,
typename Policy = reductions::Collapse>
255 && !internal::isLinearizedAbout<Policy>
260 return updateAbout(state, measurement, internal::NoReference{}, policy);
270 template <Measurement M,
typename Reference,
typename Policy = reductions::Collapse>
271 requires(IsForm || ReductionPolicy<Policy, internal::MeasuredUpdate<Params<Component_>, M>,
Params<Component_>>)
275 M
const & measurement,
277 Policy
const & policy = {}
280 return updateAbout(state, measurement, about, policy);
291 template <Measurement M,
typename Policy,
typename Result>
293 (IsForm || ReductionPolicy<Policy, internal::MeasuredUpdate<Params<Component_>, M>,
Params<Component_>>)
294 && !internal::isLinearizedAbout<Policy>
296 [[nodiscard]] std::expected<void, GaussianError>
299 return updateAboutInto(state, measurement, internal::NoReference{}, policy, result);
308 template <Measurement M,
typename Reference,
typename Policy,
typename Result>
310 [[nodiscard]] std::expected<void, GaussianError>
313 M
const & measurement,
315 Policy
const & policy,
319 return updateAboutInto(state, measurement, about, policy, result);
327 template <Measurement M,
typename Reference,
typename Policy>
331 M
const & measurement,
332 Reference
const & reference,
333 Policy
const & policy
336 constexpr bool Statistics = internal::policyReadsStatistics<Policy>;
337 if constexpr (IsForm)
340 internal::isOneBranchInPlacePolicy<Policy>,
341 "a square-root or information form has one branch and takes Collapse, Select, or a Gate over them; "
342 "a policy of the user's own is the covariance form's (decisions.md [gaussian-forms])"
344 return internal::updateInPlace<Statistics>(
348 internal::oneBranchAcceptor(policy)
353 using Measured =
typename decltype(internal::updateBranches<Statistics>(state, measurement))::value_type;
354 if constexpr (internal::isOneBranchInPlacePolicy<Policy> && Measured::BranchCount == 1)
359 return internal::updateInPlace<Statistics>(
363 internal::oneBranchAcceptor(policy)
366 else if constexpr (Measured::BranchCount == std::dynamic_extent)
369 auto const reduced = reduceBranches(state, measurement, reference, policy, *result);
372 return std::unexpected{reduced.error()};
378 auto measured = internal::updateBranches<Statistics>(state, measurement, reference);
381 return std::unexpected{measured.error()};
384 auto out = internal::OneComponentOutput<Params<Component_>,
Scalar>{state};
385 internal::reduceInto(policy, std::move(measured->branches), out);
386 auto result = internal::filterUpdate(std::move(*measured), out.added);
387 internal::MixtureEvidenceAccess::setLogKeptWeight(result, out.logWeight);
396 template <Measurement M,
typename Reference,
typename Policy,
typename Result>
397 [[nodiscard]] std::expected<void, GaussianError>
400 M
const & measurement,
401 Reference
const & reference,
402 Policy
const & policy,
406 if constexpr (!IsForm && Result::BranchCount == std::dynamic_extent)
408 return reduceBranches(state, measurement, reference, policy, result);
412 auto updated = updateAbout(state, measurement, reference, policy);
415 return std::unexpected{updated.error()};
417 result = std::move(*updated);
428 template <Measurement M,
typename Reference,
typename Policy,
typename Result>
429 [[nodiscard]] std::expected<void, GaussianError>
432 M
const & measurement,
433 Reference
const & reference,
434 Policy
const & policy,
438 constexpr bool Statistics = internal::policyReadsStatistics<Policy>;
439 auto const measured = internal::updateBranchesInto<Statistics>(state, measurement, result.measured, reference);
445 auto out = internal::OneComponentOutput<Params<Component_>,
Scalar>{state};
446 internal::reduceInto(policy, std::move(result.measured.branches), out);
447 internal::filterUpdateInto(result.measured, out.added, result);
448 internal::MixtureEvidenceAccess::setLogKeptWeight(result, out.logWeight);
464template <KalmanState Component_,
typename Model,
typename Method,
typename Allocator>
467 using type = KalmanRecursion<Component_, Model, Method>;
471template <KalmanState Component_,
typename Model,
typename Method,
typename Allocator>
472using RecursionForType =
typename RecursionFor<Component_, Model, Method, Allocator>::type;
557 requires std::same_as<typename Recursion_::ModelType, Model_>
558 && std::same_as<typename Recursion_::MethodType, Method_>
560 :
public internal::HeldUpkeep<KalmanFilter<Component_, Model_, Method_, Recursion_, Upkeep_>, Upkeep_>
562 using UpkeepBase = internal::HeldUpkeep<KalmanFilter, Upkeep_>;
565 static constexpr bool IsForm = internal::isOtherGaussianForm<Params<Component_>>;
584 std::type_identity_t<Upkeep_>
upkeep = {}
586 : UpkeepBase{std::move(upkeep)}
588 , m_state{std::move(
state)}
590 internal::assertPartitions(m_recursion.model(), m_state.space());
597 requires(!std::same_as<Upkeep_, Emrys::upkeep::None>)
606 : UpkeepBase{std::move(
upkeep)}
607 , m_recursion{std::move(recursion)}
608 , m_state{std::move(state)}
610 internal::assertPartitions(m_recursion.model(), m_state.space());
614 [[nodiscard]] StateType
const &
624 [[nodiscard]] StateType &
636 internal::assertPartitions(m_recursion.model(),
state.space());
637 m_state = std::move(
state);
641 [[nodiscard]] RecursionType
const &
648 [[nodiscard]] Model_
const &
651 return m_recursion.model();
655 [[nodiscard]] Model_ &
658 return m_recursion.model();
662 [[nodiscard]] Method_
const &
665 return m_recursion.method();
678 template <
typename... Inputs>
683 return m_recursion.predict(m_state, internal::toScalarTime<Scalar>(dt), inputs...);
689 template <
typename... Inputs>
694 internal::rejectTimeStep<Inputs...>();
695 return m_recursion.predict(m_state, inputs...);
704 template <
typename... Inputs>
709 EMRYS_FILTER_ASSERT(steps.
count >= 0 &&
"the number of steps must be nonnegative");
710 if constexpr (IsForm)
712 using Result =
decltype(m_recursion.predict(m_state, inputs...));
713 for (Eigen::Index i = 0; i < steps.
count; ++i)
715 if (Result result = m_recursion.predict(m_state, inputs...); !result)
724 for (Eigen::Index i = 0; i < steps.
count; ++i)
726 m_recursion.predict(m_state, inputs...);
736 template <
typename... Inputs>
741 return m_recursion.predictJoint(m_state, dt, inputs...);
748 template <
typename... Inputs>
753 internal::rejectTimeStep<Inputs...>();
754 return m_recursion.predictJoint(m_state, inputs...);
769 template <Measurement M,
typename Policy = reductions::Collapse>
770 requires(!internal::isLinearizedAbout<Policy>)
772 update(M
const & measurement, Policy
const & policy = {})
774 return m_recursion.update(m_state, measurement, policy);
784 template <Measurement M,
typename Reference,
typename Policy = reductions::Collapse>
788 return m_recursion.update(m_state, measurement, about, policy);
798 template <Measurement M,
typename Policy,
typename Result>
799 requires(!internal::isLinearizedAbout<Policy>)
800 [[nodiscard]] std::expected<void, GaussianError>
801 update(M
const & measurement, Policy
const & policy, Result & result)
803 return m_recursion.update(m_state, measurement, policy, result);
811 template <Measurement M,
typename Reference,
typename Policy,
typename Result>
812 [[nodiscard]] std::expected<void, GaussianError>
815 return m_recursion.update(m_state, measurement, about, policy, result);
820 RecursionType m_recursion;
825template <
typename P,
typename Model>
826 requires KalmanState<Density<P>> && (!Recursion<Model>)
827KalmanFilter(Model, P) -> KalmanFilter<
829 internal::BoundStep<Model, typename P::SpaceType, typename P::Scalar>,
830 DefaultMethodFor<Model>>;
832template <
typename P, Recursion R>
833 requires KalmanState<Density<P>> && std::same_as<typename R::StateType, P>
834KalmanFilter(R, P) -> KalmanFilter<Density<P>,
typename R::ModelType,
typename R::MethodType, R>;
837template <
typename P,
typename Model,
typename X>
838 requires KalmanState<Density<P>> && (!Recursion<Model>)
839KalmanFilter(Model, P, X) -> KalmanFilter<
841 internal::BoundStep<Model, typename P::SpaceType, typename P::Scalar>,
842 internal::MethodArgumentFor<Model, X>,
845 internal::BoundStep<Model, typename P::SpaceType, typename P::Scalar>,
846 internal::MethodArgumentFor<Model, X>>,
847 internal::UpkeepArgumentFor<X>>;
849template <
typename P,
typename Model,
typename Method,
typename U>
850 requires KalmanState<Density<P>>
851KalmanFilter(Model, P, Method, U) -> KalmanFilter<
853 internal::BoundStep<Model, typename P::SpaceType, typename P::Scalar>,
855 KalmanRecursion<Density<P>, internal::BoundStep<Model, typename P::SpaceType, typename P::Scalar>, Method>,
858template <
typename P, Recursion R,
typename U>
859 requires KalmanState<Density<P>> && std::same_as<typename R::StateType, P> && internal::UpkeepArgument<U>
860KalmanFilter(R, P, U) -> KalmanFilter<Density<P>,
typename R::ModelType,
typename R::MethodType, R, U>;
865#ifndef EMRYS_FILTER_NO_IO
874template <
typename Component_,
typename Model_,
typename Method_,
typename Recursion_,
typename Upkeep_>
877 std::ostream & stream,
878 KalmanFilter<Component_, Model_, Method_, Recursion_, Upkeep_>
const & filter,
882 describeFilter(stream,
"Kalman filter", filter.state(), indent);
What a container of several Gaussians needs of each one (decisions.md [component-first]): the Compone...
The upkeep a filter holds (decisions.md [upkeep]): internal::HeldUpkeep, the base that gives every fi...
The Gaussian: its parameters GaussianParams, the Gaussian that evaluates the density,...
The macros every header includes first.
The update of a Gaussian by a measurement (decisions.md [templated-measurements], [weighted-branches]...
Printing: operator<< and std::formatter for every distribution, every filter (which prints its name a...
Process models as functions with reads and writes (decisions.md [model-policies], [continuous-time-no...
The Recursion concept (decisions.md [filters-and-recursions], [user-extension-points]): what a Kalman...
Reducing an update's branches (decisions.md [weighted-branches], [reduction-policies],...
The Space concept and what every continuous space shares (decisions.md [sizes-and-dimensions]): the t...
auto predict(Inputs const &... inputs)
Moves the state forward by the fixed-step model's step, with inputs passed as in Emrys::predict(),...
Definition KalmanFilter.h:692
PredictedJoint< SpaceType, Scalar > predictJoint(Inputs const &... inputs)
Moves the state forward as predict(inputs...) does with a fixed-step model.
Definition KalmanFilter.h:751
Method_ const & method() const
Definition KalmanFilter.h:663
auto update(M const &measurement, Policy const &policy={})
Conditions the state on measurement, by the measurement's own method, and reduces the branches to the...
Definition KalmanFilter.h:772
RecursionType const & recursion() const
Definition KalmanFilter.h:642
std::expected< void, GaussianError > update(M const &measurement, Policy const &policy, Result &result)
As update(measurement, policy), but into result, the update inside the std::expected that update() re...
Definition KalmanFilter.h:801
KalmanFilter(Recursion_ recursion, StateType state, std::type_identity_t< Upkeep_ > upkeep={})
A filter that runs recursion, the library's or one of the user's own (see Recursion),...
Definition KalmanFilter.h:605
auto predict(TimeStep< Scalar > auto const &dt, Inputs const &... inputs)
Moves the state forward by dt, any TimeStep (see Time steps), through the process model,...
Definition KalmanFilter.h:681
KalmanFilter(Model_ model, Params< Component_ > state, MethodFor< Model_, Method_ > method={}, std::type_identity_t< Upkeep_ > upkeep={})
A filter with process model model, initial state state, prediction method method, and upkeep upkeep,...
Definition KalmanFilter.h:580
typename Params< Component_ >::SpaceType SpaceType
Definition KalmanFilter.h:570
Model_ & model()
Definition KalmanFilter.h:656
typename Params< Component_ >::Scalar Scalar
Definition KalmanFilter.h:569
void setState(StateType state)
Replaces the state estimate, as when reinitializing, with one whose space the process model's writes ...
Definition KalmanFilter.h:634
StateType & state()
Definition KalmanFilter.h:625
PredictedJoint< SpaceType, Scalar > predictJoint(TimeStep< Scalar > auto const &dt, Inputs const &... inputs)
Moves the state forward as predict(dt, inputs...) does.
Definition KalmanFilter.h:739
Method_ MethodType
Definition KalmanFilter.h:572
Recursion_ RecursionType
Definition KalmanFilter.h:574
std::expected< void, GaussianError > update(M const &measurement, LinearizedAbout< Reference > const &about, Policy const &policy, Result &result)
As update(measurement, about, policy), but into result, as update(measurement, policy,...
Definition KalmanFilter.h:813
auto update(M const &measurement, LinearizedAbout< Reference > const &about, Policy const &policy={})
Conditions the state on measurement as update(measurement, policy) does, with the measurement lineari...
Definition KalmanFilter.h:786
Params< Component_ > StateType
Definition KalmanFilter.h:573
StateType const & state() const
Definition KalmanFilter.h:615
Model_ ModelType
Definition KalmanFilter.h:571
KalmanFilter(Model_ model, Params< Component_ > state, std::type_identity_t< Upkeep_ > upkeep)
A filter with process model model, initial state state, the default prediction method,...
Definition KalmanFilter.h:596
auto predict(Steps steps, Inputs const &... inputs)
Moves the state forward by steps of the fixed-step model, as that many calls of predict(inputs....
Definition KalmanFilter.h:707
Model_ const & model() const
Definition KalmanFilter.h:649
The Kalman filter's steps over one component, without the state: a process model and a prediction met...
Definition KalmanFilter.h:121
Model_ & model()
Definition KalmanFilter.h:165
Params< Component_ > StateType
the state the steps act on
Definition KalmanFilter.h:137
UpdateType< M > update(Params< Component_ > &state, M const &measurement, LinearizedAbout< Reference > const &about, Policy const &policy={}) const
Conditions state on measurement as update(state, measurement, policy) does, with the measurement line...
Definition KalmanFilter.h:273
PredictedJoint< SpaceType, Scalar > predictJoint(Params< Component_ > &state, TimeStep< Scalar > auto const &dt, Inputs const &... inputs) const
Moves state forward as predict(state, dt, inputs...) does.
Definition KalmanFilter.h:219
UpdateType< M > update(Params< Component_ > &state, M const &measurement, Policy const &policy={}) const
Conditions state on measurement, by the measurement's own method, and reduces the branches to the new...
Definition KalmanFilter.h:258
std::expected< void, GaussianError > update(Params< Component_ > &state, M const &measurement, LinearizedAbout< Reference > const &about, Policy const &policy, Result &result) const
update(state, measurement, about, policy) into result, as update(state, measurement,...
Definition KalmanFilter.h:311
auto predict(Params< Component_ > &state, Inputs const &... inputs) const
Moves state forward by the fixed-step model's step, with inputs passed as in Emrys::predict(),...
Definition KalmanFilter.h:206
typename Params< Component_ >::Scalar Scalar
the scalar type
Definition KalmanFilter.h:133
Model_ ModelType
the process model
Definition KalmanFilter.h:135
KalmanRecursion(Model_ model, MethodFor< Model_, Method_ > method={})
The recursion with process model model and prediction method method; a fixed-step model carries its o...
Definition KalmanFilter.h:151
bool partitions(SpaceType const &space) const
Definition KalmanFilter.h:179
typename Params< Component_ >::SpaceType SpaceType
the state space
Definition KalmanFilter.h:134
std::expected< void, GaussianError > update(Params< Component_ > &state, M const &measurement, Policy const &policy, Result &result) const
update(state, measurement, policy) into result, a ResultType: the form every recursion has,...
Definition KalmanFilter.h:297
static constexpr bool Reentrant
Definition KalmanFilter.h:138
Model const & model() const
Definition KalmanFilter.h:158
Method_ MethodType
the prediction method
Definition KalmanFilter.h:136
typename UpdateType< M >::value_type ResultType
What update() with M fills when given a result: the FilterUpdate of UpdateType.
Definition KalmanFilter.h:146
auto predict(Params< Component_ > &state, TimeStep< Scalar > auto const &dt, Inputs const &... inputs) const
Moves state forward by dt, any TimeStep (see Time steps), through the process model,...
Definition KalmanFilter.h:195
Method const & method() const
Definition KalmanFilter.h:172
typename decltype(internal::kalmanUpdateType< Params< Component_ >, M >())::type UpdateType
What update() with M returns: a FilterUpdate in a std::expected (decisions.md [innovation-cholesky]).
Definition KalmanFilter.h:142
PredictedJoint< SpaceType, Scalar > predictJoint(Params< Component_ > &state, Inputs const &... inputs) const
Moves state forward as predict(state, inputs...) does with a fixed-step model.
Definition KalmanFilter.h:233
What a KalmanFilter holds and a KalmanRecursion acts on: a Component, such as a Gaussian,...
Definition KalmanFilter.h:54
A Recursion whose steps act on the parameters of the component Component_, the constraint a filter ov...
Definition Recursion.h:87
A reduction policy for a filter that keeps a State per update: it reduces an update's branches to at ...
Definition Reduction.h:632
A step of time that converts to Scalar: Scalar itself, or any type with a TimeTraits,...
Definition Time.h:128
std::allocator< std::byte > DefaultAllocator
The allocator a type with a run-time count uses unless given one.
Definition Allocation.h:47
#define EMRYS_FILTER_NO_UNIQUE_ADDRESS
Assertion used for programmer errors (misuse of the API).
Definition Macros.h:38
NumericError GaussianError
Reasons a Gaussian, in any of its forms (decisions.md [gaussian-forms]), can fail to give a density,...
Definition NumericError.h:45
typename ParamsOf< D >::type Params
The parameters of the density D: GaussianParams for a Gaussian, and D itself for a distribution whose...
Definition Params.h:42
typename internal::DefaultMethodOf< Model >::type DefaultMethodFor
The prediction method of a filter with process model Model, unless it is given one: Linearized,...
Definition ProcessModel.h:3220
constexpr bool isFixedStep
Whether Model is a FixedStepModel, whose predictions take no time step.
Definition ProcessModel.h:2776
PredictedJoint< typename Prior::SpaceType, typename Prior::Scalar > predictJoint(Method const &method, Prior const &prior, Model const &model, TimeStep< typename Prior::Scalar > auto const &time, Args const &... args)
Definition ProcessModel.h:3362
std::expected< CategoricalUpdate< Space, Scalar >, WeightError > update(CategoricalParams< Space, Scalar > const &prior, E const &emission)
Definition Emission.h:97
std::conditional_t< isFixedStep< Model >, ModelsMethod, Method > MethodFor
The type of a filter constructor's method argument: Method, or ModelsMethod for a fixed-step Model,...
Definition ProcessModel.h:3236
The upkeep operations, each made by its factory (decisions.md [policy-factories], [upkeep]): the acti...
Definition Upkeep.h:380
Where a step linearizes its input: a point, or a distribution, in place of the input's own mean and s...
Definition TransformArgs.h:156
One prediction step as a joint: the Gaussian the step started from, the Gaussian it predicted,...
Definition ProcessModel.h:2817
A count of a fixed-step model's steps, for predict(Steps{n}).
Definition Time.h:136
Eigen::Index count
the number of steps, at least zero
Definition Time.h:137
The upkeep a filter holds when it is given none: it takes any state, changes nothing,...
Definition Upkeep.h:889