47template <
typename Gr
id_,
typename Model_,
typename Covariance_,
typename Method_,
typename Upkeep_>
66template <
typename Block,
int I = 0>
77template <
typename Block, std::size_t... I>
78std::tuple<
GridAxis<Block, int(I)>...> leafGridAxes(std::index_sequence<I...>);
81template <
typename Block>
85 using type =
decltype(leafGridAxes<Block>(std::make_index_sequence<std::size_t(Block::FixedValueDimension)>{}));
89template <
typename Block>
90 requires IsComposite<Block>
91struct GridAxesOf<Block>
94 template <
typename... Blocks>
96 of(std::tuple<Blocks...> *) ->
decltype(std::tuple_cat(std::declval<
typename GridAxesOf<Blocks>::type>()...));
99 using type =
decltype(of(
static_cast<CompositeBlocks<Block> *
>(
nullptr)));
103template <
typename... Axes>
104DiscreteProduct<Axes...>
105gridProduct(std::tuple<Axes...> *);
108template <
typename Axis,
typename... Axes>
109inline constexpr int axisOccurrences = (0 + ... + int(std::is_same_v<Axis, Axes>));
112template <
typename... Axes>
114distinctAxes(std::tuple<Axes...> *)
116 return ((axisOccurrences<Axes, Axes...> == 1) && ...);
120template <
typename Path>
121using GridAxes =
typename GridAxesOf<PathTag<Path>>::type;
133template <
typename Path>
134struct GridCells : decltype(internal::gridProduct(static_cast<internal::GridAxes<Path> *>(nullptr)))
137 internal::distinctAxes(
static_cast<internal::GridAxes<Path> *
>(
nullptr)),
138 "two coordinates of the block lie in blocks with the same tag, so their grid axes would share a name"
142 using Product =
decltype(internal::gridProduct(
static_cast<internal::GridAxes<Path> *
>(
nullptr)));
151template <
typename Path>
155 using Finite::Finite;
162template <
typename Cells>
163struct IsGridCells : std::false_type
167template <
typename Path>
168struct IsGridCells<GridCells<Path>> : std::true_type
211 internal::CovarianceForm<CellCovariance_>,
212 "the cell covariance is SharedCovariance or PerPointCovariance"
215 static constexpr bool Shared = std::is_same_v<CellCovariance_, SharedCovariance>;
238 using PinnedSpace =
typename internal::BlockSplit<Space_, Path_>::PinnedSpace;
241 using RestSpace =
typename internal::BlockSplit<Space_, Path_>::RestSpace;
253 static constexpr bool Regular = internal::IsGridCells<Cells_>::value;
256 !
Regular || std::is_same_v<Cells_, GridCells<Path_>>,
257 "a regular grid's cells are the GridCells of its own block"
265 template <
typename CentersDerived>
269 Eigen::MatrixBase<CentersDerived>
const &
centers,
271 Allocator_
const & allocator = {}
283 template <
typename CentersDerived>
287 Eigen::MatrixBase<CentersDerived>
const &
centers,
288 std::span<PinnedMatrix const> cellCovariances,
289 Allocator_
const & allocator = {}
308 Allocator_
const & allocator = {}
324 std::span<PinnedMatrix const> cellCovariances,
325 Allocator_
const & allocator = {}
341 [[nodiscard]] Space_
const &
348 [[nodiscard]] Cells_
const &
358 return m_split.pinnedSpace();
365 return m_split.restSpace();
369 [[nodiscard]] Eigen::Index
372 return m_cells.cardinality();
379 EMRYS_FILTER_ASSERT(cell >= 0 && cell <
size() &&
"the cell is out of range");
382 auto const coordinates = m_cells.coordinates(cell);
384 for (std::size_t i = 0; i < coordinates.size(); ++i)
386 Eigen::Index
const row = Eigen::Index(i);
387 result(row) +=
Scalar(coordinates[i]) * m_spacing(row);
426 return !m_cellCovariances.empty();
434 EMRYS_FILTER_ASSERT(cell >= 0 && cell <
size() &&
"the cell is out of range");
435 return m_cellCovariances[Shared ? 0 : std::size_t(cell)];
442 return m_split.pinnedRows();
446 [[nodiscard]]
auto const &
449 return m_split.restIndices();
456 return m_split.pinnedDifferenceRows();
460 [[nodiscard]]
auto const &
463 return m_split.restDifferenceIndices();
478 EMRYS_FILTER_ASSERT(factor >= 1 &&
"subdivide each cell into at least one");
479 Cells_
cells = [&]<std::size_t... I>(std::index_sequence<I...>) {
480 return Cells_{std::tuple_element_t<I, internal::DiscreteProductAxes<Cells_>>{
481 m_cells.template axis<I>().cardinality() * factor
483 }(std::make_index_sequence<Cells_::AxisCount>{});
508 [[nodiscard]]
static std::span<PinnedMatrix const>
509 listOf(std::optional<PinnedMatrix>
const & covariance)
511 return covariance ? std::span<PinnedMatrix const>{&*covariance, 1} : std::span<PinnedMatrix const>{};
521 std::span<PinnedMatrix const> cellCovariances,
522 Allocator_
const & allocator
524 : m_space{std::move(
space)}
525 , m_cells{std::move(
cells)}
527 , m_cellCovariances(cellCovariances.begin(), cellCovariances.end(), MatrixAllocator(allocator))
528 , m_centers(ScalarAllocator(allocator))
531 (Shared || Eigen::Index(m_cellCovariances.size()) ==
size()) &&
"give one covariance per cell"
533 for (
PinnedMatrix const & covariance : m_cellCovariances)
535 checkCovariance(covariance);
540 template <
typename CentersDerived>
542 setCenters(Eigen::MatrixBase<CentersDerived>
const &
centers)
544 EMRYS_FILTER_ASSERT(
centers.cols() == m_cells.cardinality() &&
"give one center per cell");
546 m_centers.resize(std::size_t(
centers.size()));
559 &&
"give the first point and spacing per axis, one axis per coordinate of the block"
561 m_first = std::move(
first);
562 m_spacing = std::move(
spacing);
571 &&
"a cell covariance does not fit the block"
576 using MatrixAllocator = internal::ReBound<Allocator_, PinnedMatrix>;
579 using ScalarAllocator = internal::ReBound<Allocator_, Scalar_>;
583 internal::BlockSplit<Space_, Path_> m_split;
584 internal::Buffer<PinnedMatrix, Allocator_> m_cellCovariances;
585 internal::Buffer<Scalar_, Allocator_> m_centers;
595template <
typename P, Space S,
typename Derived,
typename Allocator = DefaultAllocator>
599 Eigen::MatrixBase<Derived>
const & centers,
600 std::optional<
typename Moments<internal::PathTag<P>,
typename Derived::Scalar>::MatrixType> cellCovariance = {},
601 Allocator
const & allocator = {}
605 return Grid{std::move(space),
PointCells<P>{centers.cols()}, centers, std::move(cellCovariance), allocator};
613template <
typename P, Space S,
typename Derived,
typename Allocator = DefaultAllocator>
617 Eigen::MatrixBase<Derived>
const & centers,
618 std::span<
typename Moments<internal::PathTag<P>,
typename Derived::Scalar>::MatrixType
const> cellCovariances,
619 Allocator
const & allocator = {}
622 using Grid = PointGrid<S, P, PointCells<P>, PerPointCovariance,
typename Derived::Scalar, Allocator>;
623 return Grid{std::move(space), PointCells<P>{centers.cols()}, centers, cellCovariances, allocator};
630template <FixedSizeSpace S,
typename P,
typename Derived,
typename Allocator = DefaultAllocator>
633 Eigen::MatrixBase<Derived>
const & centers,
634 std::optional<
typename Moments<internal::PathTag<P>,
typename Derived::Scalar>::MatrixType> cellCovariance = {},
635 Allocator
const & allocator = {}
638 return pointGrid<P>(S{}, centers, std::move(cellCovariance), allocator);
645template <FixedSizeSpace S,
typename P,
typename Derived,
typename Allocator = DefaultAllocator>
648 Eigen::MatrixBase<Derived>
const & centers,
649 std::span<
typename Moments<internal::PathTag<P>,
typename Derived::Scalar>::MatrixType
const> cellCovariances,
650 Allocator
const & allocator = {}
653 return pointGrid<P>(S{}, centers, cellCovariances, allocator);
660template <
typename Cells, std::
size_t D>
662regularCells(std::array<Eigen::Index, D>
const & counts)
664 return [&]<std::size_t... I>(std::index_sequence<I...>) {
665 return Cells{std::tuple_element_t<I, DiscreteProductAxes<Cells>>{counts[I]}...};
666 }(std::make_index_sequence<D>{});
679template <
typename P, Space S,
typename FirstDerived,
typename SpacingDerived,
typename Allocator = DefaultAllocator>
683 Eigen::MatrixBase<FirstDerived>
const & first,
684 Eigen::MatrixBase<SpacingDerived>
const & spacing,
685 std::array<Eigen::Index, std::size_t(internal::PathTag<P>::FixedValueDimension)>
const & counts,
686 std::optional<
typename Moments<internal::PathTag<P>,
typename FirstDerived::Scalar>::MatrixType> cellCovariance =
688 Allocator
const & allocator = {}
691 static_assert(internal::PathTag<P>::ValueDimensionStep == 0,
"a regular grid needs a fixed-size block");
695 internal::regularCells<typename Grid::CellsType>(counts),
696 typename Grid::PinnedVector{first},
697 typename Grid::PinnedVector{spacing},
698 std::move(cellCovariance),
708template <
typename P, Space S,
typename FirstDerived,
typename SpacingDerived,
typename Allocator = DefaultAllocator>
712 Eigen::MatrixBase<FirstDerived>
const & first,
713 Eigen::MatrixBase<SpacingDerived>
const & spacing,
714 std::array<Eigen::Index, std::size_t(internal::PathTag<P>::FixedValueDimension)>
const & counts,
715 std::span<
typename Moments<internal::PathTag<P>,
typename FirstDerived::Scalar>::MatrixType
const> cellCovariances,
716 Allocator
const & allocator = {}
719 static_assert(internal::PathTag<P>::ValueDimensionStep == 0,
"a regular grid needs a fixed-size block");
720 using Grid = PointGrid<S, P, GridCells<P>, PerPointCovariance,
typename FirstDerived::Scalar, Allocator>;
723 internal::regularCells<typename Grid::CellsType>(counts),
724 typename Grid::PinnedVector{first},
725 typename Grid::PinnedVector{spacing},
739 typename FirstDerived,
740 typename SpacingDerived,
744 Eigen::MatrixBase<FirstDerived>
const & first,
745 Eigen::MatrixBase<SpacingDerived>
const & spacing,
746 std::array<Eigen::Index, std::size_t(internal::PathTag<P>::FixedValueDimension)>
const & counts,
747 std::optional<
typename Moments<internal::PathTag<P>,
typename FirstDerived::Scalar>::MatrixType> cellCovariance =
749 Allocator
const & allocator = {}
752 return regularGrid<P>(S{}, first, spacing, counts, std::move(cellCovariance), allocator);
762 typename FirstDerived,
763 typename SpacingDerived,
767 Eigen::MatrixBase<FirstDerived>
const & first,
768 Eigen::MatrixBase<SpacingDerived>
const & spacing,
769 std::array<Eigen::Index, std::size_t(internal::PathTag<P>::FixedValueDimension)>
const & counts,
770 std::span<
typename Moments<internal::PathTag<P>,
typename FirstDerived::Scalar>::MatrixType
const> cellCovariances,
771 Allocator
const & allocator = {}
774 return regularGrid<P>(S{}, first, spacing, counts, cellCovariances, allocator);
781template <
typename Gr
id>
787 using Scalar =
typename Grid::Scalar;
790 using SpaceType =
typename Grid::SpaceType;
793 using PathType =
typename Grid::PathType;
796 using PinnedSpace =
typename Grid::PinnedSpace;
799 using RestSpace =
typename Grid::RestSpace;
802 static constexpr bool HasKernels =
true;
805 GridPoints(Grid
const & grid, std::span<Eigen::Index const> cells)
811 [[nodiscard]] SpaceType
const &
814 return m_grid.space();
818 [[nodiscard]] PinnedSpace
const &
821 return m_grid.pinnedSpace();
825 [[nodiscard]] RestSpace
const &
828 return m_grid.restSpace();
832 [[nodiscard]] BlockRows
835 return m_grid.pinnedRows();
839 [[nodiscard]]
auto const &
842 return m_grid.restIndices();
846 [[nodiscard]] BlockRows
847 pinnedDifferenceRows()
const
849 return m_grid.pinnedDifferenceRows();
853 [[nodiscard]]
auto const &
854 restDifferenceIndices()
const
856 return m_grid.restDifferenceIndices();
860 [[nodiscard]] Eigen::Index
863 return Eigen::Index(m_cells.size());
868 center(Eigen::Index i)
const
870 return m_grid.center(m_cells[std::size_t(i)]);
876 [[nodiscard]]
typename Grid::PinnedMatrix
const *
877 kernel(Eigen::Index i)
const
879 return m_grid.hasCellCovariance() ? &m_grid.cellCovariance(m_cells[std::size_t(i)]) :
nullptr;
885 std::span<Eigen::Index const> m_cells;
937 static_assert(internal::CovarianceForm<Covariance_>,
"the covariance is SharedCovariance or PerPointCovariance");
938 static constexpr bool Shared = std::is_same_v<Covariance_, SharedCovariance>;
941 !Shared || std::is_same_v<typename Grid_::CellCovarianceType, SharedCovariance>,
942 "cells with covariances of their own give each cell its own innovation covariance, so the "
943 "filter needs PerPointCovariance"
947 static constexpr bool IsHybrid = internal::isGaussianHybrid<Params<Component_>>;
954 "a cell holds a Gaussian or a hybrid of Gaussians"
957 std::is_same_v<typename Params<Component_>::SpaceType,
typename Grid_::RestSpace>
958 && std::is_same_v<typename Params<Component_>::Scalar,
typename Grid_::Scalar>,
959 "a cell's distribution is over the grid's RestSpace, in the grid's scalar"
962 !(IsHybrid && Shared),
963 "mixing a cell's modes gives each cell covariances of its own, so a hybrid per cell needs PerPointCovariance"
1010 : m_grid{std::move(
grid)}
1018 EMRYS_FILTER_ASSERT(
1019 conditional.space() == m_grid.restSpace() &&
"the Gaussian must be over the rest of the state"
1021 m_cells.resize(std::size_t(m_grid.size()));
1022 for (std::size_t c = 0; c < m_cells.size(); ++c)
1024 m_cells[c] = Eigen::Index(c);
1026 m_logWeights.assign(std::size_t(m_grid.size()), -Eigen::numext::log(
Scalar(m_grid.size())));
1027 m_kept.reserve(m_cells.size());
1028 m_weightScratch.reserve(m_cells.size());
1035 return m_grid.get_allocator();
1039 [[nodiscard]] Grid_
const &
1046 [[nodiscard]] Eigen::Index
1049 return Eigen::Index(m_cells.size());
1053 [[nodiscard]] Eigen::Index
1057 return m_cells[std::size_t(i)];
1061 [[nodiscard]] std::span<Eigen::Index const>
1064 return {m_cells.data(), m_cells.size()};
1068 [[nodiscard]] std::optional<Eigen::Index>
1071 auto const found = std::lower_bound(m_cells.begin(), m_cells.end(),
cell);
1072 if (found == m_cells.end() || *found !=
cell)
1074 return std::nullopt;
1076 return Eigen::Index(found - m_cells.begin());
1083 return m_grid.center(
cell(i));
1090 return {m_logWeights.data(),
size()};
1098 return m_logWeights[std::size_t(i)];
1102 [[nodiscard]] Eigen::Index
1105 Eigen::Index best = 0;
1115 ArrayType logP = ArrayType::Constant(m_grid.size(), -Eigen::NumTraits<Scalar>::infinity());
1116 for (Eigen::Index i = 0; i <
size(); ++i)
1118 logP(m_cells[std::size_t(i)]) =
logWeight(i);
1127 template <
typename P>
1131 auto const [stride, axis] = internal::locateAxisByPath<P>(m_grid.cells());
1132 using Axis = std::remove_cvref_t<
decltype(*axis)>;
1134 Eigen::Index
const count = axis->cardinality();
1136 auto logP = ArrayType{};
1138 for (Eigen::Index v = 0; v < count; ++v)
1141 for (Eigen::Index i = 0; i <
size(); ++i)
1143 if ((m_cells[std::size_t(i)] / stride) % count == v)
1148 logP(v) = total.
value();
1161 [[nodiscard]] std::expected<void, WeightError>
1164 EMRYS_FILTER_ASSERT(weights.
space() == m_grid.cells() &&
"the weights are over different cells");
1165 m_stamp.touchShape();
1166 m_weightScratch.resize(m_logWeights.size());
1167 for (Eigen::Index i = 0; i <
size(); ++i)
1169 m_weightScratch[std::size_t(i)] = weights.
logWeight(m_cells[std::size_t(i)]);
1172 internal::logTotalWeight<Scalar>(std::span<Scalar const>{m_weightScratch.data(), m_weightScratch.size()});
1175 return std::unexpected{total.error()};
1177 m_logWeights.swap(m_weightScratch);
1178 normalizeAndRemoveDead();
1185 [[nodiscard]]
decltype(
auto)
1189 return m_conditionals.conditional(i);
1199 return internal::summedModes(m_conditionals,
logWeights());
1207 return m_conditionals.sharedCovariance();
1216 [[nodiscard]] std::expected<void, NumericError>
1219 return m_conditionals.factorize();
1226 [[nodiscard]] std::expected<DensityType, NumericError>
1231 return std::unexpected{result.error()};
1233 return DensityType{*
this};
1253 return pruneWith(internal::PruneBelowRule<Scalar>{logThreshold});
1268 return pruneWith(internal::PruneTailRule<Scalar>{logFraction});
1282 return pruneWith(internal::PruneToSizeRule{maxSize});
1298 requires(Grid_::Regular && std::is_same_v<typename Grid_::CellCovarianceType, SharedCovariance>)
1300 constexpr std::size_t D = CellsType::AxisCount;
1301 EMRYS_FILTER_ASSERT(factor >= 1 &&
"subdivide each cell into at least one");
1302 m_stamp.touchShape();
1303 Grid_ refined = m_grid.subdivided(factor);
1304 Eigen::Index offsets = 1;
1305 for (std::size_t d = 0; d < D; ++d)
1309 auto & children = m_children;
1311 children.reserve(m_cells.size() * std::size_t(offsets));
1312 for (Eigen::Index i = 0; i <
size(); ++i)
1314 auto const parent = m_grid.cells().coordinates(m_cells[std::size_t(i)]);
1315 for (Eigen::Index o = 0; o < offsets; ++o)
1317 auto child = std::array<Eigen::Index, D>{};
1318 Eigen::Index rest = o;
1319 for (std::size_t d = D; d-- > 0;)
1321 child[d] = factor * parent[d] + rest % factor;
1324 children.emplace_back(refined.cells().value(child), i);
1327 std::sort(children.begin(), children.end());
1329 m_weightScratch.clear();
1330 Scalar const share = Eigen::numext::log(
Scalar(offsets));
1331 for (std::size_t k = 0; k < children.size(); ++k)
1333 m_kept.push_back(children[k].second);
1334 m_weightScratch.push_back(m_logWeights[std::size_t(children[k].second)] - share);
1336 m_conditionals.select(m_kept);
1337 m_grid = std::move(refined);
1338 m_cells.resize(children.size());
1339 for (std::size_t k = 0; k < children.size(); ++k)
1341 m_cells[k] = children[k].first;
1343 m_logWeights.swap(m_weightScratch);
1349 template <
typename,
typename,
typename,
typename,
typename>
1356 friend class internal::ValuesCheck;
1359 using ConditionalsType = internal::Conditionals<RestSpace, Covariance_, Scalar, allocator_type, ConditionalType>;
1362 using IndexAllocator = internal::ReBound<allocator_type, Eigen::Index>;
1365 using ScalarAllocator = internal::ReBound<allocator_type, Scalar>;
1368 [[nodiscard]] internal::GridPoints<Grid_>
1371 return {m_grid,
cells()};
1379 [[nodiscard]] GaussianParams<SpaceType, Scalar>
1380 collapseCells()
const
1382 if constexpr (IsHybrid)
1388 return internal::collapseGivenPoints(points(), m_conditionals,
logWeights());
1394 assertPosition([[maybe_unused]] Eigen::Index i)
const
1396 EMRYS_FILTER_ASSERT(i >= 0 && i <
size() &&
"the position is out of range");
1406 template <ExecutionPolicy P,
typename Derived>
1407 [[nodiscard]] std::pair<Scalar, bool>
1408 reweight(P && policy, Eigen::ArrayBase<Derived>
const &
logLikelihoods, ConditionalsType & posterior)
1410 return reweightThen(std::forward<P>(policy),
logLikelihoods, [&] {
1411 m_conditionals.swap(posterior);
1421 template <ExecutionPolicy P,
typename Derived>
1422 [[nodiscard]] std::pair<Scalar, bool>
1423 reweight(P && policy, Eigen::ArrayBase<Derived>
const &
logLikelihoods)
1425 return reweightThen(std::forward<P>(policy),
logLikelihoods, [] {});
1431 template <ExecutionPolicy P,
typename Derived,
typename Place>
1432 [[nodiscard]] std::pair<Scalar, bool>
1433 reweightThen(P && policy, Eigen::ArrayBase<Derived>
const &
logLikelihoods, Place
const & place)
1435 EMRYS_FILTER_ASSERT(
logLikelihoods.size() ==
size() &&
"give one log-likelihood per live cell");
1436 m_weightScratch.resize(m_logWeights.size());
1437 internal::forEachIndex(policy,
size(), [&](Eigen::Index i) {
1438 m_weightScratch[std::size_t(i)] = m_logWeights[std::size_t(i)] +
logLikelihoods(i);
1440 auto const evidence = internal::logTotalWeight<Scalar>(
1442 std::span<Scalar const>{m_weightScratch.data(), m_weightScratch.size()}
1448 std::forward<P>(policy),
1450 [&](Eigen::Index i) {
1451 return m_weightScratch[std::size_t(i)];
1457 m_stamp.touchShape();
1458 m_logWeights.swap(m_weightScratch);
1460 normalizeAndRemoveDead();
1461 return {*evidence,
true};
1470 template <
typename Rule>
1472 pruneWith(Rule
const & rule)
1474 m_stamp.touchShape();
1477 [&](Eigen::Index i) {
1478 return m_logWeights[std::size_t(i)];
1483 auto removed = LogSumExp<Scalar>{};
1489 logWeight = -Eigen::NumTraits<Scalar>::infinity();
1492 normalizeAndRemoveDead();
1493 return removed.value();
1501 normalizeAndRemoveDead()
1503 auto const total = internal::logTotalWeight<Scalar>(m_logWeights);
1504 EMRYS_FILTER_ASSERT(total &&
"some live cell must keep a nonzero weight");
1510 for (Eigen::Index i = 0; i <
size(); ++i)
1512 if (m_logWeights[std::size_t(i)] > -Eigen::NumTraits<Scalar>::infinity())
1514 m_kept.push_back(i);
1517 if (m_kept.size() == m_cells.size())
1521 for (std::size_t k = 0; k < m_kept.size(); ++k)
1523 m_cells[k] = m_cells[std::size_t(m_kept[k])];
1524 m_logWeights[k] = m_logWeights[std::size_t(m_kept[k])];
1526 m_conditionals.keep(m_kept);
1527 m_cells.resize(m_kept.size());
1528 m_logWeights.resize(m_kept.size());
1532 internal::Buffer<Eigen::Index, allocator_type> m_cells;
1533 internal::Buffer<Scalar, allocator_type> m_logWeights;
1534 ConditionalsType m_conditionals;
1537 internal::Buffer<Eigen::Index, allocator_type> m_kept;
1539 internal::Buffer<Scalar, allocator_type> m_weightScratch;
1542 using Child = std::pair<Eigen::Index, Eigen::Index>;
1545 using ChildAllocator = internal::ReBound<allocator_type, Child>;
1547 internal::Buffer<Child, allocator_type> m_children;
1549 internal::Stamp m_stamp;
1569template <
typename Gr
id_,
typename Covariance_,
typename Component_>
1585 [[nodiscard]] Grid_
const &
1588 return source().grid();
1592 [[nodiscard]] Eigen::Index
1595 return source().size();
1599 [[nodiscard]]
decltype(
auto)
1602 return source().conditional(i);
1612 return source().collapseCells();
1637 return m_check.get();
1640 internal::ValuesCheck<ParamsType> m_check;
1645template <
typename Gr
id_,
typename Component_,
typename ModeSpace_,
typename Allocator_>
1652#ifndef EMRYS_FILTER_NO_IO
1663template <
typename Gr
id_,
typename Covariance_,
typename Component_>
1665describe(std::ostream & stream, GridGaussianParams<Grid_, Covariance_, Component_>
const & state, Indent indent)
1667 stream << indent <<
"Rao-Blackwellized grid of ";
1668 printCount(stream, state.size(),
"cell");
1670 auto const density = state.toDensity();
1674 describe(stream, density.error(), indent.deeper());
1677 auto const collapsed = density->collapsed();
1678 printDimension(stream, collapsed.valueDimension(), collapsed.differenceDimension());
1679 printMoments(stream, indent.deeper(), collapsed.moments());
The allocator conventions of decisions.md [allocation]: DefaultAllocator, Capacity,...
The distribution over a discrete space (decisions.md [discrete-spaces], [params-and-density]): Catego...
What the Rao-Blackwellized states share (decisions.md [rao-blackwellized-core], [rb-particle-filter])...
Discrete spaces (decisions.md [discrete-spaces]): the DiscreteSpace concept; Finite,...
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.
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...
Params and Density: the traits that pair a distribution's parameters with its density,...
Printing: operator<< and std::formatter for every distribution, every filter (which prints its name a...
SampleSet: a matrix whose columns are samples in a space, which the samplers return and the unscented...
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,...
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...
The parameters of a probability distribution over a discrete space: one weight per value.
Definition Categorical.h:257
Space_ const & space() const
Definition Categorical.h:330
Scalar logWeight(Eigen::Index value) const
Definition Categorical.h:351
Eigen::Array< Scalar_, CardinalityAtCompileTime, 1, Eigen::ColMajor, MaxCardinalityAtCompileTime, 1 > ArrayType
One entry per value, in flat-index order.
Definition Categorical.h:268
A Gaussian distribution: a mean and covariance in a space.
Definition Gaussian.h:259
The density of a Gaussian whose covariance has been factorized: a read-only view.
Definition Gaussian.h:1011
The parameters of a Rao-Blackwellized point-mass filter's state: the cells of a grid still alive,...
Definition GridGaussian.h:936
Params< Component_ > ConditionalType
A cell's distribution over the rest: a Gaussian, or a hybrid of Gaussians.
Definition GridGaussian.h:990
GridGaussian< Grid_, Covariance_, Component_ > DensityType
The view toDensity() returns.
Definition GridGaussian.h:1002
void toDensity() const &&=delete
A density of a temporary would outlive it.
static constexpr bool IsParams
Definition GridGaussian.h:1004
Eigen::Index mostProbable() const
Definition GridGaussian.h:1103
Scalar pruneTail(Scalar logFraction)
Removes the least probable live cells, as many as can be while their combined probability stays below...
Definition GridGaussian.h:1266
auto modes() const
Definition GridGaussian.h:1196
Scalar pruneBelow(Scalar logThreshold)
Definition GridGaussian.h:1251
friend class RbPointMassFilter
Definition GridGaussian.h:1350
auto center(Eigen::Index i) const
Definition GridGaussian.h:1081
LogWeightsType logWeights() const
Definition GridGaussian.h:1088
std::expected< void, WeightError > setWeights(CategoricalParams< CellsType, Scalar > const &weights)
Replaces the live cells' weights with those of weights, normalized over the live cells,...
Definition GridGaussian.h:1162
typename Grid_::RestSpace RestSpace
The rest's space, in order.
Definition GridGaussian.h:981
Eigen::Index cell(Eigen::Index i) const
Definition GridGaussian.h:1054
typename Grid_::PinnedSpace PinnedSpace
The fixed block's space.
Definition GridGaussian.h:984
GridGaussianParams(Grid_ grid, ConditionalType const &conditional, Covariance_={})
Every cell of grid alive and equally probable, each with conditional as its Gaussian over the rest of...
Definition GridGaussian.h:1009
void subdivide(Eigen::Index factor)
Splits every live cell into factor cells along each axis (see PointGrid::subdivided()),...
Definition GridGaussian.h:1297
Scalar logWeight(Eigen::Index i) const
Definition GridGaussian.h:1095
std::expected< void, NumericError > factorize() const
Factorizes each live cell's Gaussian, the one they share once, or checks each cell's hybrid,...
Definition GridGaussian.h:1217
Eigen::Array< Scalar, Eigen::Dynamic, 1 > WeightArrayType
One entry per live cell.
Definition GridGaussian.h:993
Eigen::Index size() const
Definition GridGaussian.h:1047
typename Grid_::Scalar Scalar
The scalar type.
Definition GridGaussian.h:972
Covariance_ CovarianceType
SharedCovariance or PerPointCovariance.
Definition GridGaussian.h:987
Scalar pruneToSize(Eigen::Index maxSize)
Removes the least probable live cells until at most maxSize, at least one, remain,...
Definition GridGaussian.h:1280
Grid_ GridType
The grid.
Definition GridGaussian.h:969
std::span< Eigen::Index const > cells() const
Definition GridGaussian.h:1062
Eigen::Map< WeightArrayType const > LogWeightsType
The live cells' log-probabilities.
Definition GridGaussian.h:996
Moments< RestSpace, Scalar >::MatrixType const & sharedCovariance() const
Definition GridGaussian.h:1204
Grid_ const & grid() const
Definition GridGaussian.h:1040
std::optional< Eigen::Index > find(Eigen::Index cell) const
Definition GridGaussian.h:1069
decltype(auto) conditional(Eigen::Index i) const
Definition GridGaussian.h:1186
allocator_type get_allocator() const
Definition GridGaussian.h:1033
typename Grid_::SpaceType SpaceType
The whole state space.
Definition GridGaussian.h:975
std::expected< DensityType, NumericError > toDensity() const &
Checks the cells (factorize()) and views the state.
Definition GridGaussian.h:1227
typename Grid_::allocator_type allocator_type
The grid's allocator.
Definition GridGaussian.h:999
CategoricalParams< CellsType, Scalar > toCategorical() const
Definition GridGaussian.h:1112
typename Grid_::CellsType CellsType
The discrete space of cells.
Definition GridGaussian.h:978
auto marginal() const
Definition GridGaussian.h:1129
The density of a Rao-Blackwellized point-mass filter's state, a checked view of its GridGaussianParam...
Definition GridGaussian.h:1571
typename ParamsType::ConditionalType ConditionalType
a cell's distribution over the rest
Definition GridGaussian.h:1578
static constexpr bool IsParams
a view: it checks its parameters
Definition GridGaussian.h:1582
Eigen::Index size() const
Definition GridGaussian.h:1593
MomentsType moments() const
Definition GridGaussian.h:1617
Moments< SpaceType, Scalar > MomentsType
a mean and covariance of the whole state
Definition GridGaussian.h:1579
typename Grid_::Scalar Scalar
the scalar type
Definition GridGaussian.h:1576
decltype(auto) conditional(Eigen::Index i) const
Definition GridGaussian.h:1600
typename Grid_::SpaceType SpaceType
the whole state space
Definition GridGaussian.h:1577
Grid_ const & grid() const
Definition GridGaussian.h:1586
GaussianParams< SpaceType, Scalar > collapsed() const
Definition GridGaussian.h:1610
Grid_ GridType
the grid
Definition GridGaussian.h:1575
typename ParamsType::allocator_type allocator_type
the parameters' allocator
Definition GridGaussian.h:1580
GridGaussianParams< Grid_, Covariance_, Component_ > ParamsType
the parameters it reads
Definition GridGaussian.h:1574
The parameters of a hybrid state: a discrete mode, and a component conditioned on each mode.
Definition Hybrid.h:86
The density of a hybrid state, a checked view of its HybridParams (decisions.md [params-and-density],...
Definition Hybrid.h:528
Streaming log-sum-exp: accumulates without overflow.
Definition Weights.h:46
Scalar value() const
Definition Weights.h:133
First and second moments (mean and covariance) of a distribution.
Definition Moments.h:55
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
Fixed points for the block named by the path Path_ of a state in Space_, one per value of the discret...
Definition GridGaussian.h:209
Path_ PathType
The path naming the fixed block.
Definition GridGaussian.h:229
typename internal::BlockSplit< Space_, Path_ >::PinnedSpace PinnedSpace
The space of the fixed block.
Definition GridGaussian.h:238
PinnedMatrix const & cellCovariance(Eigen::Index cell) const
Definition GridGaussian.h:431
PinnedSpace const & pinnedSpace() const
Definition GridGaussian.h:356
PointGrid(Space_ space, Cells_ cells, Eigen::MatrixBase< CentersDerived > const ¢ers, std::span< PinnedMatrix const > cellCovariances, Allocator_ const &allocator={})
Points in space with centers, one column per value of cells in flat-index order, and cellCovariances,...
Definition GridGaussian.h:284
typename Moments< PinnedSpace, Scalar_ >::MatrixType PinnedMatrix
A covariance over the block.
Definition GridGaussian.h:250
Eigen::Index size() const
Definition GridGaussian.h:370
auto const & restDifferenceIndices() const
Definition GridGaussian.h:461
Cells_ CellsType
The discrete space of cells.
Definition GridGaussian.h:226
PointGrid(Space_ space, Cells_ cells, PinnedVector first, PinnedVector spacing, std::span< PinnedMatrix const > cellCovariances, Allocator_ const &allocator={})
A regular grid as above, with cellCovariances, each cell's covariance about its center in flat-index ...
Definition GridGaussian.h:319
PinnedVector const & first() const
Definition GridGaussian.h:408
BlockRows pinnedDifferenceRows() const
Definition GridGaussian.h:454
bool hasCellCovariance() const
Definition GridGaussian.h:424
SampleSet< PinnedSpace, Scalar_ > CentersType
A plain matrix of centers, one per column, laid out as centers() is.
Definition GridGaussian.h:244
Allocator_ allocator_type
The allocator, re-bound per buffer.
Definition GridGaussian.h:235
Scalar_ Scalar
The scalar type.
Definition GridGaussian.h:220
Space_ const & space() const
Definition GridGaussian.h:342
PinnedVector center(Eigen::Index cell) const
Definition GridGaussian.h:377
PointGrid(Space_ space, Cells_ cells, Eigen::MatrixBase< CentersDerived > const ¢ers, std::optional< PinnedMatrix > cellCovariance={}, Allocator_ const &allocator={})
Points in space with centers, one column per value of cells in flat-index order, and cellCovariance,...
Definition GridGaussian.h:266
PointGrid subdivided(Eigen::Index factor) const
Definition GridGaussian.h:475
PinnedVector const & spacing() const
Definition GridGaussian.h:416
Cells_ const & cells() const
Definition GridGaussian.h:349
PointGrid(Space_ space, Cells_ cells, PinnedVector first, PinnedVector spacing, std::optional< PinnedMatrix > cellCovariance={}, Allocator_ const &allocator={})
A regular grid in space over cells, whose cell with coordinates (see DiscreteProduct::coordinates())...
Definition GridGaussian.h:302
typename internal::BlockSplit< Space_, Path_ >::RestSpace RestSpace
The space of the rest of the state, in order.
Definition GridGaussian.h:241
RestSpace const & restSpace() const
Definition GridGaussian.h:363
allocator_type get_allocator() const
Definition GridGaussian.h:335
ConstSampleSetMap< PinnedSpace, Scalar_ > centers() const
Definition GridGaussian.h:400
auto const & restIndices() const
Definition GridGaussian.h:447
static constexpr bool Regular
Whether the grid is regular: its cells are GridCells, and its centers are computed.
Definition GridGaussian.h:253
BlockRows pinnedRows() const
Definition GridGaussian.h:440
typename Moments< PinnedSpace, Scalar_ >::VectorType PinnedVector
A value of the block, such as a center.
Definition GridGaussian.h:247
CellCovariance_ CellCovarianceType
SharedCovariance or PerPointCovariance.
Definition GridGaussian.h:232
Space_ SpaceType
The whole state space.
Definition GridGaussian.h:223
Product(Space_ space, Placed... placed)
The product of the factors placed, made by on() or onEach(), in space.
Definition Product.h:821
A Rao-Blackwellized point-mass filter: fixed points for one block of the state, such as a coarse posi...
Definition RbPointMassFilter.h:241
A type usable as a discrete space: a finite set of values.
Definition Discrete.h:72
A space whose instance holds nothing, so that S{} is the only one there is: a space of fixed size,...
Definition Space.h:217
A type usable as the scalar of a distribution: a real number type such as float, double,...
Definition Math.h:80
A type usable as the space of a distribution.
Definition Space.h:186
std::allocator< std::byte > DefaultAllocator
The allocator a type with a run-time count uses unless given one.
Definition Allocation.h:47
Scalar logSumExp(P &&policy, Eigen::Index count, LogAt const &logAt)
Definition Weights.h:151
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
auto regularGrid(S space, Eigen::MatrixBase< FirstDerived > const &first, Eigen::MatrixBase< SpacingDerived > const &spacing, std::array< Eigen::Index, std::size_t(internal::PathTag< P >::FixedValueDimension)> const &counts, std::optional< typename Moments< internal::PathTag< P >, typename FirstDerived::Scalar >::MatrixType > cellCovariance={}, Allocator const &allocator={})
Definition GridGaussian.h:681
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
auto pointGrid(S space, Eigen::MatrixBase< Derived > const ¢ers, std::optional< typename Moments< internal::PathTag< P >, typename Derived::Scalar >::MatrixType > cellCovariance={}, Allocator const &allocator={})
Definition GridGaussian.h:597
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
Eigen::Array< typename Derived::Scalar, Eigen::Dynamic, 1 > logLikelihoods(M const &measurement, Space const &space, Eigen::MatrixBase< Derived > const &states)
Definition Likelihood.h:408
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
Rows of a contiguous block of a space.
Definition TagPath.h:825
Eigen::Index size
number of rows
Definition TagPath.h:827
The axis of a regular grid of points (see regularGrid()) along coordinate I of the block Block: a run...
Definition GridGaussian.h:68
Finite()=default
A GridAxis is made like a Finite, with its number of cells.
The cells of a regular grid over the block named by the path Path: the DiscreteProduct of its GridAxi...
Definition GridGaussian.h:135
decltype(internal::gridProduct(static_cast< internal::GridAxes< Path > * >(nullptr))) Product
The DiscreteProduct of the axes.
Definition GridGaussian.h:142
A covariance per point.
Definition Conditionals.h:59
The cells of a grid of given points (see pointGrid()) for the block named by the path Path: one value...
Definition GridGaussian.h:153
Finite()=default
PointCells are made like a Finite, with their number of points.
One covariance for every point.
Definition Conditionals.h:49