EmrysFilter 0.1.0
State estimation utilities in C++23 using Eigen
Loading...
Searching...
No Matches
InfoGaussian.h
Go to the documentation of this file.
1#pragma once
2
10
11#include <expected>
12#include <type_traits>
13#include <utility>
14
15#include <Eigen/Cholesky>
16
32
33namespace Emrys
34{
35
72template <Space Space_, RealScalar Scalar_ = double>
74{
75public:
76
78 using Scalar = typename MomentsType::Scalar;
79 using Index = typename MomentsType::Index;
81
84
86 using SpaceType = Space_;
88
91
94
97
100
101 static constexpr bool IsParams = true;
102 static constexpr bool IsInfoForm = true;
103 static constexpr bool IsSqrtForm = false;
104
109 : InfoGaussianParams{Space_{}}
110 {}
111
113 explicit InfoGaussianParams(Space_ space)
114 : m_space{std::move(space)}
115 {
116 m_reference.setZero(Emrys::valueDimension(m_space));
117 m_infoMatrix.setZero(differenceDimension(), differenceDimension());
118 m_infoVector.setZero(differenceDimension());
119 }
120
125 template <MatrixExpression Reference, MatrixExpression Matrix, MatrixExpression Vector>
126 requires internal::SizedByLength<Space_>
127 InfoGaussianParams(Reference && reference, Matrix && infoMatrix, Vector && infoVector)
128 : m_reference{std::forward<Reference>(reference)}
129 , m_infoMatrix{std::forward<Matrix>(infoMatrix)}
130 , m_infoVector{std::forward<Vector>(infoVector)}
131 {
132 fitSpace();
133 }
134
138 template <MatrixExpression Reference, MatrixExpression Matrix, MatrixExpression Vector>
139 InfoGaussianParams(Space_ space, Reference && reference, Matrix && infoMatrix, Vector && infoVector)
140 : m_reference{std::forward<Reference>(reference)}
141 , m_infoMatrix{std::forward<Matrix>(infoMatrix)}
142 , m_infoVector{std::forward<Vector>(infoVector)}
143 , m_space{std::move(space)}
144 {
145 fitSpace();
146 }
147
150 : m_reference{other.m_reference}
151 , m_infoMatrix{other.m_infoMatrix}
152 , m_infoVector{other.m_infoVector}
153 , m_space{other.m_space}
154 , m_llt{other.m_factorValid ? other.m_llt : std::nullopt}
155 , m_factorValid{other.m_factorValid}
156 {
157 if (m_factorValid)
158 {
159 m_logDeterminant = other.m_logDeterminant;
160 }
161 }
162
165 : m_reference{std::move(other.m_reference)}
166 , m_infoMatrix{std::move(other.m_infoMatrix)}
167 , m_infoVector{std::move(other.m_infoVector)}
168 , m_space{std::move(other.m_space)}
169 , m_llt{other.m_factorValid ? std::move(other.m_llt) : std::nullopt}
170 , m_factorValid{other.m_factorValid}
171 {
172 if (m_factorValid)
173 {
174 m_logDeterminant = other.m_logDeterminant;
175 }
176 other.m_stamp.touchShape();
177 other.m_factorValid = false;
178 }
179
185 {
186 m_stamp.touchShape();
187 m_reference = other.m_reference;
188 m_infoMatrix = other.m_infoMatrix;
189 m_infoVector = other.m_infoVector;
190 m_space = other.m_space;
191 if (other.m_factorValid)
192 {
193 m_llt = other.m_llt;
194 m_logDeterminant = other.m_logDeterminant;
195 }
196 m_factorValid = other.m_factorValid;
197 return *this;
198 }
199
204 operator=(InfoGaussianParams && other) noexcept
205 {
206 m_stamp.touchShape();
207 other.m_stamp.touchShape();
208 m_reference = std::move(other.m_reference);
209 m_infoMatrix = std::move(other.m_infoMatrix);
210 m_infoVector = std::move(other.m_infoVector);
211 m_space = std::move(other.m_space);
212 if (other.m_factorValid)
213 {
214 m_llt = std::move(other.m_llt);
215 m_logDeterminant = other.m_logDeterminant;
216 }
217 m_factorValid = other.m_factorValid;
218 other.m_factorValid = false;
219 return *this;
220 }
221
223 [[nodiscard]] Index
225 {
226 return Emrys::valueDimension(m_space);
227 }
228
230 [[nodiscard]] Index
232 {
233 return Emrys::differenceDimension(m_space);
234 }
235
237 [[nodiscard]] Space_ const &
238 space() const
239 {
240 return m_space;
241 }
242
244 [[nodiscard]] VectorType const &
245 reference() const
246 {
247 return m_reference;
248 }
249
251 [[nodiscard]] MatrixType const &
253 {
254 return m_infoMatrix;
255 }
256
258 [[nodiscard]] DifferenceVectorType const &
260 {
261 return m_infoVector;
262 }
263
274 template <typename Derived>
275 void
276 setReference(Eigen::MatrixBase<Derived> const & reference)
277 {
278 m_stamp.touchValues();
279 EMRYS_FILTER_ASSERT(reference.size() == valueDimension());
280 VectorType moved = reference;
281 normalizeValues(m_space, moved);
282 DifferenceVectorType const shift = Emrys::minus(m_space, moved, m_reference);
283 // The product and the reset read the precision whole, so mirror the lower triangle first:
284 // a dense product keeps fixed sizes fixed (internal::multiply()), where a self-adjoint view's never does.
285 m_infoMatrix.template triangularView<Eigen::StrictlyUpper>() = m_infoMatrix.transpose();
286 m_infoVector.noalias() -= internal::multiply(m_infoMatrix, shift);
287 if constexpr (!hasIdentityReset<Space_>)
288 {
289 internal::resetInfoAt(m_space, m_reference, shift, moved, m_infoMatrix, m_infoVector);
290 m_factorValid = false;
291 }
292 m_reference = std::move(moved);
293 }
294
299 template <MatrixExpression Matrix, MatrixExpression Vector>
300 void
301 setInfo(Matrix && infoMatrix, Vector && infoVector)
302 {
303 m_stamp.touchValues();
304 EMRYS_FILTER_ASSERT(
306 && infoVector.size() == differenceDimension()
307 );
308 m_infoMatrix = std::forward<Matrix>(infoMatrix);
309 m_infoVector = std::forward<Vector>(infoVector);
310 m_factorValid = false;
311 }
312
319 template <typename MatrixDerived, typename VectorDerived>
320 void
321 addInfo(Eigen::MatrixBase<MatrixDerived> const & infoMatrix, Eigen::MatrixBase<VectorDerived> const & infoVector)
322 {
323 m_stamp.touchValues();
324 EMRYS_FILTER_ASSERT(
326 && infoVector.size() == differenceDimension()
327 );
328 m_infoMatrix.template triangularView<Eigen::Lower>() += infoMatrix;
329 m_infoVector += infoVector;
330 m_factorValid = false;
331 }
332
336 [[nodiscard]] std::expected<VectorType, GaussianError>
337 mean() const
338 {
339 if (auto factorized = factorize(); !factorized)
340 {
341 return std::unexpected{factorized.error()};
342 }
343 return solvedMean();
344 }
345
350 [[nodiscard]] std::expected<MomentsType, GaussianError>
351 moments() const
352 {
353 if (auto factorized = factorize(); !factorized)
354 {
355 return std::unexpected{factorized.error()};
356 }
357 return momentsWithMean(solvedMean());
358 }
359
363 [[nodiscard]] std::expected<MatrixType, GaussianError>
365 {
366 if (auto factorized = factorize(); !factorized)
367 {
368 return std::unexpected{factorized.error()};
369 }
370 MatrixType result = MatrixType::Identity(differenceDimension(), differenceDimension());
371 internal::solveInPlace(*m_llt, result);
372 return result;
373 }
374
376 [[nodiscard]] std::expected<MatrixType, GaussianError>
377 precision() const
378 {
379 MatrixType result = m_infoMatrix.template selfadjointView<Eigen::Lower>();
380 return result;
381 }
382
386 [[nodiscard]] std::expected<MatrixType, GaussianError>
388 {
389 if (auto factorized = factorize(); !factorized)
390 {
391 return std::unexpected{factorized.error()};
392 }
393 MatrixType result = MatrixType::Identity(differenceDimension(), differenceDimension());
394 internal::solveInPlace(m_llt->matrixU(), result);
395 return result;
396 }
397
401 [[nodiscard]] std::expected<MatrixType, GaussianError>
403 {
404 if (auto factorized = factorize(); !factorized)
405 {
406 return std::unexpected{factorized.error()};
407 }
408 MatrixType result = m_llt->matrixU();
409 return result;
410 }
411
423 [[nodiscard]] std::expected<void, GaussianError>
424 factorize() const
425 {
426 if (m_factorValid)
427 {
428 return {};
429 }
430 if (!m_llt)
431 {
432 m_llt.emplace(differenceDimension());
433 }
434 m_llt->compute(m_infoMatrix);
435 if (m_llt->info() != Eigen::Success)
436 {
437 return std::unexpected{GaussianError::Singular};
438 }
439 // As in GaussianParams::factorize(): NaN passes LLT's test but reaches the factor's
440 // diagonal.
441 Scalar const logDeterminant = Scalar(-2) * m_llt->matrixLLT().diagonal().array().log().sum();
442 if (!isFinite(logDeterminant))
443 {
444 return std::unexpected{GaussianError::NonFinite};
445 }
446 m_logDeterminant = logDeterminant;
447 m_factorValid = true;
448 return {};
449 }
450
456 [[nodiscard]] std::expected<DensityType, GaussianError>
457 toDensity() const &
458 {
459 if (auto factorized = factorize(); !factorized)
460 {
461 return std::unexpected{factorized.error()};
462 }
463 m_densityMean = solvedMean();
464 return DensityType{*this};
465 }
466
468 void
469 toDensity() const && = delete;
470
483 template <typename Path>
484 [[nodiscard]] auto
485 marginal() const
486 {
487 return internal::marginalOverPath<Path>(m_space, [&](auto const & kept, auto const & keptSpace) {
488 return marginalAt(kept, keptSpace);
489 });
490 }
491
495 template <typename Path>
496 [[nodiscard]] auto
497 marginal(Index element) const
498 {
499 return internal::marginalOverElement<Path>(m_space, element, [&](auto const & kept, auto const & keptSpace) {
500 return marginalAt(kept, keptSpace);
501 });
502 }
503
517 template <typename GivenPath, typename Derived>
518 [[nodiscard]] auto
519 conditional(Eigen::MatrixBase<Derived> const & values) const
520 {
521 return internal::tagConditional<GivenPath>(
522 m_space,
523 [&](auto const & target, auto const & given, auto const & targetSpace, auto const & givenSpace) {
524 using GivenSpace = std::remove_cvref_t<decltype(givenSpace)>;
525 using Result = InfoGaussianParams<std::remove_cvref_t<decltype(targetSpace)>, Scalar>;
528 constexpr int TargetSize = Result::DifferenceDimensionAtCompileTime;
529 constexpr int TargetMaxSize = Result::MaxDifferenceDimensionAtCompileTime;
530 using GivenVector = Eigen::Matrix<Scalar, GivenSize, 1, Eigen::ColMajor, GivenMaxSize, 1>;
531 using CrossMatrix = internal::MatrixOf<Scalar, TargetSize, GivenSize, TargetMaxSize, GivenMaxSize>;
532 EMRYS_FILTER_ASSERT(values.size() == given.values.size());
533
534 typename Result::VectorType reference = m_reference(target.values);
535 typename Result::MatrixType matrix =
536 internal::lowerSymmetricBlock(m_infoMatrix, target.differences, target.differences);
537 typename Result::DifferenceVectorType vector = m_infoVector(target.differences);
538 // MSVC can't form the empty products of a conditional on everything or on nothing.
539 if constexpr (TargetSize != 0 && GivenSize != 0)
540 {
541 GivenVector const offset = Emrys::minus(givenSpace, values, m_reference(given.values));
542 CrossMatrix const cross =
543 internal::lowerSymmetricBlock(m_infoMatrix, target.differences, given.differences);
544 vector.noalias() -= internal::multiply(cross, offset);
545 }
546 return Result{targetSpace, std::move(reference), std::move(matrix), std::move(vector)};
547 }
548 );
549 }
550
551private:
552
553 friend DensityType;
554
556 template <typename>
557 friend class internal::ValuesCheck;
558
560 using AugmentedType = internal::MatrixOf<
561 Scalar,
562 DifferenceDimensionAtCompileTime,
563 DifferenceDimensionAtCompileTime == Eigen::Dynamic ? Eigen::Dynamic : DifferenceDimensionAtCompileTime + 1,
564 MaxDifferenceDimensionAtCompileTime,
565 MaxDifferenceDimensionAtCompileTime == Eigen::Dynamic ? Eigen::Dynamic
566 : MaxDifferenceDimensionAtCompileTime + 1>;
567
571 template <typename Kept, typename KeptSpace>
572 [[nodiscard]] std::expected<InfoGaussianParams<KeptSpace, Scalar>, GaussianError>
573 marginalAt(Kept const & kept, KeptSpace const & keptSpace) const
574 {
576 using Expected = std::expected<Result, GaussianError>;
577 constexpr int D = DifferenceDimensionAtCompileTime;
578 constexpr int DMax = MaxDifferenceDimensionAtCompileTime;
579 constexpr int KeptSize = Result::DifferenceDimensionAtCompileTime;
580 constexpr int KeptMaxSize = Result::MaxDifferenceDimensionAtCompileTime;
581 Eigen::Index const n = differenceDimension();
582 auto const rest =
583 internal::resolveIndices<D, DMax>(n, internal::complementIndices<D, DMax>(n, kept.differences));
584 using RestIndices = std::remove_cvref_t<decltype(rest)>;
585 constexpr int RestSize = RestIndices::RowsAtCompileTime;
586 constexpr int RestMaxSize = RestIndices::MaxRowsAtCompileTime;
587 using RestMatrix = internal::MatrixOf<Scalar, RestSize, RestSize, RestMaxSize, RestMaxSize>;
588 using RestVector = Eigen::Matrix<Scalar, RestSize, 1, Eigen::ColMajor, RestMaxSize, 1>;
589 using CrossMatrix = internal::MatrixOf<Scalar, RestSize, KeptSize, RestMaxSize, KeptMaxSize>;
590
591 typename Result::VectorType reference = m_reference(kept.values);
592 typename Result::MatrixType matrix =
593 internal::lowerSymmetricBlock(m_infoMatrix, kept.differences, kept.differences);
594 typename Result::DifferenceVectorType vector = m_infoVector(kept.differences);
595 // MSVC can't form the empty products of a marginal over the whole space or over nothing.
596 if constexpr (RestSize != 0 && KeptSize != 0)
597 {
598 if (rest.size() > 0 && kept.differences.size() > 0)
599 {
600 auto const llt =
601 Eigen::LLT<RestMatrix>{RestMatrix{internal::lowerSymmetricBlock(m_infoMatrix, rest, rest)}};
602 if (llt.info() != Eigen::Success)
603 {
604 return Expected{std::unexpected{GaussianError::Singular}};
605 }
606 if (!allFinite(llt.matrixLLT().diagonal()))
607 {
608 return Expected{std::unexpected{GaussianError::NonFinite}};
609 }
610 CrossMatrix const cross = internal::lowerSymmetricBlock(m_infoMatrix, rest, kept.differences);
611 CrossMatrix solved = cross;
612 internal::solveInPlace(llt, solved);
613 RestVector const restVector = m_infoVector(rest);
614 matrix.noalias() -= internal::multiply(cross.transpose(), solved);
615 vector.noalias() -= internal::multiply(solved.transpose(), restVector);
616 }
617 }
618 return Expected{Result{keptSpace, std::move(reference), std::move(matrix), std::move(vector)}};
619 }
620
628 template <typename Kept, typename KeptSpace>
630 densityMarginalAt(Kept const & kept, KeptSpace const & keptSpace) const
631 {
633 constexpr int D = DifferenceDimensionAtCompileTime;
634 constexpr int DMax = MaxDifferenceDimensionAtCompileTime;
635 Eigen::Index const n = differenceDimension();
636 Eigen::Index const k = kept.differences.size();
637 auto const rest =
638 internal::resolveIndices<D, DMax>(n, internal::complementIndices<D, DMax>(n, kept.differences));
639 Eigen::Index const r = rest.size();
640
641 MatrixType const factor = m_llt->matrixU();
642 DifferenceVectorType whitened = m_infoVector;
643 internal::solveInPlace(m_llt->matrixL(), whitened);
644 AugmentedType stacked(n, n + 1);
645 stacked.leftCols(r) = factor(Eigen::placeholders::all, rest);
646 stacked.middleCols(r, k) = factor(Eigen::placeholders::all, kept.differences);
647 stacked.col(n) = whitened;
648 triangularize(stacked);
649
650 typename Result::VectorType reference = m_reference(kept.values);
651 auto matrix = typename Result::MatrixType{};
652 matrix.resize(k, k);
653 auto vector = typename Result::DifferenceVectorType{};
654 vector.resize(k);
655 // MSVC can't form the empty products of a marginal over nothing.
656 if constexpr (Result::DifferenceDimensionAtCompileTime != 0)
657 {
658 typename Result::MatrixType const trailing = stacked.block(r, r, k, k);
659 typename Result::DifferenceVectorType const tail = stacked.col(n).tail(k);
660 matrix.noalias() = internal::multiply(trailing.transpose(), trailing);
661 vector.noalias() = internal::multiply(trailing.transpose(), tail);
662 }
663 return Result{keptSpace, std::move(reference), std::move(matrix), std::move(vector)};
664 }
665
669 [[nodiscard]] MomentsType
670 momentsWithMean(VectorType mean) const
671 {
672 auto result = MomentsType{std::move(mean), *(covariance())};
673 if constexpr (!hasIdentityReset<Space_>)
674 {
675 DifferenceVectorType const step = Emrys::minus(m_space, result.mean(), m_reference);
676 resetCovariance(m_space, m_reference, step, result.covarianceLower());
677 }
678 return result;
679 }
680
682 [[nodiscard]] MomentsType
683 densityMoments() const
684 {
685 return momentsWithMean(m_densityMean);
686 }
687
689 [[nodiscard]] VectorType
690 solvedMean() const
691 {
692 DifferenceVectorType const offset = m_llt->solve(m_infoVector);
693 VectorType result = Emrys::plus(m_space, m_reference, offset);
694 return result;
695 }
696
698 [[nodiscard]] VectorType const &
699 densityMean() const
700 {
701 return m_densityMean;
702 }
703
705 void
706 whitenInPlace(DifferenceVectorType & residual) const
707 {
708 residual =
709 internal::multiply(internal::asTriangular<Eigen::Lower>(m_llt->matrixLLT()).transpose(), residual).eval();
710 }
711
715 void
716 colorInto(auto & colored, auto const & normals) const
717 {
718 colored = normals;
719 internal::solveInPlace(m_llt->matrixU(), colored);
720 }
721
725 void
726 fitSpace()
727 {
728 internal::fitValueDimension(m_space, m_reference.size());
729 EMRYS_FILTER_ASSERT(
730 m_infoMatrix.rows() == differenceDimension() && m_infoMatrix.cols() == differenceDimension()
731 && m_infoVector.size() == differenceDimension()
732 && "the precision and information vector must have a row per difference coordinate of the space"
733 );
734 normalizeValues(m_space, m_reference);
735 }
736
737 VectorType m_reference;
738 MatrixType m_infoMatrix;
739 DifferenceVectorType m_infoVector;
740 EMRYS_FILTER_NO_UNIQUE_ADDRESS Space_ m_space;
741
742 // Factorization cache, filled lazily by factorize().
744 mutable std::optional<Eigen::LLT<MatrixType>> m_llt;
745
746 mutable Scalar m_logDeterminant{};
747 mutable bool m_factorValid{false};
748 mutable VectorType m_densityMean;
749 internal::Stamp m_stamp;
750};
751
760template <Space Space_, RealScalar Scalar_ = double>
762
769template <Space Space_, RealScalar Scalar_>
772{
774 EMRYS_FILTER_ASSERT(first.differenceDimension() == second.differenceDimension());
775 Result moved = second;
776 moved.setReference(first.reference());
777 // Built from parts rather than as a copy of first, whose cached factorization would be copied
778 // only to be invalidated. Only the lower triangles are reliable, as in every stored matrix.
779 return Result{
780 first.space(),
781 first.reference(),
782 typename Result::MatrixType{first.infoMatrix() + moved.infoMatrix()},
783 typename Result::DifferenceVectorType{first.infoVector() + moved.infoVector()}
784 };
785}
786
796template <GaussianForm G>
797[[nodiscard]] std::expected<InfoGaussianParams<typename G::SpaceType, typename G::Scalar>, GaussianError>
798toInfo(G const & form)
799{
801 auto precision = form.precision();
802 if (!precision)
803 {
804 return std::unexpected{precision.error()};
805 }
806 if constexpr (isInfoForm<G>)
807 {
808 return Result{form.space(), form.reference(), std::move(*precision), form.infoVector()};
809 }
810 else
811 {
812 std::expected<typename G::VectorType, GaussianError> mean = form.mean();
813 if (!mean)
814 {
815 return std::unexpected{mean.error()};
816 }
817 return Result{
818 form.space(),
819 std::move(*mean),
820 std::move(*precision),
821 Result::DifferenceVectorType::Zero(form.differenceDimension())
822 };
823 }
824}
825
826} // namespace Emrys
827
828#ifndef EMRYS_FILTER_NO_IO
829
830namespace Emrys
831{
832
833namespace internal
834{
835
839template <typename Space_, typename Scalar_>
840void
841describe(std::ostream & stream, InfoGaussianParams<Space_, Scalar_> const & gaussian, Indent indent)
842{
843 stream << indent << "information Gaussian";
844 printDimension(stream, gaussian.valueDimension(), gaussian.differenceDimension());
845 printMoments(stream, indent.deeper(), gaussian.moments());
846}
847
848} // namespace internal
849
850} // namespace Emrys
851
852#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
A Gaussian kept as its precision and information vector, about a reference value.
Definition InfoGaussian.h:74
static constexpr int MaxDifferenceDimensionAtCompileTime
a bound on the length of a difference, or Eigen::Dynamic
Definition InfoGaussian.h:99
VectorType const & reference() const
Definition InfoGaussian.h:245
InfoGaussianParams(InfoGaussianParams const &other)
Copies the data and any valid factorization.
Definition InfoGaussian.h:149
typename MomentsType::Index Index
Eigen's index type.
Definition InfoGaussian.h:79
void addInfo(Eigen::MatrixBase< MatrixDerived > const &infoMatrix, Eigen::MatrixBase< VectorDerived > const &infoVector)
Adds infoMatrix (its lower triangle) to the precision and infoVector to the information vector,...
Definition InfoGaussian.h:321
InfoGaussianParams(Space_ space)
Constructs an InfoGaussianParams in space, with a zero reference and no information.
Definition InfoGaussian.h:113
Moments< Space_, Scalar_ > MomentsType
the mean and covariance together
Definition InfoGaussian.h:77
InfoGaussianParams()
Constructs an InfoGaussianParams in a default space, with a zero reference and no information.
Definition InfoGaussian.h:108
std::expected< MatrixType, GaussianError > precision() const
Definition InfoGaussian.h:377
InfoGaussianParams(InfoGaussianParams &&other) noexcept
Moves the data and any valid factorization; a view of other may not be read afterward.
Definition InfoGaussian.h:164
typename MomentsType::DifferenceVectorType DifferenceVectorType
A difference, or the information vector.
Definition InfoGaussian.h:83
static constexpr int DifferenceDimensionAtCompileTime
the length of a difference and the rows of the precision, or Eigen::Dynamic
Definition InfoGaussian.h:96
auto marginal(Index element) const
marginal<Path>() of repetition element of the repeated block Path starts at (see GaussianParams::marg...
Definition InfoGaussian.h:497
static constexpr bool IsParams
parameters, which views check
Definition InfoGaussian.h:101
DifferenceVectorType const & infoVector() const
Definition InfoGaussian.h:259
FormGaussian< InfoGaussianParams > DensityType
the view toDensity() returns
Definition InfoGaussian.h:87
std::expected< MatrixType, GaussianError > precisionRoot() const
Definition InfoGaussian.h:402
InfoGaussianParams(Reference &&reference, Matrix &&infoMatrix, Vector &&infoVector)
Constructs an InfoGaussianParams about reference, with the lower triangle of infoMatrix as the precis...
Definition InfoGaussian.h:127
Index differenceDimension() const
Definition InfoGaussian.h:231
typename MomentsType::Scalar Scalar
the scalar type
Definition InfoGaussian.h:78
static constexpr int ValueDimensionAtCompileTime
the length of a value, or Eigen::Dynamic
Definition InfoGaussian.h:90
Space_ const & space() const
Definition InfoGaussian.h:238
InfoGaussianParams & operator=(InfoGaussianParams const &other)
Copies the data and any valid factorization; a view of this object may not be read afterward.
Definition InfoGaussian.h:184
Index valueDimension() const
Definition InfoGaussian.h:224
Space_ SpaceType
the space the values live in
Definition InfoGaussian.h:86
void setReference(Eigen::MatrixBase< Derived > const &reference)
Moves the reference to reference, normalized by the space, and re-expresses the information about it.
Definition InfoGaussian.h:276
InfoGaussianParams & operator=(InfoGaussianParams &&other) noexcept
Moves the data and any valid factorization; a view of either object may not be read afterward.
Definition InfoGaussian.h:204
static constexpr int MaxValueDimensionAtCompileTime
a bound on the length of a value, or Eigen::Dynamic
Definition InfoGaussian.h:93
static constexpr bool IsInfoForm
holds the precision
Definition InfoGaussian.h:102
typename MomentsType::MatrixType MatrixType
a matrix over differences
Definition InfoGaussian.h:85
std::expected< MatrixType, GaussianError > covarianceRoot() const
Definition InfoGaussian.h:387
typename MomentsType::VectorType VectorType
a value, such as the reference
Definition InfoGaussian.h:80
std::expected< DensityType, GaussianError > toDensity() const &
Factorizes the precision if needed (see factorize()) and solves for the mean, writing both to the cac...
Definition InfoGaussian.h:457
auto conditional(Eigen::MatrixBase< Derived > const &values) const
Definition InfoGaussian.h:519
InfoGaussianParams(Space_ space, Reference &&reference, Matrix &&infoMatrix, Vector &&infoVector)
InfoGaussianParams(reference, infoMatrix, infoVector) in space, which is resized to fit them if it ha...
Definition InfoGaussian.h:139
std::expected< VectorType, GaussianError > mean() const
Definition InfoGaussian.h:337
void toDensity() const &&=delete
A density of a temporary would outlive it.
std::expected< MatrixType, GaussianError > covariance() const
Definition InfoGaussian.h:364
std::expected< MomentsType, GaussianError > moments() const
Definition InfoGaussian.h:351
void setInfo(Matrix &&infoMatrix, Vector &&infoVector)
Sets the precision to the lower triangle of infoMatrix and the information vector to infoVector,...
Definition InfoGaussian.h:301
MatrixType const & infoMatrix() const
Definition InfoGaussian.h:252
auto marginal() const
Definition InfoGaussian.h:485
static constexpr bool IsSqrtForm
holds the precision whole, not a factor
Definition InfoGaussian.h:103
std::expected< void, GaussianError > factorize() const
Factorizes the precision if it has changed since the last factorization.
Definition InfoGaussian.h:424
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
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
bool isFinite(T const &x)
Definition Math.h:305
@ 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
std::expected< InfoGaussianParams< typename G::SpaceType, typename G::Scalar >, GaussianError > toInfo(G const &form)
Definition InfoGaussian.h:798
InfoGaussianParams< Space_, Scalar_ > multiply(InfoGaussianParams< Space_, Scalar_ > const &first, InfoGaussianParams< Space_, Scalar_ > const &second)
Definition InfoGaussian.h:771
FormGaussian< InfoGaussianParams< Space_, Scalar_ > > InfoGaussian
The Gaussian in information form, which evaluates its density: what InfoGaussianParams::toDensity() r...
Definition InfoGaussian.h:761
constexpr bool isInfoForm
Whether the GaussianForm G holds the precision, as InfoGaussianParams and SqrtInfoGaussianParams do,...
Definition GaussianForm.h:69
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