21#include <Eigen/Cholesky>
22#include <Eigen/Eigenvalues>
39template <
typename Derived>
40using SquareMatrixOf = Eigen::Matrix<
41 typename Derived::Scalar,
42 Derived::RowsAtCompileTime,
43 Derived::RowsAtCompileTime,
45 Derived::MaxRowsAtCompileTime,
46 Derived::MaxRowsAtCompileTime>;
49template <
typename Matrix>
50using RootColumnOf = Eigen::
51 Matrix<typename Matrix::Scalar, Matrix::RowsAtCompileTime, 1, Eigen::ColMajor, Matrix::MaxRowsAtCompileTime, 1>;
54template <
bool CanFail,
typename Matrix>
55using RootResult = std::conditional_t<CanFail, std::expected<Matrix, GaussianError>, Matrix>;
63 template <
typename Report>
65 operator()(Report
const & )
const noexcept
72template <
typename Scalar,
double Value>
76 using Literal =
typename Eigen::NumTraits<Scalar>::Literal;
77 return Scalar(
static_cast<Literal
>(Value));
81template <
typename Derived>
83lowerFinite(Eigen::MatrixBase<Derived>
const & a)
85 for (Eigen::Index j = 0; j < a.cols(); ++j)
87 if (!
allFinite(a.col(j).tail(a.rows() - j)))
111template <
double Relative = 1.0,
double Absolute = 0.0,
typename Derived>
112[[nodiscard]] std::expected<typename Derived::PlainObject, GaussianError>
113ridgedCovariance(Eigen::MatrixBase<Derived>
const & cov,
typename Derived::Scalar * delta =
nullptr)
115 using Scalar =
typename Derived::Scalar;
116 EMRYS_FILTER_ASSERT(cov.rows() == cov.cols() &&
"a covariance must be square");
117 Eigen::Index
const n = cov.rows();
121 auto const diagonal = cov.diagonal();
122 Scalar bound = Eigen::NumTraits<Scalar>::infinity();
123 for (Eigen::Index i = 0; i < n; ++i)
125 Scalar
const radius = cov.row(i).head(i).cwiseAbs().sum() + cov.col(i).tail(n - i - 1).cwiseAbs().sum();
126 Scalar
const rowBound = diagonal(i) - radius;
131 bound = Eigen::numext::mini(bound, rowBound);
134 Scalar
const shift = Eigen::numext::maxi(-bound, Scalar(0));
135 Scalar
const scale = Eigen::numext::maxi(n > 0 ? diagonal.cwiseAbs().maxCoeff() : Scalar(0), shift);
136 Scalar
const margin =
137 scalarFromConstant<Scalar, Relative>() * Eigen::numext::sqrt(Eigen::NumTraits<Scalar>::epsilon()) * scale
138 + scalarFromConstant<Scalar, Absolute>();
139 typename Derived::PlainObject ridged = cov;
140 ridged.diagonal().array() += shift + margin;
141 if (delta !=
nullptr)
143 *delta = shift + margin;
151template <
typename Matrix>
153fixColumnSigns(Matrix & root)
155 for (Eigen::Index j = 0; j < root.cols(); ++j)
157 Eigen::Index largest = 0;
158 root.col(j).cwiseAbs().maxCoeff(&largest);
159 if (root(largest, j) <
typename Matrix::Scalar(0))
161 root.col(j) *=
typename Matrix::Scalar(-1);
169template <
typename Derived>
171isTriangularRoot(Eigen::MatrixBase<Derived>
const & a)
173 using Scalar =
typename Derived::Scalar;
174 if (a.rows() != a.cols())
178 for (Eigen::Index j = 0; j < a.cols(); ++j)
180 if (a(j, j) < Scalar(0))
184 for (Eigen::Index i = 0; i < j; ++i)
186 if (a(i, j) != Scalar(0))
199template <
typename Derived>
200[[nodiscard]] SquareMatrixOf<Derived>
201triangularRootOf(Eigen::MatrixBase<Derived>
const & factor)
203 if constexpr (Derived::ColsAtCompileTime == Eigen::Dynamic
204 || Derived::ColsAtCompileTime == Derived::RowsAtCompileTime)
206 if (isTriangularRoot(factor))
208 return SquareMatrixOf<Derived>{factor};
211 return lowerTriangularRoot(factor);
219template <
typename Derived>
222 SquareMatrixOf<Derived> vectors;
223 RootColumnOf<SquareMatrixOf<Derived>> roots;
224 Eigen::Index clamped = 0;
228template <
typename Derived>
229[[nodiscard]] PrincipalAxes<Derived>
230principalAxesOfCovariance(Eigen::MatrixBase<Derived>
const & cov)
232 using Matrix = SquareMatrixOf<Derived>;
233 using Scalar =
typename Matrix::Scalar;
234 auto const solver = Eigen::SelfAdjointEigenSolver<Matrix>{Matrix{cov}, Eigen::ComputeEigenvectors};
235 Eigen::Index
const n = cov.rows();
236 auto axes = PrincipalAxes<Derived>{};
237 axes.vectors.resize(n, n);
238 axes.roots.resize(n);
239 for (Eigen::Index j = 0; j < n; ++j)
242 Scalar
const value = solver.eigenvalues()(n - 1 - j);
243 if (value < Scalar(0))
247 axes.vectors.col(j) = solver.eigenvectors().col(n - 1 - j);
248 axes.roots(j) = Eigen::numext::sqrt(Eigen::numext::maxi(value, Scalar(0)));
257template <
typename Derived>
258[[nodiscard]] PrincipalAxes<Derived>
259principalAxesOfFactor(Eigen::MatrixBase<Derived>
const & factor)
261 using Matrix = SquareMatrixOf<Derived>;
262 Matrix
const lower = triangularRootOf(factor);
263 auto const svd = Eigen::JacobiSVD<Matrix, Eigen::ComputeFullU>{lower};
264 return PrincipalAxes<Derived>{svd.matrixU(), svd.singularValues(), 0};
269inline constexpr bool isFallbackList =
false;
301 { std::bool_constant<T::canFail>{} } -> std::convertible_to<bool>;
302} &&
requires(T
const & axes, Eigen::Matrix3d
const & cov) {
303 { axes.root(cov) } -> std::same_as<internal::RootResult<T::canFail, Eigen::Matrix3d>>;
321concept Repair =
requires(T
const & repair, Eigen::Matrix3d
const & cov) {
322 { repair.repaired(cov) } -> std::same_as<std::expected<Eigen::Matrix3d, GaussianError>>;
349template <
typename Derived>
373template <
typename Scalar>
401 template <
typename Derived>
402 [[nodiscard]] std::expected<internal::SquareMatrixOf<Derived>,
GaussianError>
403 root(Eigen::MatrixBase<Derived>
const & cov)
const
405 using Matrix = internal::SquareMatrixOf<Derived>;
406 if (!internal::lowerFinite(cov))
410 auto const llt = Eigen::LLT<Matrix>{Matrix{cov}};
411 if (llt.info() != Eigen::Success)
415 return Matrix{llt.matrixL()};
419 template <
typename Derived>
420 [[nodiscard]] std::expected<internal::SquareMatrixOf<Derived>,
GaussianError>
427 return internal::triangularRootOf(factor);
450 template <
typename Scalar>
454 template <
typename Derived>
455 [[nodiscard]] internal::SquareMatrixOf<Derived>
456 root(Eigen::MatrixBase<Derived>
const & cov)
const
458 return root(cov, internal::DiscardReport{});
462 template <
typename Derived,
typename Sink>
463 [[nodiscard]] internal::SquareMatrixOf<Derived>
464 root(Eigen::MatrixBase<Derived>
const & cov, Sink && sink)
const
466 using Matrix = internal::SquareMatrixOf<Derived>;
467 using Scalar =
typename Matrix::Scalar;
468 auto const ldlt = Eigen::LDLT<Matrix>{Matrix{cov}};
469 auto const pivots = ldlt.vectorD();
470 sink(
ClampReport{(pivots.array() < Scalar(0)).count()});
471 auto const d = pivots.cwiseMax(Scalar(0)).cwiseSqrt().eval();
472 Matrix lowerD = ldlt.matrixL();
473 lowerD *= d.asDiagonal();
474 return ldlt.transpositionsP().transpose() * lowerD;
497 template <
typename Scalar>
501 template <
typename Derived>
502 [[nodiscard]] internal::SquareMatrixOf<Derived>
503 root(Eigen::MatrixBase<Derived>
const & cov)
const
505 return root(cov, internal::DiscardReport{});
509 template <
typename Derived,
typename Sink>
510 [[nodiscard]] internal::SquareMatrixOf<Derived>
511 root(Eigen::MatrixBase<Derived>
const & cov, Sink && sink)
const
513 auto const axes = internal::principalAxesOfCovariance(cov);
515 return fromAxes<Derived>(axes);
519 template <
typename Derived>
520 [[nodiscard]] internal::SquareMatrixOf<Derived>
523 return fromAxes<Derived>(internal::principalAxesOfFactor(factor));
529 template <
typename Derived>
530 [[nodiscard]]
static internal::SquareMatrixOf<Derived>
531 fromAxes(internal::PrincipalAxes<Derived>
const & axes)
533 internal::SquareMatrixOf<Derived>
root = axes.vectors * axes.roots.asDiagonal();
534 internal::fixColumnSigns(
root);
556 template <
typename Scalar>
560 template <
typename Derived>
561 [[nodiscard]] internal::SquareMatrixOf<Derived>
562 root(Eigen::MatrixBase<Derived>
const & cov)
const
564 return root(cov, internal::DiscardReport{});
568 template <
typename Derived,
typename Sink>
569 [[nodiscard]] internal::SquareMatrixOf<Derived>
570 root(Eigen::MatrixBase<Derived>
const & cov, Sink && sink)
const
572 auto const axes = internal::principalAxesOfCovariance(cov);
574 return fromAxes<Derived>(axes);
580 template <
typename Derived>
581 [[nodiscard]] internal::SquareMatrixOf<Derived>
584 return fromAxes<Derived>(internal::principalAxesOfFactor(factor));
590 template <
typename Derived>
591 [[nodiscard]]
static internal::SquareMatrixOf<Derived>
592 fromAxes(internal::PrincipalAxes<Derived>
const & axes)
594 return axes.vectors * axes.roots.asDiagonal() * axes.vectors.transpose();
617template <
typename Vector>
627 template <
typename Derived>
628 [[nodiscard]] std::expected<internal::SquareMatrixOf<Derived>,
GaussianError>
629 root(Eigen::MatrixBase<Derived>
const & cov)
const
634 return std::unexpected{lower.error()};
636 return rotated(*lower);
640 template <
typename Derived>
641 [[nodiscard]] std::expected<internal::SquareMatrixOf<Derived>,
GaussianError>
647 return std::unexpected{lower.error()};
649 return rotated(*lower);
657 template <
typename Matrix>
658 [[nodiscard]] std::expected<Matrix, GaussianError>
659 rotated(Matrix
const & lower)
const
661 using Scalar =
typename Matrix::Scalar;
662 using ColumnType = internal::RootColumnOf<Matrix>;
664 direction.size() == lower.rows() &&
"a direction has a coordinate per coordinate of the covariance"
666 ColumnType
const whitened =
667 lower.template triangularView<Eigen::Lower>().solve(
direction.template cast<Scalar>());
668 Scalar
const length = whitened.norm();
669 if (!
isFinite(length) || !(length > Scalar(0)))
673 ColumnType
const unit = whitened / length;
677 Scalar
const sign = unit(0) < Scalar(0) ? Scalar(1) : Scalar(-1);
678 ColumnType v = -sign * unit;
680 Matrix
root = lower - (Scalar(2) / v.squaredNorm()) * (lower * v) * v.transpose();
702template <
double Relative = 1.0,
double Absolute = 0.0>
705 static_assert(Relative >= 0 && Absolute >= 0,
"a ridge's margins are at least zero");
711 template <
typename Scalar>
715 template <
typename Derived>
716 [[nodiscard]] std::expected<typename Derived::PlainObject, GaussianError>
717 repaired(Eigen::MatrixBase<Derived>
const & cov)
const
719 return internal::ridgedCovariance<Relative, Absolute>(cov);
723 template <
typename Derived,
typename Sink>
724 [[nodiscard]] std::expected<typename Derived::PlainObject, GaussianError>
725 repaired(Eigen::MatrixBase<Derived>
const & cov, Sink && sink)
const
727 auto delta =
typename Derived::Scalar(0);
728 auto result = internal::ridgedCovariance<Relative, Absolute>(cov, &delta);
742template <
typename Entry,
typename Scalar>
745 using type = roots::NoReport;
749template <
typename Entry,
typename Scalar>
750 requires requires {
typename Entry::template Report<Scalar>; }
751struct ReportOf<Entry, Scalar>
753 using type =
typename Entry::template Report<Scalar>;
759template <
typename Entry,
typename Scalar>
760using ReportOfT =
typename ReportOf<Entry, Scalar>::type;
765template <
typename A,
typename Scalar>
766struct FailureReportOf
768 using type = ReportOfT<A, Scalar>;
772template <
typename A,
typename Scalar>
773 requires requires {
typename A::template FailureReport<Scalar>; }
774struct FailureReportOf<A, Scalar>
776 using type =
typename A::template FailureReport<Scalar>;
782template <
typename A,
typename Scalar>
783using FailureReportOfT =
typename FailureReportOf<A, Scalar>::type;
788template <
typename Entry>
789[[nodiscard]]
consteval bool
792 if constexpr (
requires { Entry::canFail; })
794 return Entry::canFail;
805template <
typename... Fallbacks>
806[[nodiscard]]
consteval bool
809 constexpr bool canFail[] = {entryCanFail<Fallbacks>()...,
true};
810 for (std::size_t i = 0; i + 1 <
sizeof...(Fallbacks); ++i)
823template <
typename A,
typename Derived,
typename Sink>
825rootWithSink(A
const & axes, Eigen::MatrixBase<Derived>
const & cov, Sink && sink)
827 if constexpr (
requires { axes.root(cov, sink); })
829 return axes.root(cov, sink);
833 sink(roots::NoReport{});
834 return axes.root(cov);
839template <
typename R,
typename Derived,
typename Sink>
841repairWithSink(R
const & repair, Eigen::MatrixBase<Derived>
const & cov, Sink && sink)
843 if constexpr (
requires { repair.repaired(cov, sink); })
845 return repair.repaired(cov, sink);
849 sink(roots::NoReport{});
850 return repair.repaired(cov);
857template <
typename A,
typename Derived>
859rootFromFactor(A
const & axes, Eigen::MatrixBase<Derived>
const & factor)
861 if constexpr (
requires { axes.rootFromFactor(factor); })
863 return axes.rootFromFactor(factor);
867 return axes.root(SquareMatrixOf<Derived>{factor * factor.transpose()});
872template <
typename Matrix,
typename Result>
873[[nodiscard]] std::expected<Matrix, GaussianError>
874asExpected(Result && result)
876 if constexpr (
requires { result.has_value(); })
880 return std::unexpected{result.error()};
882 return Matrix{std::move(*result)};
886 return Matrix{std::forward<Result>(result)};
915template <
typename Head,
typename... Fallbacks>
918 static_assert(
Axes<Head>,
"a fallback list starts with axes");
919 static_assert(internal::entryCanFail<Head>(),
"axes that cannot fail take no fallback");
922 (!internal::isFallbackList<Fallbacks> && ...),
923 "a fallback list is flat: give a fallback's fallbacks to the list itself"
926 internal::fallbacksReached<Fallbacks...>(),
927 "a fallback after axes that cannot fail is never reached"
932 internal::entryCanFail<std::tuple_element_t<
sizeof...(Fallbacks) - 1, std::tuple<Fallbacks...>>>();
935 template <
typename Scalar>
936 using Report = std::variant<internal::ReportOfT<Head, Scalar>, internal::ReportOfT<Fallbacks, Scalar>...>;
939 template <
typename Scalar>
941 std::optional<internal::ReportOfT<Head, Scalar>>,
942 std::optional<internal::ReportOfT<Fallbacks, Scalar>>...>;
950 template <
typename Derived>
951 [[nodiscard]] internal::RootResult<canFail, internal::SquareMatrixOf<Derived>>
952 root(Eigen::MatrixBase<Derived>
const & cov)
const
954 return root(cov, internal::DiscardReport{});
960 template <
typename Derived,
typename Sink>
961 [[nodiscard]] internal::RootResult<canFail, internal::SquareMatrixOf<Derived>>
962 root(Eigen::MatrixBase<Derived>
const & cov, Sink && sink)
const
964 using Matrix = internal::SquareMatrixOf<Derived>;
965 using Scalar =
typename Derived::Scalar;
967 auto const recordInto = [&tried]<std::size_t I>(std::integral_constant<std::size_t, I>) {
968 return [&tried](
auto const & report) {
969 std::get<I>(tried) = report;
972 std::optional<Matrix> found;
973 std::size_t used = 0;
975 auto const keep = [&](std::size_t index,
auto && result) {
976 auto const root = internal::asExpected<Matrix>(std::forward<
decltype(result)>(result));
984 error =
root.error();
987 keep(0, internal::rootWithSink(
head, cov, recordInto(std::integral_constant<std::size_t, 0>{})));
988 [&]<std::size_t... I>(std::index_sequence<I...>) {
995 auto const & entry = std::get<I>(
fallbacks);
996 auto const record = recordInto(std::integral_constant<std::size_t, I + 1>{});
997 using Entry = std::tuple_element_t<I, std::tuple<Fallbacks...>>;
1000 auto const fixed = internal::repairWithSink(entry, cov, record);
1003 error = fixed.error();
1006 keep(I + 1,
head.root(*fixed));
1010 keep(I + 1, internal::rootWithSink(entry, cov, record));
1015 }(std::index_sequence_for<Fallbacks...>{});
1018 sink(successReport<Scalar>(tried, used));
1019 return std::move(*found);
1024 return std::unexpected{error};
1028 EMRYS_FILTER_ASSERT(
false &&
"the last fallback cannot fail");
1034 template <
typename Derived>
1035 [[nodiscard]] internal::RootResult<canFail, internal::SquareMatrixOf<Derived>>
1038 using Matrix = internal::SquareMatrixOf<Derived>;
1039 auto first = internal::asExpected<Matrix>(internal::rootFromFactor(
head, factor));
1042 return std::move(*first);
1044 std::optional<Matrix> found;
1045 auto error = first.error();
1046 std::optional<Matrix> covariance;
1047 [&]<std::size_t... I>(std::index_sequence<I...>) {
1054 auto const & entry = std::get<I>(
fallbacks);
1055 using Entry = std::tuple_element_t<I, std::tuple<Fallbacks...>>;
1056 std::expected<Matrix, GaussianError>
root = std::unexpected{error};
1061 covariance = Matrix{factor * factor.transpose()};
1063 auto const fixed = entry.repaired(*covariance);
1066 error = fixed.error();
1069 root = internal::asExpected<Matrix>(
head.root(*fixed));
1073 root = internal::asExpected<Matrix>(internal::rootFromFactor(entry, factor));
1077 found = std::move(*
root);
1081 error =
root.error();
1086 }(std::index_sequence_for<Fallbacks...>{});
1089 return std::move(*found);
1093 return std::unexpected{error};
1097 EMRYS_FILTER_ASSERT(
false &&
"the last fallback cannot fail");
1105 template <
typename Scalar, std::
size_t I = 0>
1109 if constexpr (I + 1 < std::tuple_size_v<FailureReport<Scalar>>)
1113 return successReport<Scalar, I + 1>(tried, used);
1116 EMRYS_FILTER_ASSERT(std::get<I>(tried).has_value());
1117 return Report<Scalar>{std::in_place_index<I>, *std::get<I>(tried)};
1127template <
typename Head,
typename... Fallbacks>
1128inline constexpr bool isFallbackList<roots::WithFallbacks<Head, Fallbacks...>>{
true};
1138template <
typename Derived>
1139[[nodiscard]] SquareMatrixOf<Derived>
1140defaultRoot(Eigen::MatrixBase<Derived>
const & cov)
1142 return roots::WithFallbacks<roots::Cholesky, roots::Pivoted>{}.root(cov);
1146template <
typename Head,
typename... Fallbacks>
1147[[nodiscard]]
constexpr auto
1148withFallbacks(Head head, Fallbacks... fallbacks)
1150 if constexpr (
sizeof...(Fallbacks) == 0)
1156 return roots::WithFallbacks<Head, Fallbacks...>{
1158 std::tuple<Fallbacks...>{std::move(fallbacks)...}
1172template <
typename... Fallbacks>
1173[[nodiscard]]
constexpr auto
1176 return internal::withFallbacks(
Cholesky{}, std::move(fallbacks)...);
1182template <
typename... Fallbacks>
1183[[nodiscard]]
constexpr auto
1186 return internal::withFallbacks(
Pivoted{}, std::move(fallbacks)...);
1192template <
typename... Fallbacks>
1193[[nodiscard]]
constexpr auto
1196 return internal::withFallbacks(
Principal{}, std::move(fallbacks)...);
1202template <
typename... Fallbacks>
1203[[nodiscard]]
constexpr auto
1206 return internal::withFallbacks(
Symmetric{}, std::move(fallbacks)...);
1214template <
typename Derived,
typename... Fallbacks>
1216along(Eigen::MatrixBase<Derived>
const & direction, Fallbacks... fallbacks)
1218 static_assert(Derived::ColsAtCompileTime == 1,
"along() takes a direction as a column vector");
1219 return internal::withFallbacks(
1221 std::move(fallbacks)...
1230template <
double Relative = 1.0,
double Absolute = 0.0>
1231[[nodiscard]]
constexpr Ridge<Relative, Absolute>
1242template <
typename Head,
typename First,
typename... Rest>
1243[[nodiscard]]
constexpr WithFallbacks<Head, First, Rest...>
1246 return {std::move(axes), std::tuple<First, Rest...>{std::move(first), std::move(rest)...}};
1269template <Axes A,
typename Derived>
1271squareRoot(A
const & axes, Eigen::MatrixBase<Derived>
const & cov)
1273 EMRYS_FILTER_ASSERT(cov.rows() == cov.cols() &&
"a covariance must be square");
1274 return axes.root(cov);
1284template <
typename Matrix,
typename Report>
1296template <
typename Report>
1310template <Axes A,
typename Derived>
1314 using Scalar =
typename Derived::Scalar;
1315 using Matrix = internal::SquareMatrixOf<Derived>;
1316 using Report = internal::ReportOfT<A, Scalar>;
1317 using Failure = internal::FailureReportOfT<A, Scalar>;
1318 std::optional<Report> report;
1319 std::optional<Failure> failure;
1320 auto result = internal::rootWithSink(axes, cov, [&](
auto const &
given) {
1321 using Given = std::remove_cvref_t<
decltype(
given)>;
1322 if constexpr (std::same_as<Given, Report>)
1326 if constexpr (std::same_as<Given, Failure>)
1331 if constexpr (A::canFail)
1336 return Result{std::unexpect,
RootFailure<Failure>{result.error(), failure.value_or(Failure{})}};
The macros every header includes first.
Mathematical constants and scalar functions that work in every scalar type the library accepts,...
NumericError, the reasons a factorization or a normalization can fail, and its two names,...
Triangularization: the triangular factor of a stacked matrix by Householder reflections,...
Axes: a way of taking a root of a covariance , , whose columns carry a sigma-point rule's unit point...
Definition Roots.h:300
A repair: what turns a covariance whose root failed into one to retry (decisions.md [sigma-point-axes...
Definition Roots.h:321
bool allFinite(Eigen::DenseBase< Derived > const &x)
Definition Math.h:354
bool isFinite(T const &x)
Definition Math.h:305
@ NotPositiveDefinite
the covariance is not positive definite, so it has no Cholesky factor or inverse
Definition NumericError.h:31
@ NonFinite
a matrix, a factor, or a log-weight holds NaN or infinity (+inf, for a log-weight)
Definition NumericError.h:33
NumericError GaussianError
Reasons a Gaussian, in any of its forms (decisions.md [gaussian-forms]), can fail to give a density,...
Definition NumericError.h:45
constexpr auto symmetric(Fallbacks... fallbacks)
Definition Roots.h:1204
constexpr auto cholesky(Fallbacks... fallbacks)
Definition Roots.h:1174
auto squareRoot(A const &axes, Eigen::MatrixBase< Derived > const &cov)
Definition Roots.h:1271
constexpr WithFallbacks< Head, First, Rest... > withFallbacks(Head axes, First first, Rest... rest)
Definition Roots.h:1244
auto squareRootWithReport(A const &axes, Eigen::MatrixBase< Derived > const &cov)
Definition Roots.h:1312
constexpr Ridge< Relative, Absolute > ridge()
Definition Roots.h:1232
constexpr auto principal(Fallbacks... fallbacks)
Definition Roots.h:1194
internal::SquareMatrixOf< Derived > RootMatrix
The type of a root of the covariance or factor Derived: square, with a row and a column per row of it...
Definition Roots.h:350
constexpr auto pivoted(Fallbacks... fallbacks)
Definition Roots.h:1184
auto along(Eigen::MatrixBase< Derived > const &direction, Fallbacks... fallbacks)
Definition Roots.h:1216
WithFallbacks< Cholesky, Pivoted > DefaultAxes
The axes every root the library takes uses unless told otherwise, cholesky(pivoted()): the Cholesky f...
Definition Roots.h:1254
GivenBlock< Space, P, Value > given(Space const &space, Value const &value)
Definition Measurement.h:917
The axes and repairs, each made by its factory (decisions.md [policy-factories]), and the roots taken...
Definition Roots.h:342
Axes along a direction: a root whose first column is parallel to , so that a sigma-point rule puts it...
Definition Roots.h:619
Vector direction
, in the covariance's coordinates
Definition Roots.h:622
std::expected< internal::SquareMatrixOf< Derived >, GaussianError > rootFromFactor(Eigen::MatrixBase< Derived > const &factor) const
Definition Roots.h:642
std::expected< internal::SquareMatrixOf< Derived >, GaussianError > root(Eigen::MatrixBase< Derived > const &cov) const
Definition Roots.h:629
static constexpr bool canFail
a direction outside the covariance's range has no length
Definition Roots.h:620
Cholesky axes: the lower Cholesky factor , , by Eigen's LLT, which fails on a covariance that is not ...
Definition Roots.h:397
std::expected< internal::SquareMatrixOf< Derived >, GaussianError > root(Eigen::MatrixBase< Derived > const &cov) const
Definition Roots.h:403
std::expected< internal::SquareMatrixOf< Derived >, GaussianError > rootFromFactor(Eigen::MatrixBase< Derived > const &factor) const
Definition Roots.h:421
static constexpr bool canFail
a covariance that is not positive definite has no Cholesky factor
Definition Roots.h:398
The report of Pivoted, Principal, and Symmetric: how many pivots or eigenvalues were below zero and t...
Definition Roots.h:364
Eigen::Index clamped
the pivots or eigenvalues taken as zero
Definition Roots.h:365
The report of axes or a repair with nothing to say, as Cholesky's: it either took the root or failed.
Definition Roots.h:357
Pivoted axes: from Eigen's pivoted LDL decomposition , with a negative pivot, which rounding can giv...
Definition Roots.h:446
ClampReport Report
The report: the pivots taken as zero.
Definition Roots.h:451
internal::SquareMatrixOf< Derived > root(Eigen::MatrixBase< Derived > const &cov) const
Definition Roots.h:456
static constexpr bool canFail
every positive semidefinite part has a root
Definition Roots.h:447
internal::SquareMatrixOf< Derived > root(Eigen::MatrixBase< Derived > const &cov, Sink &&sink) const
Definition Roots.h:464
Principal axes: , the eigenvectors of scaled by the roots of their eigenvalues, largest first,...
Definition Roots.h:493
internal::SquareMatrixOf< Derived > root(Eigen::MatrixBase< Derived > const &cov) const
Definition Roots.h:503
static constexpr bool canFail
every positive semidefinite part has a root
Definition Roots.h:494
ClampReport Report
The report: the eigenvalues taken as zero.
Definition Roots.h:498
internal::SquareMatrixOf< Derived > root(Eigen::MatrixBase< Derived > const &cov, Sink &&sink) const
Definition Roots.h:511
internal::SquareMatrixOf< Derived > rootFromFactor(Eigen::MatrixBase< Derived > const &factor) const
Definition Roots.h:521
The report of a Ridge: the ridge it added to the diagonal.
Definition Roots.h:375
Scalar ridge
Definition Roots.h:376
The ridge repair: the Gershgorin ridge of decisions.md [covariance-repair], added to the diagonal of ...
Definition Roots.h:704
std::expected< typename Derived::PlainObject, GaussianError > repaired(Eigen::MatrixBase< Derived > const &cov) const
Definition Roots.h:717
RidgeReport< Scalar > Report
The report: the ridge added.
Definition Roots.h:712
static constexpr double absolute
Absolute
Definition Roots.h:708
static constexpr double relative
Relative
Definition Roots.h:707
std::expected< typename Derived::PlainObject, GaussianError > repaired(Eigen::MatrixBase< Derived > const &cov, Sink &&sink) const
Definition Roots.h:725
Why squareRootWithReport() failed, and what each entry tried did.
Definition Roots.h:1298
Report report
what each entry did
Definition Roots.h:1300
GaussianError error
the last entry's error
Definition Roots.h:1299
A root and the report of the axes that took it, from squareRootWithReport().
Definition Roots.h:1286
Report report
what the axes did
Definition Roots.h:1288
Matrix root
,
Definition Roots.h:1287
Symmetric axes: the principal square root , the one symmetric positive semidefinite root,...
Definition Roots.h:552
internal::SquareMatrixOf< Derived > rootFromFactor(Eigen::MatrixBase< Derived > const &factor) const
Definition Roots.h:582
ClampReport Report
The report: the eigenvalues taken as zero.
Definition Roots.h:557
static constexpr bool canFail
every positive semidefinite part has a root
Definition Roots.h:553
internal::SquareMatrixOf< Derived > root(Eigen::MatrixBase< Derived > const &cov) const
Definition Roots.h:562
internal::SquareMatrixOf< Derived > root(Eigen::MatrixBase< Derived > const &cov, Sink &&sink) const
Definition Roots.h:570
Axes that can fail, followed by their fallbacks, tried in order (decisions.md [sigma-point-axes]): a ...
Definition Roots.h:917
internal::RootResult< canFail, internal::SquareMatrixOf< Derived > > rootFromFactor(Eigen::MatrixBase< Derived > const &factor) const
Definition Roots.h:1036
internal::RootResult< canFail, internal::SquareMatrixOf< Derived > > root(Eigen::MatrixBase< Derived > const &cov, Sink &&sink) const
Definition Roots.h:962
std::variant< internal::ReportOfT< Head, Scalar >, internal::ReportOfT< Fallbacks, Scalar >... > Report
The report of the entry that succeeded, at its index.
Definition Roots.h:936
internal::RootResult< canFail, internal::SquareMatrixOf< Derived > > root(Eigen::MatrixBase< Derived > const &cov) const
Definition Roots.h:952
Cholesky head
Definition Roots.h:944
static constexpr bool canFail
Definition Roots.h:931
std::tuple< Fallbacks... > fallbacks
Definition Roots.h:945
std::tuple< std::optional< internal::ReportOfT< Head, Scalar > >, std::optional< internal::ReportOfT< Fallbacks, Scalar > >... > FailureReport
The report of every entry, on failure.
Definition Roots.h:940