EmrysFilter 0.1.0
State estimation utilities in C++23 using Eigen
Loading...
Searching...
No Matches
Conditionals.h
Go to the documentation of this file.
1#pragma once
2
11
12#include <cmath>
13#include <cstddef>
14#include <expected>
15#include <numbers>
16#include <optional>
17#include <span>
18#include <type_traits>
19#include <utility>
20#include <vector>
21
38
39namespace Emrys
40{
41
49{};
50
59{};
60
61namespace internal
62{
63
65template <typename C>
66concept CovarianceForm = std::is_same_v<C, SharedCovariance> || std::is_same_v<C, PerPointCovariance>;
67
71template <typename C>
72inline constexpr bool isGaussianHybrid = false;
73
75template <typename Component_, typename ModeSpace_, typename Allocator_>
76inline constexpr bool isGaussianHybrid<HybridParams<Component_, ModeSpace_, Allocator_>> = std::is_same_v<
79
81template <typename Space, typename P>
82struct ComplementOf
83{
85 using type = decltype(complementSubspace<P>(std::declval<Space const &>()));
86};
87
89template <typename Space, typename... Tags>
90struct ComplementOf<Space, TagPath<Tags...>>
91{
93 using type = decltype(complementSubspace<Tags...>(std::declval<Space const &>()));
94};
95
97template <typename P, typename Space>
98[[nodiscard]] auto
99complementOf(Space const & space)
100{
101 return withPathTags<P>([&]<typename... Tags>() {
102 return complementSubspace<Tags...>(space);
103 });
104}
105
109template <typename Space_, typename Path_>
110class BlockSplit
111{
112public:
113
115 using PathType = Path_;
116
118 using PinnedSpace = PathTag<Path_>;
119
121 using RestSpace = typename ComplementOf<Space_, Path_>::type;
122
124 using RestIndices = IndexVector<valueDimensionAtCompileTime<RestSpace>, maxValueDimensionAtCompileTime<RestSpace>>;
125
127 using RestDifferenceIndices = IndexVector<
130
132 explicit BlockSplit(Space_ const & space)
133 : m_pinned{pathBlock<Path_>(space)}
134 , m_rest{complementOf<Path_>(space)}
135 , m_rows{blockRows<Path_>(space)}
136 , m_differenceRows{differenceBlockRows<Path_>(space)}
137 , m_size{valueDimension(space)}
138 , m_restIndices{outside<RestIndices>(m_rows, m_size)}
139 , m_restDifferenceIndices{outside<RestDifferenceIndices>(m_differenceRows, differenceDimension(space))}
140 {}
141
143 [[nodiscard]] PinnedSpace const &
144 pinnedSpace() const
145 {
146 return m_pinned;
147 }
148
150 [[nodiscard]] RestSpace const &
151 restSpace() const
152 {
153 return m_rest;
154 }
155
157 [[nodiscard]] BlockRows
158 pinnedRows() const
159 {
160 return m_rows;
161 }
162
164 [[nodiscard]] RestIndices const &
165 restIndices() const
166 {
167 return m_restIndices;
168 }
169
171 [[nodiscard]] BlockRows
172 pinnedDifferenceRows() const
173 {
174 return m_differenceRows;
175 }
176
178 [[nodiscard]] RestDifferenceIndices const &
179 restDifferenceIndices() const
180 {
181 return m_restDifferenceIndices;
182 }
183
187 template <typename X, typename P>
188 [[nodiscard]] auto
189 assemble(X const & rest, P const & pinned) const
190 {
191 using T = ScalarOf<X>;
192 EMRYS_FILTER_ASSERT(
193 rest.size() == m_restIndices.size() && pinned.size() == m_rows.size && "the blocks do not fit the space"
194 );
195 Eigen::Matrix<
196 T,
198 1,
199 Eigen::ColMajor,
201 1>
202 full;
203 full.resize(m_size);
204 full(m_restIndices) = rest;
205 middleRowsOf<valueDimensionAtCompileTime<PinnedSpace>>(full, m_rows.start, m_rows.size) =
206 pinned.template cast<T>();
207 return full;
208 }
209
210private:
211
213 template <typename Indices>
214 [[nodiscard]] static Indices
215 outside(BlockRows rows, Eigen::Index n)
216 {
217 auto result = Indices{};
218 result.resize(n - rows.size);
219 Eigen::Index k = 0;
220 for (Eigen::Index i = 0; i < n; ++i)
221 {
222 if (i < rows.start || i >= rows.start + rows.size)
223 {
224 result(k++) = i;
225 }
226 }
227 return result;
228 }
229
230 PinnedSpace m_pinned;
231 RestSpace m_rest;
232 BlockRows m_rows;
233 BlockRows m_differenceRows;
234 Eigen::Index m_size;
235 RestIndices m_restIndices;
236 RestDifferenceIndices m_restDifferenceIndices;
237};
238
244template <
245 typename Space,
246 typename Covariance,
247 typename Scalar,
248 typename Allocator = DefaultAllocator,
249 typename Element = GaussianParams<Space, Scalar>>
250class Conditionals;
251
253template <typename Space, typename Scalar_, typename Allocator>
254class Conditionals<Space, SharedCovariance, Scalar_, Allocator, GaussianParams<Space, Scalar_>>
255{
256public:
257
259 using Scalar = Scalar_;
260
262 using ConditionalType = GaussianParams<Space, Scalar>;
263
265 using MatrixType = typename ConditionalType::MatrixType;
266
268 using MeansType = SampleSet<Space, Scalar>;
269
270 static constexpr bool Shared = true;
271
273 Conditionals(ConditionalType const & conditional, Eigen::Index count, Allocator const & allocator = {})
274 : m_space{conditional.space()}
275 , m_rows{conditional.valueDimension()}
276 , m_count{count}
277 , m_means(ScalarAllocator(allocator))
278 , m_scratch(ScalarAllocator(allocator))
279 , m_cov{conditional.covarianceLower()}
280 {
281 m_means.resize(std::size_t(m_rows * m_count));
282 means().colwise() = conditional.mean();
283 }
284
286 Conditionals(Conditionals const & other, Allocator const & allocator)
287 : m_space{other.m_space}
288 , m_rows{other.m_rows}
289 , m_count{other.m_count}
290 , m_means(other.m_means, ScalarAllocator(allocator))
291 , m_scratch(ScalarAllocator(allocator))
292 , m_cov{other.m_cov}
293 {}
294
296 Conditionals(Conditionals const & other)
297 : Conditionals{other, other.m_means.get_allocator()}
298 {}
299
300 Conditionals(Conditionals &&) noexcept = default;
301
303 Conditionals &
304 operator=(Conditionals const & other)
305 {
306 if (this == &other)
307 {
308 return *this;
309 }
310 m_space = other.m_space;
311 m_rows = other.m_rows;
312 m_count = other.m_count;
313 m_means.assign(other.m_means.begin(), other.m_means.end());
314 m_cov = other.m_cov;
315 return *this;
316 }
317
319 Conditionals &
320 operator=(Conditionals &&) noexcept = default;
321
322 ~Conditionals() = default;
323
328 void
329 resizeLike(Conditionals const & other)
330 {
331 m_space = other.m_space;
332 m_rows = other.m_rows;
333 m_count = other.m_count;
334 m_means.resize(std::size_t(m_rows * m_count));
335 }
336
338 void
339 swap(Conditionals & other) noexcept
340 {
341 std::swap(m_space, other.m_space);
342 std::swap(m_rows, other.m_rows);
343 std::swap(m_count, other.m_count);
344 m_means.swap(other.m_means);
345 m_scratch.swap(other.m_scratch);
346 std::swap(m_cov, other.m_cov);
347 }
348
350 [[nodiscard]] Eigen::Index
351 size() const
352 {
353 return m_count;
354 }
355
357 [[nodiscard]] Space const &
358 space() const
359 {
360 return m_space;
361 }
362
364 [[nodiscard]] auto
365 mean(Eigen::Index i) const
366 {
367 return means().col(i);
368 }
369
371 [[nodiscard]] MatrixType const &
372 covarianceLower(Eigen::Index /*i*/) const
373 {
374 return m_cov;
375 }
376
378 [[nodiscard]] ConditionalType
379 conditional(Eigen::Index i) const
380 {
381 return ConditionalType{m_space, mean(i), m_cov};
382 }
383
389 [[nodiscard]] std::expected<void, NumericError>
390 factorize() const
391 {
392 if constexpr (MatrixType::RowsAtCompileTime == 0)
393 {
394 return {};
395 }
396 else
397 {
398 ConditionalType const first = conditional(0);
399 return first.factorize();
400 }
401 }
402
405 means() const
406 {
407 return {m_means.data(), m_rows, m_count};
408 }
409
411 [[nodiscard]] SampleSetMap<Space, Scalar>
412 means()
413 {
414 return {m_means.data(), m_rows, m_count};
415 }
416
418 [[nodiscard]] MatrixType const &
419 sharedCovariance() const
420 {
421 return m_cov;
422 }
423
425 [[nodiscard]] MatrixType &
426 sharedCovariance()
427 {
428 return m_cov;
429 }
430
432 void
433 reserve(Eigen::Index count)
434 {
435 m_means.reserve(std::size_t(m_rows * count));
436 m_scratch.reserve(std::size_t(m_rows * count));
437 }
438
440 void
441 select(std::span<Eigen::Index const> from)
442 {
444 }
445
447 template <ExecutionPolicy P>
448 void
449 select(P && policy, std::span<Eigen::Index const> from)
450 {
451 Eigen::Index const count = Eigen::Index(from.size());
452 m_scratch.resize(std::size_t(m_rows * count));
453 gather(std::forward<P>(policy), from, means(), SampleSetMap<Space, Scalar>{m_scratch.data(), m_rows, count});
454 m_means.swap(m_scratch);
455 m_count = count;
456 }
457
459 void
460 keep(std::span<Eigen::Index const> kept)
461 {
462 auto all = means();
463 for (std::size_t k = 0; k < kept.size(); ++k)
464 {
465 if (kept[k] != Eigen::Index(k))
466 {
467 all.col(Eigen::Index(k)) = all.col(kept[k]);
468 }
469 }
470 m_count = Eigen::Index(kept.size());
471 m_means.resize(std::size_t(m_rows * m_count));
472 }
473
474private:
475
477 using ScalarAllocator = ReBound<Allocator, Scalar>;
478
479 Space m_space;
480 Eigen::Index m_rows;
481 Eigen::Index m_count;
482 Buffer<Scalar, Allocator> m_means;
483 Buffer<Scalar, Allocator> m_scratch;
484 MatrixType m_cov;
485};
486
488template <typename Space, typename Scalar_, typename Allocator, typename Element>
489class Conditionals<Space, PerPointCovariance, Scalar_, Allocator, Element>
490{
492 static constexpr bool IsGaussian = std::is_same_v<Element, GaussianParams<Space, Scalar_>>;
493
494public:
495
497 using Scalar = Scalar_;
498
500 using ConditionalType = Element;
501
503 using MatrixType = typename Moments<Space, Scalar>::MatrixType;
504
505 static constexpr bool Shared = false;
506
508 Conditionals(ConditionalType const & conditional, Eigen::Index count, Allocator const & allocator = {})
509 : m_conditionals(std::size_t(count), conditional, GaussianAllocator(allocator))
510 , m_scratch(GaussianAllocator(allocator))
511 {}
512
514 Conditionals(Conditionals const & other, Allocator const & allocator)
515 : m_conditionals(other.m_conditionals, GaussianAllocator(allocator))
516 , m_scratch(GaussianAllocator(allocator))
517 {}
518
520 Conditionals(Conditionals const & other)
521 : Conditionals{other, other.m_conditionals.get_allocator()}
522 {}
523
524 Conditionals(Conditionals &&) noexcept = default;
525
527 Conditionals &
528 operator=(Conditionals const & other)
529 {
530 if (this != &other)
531 {
532 m_conditionals.assign(other.m_conditionals.begin(), other.m_conditionals.end());
533 }
534 return *this;
535 }
536
538 Conditionals &
539 operator=(Conditionals &&) noexcept = default;
540
541 ~Conditionals() = default;
542
546 void
547 resizeLike(Conditionals const & other)
548 requires IsGaussian
549 {
550 m_conditionals.resize(other.m_conditionals.size());
551 }
552
554 void
555 swap(Conditionals & other) noexcept
556 {
557 m_conditionals.swap(other.m_conditionals);
558 m_scratch.swap(other.m_scratch);
559 }
560
562 [[nodiscard]] Eigen::Index
563 size() const
564 {
565 return Eigen::Index(m_conditionals.size());
566 }
567
569 [[nodiscard]] Space const &
570 space() const
571 {
572 return m_conditionals.front().space();
573 }
574
576 [[nodiscard]] decltype(auto)
577 mean(Eigen::Index i) const
578 requires IsGaussian
579 {
580 return m_conditionals[std::size_t(i)].mean();
581 }
582
584 [[nodiscard]] MatrixType const &
585 covarianceLower(Eigen::Index i) const
586 requires IsGaussian
587 {
588 return m_conditionals[std::size_t(i)].covarianceLower();
589 }
590
592 [[nodiscard]] ConditionalType const &
593 conditional(Eigen::Index i) const
594 {
595 return m_conditionals[std::size_t(i)];
596 }
597
599 [[nodiscard]] ConditionalType &
600 conditional(Eigen::Index i)
601 {
602 return m_conditionals[std::size_t(i)];
603 }
604
610 [[nodiscard]] std::expected<void, NumericError>
611 factorize() const
612 {
613 if constexpr (MatrixType::RowsAtCompileTime != 0)
614 {
615 for (auto const & conditional : m_conditionals)
616 {
617 if (auto result = conditional.factorize(); !result)
618 {
619 return std::unexpected{result.error()};
620 }
621 }
622 }
623 return {};
624 }
625
627 void
628 reserve(Eigen::Index count)
629 {
630 m_conditionals.reserve(std::size_t(count));
631 m_scratch.reserve(std::size_t(count));
632 }
633
635 void
636 select(std::span<Eigen::Index const> from)
637 {
639 }
640
644 template <ExecutionPolicy P>
645 void
646 select(P && policy, std::span<Eigen::Index const> from)
647 {
648 if (from.size() < m_scratch.size())
649 {
650 m_scratch.erase(m_scratch.begin() + std::ptrdiff_t(from.size()), m_scratch.end());
651 }
652 while (m_scratch.size() < from.size())
653 {
654 m_scratch.push_back(m_conditionals.front());
655 }
656 if constexpr (isSequential<P>)
657 {
658 for (std::size_t j = 0; j < from.size(); ++j)
659 {
660 m_scratch[j] = m_conditionals[std::size_t(from[j])];
661 }
662 }
663 else
664 {
665 forEachIndex(std::forward<P>(policy), Eigen::Index(from.size()), [&](Eigen::Index j) {
666 m_scratch[std::size_t(j)] = m_conditionals[std::size_t(from[std::size_t(j)])];
667 });
668 }
669 m_conditionals.swap(m_scratch);
670 }
671
673 void
674 keep(std::span<Eigen::Index const> kept)
675 {
676 for (std::size_t k = 0; k < kept.size(); ++k)
677 {
678 if (kept[k] != Eigen::Index(k))
679 {
680 m_conditionals[k] = m_conditionals[std::size_t(kept[k])];
681 }
682 }
683 m_conditionals.erase(m_conditionals.begin() + std::ptrdiff_t(kept.size()), m_conditionals.end());
684 }
685
686private:
687
689 using GaussianAllocator = ReBound<Allocator, ConditionalType>;
690
691 Buffer<ConditionalType, Allocator> m_conditionals;
692 Buffer<ConditionalType, Allocator> m_scratch;
693};
694
706template <typename Points, typename F>
707[[nodiscard]] auto
708withPoint(Points const & points, Eigen::Index i, F && f)
709{
710 using Scalar = typename Points::Scalar;
712 PinnedVector center = points.center(i);
713 if constexpr (Points::HasKernels)
714 {
715 if (auto const * kernel = points.kernel(i))
716 {
717 return f(
718 GaussianParams<typename Points::PinnedSpace, Scalar>{points.pinnedSpace(), std::move(center), *kernel}
719 );
720 }
721 }
722 return f(center);
723}
724
733template <typename Points, typename Store, typename WeightsDerived>
734[[nodiscard]] GaussianParams<typename Points::SpaceType, typename Points::Scalar>
735collapseGivenPoints(
736 Points const & points,
737 Store const & conditionals,
738 Eigen::ArrayBase<WeightsDerived> const & logWeights
739)
740{
741 using Scalar = typename Points::Scalar;
742 using SpaceType = typename Points::SpaceType;
743 using MomentsType = Moments<SpaceType, Scalar>;
744 EMRYS_FILTER_ASSERT(
745 logWeights.size() == points.size() && conditionals.size() == points.size()
746 && "give one weight and one Gaussian per point"
747 );
748 BlockRows const rows = points.pinnedRows();
749 auto const & rest = points.restIndices();
750 BlockRows const differenceRows = points.pinnedDifferenceRows();
751 auto const & restDifferences = points.restDifferenceIndices();
752 auto const logTotal = logTotalWeight<Scalar>(logWeights);
753 EMRYS_FILTER_ASSERT(logTotal && "the weights must be finite and not all zero");
754 // The whole state at point i: its center in the block's rows, its Gaussian's mean in the rest's.
757 auto const meanAt = [&](Eigen::Index i) {
758 auto mean = typename MomentsType::VectorType{};
759 mean.resize(valueDimension(points.space()));
760 middleRowsOf<PinnedValues>(mean, rows.start, rows.size) = points.center(i);
761 mean(rest) = conditionals.mean(i);
762 return mean;
763 };
764 MomentsType moments = pointMomentsIn<MomentsType>(
765 points.space(),
766 points.size(),
767 meanAt,
768 [&](Eigen::Index i) {
769 return logWeights.derived()(i);
770 },
771 *logTotal
772 );
773 auto & cov = moments.covarianceLower();
774 auto pinned = blockOf<PinnedDifferences, PinnedDifferences>(
775 cov,
776 differenceRows.start,
777 differenceRows.start,
778 differenceRows.size,
779 differenceRows.size
780 );
781 for (Eigen::Index i = 0; i < points.size(); ++i)
782 {
783 Scalar const logWeight = logWeights.derived()(i);
784 if (logWeight == -Eigen::NumTraits<Scalar>::infinity())
785 {
786 continue;
787 }
788 Scalar const weight = Eigen::numext::exp(logWeight - *logTotal);
789 if constexpr (Points::HasKernels)
790 {
791 if (auto const * kernel = points.kernel(i))
792 {
793 pinned += weight * *kernel;
794 }
795 }
796 if constexpr (!Store::Shared)
797 {
798 cov(restDifferences, restDifferences) += weight * conditionals.covarianceLower(i);
799 }
800 }
801 if constexpr (Store::Shared)
802 {
803 cov(restDifferences, restDifferences) += conditionals.sharedCovariance();
804 }
805 mirrorLower(cov);
806 return GaussianParams<SpaceType, Scalar>{points.space(), std::move(moments)};
807}
808
813template <typename Points, typename Store, typename WeightsDerived, typename Allocator>
814[[nodiscard]] GaussianParams<typename Points::SpaceType, typename Points::Scalar>
815collapseGivenHybrids(
816 Points const & points,
817 Store const & hybrids,
818 Eigen::ArrayBase<WeightsDerived> const & logWeights,
819 Allocator const & allocator
820)
821{
822 using Scalar = typename Points::Scalar;
823 using Traits = ComponentTraits<typename Store::ConditionalType>;
824 using Gaussians = Conditionals<typename Points::RestSpace, PerPointCovariance, Scalar, Allocator>;
825 auto gaussians = Gaussians{Traits::collapseModes(hybrids.conditional(0)), hybrids.size(), allocator};
826 for (Eigen::Index i = 1; i < hybrids.size(); ++i)
827 {
828 gaussians.conditional(i) = Traits::collapseModes(hybrids.conditional(i));
829 }
830 return collapseGivenPoints(points, gaussians, logWeights);
831}
832
838template <typename Store, typename WeightsDerived>
839[[nodiscard]] auto
840summedModes(Store const & hybrids, Eigen::ArrayBase<WeightsDerived> const & logWeights)
841{
842 using ModesType = typename Store::ConditionalType::ModesType;
843 using Scalar = typename ModesType::Scalar;
844 auto const & modeSpace = hybrids.conditional(0).modeSpace();
845 Eigen::Index const count = modeSpace.cardinality();
846 auto logP = typename ModesType::ArrayType{};
847 logP.resize(count);
848 for (Eigen::Index m = 0; m < count; ++m)
849 {
850 auto total = LogSumExp<Scalar>{};
851 for (Eigen::Index i = 0; i < hybrids.size(); ++i)
852 {
853 auto const & modes = hybrids.conditional(i).modes();
854 // A point's mode weights are proportional to its probabilities, so each is normalized.
855 total.add(Scalar(logWeights.derived()(i)) + modes.logWeight(m) - modes.logTotalWeight().value());
856 }
857 logP(m) = total.value();
858 }
859 auto modes = ModesType{modeSpace, logP};
860 [[maybe_unused]] auto const normalized = modes.normalize();
861 EMRYS_FILTER_ASSERT(normalized && "the points' weights must define a distribution");
862 return modes;
863}
864
870template <typename Factor, typename Gain, typename Cov>
871struct PinnedConditioning
872{
873 Factor factor;
874 Gain gain;
875 Cov cov;
876};
877
887template <typename Split, typename CovDerived>
888[[nodiscard]] auto
889pinnedConditioning(Split const & split, Eigen::MatrixBase<CovDerived> const & cov)
890{
891 using Scalar = typename CovDerived::Scalar;
892 using PinnedMoments = Moments<typename Split::PinnedSpace, Scalar>;
893 using RestMoments = Moments<typename Split::RestSpace, Scalar>;
894 using PinnedMatrix = typename PinnedMoments::MatrixType;
895 using RestMatrix = typename RestMoments::MatrixType;
896 // Typed by the blocks' bounds: evaluating an indexed view would give an unbounded matrix.
897 using PinnedRestMatrix = MatrixOf<
898 Scalar,
899 PinnedMoments::DifferenceDimensionAtCompileTime,
900 RestMoments::DifferenceDimensionAtCompileTime,
901 PinnedMoments::MaxDifferenceDimensionAtCompileTime,
902 RestMoments::MaxDifferenceDimensionAtCompileTime>;
903 using GainMatrix = MatrixOf<
904 Scalar,
905 RestMoments::DifferenceDimensionAtCompileTime,
906 PinnedMoments::DifferenceDimensionAtCompileTime,
907 RestMoments::MaxDifferenceDimensionAtCompileTime,
908 PinnedMoments::MaxDifferenceDimensionAtCompileTime>;
909 BlockRows const rows = split.pinnedDifferenceRows();
910 auto const & rest = split.restDifferenceIndices();
911 constexpr int PinnedRows = PinnedMoments::DifferenceDimensionAtCompileTime;
912 PinnedMatrix const pinned = blockOf<PinnedRows, PinnedRows>(cov, rows.start, rows.start, rows.size, rows.size);
913 PinnedRestMatrix const pinnedRest = cov(Eigen::seqN(rows.start, rows.size), rest);
914 auto const ldlt = Eigen::LDLT<PinnedMatrix>{pinned};
915 auto gain = transposedSolve<GainMatrix>(ldlt, pinnedRest);
916 RestMatrix restCov = cov(rest, rest);
917 restCov -= multiply(gain, pinnedRest);
918 restCov = (Scalar(0.5) * (restCov + restCov.transpose())).eval();
919 return PinnedConditioning{defaultRoot(pinned), std::move(gain), std::move(restCov)};
920}
921
930template <
931 typename Split,
932 typename Conditioning,
933 typename MeanDerived,
934 typename ZDerived,
935 typename PinnedOut,
936 typename RestOut>
937void
938drawPinned(
939 Split const & split,
940 Conditioning const & conditioning,
941 Eigen::MatrixBase<MeanDerived> const & mean,
942 Eigen::MatrixBase<ZDerived> const & z,
943 PinnedOut && pinned,
944 RestOut && restMean
945)
946{
947 BlockRows const rows = split.pinnedRows();
948 auto const offset = multiply(conditioning.factor, z).eval();
950 pinned = Emrys::plus(split.pinnedSpace(), middleRowsOf<PinnedValues>(mean, rows.start, rows.size), offset);
951 restMean = Emrys::plus(split.restSpace(), mean(split.restIndices()), multiply(conditioning.gain, offset));
952}
953
954} // namespace internal
955
956} // namespace Emrys
The allocator conventions of decisions.md [allocation]: DefaultAllocator, Capacity,...
Execution policies (decisions.md [execution-policies]): execution::sequential, the ExecutionPolicy co...
The Gaussian: its parameters GaussianParams, the Gaussian that evaluates the density,...
The hybrid state of a discrete mode and a component per mode (decisions.md [imm], [component-first]):...
The macros every header includes first.
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'...
Params and Density: the traits that pair a distribution's parameters with its density,...
SampleSet: a matrix whose columns are samples in a space, which the samplers return and the unscented...
Drawing samples: SamplesWithLogDensity and SampleWithLogDensity, the Gaussian draws drawSamples(),...
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...
Weighted statistics over points, all in internal, which the containers of weighted elements (Gaussian...
Subspaces, and growing and shrinking blocks (decisions.md [several-resizable-blocks]).
Tag paths and the index utilities (decisions.md [tag-addressing], [index-names]): TagPath and TagPath...
Log-weights: the WeightError a normalization can fail with (NumericError.h), and the streaming log-su...
A Gaussian distribution: a mean and covariance in a space.
Definition Gaussian.h:259
DifferenceMatrix< Space_, Space_, Scalar > MatrixType
a matrix over differences, such as the covariance
Definition Moments.h:76
ValueVector< Space_, Scalar > VectorType
a value, such as the mean
Definition Moments.h:74
std::allocator< std::byte > DefaultAllocator
The allocator a type with a run-time count uses unless given one.
Definition Allocation.h:47
Eigen::Matrix< Scalar, valueDimensionAtCompileTime< Space >, Eigen::Dynamic,(maxValueDimensionAtCompileTime< Space >==1 ? Eigen::RowMajor :Eigen::ColMajor), maxValueDimensionAtCompileTime< Space >, Eigen::Dynamic > SampleSet
A matrix whose columns are samples in Space (see Spaces), with the space's size and storage bound.
Definition SampleSet.h:33
Eigen::Map< SampleSet< Space, Scalar > > SampleSetMap
A writable view of samples in Space, one per column, over memory it does not own, laid out as a Sampl...
Definition SampleSet.h:50
typename std::remove_cvref_t< X >::Scalar ScalarOf
The scalar type of the Eigen object or distribution X, for writing functions generic in it.
Definition Moments.h:26
Eigen::Map< SampleSet< Space, Scalar > const > ConstSampleSetMap
A read-only view of samples in Space, one per column, over memory it does not own,...
Definition SampleSet.h:60
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
constexpr Sequential sequential
The default execution policy: plain loops on the calling thread, in index order (Sequential).
Definition Execution.h:128
constexpr Select select()
Definition Reduction.h:334
constexpr Keep keep()
Definition Reduction.h:371
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
Eigen::Index differenceDimension(S const &space)
Definition Space.h:284
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
A covariance per point.
Definition Conditionals.h:59
One covariance for every point.
Definition Conditionals.h:49