EmrysFilter 0.1.0
State estimation utilities in C++23 using Eigen
Loading...
Searching...
No Matches
SqrtInfoGaussian.h
Go to the documentation of this file.
1#pragma once
2
11
12#include <expected>
13#include <type_traits>
14#include <utility>
15
31
32namespace Emrys
33{
34
67template <Space Space_, RealScalar Scalar_ = double>
69{
70public:
71
73 using Scalar = typename MomentsType::Scalar;
74 using Index = typename MomentsType::Index;
78 using SpaceType = Space_;
80
83
86
89
92
93 static constexpr bool IsParams = true;
94 static constexpr bool IsInfoForm = true;
95 static constexpr bool IsSqrtForm = true;
96
103
106 : m_space{std::move(space)}
107 {
108 m_reference.setZero(Emrys::valueDimension(m_space));
109 m_root.setZero(differenceDimension(), differenceDimension());
110 m_whitenedOffset.setZero(differenceDimension());
111 m_densityMean.setZero(valueDimension());
112 }
113
118 template <MatrixExpression Reference, MatrixExpression Root, MatrixExpression Offset>
119 requires internal::SizedByLength<Space_>
120 SqrtInfoGaussianParams(Reference && reference, Root && root, Offset && whitenedOffset)
121 : m_reference{std::forward<Reference>(reference)}
122 , m_root{std::forward<Root>(root)}
123 , m_whitenedOffset{std::forward<Offset>(whitenedOffset)}
124 {
125 fitSpace();
126 }
127
131 template <MatrixExpression Reference, MatrixExpression Root, MatrixExpression Offset>
132 SqrtInfoGaussianParams(Space_ space, Reference && reference, Root && root, Offset && whitenedOffset)
133 : m_reference{std::forward<Reference>(reference)}
134 , m_root{std::forward<Root>(root)}
135 , m_whitenedOffset{std::forward<Offset>(whitenedOffset)}
136 , m_space{std::move(space)}
137 {
138 fitSpace();
139 }
140
142 [[nodiscard]] Index
144 {
145 return Emrys::valueDimension(m_space);
146 }
147
149 [[nodiscard]] Index
151 {
152 return Emrys::differenceDimension(m_space);
153 }
154
156 [[nodiscard]] Space_ const &
157 space() const
158 {
159 return m_space;
160 }
161
163 [[nodiscard]] VectorType const &
164 reference() const
165 {
166 return m_reference;
167 }
168
173 [[nodiscard]] MatrixType const &
174 infoRoot() const
175 {
176 return m_root;
177 }
178
180 [[nodiscard]] DifferenceVectorType const &
182 {
183 return m_whitenedOffset;
184 }
185
187 [[nodiscard]] DifferenceVectorType
189 {
190 DifferenceVectorType result =
191 internal::multiply(internal::asTriangular<Eigen::Upper>(m_root).transpose(), m_whitenedOffset);
192 return result;
193 }
194
203 template <typename Derived>
204 void
205 setReference(Eigen::MatrixBase<Derived> const & reference)
206 {
207 m_stamp.touchValues();
208 EMRYS_FILTER_ASSERT(reference.size() == valueDimension());
209 VectorType moved = reference;
210 normalizeValues(m_space, moved);
211 DifferenceVectorType const shift = Emrys::minus(m_space, moved, m_reference);
212 m_whitenedOffset.noalias() -= internal::multiply(internal::asTriangular<Eigen::Upper>(m_root), shift);
213 if constexpr (!hasIdentityReset<Space_>)
214 {
215 Eigen::Index const n = differenceDimension();
216 AugmentedType stacked(n, n + 1);
217 stacked.leftCols(n) = m_root;
218 internal::forEachInverseResetJacobian(
219 m_space,
220 m_reference,
221 shift,
222 moved,
223 [&](Eigen::Index differences, auto const & gInverse) {
224 Eigen::Index const k = gInverse.rows();
225 stacked.middleCols(differences, k) = m_root.middleCols(differences, k) * gInverse;
226 }
227 );
228 stacked.col(n) = m_whitenedOffset;
229 triangularize(stacked);
230 m_root = stacked.leftCols(n);
231 m_whitenedOffset = stacked.col(n);
232 }
233 m_reference = std::move(moved);
234 }
235
239 template <MatrixExpression Root, MatrixExpression Offset>
240 void
241 setRoot(Root && root, Offset && whitenedOffset)
242 {
243 m_stamp.touchValues();
244 EMRYS_FILTER_ASSERT(
245 root.rows() == differenceDimension() && root.cols() == differenceDimension()
247 );
248 m_root = std::forward<Root>(root);
249 m_root.template triangularView<Eigen::StrictlyLower>().setZero();
250 m_whitenedOffset = std::forward<Offset>(whitenedOffset);
251 }
252
256 [[nodiscard]] std::expected<VectorType, GaussianError>
257 mean() const
258 {
259 if (auto checked = checkRoot(); !checked)
260 {
261 return std::unexpected{checked.error()};
262 }
263 return solvedMean();
264 }
265
269 [[nodiscard]] std::expected<MomentsType, GaussianError>
270 moments() const
271 {
272 if (auto checked = checkRoot(); !checked)
273 {
274 return std::unexpected{checked.error()};
275 }
276 return momentsWithMean(solvedMean());
277 }
278
282 [[nodiscard]] std::expected<MatrixType, GaussianError>
284 {
285 auto inverse = covarianceRoot();
286 if (!inverse)
287 {
288 return std::unexpected{inverse.error()};
289 }
290 MatrixType result = internal::multiply(*inverse, inverse->transpose());
291 return result;
292 }
293
295 [[nodiscard]] std::expected<MatrixType, GaussianError>
296 precision() const
297 {
298 MatrixType result = internal::multiply(m_root.transpose(), internal::asTriangular<Eigen::Upper>(m_root));
299 return result;
300 }
301
305 [[nodiscard]] std::expected<MatrixType, GaussianError>
307 {
308 if (auto checked = checkRoot(); !checked)
309 {
310 return std::unexpected{checked.error()};
311 }
312 MatrixType result = MatrixType::Identity(differenceDimension(), differenceDimension());
313 internal::solveInPlace(m_root.template triangularView<Eigen::Upper>(), result);
314 return result;
315 }
316
318 [[nodiscard]] std::expected<MatrixType, GaussianError>
320 {
321 return m_root;
322 }
323
331 [[nodiscard]] std::expected<DensityType, GaussianError>
332 toDensity() const &
333 {
334 if (auto checked = checkRoot(); !checked)
335 {
336 return std::unexpected{checked.error()};
337 }
338 m_densityMean = solvedMean();
339 m_logDeterminant = Scalar(-2) * m_root.diagonal().array().abs().log().sum();
340 return DensityType{*this};
341 }
342
344 void
345 toDensity() const && = delete;
346
363 template <typename Path>
364 [[nodiscard]] auto
365 marginal() const
366 {
367 return internal::marginalOverPath<Path>(m_space, [&](auto const & kept, auto const & keptSpace) {
368 return marginalAt(kept, keptSpace);
369 });
370 }
371
375 template <typename Path>
376 [[nodiscard]] auto
377 marginal(Index element) const
378 {
379 return internal::marginalOverElement<Path>(m_space, element, [&](auto const & kept, auto const & keptSpace) {
380 return marginalAt(kept, keptSpace);
381 });
382 }
383
395 template <typename GivenPath, typename Derived>
396 [[nodiscard]] auto
397 conditional(Eigen::MatrixBase<Derived> const & values) const
398 {
399 return internal::tagConditional<GivenPath>(
400 m_space,
401 [&](auto const & target, auto const & given, auto const & targetSpace, auto const & givenSpace) {
402 using GivenSpace = std::remove_cvref_t<decltype(givenSpace)>;
403 using Result = SqrtInfoGaussianParams<std::remove_cvref_t<decltype(targetSpace)>, Scalar>;
406 constexpr int TargetSize = Result::DifferenceDimensionAtCompileTime;
407 constexpr int TargetMaxSize = Result::MaxDifferenceDimensionAtCompileTime;
408 using GivenVector = Eigen::Matrix<Scalar, GivenSize, 1, Eigen::ColMajor, GivenMaxSize, 1>;
409 using Stacked = internal::MatrixOf<
410 Scalar,
412 TargetSize == Eigen::Dynamic ? Eigen::Dynamic : TargetSize + 1,
414 TargetMaxSize == Eigen::Dynamic ? Eigen::Dynamic : TargetMaxSize + 1>;
415 EMRYS_FILTER_ASSERT(values.size() == given.values.size());
416
417 Eigen::Index const n = differenceDimension();
418 Eigen::Index const t = target.differences.size();
419 typename Result::VectorType reference = m_reference(target.values);
420 auto root = typename Result::MatrixType{};
421 root.resize(t, t);
422 auto whitened = typename Result::DifferenceVectorType{};
423 whitened.resize(t);
424 // MSVC can't form the empty products of a conditional on everything or on nothing.
425 if constexpr (TargetSize != 0 && GivenSize != 0)
426 {
427 GivenVector const offset = Emrys::minus(givenSpace, values, m_reference(given.values));
428 Stacked stacked(n, t + 1);
429 stacked.leftCols(t) = m_root(Eigen::placeholders::all, target.differences);
430 stacked.col(t) = m_whitenedOffset
431 - internal::multiply(m_root(Eigen::placeholders::all, given.differences), offset);
432 triangularize(stacked);
433 root = stacked.topLeftCorner(t, t);
434 whitened = stacked.col(t).head(t);
435 }
436 else
437 {
438 root = m_root(target.differences, target.differences);
439 whitened = m_whitenedOffset(target.differences);
440 }
441 return Result{targetSpace, std::move(reference), std::move(root), std::move(whitened)};
442 }
443 );
444 }
445
446private:
447
448 friend DensityType;
449
451 template <typename>
452 friend class internal::ValuesCheck;
453
455 using AugmentedType = internal::MatrixOf<
456 Scalar,
458 DifferenceDimensionAtCompileTime == Eigen::Dynamic ? Eigen::Dynamic : DifferenceDimensionAtCompileTime + 1,
460 MaxDifferenceDimensionAtCompileTime == Eigen::Dynamic ? Eigen::Dynamic
462
466 [[nodiscard]] std::expected<void, GaussianError>
467 checkRoot() const
468 {
469 if (!allFinite(m_root))
470 {
471 return std::unexpected{GaussianError::NonFinite};
472 }
473 if ((m_root.diagonal().array() == Scalar(0)).any())
474 {
475 return std::unexpected{GaussianError::Singular};
476 }
477 return {};
478 }
479
483 template <typename Kept, typename KeptSpace>
484 [[nodiscard]] std::expected<SqrtInfoGaussianParams<KeptSpace, Scalar>, GaussianError>
485 marginalAt(Kept const & kept, KeptSpace const & keptSpace) const
486 {
488 using Expected = std::expected<Result, GaussianError>;
489 constexpr int D = DifferenceDimensionAtCompileTime;
490 constexpr int DMax = MaxDifferenceDimensionAtCompileTime;
491 Eigen::Index const n = differenceDimension();
492 Eigen::Index const k = kept.differences.size();
493 auto const rest =
494 internal::resolveIndices<D, DMax>(n, internal::complementIndices<D, DMax>(n, kept.differences));
495 Eigen::Index const r = rest.size();
496
497 typename Result::VectorType reference = m_reference(kept.values);
498 AugmentedType stacked(n, n + 1);
499 stacked.leftCols(r) = m_root(Eigen::placeholders::all, rest);
500 stacked.middleCols(r, k) = m_root(Eigen::placeholders::all, kept.differences);
501 stacked.col(n) = m_whitenedOffset;
502 triangularize(stacked);
503 if ((stacked.diagonal().head(r).array() == Scalar(0)).any())
504 {
505 return Expected{std::unexpected{GaussianError::Singular}};
506 }
507 typename Result::MatrixType root = stacked.block(r, r, k, k);
508 typename Result::DifferenceVectorType whitened = stacked.col(n).tail(k);
509 return Expected{Result{keptSpace, std::move(reference), std::move(root), std::move(whitened)}};
510 }
511
515 template <typename Kept, typename KeptSpace>
517 densityMarginalAt(Kept const & kept, KeptSpace const & keptSpace) const
518 {
519 auto result = marginalAt(kept, keptSpace);
520 EMRYS_FILTER_ASSERT(result.has_value() && "a checked root's marginal cannot be singular");
521 return std::move(*result);
522 }
523
527 [[nodiscard]] MomentsType
528 momentsWithMean(VectorType mean) const
529 {
530 auto result = MomentsType{std::move(mean), *(covariance())};
531 if constexpr (!hasIdentityReset<Space_>)
532 {
533 DifferenceVectorType const step = Emrys::minus(m_space, result.mean(), m_reference);
534 resetCovariance(m_space, m_reference, step, result.covarianceLower());
535 }
536 return result;
537 }
538
540 [[nodiscard]] MomentsType
541 densityMoments() const
542 {
543 return momentsWithMean(m_densityMean);
544 }
545
547 [[nodiscard]] VectorType
548 solvedMean() const
549 {
550 DifferenceVectorType const offset = m_root.template triangularView<Eigen::Upper>().solve(m_whitenedOffset);
551 VectorType result = Emrys::plus(m_space, m_reference, offset);
552 return result;
553 }
554
556 [[nodiscard]] VectorType const &
557 densityMean() const
558 {
559 return m_densityMean;
560 }
561
563 void
564 whitenInPlace(DifferenceVectorType & residual) const
565 {
566 residual = internal::multiply(internal::asTriangular<Eigen::Upper>(m_root), residual).eval();
567 }
568
570 void
571 colorInto(auto & colored, auto const & normals) const
572 {
573 colored = normals;
574 internal::solveInPlace(m_root.template triangularView<Eigen::Upper>(), colored);
575 }
576
580 void
581 fitSpace()
582 {
583 internal::fitValueDimension(m_space, m_reference.size());
584 EMRYS_FILTER_ASSERT(
585 m_root.rows() == differenceDimension() && m_root.cols() == differenceDimension()
586 && m_whitenedOffset.size() == differenceDimension()
587 && "the root and whitened offset must have a row per difference coordinate of the space"
588 );
589 normalizeValues(m_space, m_reference);
590 m_root.template triangularView<Eigen::StrictlyLower>().setZero();
591 m_densityMean.setZero(valueDimension());
592 }
593
594 VectorType m_reference;
595 MatrixType m_root;
596 DifferenceVectorType m_whitenedOffset;
597 EMRYS_FILTER_NO_UNIQUE_ADDRESS Space_ m_space;
598 mutable Scalar m_logDeterminant{};
599 mutable VectorType m_densityMean;
600 internal::Stamp m_stamp;
601};
602
611template <Space Space_, RealScalar Scalar_ = double>
613
624template <Space Space_, RealScalar Scalar_>
627{
629 constexpr int D = Result::DifferenceDimensionAtCompileTime;
630 constexpr int DMax = Result::MaxDifferenceDimensionAtCompileTime;
631 using Stacked = internal::MatrixOf<
632 Scalar_,
633 D == Eigen::Dynamic ? Eigen::Dynamic : 2 * D,
634 D == Eigen::Dynamic ? Eigen::Dynamic : D + 1,
635 DMax == Eigen::Dynamic ? Eigen::Dynamic : 2 * DMax,
636 DMax == Eigen::Dynamic ? Eigen::Dynamic : DMax + 1>;
637 EMRYS_FILTER_ASSERT(first.differenceDimension() == second.differenceDimension());
638 Eigen::Index const n = first.differenceDimension();
639
640 Result moved = second;
641 moved.setReference(first.reference());
642 Stacked stacked(2 * n, n + 1);
643 stacked.topLeftCorner(n, n) = first.infoRoot();
644 stacked.topRightCorner(n, 1) = first.whitenedOffset();
645 stacked.bottomLeftCorner(n, n) = moved.infoRoot();
646 stacked.bottomRightCorner(n, 1) = moved.whitenedOffset();
647 triangularize(stacked);
648
649 // Built from parts rather than as a copy of first, whose root and offset would be overwritten.
650 auto root = typename Result::MatrixType{stacked.topLeftCorner(n, n)};
651 root.template triangularView<Eigen::StrictlyLower>().setZero();
652 return Result{
653 first.space(),
654 first.reference(),
655 std::move(root),
656 typename Result::DifferenceVectorType{stacked.topRightCorner(n, 1)}
657 };
658}
659
672template <GaussianForm G>
673[[nodiscard]] std::expected<SqrtInfoGaussianParams<typename G::SpaceType, typename G::Scalar>, GaussianError>
674toSqrtInfo(G const & form)
675{
677 if constexpr (std::is_same_v<G, Result>)
678 {
679 return form;
680 }
681 else
682 {
683 auto root = form.precisionRoot();
684 if (!root)
685 {
686 return std::unexpected{root.error()};
687 }
688 if constexpr (isInfoForm<G>)
689 {
690 typename Result::DifferenceVectorType whitened =
691 root->transpose().template triangularView<Eigen::Lower>().solve(form.infoVector());
692 return Result{form.space(), form.reference(), std::move(*root), std::move(whitened)};
693 }
694 else
695 {
696 std::expected<typename G::VectorType, GaussianError> mean = form.mean();
697 if (!mean)
698 {
699 return std::unexpected{mean.error()};
700 }
701 triangularize(*root);
702 return Result{
703 form.space(),
704 std::move(*mean),
705 std::move(*root),
706 Result::DifferenceVectorType::Zero(form.differenceDimension())
707 };
708 }
709 }
710}
711
712} // namespace Emrys
713
714#ifndef EMRYS_FILTER_NO_IO
715
716namespace Emrys
717{
718
719namespace internal
720{
721
725template <typename Space_, typename Scalar_>
726void
727describe(std::ostream & stream, SqrtInfoGaussianParams<Space_, Scalar_> const & gaussian, Indent indent)
728{
729 stream << indent << "square-root information Gaussian";
730 printDimension(stream, gaussian.valueDimension(), gaussian.differenceDimension());
731 printMoments(stream, indent.deeper(), gaussian.moments());
732}
733
734} // namespace internal
735
736} // namespace Emrys
737
738#endif // EMRYS_FILTER_NO_IO
Spaces built from other spaces (decisions.md [sizes-and-dimensions], [several-resizable-blocks]): Com...
How a function that stores a matrix argument takes it (decisions.md [forwarded-matrices]): the concep...
What the four forms of the Gaussian share (decisions.md [gaussian-forms], [form-densities]): the Gaus...
The Gaussian: its parameters GaussianParams, the Gaussian that evaluates the density,...
What marginals and conditionals are built from: resolving Eigen index sets against a space; the share...
The macros every header includes first.
Mathematical constants and scalar functions that work in every scalar type the library accepts,...
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'...
Printing: operator<< and std::formatter for every distribution, every filter (which prints its name a...
The covariance reset (decisions.md [covariance-reset]): hasIdentityReset<>, resetJacobian(),...
Solving by a factorization of a small matrix: transposedSolve() gives , the shape of a Kalman gain an...
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,...
Triangularization: the triangular factor of a stacked matrix by Householder reflections,...
The density of a Gaussian in a square-root or information form: a read-only view.
Definition GaussianForm.h:139
First and second moments (mean and covariance) of a distribution.
Definition Moments.h:55
Scalar_ Scalar
Definition Moments.h:58
Eigen::Index Index
Definition Moments.h:59
DifferenceMatrix< Space_, Space_, Scalar > MatrixType
Definition Moments.h:76
DifferenceVector< Space_, Scalar > DifferenceVectorType
Definition Moments.h:75
ValueVector< Space_, Scalar > VectorType
Definition Moments.h:74
static constexpr int MaxDifferenceDimensionAtCompileTime
Definition Moments.h:72
static constexpr int DifferenceDimensionAtCompileTime
Definition Moments.h:69
static constexpr int MaxValueDimensionAtCompileTime
Definition Moments.h:66
static constexpr int ValueDimensionAtCompileTime
Definition Moments.h:63
A Gaussian kept as an upper-triangular root of its precision and a whitened offset,...
Definition SqrtInfoGaussian.h:69
Space_ SpaceType
the space the values live in
Definition SqrtInfoGaussian.h:78
SqrtInfoGaussianParams(Space_ space, Reference &&reference, Root &&root, Offset &&whitenedOffset)
SqrtInfoGaussianParams(reference, root, whitenedOffset) in space, which is resized to fit them if it ...
Definition SqrtInfoGaussian.h:132
static constexpr int MaxValueDimensionAtCompileTime
a bound on the length of a value, or Eigen::Dynamic
Definition SqrtInfoGaussian.h:85
static constexpr int ValueDimensionAtCompileTime
the length of a value, or Eigen::Dynamic
Definition SqrtInfoGaussian.h:82
DifferenceVectorType infoVector() const
Definition SqrtInfoGaussian.h:188
std::expected< MatrixType, GaussianError > covarianceRoot() const
Definition SqrtInfoGaussian.h:306
std::expected< MatrixType, GaussianError > precision() const
Definition SqrtInfoGaussian.h:296
Moments< Space_, Scalar_ > MomentsType
the mean and covariance together
Definition SqrtInfoGaussian.h:72
typename MomentsType::VectorType VectorType
a value, such as the reference
Definition SqrtInfoGaussian.h:75
VectorType const & reference() const
Definition SqrtInfoGaussian.h:164
Space_ const & space() const
Definition SqrtInfoGaussian.h:157
static constexpr bool IsSqrtForm
holds a triangular root
Definition SqrtInfoGaussian.h:95
typename MomentsType::Index Index
Eigen's index type.
Definition SqrtInfoGaussian.h:74
std::expected< MatrixType, GaussianError > precisionRoot() const
Definition SqrtInfoGaussian.h:319
FormGaussian< SqrtInfoGaussianParams > DensityType
the view toDensity() returns
Definition SqrtInfoGaussian.h:79
typename MomentsType::MatrixType MatrixType
a matrix over differences
Definition SqrtInfoGaussian.h:77
Index valueDimension() const
Definition SqrtInfoGaussian.h:143
static constexpr int MaxDifferenceDimensionAtCompileTime
a bound on the length of a difference, or Eigen::Dynamic
Definition SqrtInfoGaussian.h:91
void toDensity() const &&=delete
A density of a temporary would outlive it.
void setRoot(Root &&root, Offset &&whitenedOffset)
Sets to the upper triangle of root and to whitenedOffset, about the current reference,...
Definition SqrtInfoGaussian.h:241
static constexpr int DifferenceDimensionAtCompileTime
the length of a difference and the rows of the root, or Eigen::Dynamic
Definition SqrtInfoGaussian.h:88
SqrtInfoGaussianParams(Space_ space)
Constructs a SqrtInfoGaussianParams in space, with a zero reference and no information.
Definition SqrtInfoGaussian.h:105
SqrtInfoGaussianParams()
Constructs a SqrtInfoGaussianParams in a default space, with a zero reference and no information.
Definition SqrtInfoGaussian.h:100
std::expected< MatrixType, GaussianError > covariance() const
Definition SqrtInfoGaussian.h:283
auto marginal(Index element) const
marginal<Path>() of repetition element of the repeated block Path starts at (see GaussianParams::marg...
Definition SqrtInfoGaussian.h:377
auto marginal() const
Definition SqrtInfoGaussian.h:365
typename MomentsType::Scalar Scalar
the scalar type
Definition SqrtInfoGaussian.h:73
void setReference(Eigen::MatrixBase< Derived > const &reference)
Moves the reference to reference, normalized by the space, and re-expresses the data array about it.
Definition SqrtInfoGaussian.h:205
static constexpr bool IsParams
parameters, which views check
Definition SqrtInfoGaussian.h:93
std::expected< MomentsType, GaussianError > moments() const
Definition SqrtInfoGaussian.h:270
Index differenceDimension() const
Definition SqrtInfoGaussian.h:150
std::expected< VectorType, GaussianError > mean() const
Definition SqrtInfoGaussian.h:257
typename MomentsType::DifferenceVectorType DifferenceVectorType
a difference, or the whitened offset
Definition SqrtInfoGaussian.h:76
SqrtInfoGaussianParams(Reference &&reference, Root &&root, Offset &&whitenedOffset)
Constructs a SqrtInfoGaussianParams about reference, with the upper triangle of root as and whitened...
Definition SqrtInfoGaussian.h:120
std::expected< DensityType, GaussianError > toDensity() const &
Checks the root, solves for the mean, and computes , writing both to a cache each time,...
Definition SqrtInfoGaussian.h:332
MatrixType const & infoRoot() const
Definition SqrtInfoGaussian.h:174
DifferenceVectorType const & whitenedOffset() const
Definition SqrtInfoGaussian.h:181
static constexpr bool IsInfoForm
holds a root of the precision
Definition SqrtInfoGaussian.h:94
auto conditional(Eigen::MatrixBase< Derived > const &values) const
Definition SqrtInfoGaussian.h:397
void triangularize(M &&m)
Reduces m to upper-triangular form in place by Householder reflections from the left,...
Definition Triangularization.h:52
bool allFinite(Eigen::DenseBase< Derived > const &x)
Definition Math.h:354
#define EMRYS_FILTER_NO_UNIQUE_ADDRESS
Assertion used for programmer errors (misuse of the API).
Definition Macros.h:38
@ NonFinite
a matrix, a factor, or a log-weight holds NaN or infinity (+inf, for a log-weight)
Definition NumericError.h:33
@ Singular
the precision is not positive definite, so the mean and covariance are undefined
Definition NumericError.h:32
NumericError GaussianError
Reasons a Gaussian, in any of its forms (decisions.md [gaussian-forms]), can fail to give a density,...
Definition NumericError.h:45
FormGaussian< SqrtInfoGaussianParams< Space_, Scalar_ > > SqrtInfoGaussian
The Gaussian in square-root information form, which evaluates its density: what SqrtInfoGaussianParam...
Definition SqrtInfoGaussian.h:612
InfoGaussianParams< Space_, Scalar_ > multiply(InfoGaussianParams< Space_, Scalar_ > const &first, InfoGaussianParams< Space_, Scalar_ > const &second)
Definition InfoGaussian.h:771
constexpr bool isInfoForm
Whether the GaussianForm G holds the precision, as InfoGaussianParams and SqrtInfoGaussianParams do,...
Definition GaussianForm.h:69
std::expected< SqrtInfoGaussianParams< typename G::SpaceType, typename G::Scalar >, GaussianError > toSqrtInfo(G const &form)
Definition SqrtInfoGaussian.h:674
GivenBlock< Space, P, Value > given(Space const &space, Value const &value)
Definition Measurement.h:917
constexpr Residual< Inner > residual(Inner inner={})
Definition Resampling.h:544
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
auto minus(S const &space, Eigen::MatrixBase< ADerived > const &a, Eigen::MatrixBase< BDerived > const &b)
Definition Space.h:715
constexpr bool hasIdentityReset
Whether the reset Jacobian of S is the identity, so that a covariance needs no change when its mean m...
Definition Reset.h:100
Eigen::Index differenceDimension(S const &space)
Definition Space.h:284
void resetCovariance(S const &space, Eigen::MatrixBase< XDerived > const &x, Eigen::MatrixBase< DDerived > const &d, Eigen::MatrixBase< CovDerived > const &cov)
Carries the covariance cov from the tangent space at x to the one at , in place: ,...
Definition Reset.h:426
constexpr int valueDimensionAtCompileTime
The value dimension of Space at compile time, or Eigen::Dynamic if it is resizable.
Definition Space.h:251
constexpr int maxValueDimensionAtCompileTime
The largest valid value dimension of Space, or Eigen::Dynamic if it is unbounded.
Definition Space.h:258
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