|
EmrysFilter 0.1.0
State estimation utilities in C++23 using Eigen
|
The second layer (decisions.md [layered-headers]): where values live. More...
Topics | |
| Discrete spaces | |
| A discrete space is a finite set of values, such as a maneuver regime, a sensor's inlier/outlier state, or the cells of a grid. | |
Concepts | |
| concept | Emrys::Space |
| A type usable as the space of a distribution. | |
| concept | Emrys::FixedSizeSpace |
| A space whose instance holds nothing, so that S{} is the only one there is: a space of fixed size, continuous or discrete, which is an empty type (decisions.md [space-storage]). | |
| concept | Emrys::PathValue |
| A path given as a value: a TagPath, such as path<Ownship, Position>, or a tag's own value, such as Position{}, which is a path of one tag. | |
Classes | |
| class | Emrys::Composite< Blocks > |
| The concatenation of Blocks, any number of them resizable. More... | |
| class | Emrys::Repeated< Block, MaxCount_ > |
| A fixed-size Block repeated count() times, up to MaxCount_, such as one block per vehicle. More... | |
| struct | Emrys::Linear< Dimension_, MaxDimension_ > |
Dimension_ plain coordinates, or a resizable run of at most MaxDimension_ of them if Dimension_ is Eigen::Dynamic. More... | |
| struct | Emrys::PeriodicInterval |
| Where a Periodic coordinate's values lie: the half-open interval [lower, upper), whose width is the period. More... | |
| class | Emrys::Periodic< Interval, Dimension_, MaxDimension_ > |
| Dimension_ coordinates that wrap with a common period, such as angles or DFT bins. More... | |
| struct | Emrys::TagPath< Tags > |
| A path of tags, each naming a block inside the one before: TagPath<Ownship, Position> is the Position block of Ownship. More... | |
| struct | Emrys::TagPaths< Paths > |
| A list of tag paths, each a tag or a TagPath, such as the blocks a measurement reads (TagPaths<Position, TagPath<Sensor, Bias>>). More... | |
| struct | Emrys::BlockRows |
| Rows of a contiguous block of a space. More... | |
| struct | Emrys::UnitQuaternion |
| An attitude: a unit quaternion of four coordinates whose differences are three-coordinate rotation vectors in the body frame. More... | |
Typedefs | |
| template<int Dimension = 1, int MaxDimension = Dimension> | |
| using | Emrys::RadiansPi |
| Dimension angles in radians, in [-π, π). | |
| template<int Dimension = 1, int MaxDimension = Dimension> | |
| using | Emrys::Radians2Pi = Periodic<PeriodicInterval{.lower = 0.0, .upper = 2 * std::numbers::pi}, Dimension, MaxDimension> |
| Dimension angles in radians, in [0, 2π). | |
| template<int Dimension = 1, int MaxDimension = Dimension> | |
| using | Emrys::Degrees180 = Periodic<PeriodicInterval{.lower = -180.0, .upper = 180.0}, Dimension, MaxDimension> |
| Dimension angles in degrees, in [-180, 180). | |
| template<int Dimension = 1, int MaxDimension = Dimension> | |
| using | Emrys::Degrees360 = Periodic<PeriodicInterval{.lower = 0.0, .upper = 360.0}, Dimension, MaxDimension> |
| Dimension angles in degrees, in [0, 360), such as a compass heading. | |
| template<Space S> | |
| using | Emrys::DifferenceSpace = typename internal::DifferenceSpaceOf<S>::type |
| The space that differences of values in S live in: the type of its difference(), or S itself if it has none, as a space written from scratch may not. | |
| template<Space S, typename Scalar = double> | |
| using | Emrys::ValueVector |
| A value in S as an Eigen column vector of Scalar: a mean, a sample, or a true state. | |
| template<Space S, typename Scalar = double> | |
| using | Emrys::DifferenceVector = ValueVector<DifferenceSpace<S>, Scalar> |
| A difference in S as an Eigen column vector of Scalar, the type of minus() and of the offset plus() takes: a residual, an estimation error, a step, or the variances on a covariance's diagonal. | |
| template<Space Rows, Space Cols = Rows, typename Scalar = double> | |
| using | Emrys::DifferenceMatrix |
| An Eigen matrix of Scalar over the differences of Rows and Cols: a covariance, with one space for both (DifferenceMatrix<State>), or a Jacobian, a gain, or a linear model's matrix, from Cols's differences to Rows's (DifferenceMatrix<Fix, State>). | |
Functions | |
| template<Space S, typename XDerived, typename DDerived> | |
| auto | Emrys::resetJacobian (S const &space, Eigen::MatrixBase< XDerived > const &x, Eigen::MatrixBase< DDerived > const &d) |
| template<Space S, typename XDerived, typename DDerived, typename CovDerived> | |
| void | Emrys::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 \( x \boxplus d \), in place: \( P \leftarrow G P G^T \), with \( G \) the reset Jacobian of resetJacobian() (decisions.md [covariance-reset]). | |
| template<Space S> | |
| DifferenceSpace< S > | Emrys::differenceSpace (S const &space) |
| template<Space S> | |
| Eigen::Index | Emrys::valueDimension (S const &space) |
| template<Space S> | |
| Eigen::Index | Emrys::differenceDimension (S const &space) |
| template<Space S, typename Derived> | |
| void | Emrys::normalizeValues (S const &space, Eigen::MatrixBase< Derived > const &block) |
| Brings the values in block (rows are space's coordinates, columns samples) into canonical form, writing through the const reference as the space's normalize() does: for values that come from outside, such as a user's mean or a model's output. | |
| template<Space S, typename Derived> | |
| void | Emrys::normalizeDifferences (S const &space, Eigen::MatrixBase< Derived > const &block) |
| Brings the differences in block into canonical form: normalizeValues() in the difference space of space, for differences that come from outside. | |
|
template<FixedSizeSpace S, typename Derived> requires Space<S> | |
| void | Emrys::normalizeValues (Eigen::MatrixBase< Derived > const &block) |
| normalizeValues() in the fixed-size space S, given as a template argument: normalizeValues<State>(block). | |
|
template<FixedSizeSpace S, typename Derived> requires Space<S> | |
| void | Emrys::normalizeDifferences (Eigen::MatrixBase< Derived > const &block) |
| normalizeDifferences() in the fixed-size space S, given as a template argument: normalizeDifferences<State>(block). | |
| template<typename Derived> | |
| Eigen::MatrixBase< Derived > & | Emrys::writable (Eigen::MatrixBase< Derived > const &block) |
| block, writable: Eigen's idiom for a function that writes through an expression passed as const&. | |
| template<Space S, typename XDerived, typename DDerived> | |
| auto | Emrys::plus (S const &space, Eigen::MatrixBase< XDerived > const &x, Eigen::MatrixBase< DDerived > const &d) |
| template<Space S, typename ADerived, typename BDerived> | |
| auto | Emrys::minus (S const &space, Eigen::MatrixBase< ADerived > const &a, Eigen::MatrixBase< BDerived > const &b) |
| template<Space S, typename XDerived, typename DDerived> | |
| auto | Emrys::less (S const &space, Eigen::MatrixBase< XDerived > const &x, Eigen::MatrixBase< DDerived > const &d) |
| template<FixedSizeSpace S, typename XDerived, typename DDerived> requires Space<S> | |
| auto | Emrys::plus (Eigen::MatrixBase< XDerived > const &x, Eigen::MatrixBase< DDerived > const &d) |
| template<FixedSizeSpace S, typename ADerived, typename BDerived> requires Space<S> | |
| auto | Emrys::minus (Eigen::MatrixBase< ADerived > const &a, Eigen::MatrixBase< BDerived > const &b) |
| template<FixedSizeSpace S, typename XDerived, typename DDerived> requires Space<S> | |
| auto | Emrys::less (Eigen::MatrixBase< XDerived > const &x, Eigen::MatrixBase< DDerived > const &d) |
| template<typename Space> | |
| constexpr bool | Emrys::allowsValueDimension (Eigen::Index n) |
| template<typename Path, typename X> requires (!internal::PlacesModel<X>) | |
| internal::OnPath< typename internal::HeldOf< X >::type, Path > | Emrys::on (X x) |
| template<typename Path = internal::WholeSpace, typename X> requires (!internal::PlacesModel<X>) | |
| internal::OnEach< typename internal::HeldOf< X >::type, Path > | Emrys::onEach (X x) |
| template<Space S, typename Path> | |
| constexpr auto | Emrys::idx () |
| template<Space S, typename Path> | |
| constexpr auto | Emrys::diffIdx () |
| idx<S, Path>() of the differences of the subspace named by Path: its rows of a covariance. | |
| template<typename Path> | |
| auto | Emrys::idx (Space auto const &space) |
| template<typename Path> | |
| auto | Emrys::diffIdx (Space auto const &space) |
| idx<Path>(space) of the differences of the subspace named by Path: its rows of a covariance. | |
| template<typename Path> | |
| auto | Emrys::idx (Space auto const &space, Eigen::Index element) |
| template<typename Path> | |
| auto | Emrys::diffIdx (Space auto const &space, Eigen::Index element) |
| idx<Path>(space, element) of the differences of one repetition: its rows of a covariance. | |
| template<Space S, typename Path> | |
| auto | Emrys::idx (Eigen::Index element) |
| idx<Path>(space, element) for the space type S, without a space object. | |
| template<Space S, typename Path> | |
| auto | Emrys::diffIdx (Eigen::Index element) |
| idx<S, Path>(element) of the differences of one repetition. | |
| template<typename Path, MatrixExpression X> | |
| auto | Emrys::block (Space auto const &space, X &&x) |
| template<typename Path, MatrixExpression X> | |
| auto | Emrys::block (Space auto const &space, X &&x, Eigen::Index element) |
| template<FixedSizeSpace S, typename Path, MatrixExpression X> requires Space<S> | |
| auto | Emrys::block (X &&x) |
| template<typename Path, MatrixExpression D> | |
| auto | Emrys::diffBlock (Space auto const &space, D &&d) |
| template<typename Path, MatrixExpression D> | |
| auto | Emrys::diffBlock (Space auto const &space, D &&d, Eigen::Index element) |
| template<FixedSizeSpace S, typename Path, MatrixExpression D> requires Space<S> | |
| auto | Emrys::diffBlock (D &&d) |
| template<typename Row, typename Column, MatrixExpression M> | |
| auto | Emrys::diffBlock (Space auto const &rowSpace, Space auto const &columnSpace, M &&m) |
| template<typename Row, typename Column, MatrixExpression M> | |
| auto | Emrys::diffBlock (Space auto const &space, M &&m) |
| template<FixedSizeSpace S, typename Row, typename Column, MatrixExpression M> requires Space<S> | |
| auto | Emrys::diffBlock (M &&m) |
| template<typename Scalar, Space S> | |
| ValueVector< S, Scalar > | Emrys::zeros (S const &space) |
Variables | |
| template<typename S> | |
| constexpr bool | Emrys::hasIdentityReset = internal::identityResetOf<S>() |
| Whether the reset Jacobian of S is the identity, so that a covariance needs no change when its mean moves (decisions.md [covariance-reset]). | |
| template<typename Space> | |
| constexpr int | Emrys::valueDimensionAtCompileTime |
The value dimension of Space at compile time, or Eigen::Dynamic if it is resizable. | |
| template<typename Space> | |
| constexpr int | Emrys::maxValueDimensionAtCompileTime |
The largest valid value dimension of Space, or Eigen::Dynamic if it is unbounded. | |
| template<Space S> | |
| constexpr bool | Emrys::hasPlainValues = !internal::HasNormalize<S> && !internal::HasPlus<S> |
| Whether the values of S are plain: it has neither normalize() nor plus(), so \( x \boxplus \delta \) is x + δ. | |
| template<Space S> | |
| constexpr bool | Emrys::hasPlainDifferences |
| Whether the differences of S are plain: its difference space has no normalize(), and it has neither plus() nor minus(), so \( a \boxminus b \) is a - b and \( x \boxplus \delta \) is x + δ up to normalize(). | |
| template<Space S> | |
| constexpr bool | Emrys::isLinear = hasPlainValues<S> && hasPlainDifferences<S> |
| Whether S is linear: its values and its differences are both plain vectors. | |
| template<typename... Tags> | |
| constexpr TagPath< Tags... > | Emrys::path {} |
| The path TagPath<Tags...> as a value, for a call that takes its paths as arguments rather than as template arguments: reads(path<Position>, path<Ownship, Velocity>). | |
The second layer (decisions.md [layered-headers]): where values live.
A continuous space says how long its values and differences are and how to add and subtract them (Space.h, [sizes-and-dimensions]). Its coordinate types are Linear and Periodic (Coordinates.h, [no-bounded-coordinates]), Composite and Repeated build spaces from spaces (Composite.h, [several-resizable-blocks]), tag paths name their blocks and idx() and block() index them (TagPath.h, [index-names]), and Subspace.h builds the space a path names and grows and shrinks blocks; a discrete space is a finite set of named values (Discrete.h, [discrete-spaces]); Reset.h carries a covariance to the tangent space at a moved mean [covariance-reset]; UnitQuaternion.h is an attitude stored as Eigen stores a quaternion [unit-quaternion]; and Indexing.h holds what marginals and conditionals by path are built from. Read Space.h first.
A space describes how the coordinates of a vector behave: whether they wrap or are plain linear values, and how many there are. Every distribution type, and Moments and SampleSet, is parameterized by a space and then a scalar, which defaults to double (GaussianParams<State>), and takes its size and storage bound from the space. A fixed-size space is an empty type and costs nothing. A plain vector of dimension N is Linear<N>, so GaussianParams<Linear<3>> is a Gaussian on a 3-vector.
Values and differences each live in a space. A space whose values need bringing into canonical form has a normalize() member, applied to blocks whose rows are its coordinates and whose columns are samples. Its differences live in its difference space, from difference(), which is another space: an angle in [0, 360) has differences in [-180, 180), and a Linear coordinate's differences are plain vectors. The library works with them through four free functions, which do nothing where there is nothing to do:
The coordinate types are Linear and Periodic. Their parameters are template arguments, so a fixed-size coordinate type is always an empty type, and the common periods are named: RadiansPi, Radians2Pi, Degrees180, and Degrees360. There is no bounded coordinate type [no-bounded-coordinates]: a quantity that can't be negative is estimated as the vector it is the length of, or as a log, and a distribution that has a bounded support, such as Gamma, states it itself.
Spaces compose: Composite concatenates them, and Repeated repeats a fixed-size block a runtime number of times. Named subspaces are tag types derived from a space (struct Heading : Degrees360<> {};).
A space's valueDimension() is the number of coordinates of a value. Its differences may have fewer, as a unit quaternion's four coordinates have three-coordinate rotation vectors as differences, so a distribution has two dimensions: valueDimension(), the length of a mean or a sample, and differenceDimension(), the rows of a covariance and the degrees of freedom. Generic code calls the free functions valueDimension(space) and differenceDimension(space); a space implements only the member valueDimension(), and its difference dimension is its difference space's [sizes-and-dimensions]. A fixed-size space is an empty type whose value dimension is a compile-time constant. A resizable space (a Repeated block, a coordinate type with Eigen::Dynamic dimension, or a Composite with one) stores its value dimension. Any number of a Composite's blocks may be resizable, at any depth of nested composites, such as a set of tracks and a set of landmarks. Distributions keep their space's value dimension in step with their data, and grow or shrink each resizable block in place with insert() and erase().
A space with at most one resizable block can take its sizes from a length alone, so it has resize(n), and a distribution can be built in it from a mean without a space. A space with several can't: the same length splits among the blocks in more than one way. A distribution in one is built from a space that carries its counts, and the space is grown block by block.
idx<Path>(space) turns a path (a tag or a TagPath) into an Eigen index set from the space's sizes. idx<S, Path>() gives the same index as a compile-time constant. Model code reads and writes the block a path names with block<Path>(space, x) on a vector of values, or a matrix whose columns are values, and diffBlock<Path>(space, d) on one of differences, each Eigen's block with the rows the space's type fixes, and the sizes checked against the space; diffBlock<Row, Column>(rows, columns, m) is a block of a covariance or a Jacobian, and zeros() the vector such code fills block by block. Where a call takes paths as arguments, a path is the value path<Ownship, Position> (decisions.md [tag-addressing]).
Every space exposes FixedValueDimension (the coordinates of its fixed part), ValueDimensionStep (nonzero if it is resizable: the coordinates of one element of its resizable part), and MaxValueDimension (the largest valid value dimension, or Eigen::Dynamic if unbounded). Like Eigen's matrices, the coordinate types take a dimension and a maximum dimension, and Repeated takes a maximum number of repetitions. Distributions use the space's MaxValueDimension as their storage bound, so a capped space gets fixed-capacity storage.
The \( \boxplus \) and \( \boxminus \) operators, and the idea of writing an estimator once over any state space that provides them, are those of Hertzberg, Wagner, Frese, and Schröder (2013); a Periodic coordinate is the circle \( S^1 \) of their examples. See also directional statistics for why a mean of angles is not the mean of their values.
Read Distributions next.
| using Emrys::DifferenceMatrix |
An Eigen matrix of Scalar over the differences of Rows and Cols: a covariance, with one space for both (DifferenceMatrix<State>), or a Jacobian, a gain, or a linear model's matrix, from Cols's differences to Rows's (DifferenceMatrix<Fix, State>).
A single row is stored row-major, as Eigen requires.
| using Emrys::DifferenceSpace = typename internal::DifferenceSpaceOf<S>::type |
The space that differences of values in S live in: the type of its difference(), or S itself if it has none, as a space written from scratch may not.
The library's spaces all have one, and it carries no tag: DifferenceSpace<Gyro> is Linear<1> for a tag struct Gyro : Linear<1> {};, so a block that is a difference of another quantity, such as a sensor's bias, is declared in it: struct Bias : DifferenceSpace<Gyro> {};.
| using Emrys::DifferenceVector = ValueVector<DifferenceSpace<S>, Scalar> |
A difference in S as an Eigen column vector of Scalar, the type of minus() and of the offset plus() takes: a residual, an estimation error, a step, or the variances on a covariance's diagonal.
It is a value in DifferenceSpace<S>, so it has fewer rows than a ValueVector where the space's differences are smaller, as a unit quaternion's 3 are than its 4 coordinates.
| using Emrys::RadiansPi |
Dimension angles in radians, in [-π, π).
| using Emrys::ValueVector |
A value in S as an Eigen column vector of Scalar: a mean, a sample, or a true state.
It has valueDimensionAtCompileTime<S> rows, and a resizable space's bound as its maximum, so a bounded space's vector never allocates. A block's own space gives a block's value (ValueVector<Position>), and Scalar may be an automatic-differentiation scalar, as a model's function written generically in its scalar uses.
|
nodiscardconstexpr |
FixedValueDimension, a whole number of ValueDimensionStep beyond it, and at most its MaxValueDimension. An instance's own is its valueDimension().The test is exact for a space with at most one resizable block. For one with several it is necessary but not sufficient: a Composite of blocks with strides 2 and 3 has stride 1, and no instance has 1 coordinate.
|
nodiscard |
|
nodiscard |
|
nodiscard |
|
nodiscard |
|
nodiscard |
|
nodiscard |
|
nodiscard |
|
nodiscard |
|
nodiscard |
|
nodiscard |
|
nodiscard |
|
nodiscardconstexpr |
idx<S, Path>() of the differences of the subspace named by Path: its rows of a covariance.
It differs from idx() where a block's differences have other sizes than its values.
|
nodiscardconstexpr |
Eigen::Index, as a constant expression (static_assert(idx<State, Heading>() == 3));seqN(fix<offset>, fix<size>);seq(fix<offset>, last);seq(fix<offset>, last, fix<stride>).Only available when no resizable block precedes the path's block, and a resizable or repeated block ends the space; otherwise idx<Path>(space), which works for every path. A tag that appears more than once must be qualified by an enclosing tag; one inside a repeated block is reached only through it, and is not counted against the same tag outside (see TagPath).
The overloads of idx() are told apart by their arguments: idx<S, Path>() from the type, idx<Path>(space) from a space's sizes, and idx<Path>(space, element) and idx<S, Path>(element) for one repetition. Each indexes values, such as a mean; diffIdx(), with the same overloads, indexes differences, such as the rows of a covariance.
|
nodiscard |
idx<Path>(space, element) for the space type S, without a space object.
Only available when no resizable block precedes the repeated block, and element is not range-checked, since the repetition count is unknown; otherwise use idx<Path>(space, element).
|
nodiscard |
Eigen::Index for a single fixed coordinate; seqN(offset, fix<size>) for a fixed block; seqN(offset, size) for a resizable one; and for a path through a repeated block to one of its coordinates, seqN(offset, count, fix<stride>). It works for every path, where idx<S, Path>() needs every offset fixed by the type.
|
nodiscard |
Eigen::Index for one coordinate, otherwise seqN(start, fix<size>). element must be one of its repetitions.
|
nodiscard |
|
nodiscard |
It undoes plus() exactly, less(space, plus(space, x, d), d) == x up to rounding, on a space whose plus() is a group's, as on Linear, Periodic, and UnitQuaternion; on a space whose plus() is some other retraction, it undoes it only to first order in d.
A model need not use it: on a Linear space it is x - d, and the filter normalizes the values a model returns, so bare arithmetic is a choice for plainness that is right wherever the space's plus() is addition (docs/usage.md, Conventions).
|
nodiscard |
|
nodiscard |
| void Emrys::normalizeDifferences | ( | S const & | space, |
| Eigen::MatrixBase< Derived > const & | block ) |
Brings the differences in block into canonical form: normalizeValues() in the difference space of space, for differences that come from outside.
Does nothing where that space has no normalize(). A residual goes through minus() instead.
| void Emrys::normalizeValues | ( | S const & | space, |
| Eigen::MatrixBase< Derived > const & | block ) |
Brings the values in block (rows are space's coordinates, columns samples) into canonical form, writing through the const reference as the space's normalize() does: for values that come from outside, such as a user's mean or a model's output.
Does nothing for a space without normalize(). An update goes through plus() instead.
|
nodiscard |
|
nodiscard |
|
nodiscard |
|
nodiscard |
| void Emrys::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 \( x \boxplus d \), in place: \( P \leftarrow G P G^T \), with \( G \) the reset Jacobian of resetJacobian() (decisions.md [covariance-reset]).
An update that moves a mean by a step and keeps the covariance computed at the old mean calls it, as the Kalman update and the Gaussian conditional do.
cov is read and written whole, and must be symmetric; it may be a block of a larger matrix. Where space has an identity reset (hasIdentityReset), this does nothing and compiles to nothing. Otherwise only the blocks that need it are touched: for a block of \( k \) rows at offset \( o \) in an \( n \)-row covariance, the strip \( G P_{o,:} \) is formed once and written into those rows and, transposed, into those columns, and the diagonal block \( G P_{oo} G^T \) is made exactly symmetric, about \( 4 k^2 n \) flops. A symmetric cov stays exactly symmetric, and as a congruence it keeps a positive semidefinite one so. Allocates nothing for a bounded space.
See resetJacobian() for the sources.
|
nodiscard |
\[ G = \frac{\partial}{\partial \epsilon} \Big[ \big(x \boxplus (d + \epsilon)\big) \boxminus (x \boxplus d) \Big]_{\epsilon = 0}, \]
which takes an error at x to the same error seen from \( x \boxplus d \) (decisions.md [covariance-reset]). A block gives its own in closed form with a member resetJacobian(x, d, out), declares it the identity with static constexpr bool identityReset = true;, or has it computed by forward-mode automatic differentiation of its plus() and minus(). For tests and for callers who want \( G \) itself; resetCovariance() applies it without forming it.For a unit quaternion with \( q \boxplus \delta = q \otimes \mathrm{Exp}(\delta) \) it is the right Jacobian of SO(3), \( J_r(d) \), in the closed form of Solà, Deray, and Atchuthan (2018), eq. (143). The reset is that of the error-state Kalman filter of Solà (2017), §6.3, eqs. (284) to (288), which keeps only the first-order \( I - \tfrac12 [d]_\times \) (eq. 294), and of Mueller, Hehn, and D'Andrea (2017), who derive it for a filter with an attitude and show it is missing from the multiplicative extended Kalman filter of Markley (2003), whose reset moves the attitude and leaves the covariance unchanged. The departure from all three is generality: the Jacobian comes from the space, block by block, by differentiating its own \( \boxplus \) and \( \boxminus \) unless it gives a closed form, rather than being written for an attitude.
|
nodiscard |
It is for run time and is not constexpr, even for a fixed space, as Eigen has rows() beside RowsAtCompileTime: a resizable space's dimension is never a constant, and a user's space would need every member constexpr. At compile time use valueDimensionAtCompileTime, which works for every space, and valueDimensionAtCompileTime<DifferenceSpace<S>> for the differences.
|
nodiscard |
block, writable: Eigen's idiom for a function that writes through an expression passed as const&.
A space's normalize(), plus(), and minus() take their output as a const Eigen::MatrixBase<Derived>&, so that a temporary block such as x.segment(i, n) can be passed, and write through it with this: writable(block) = block.unaryExpr(f).
|
nodiscard |
T the scalar the function is called in (decisions.md [function-scalars]), so that a function differentiated automatically builds its result in dual numbers. It is zero rather than uninitialized, so that a coordinate the function leaves unwritten reads as zero and no compiler warns of a read before a write. In a fixed-size space it is ValueVector<S, T>::Zero().
|
inlineconstexpr |
Whether the reset Jacobian of S is the identity, so that a covariance needs no change when its mean moves (decisions.md [covariance-reset]).
True for a space with no plus() of its own, such as Linear and Periodic; for one that declares static constexpr bool identityReset = true;; and for a Composite or Repeated whose blocks all have it. Where it holds, resetCovariance() does nothing at all.
|
inlineconstexpr |
Whether the differences of S are plain: its difference space has no normalize(), and it has neither plus() nor minus(), so \( a \boxminus b \) is a - b and \( x \boxplus \delta \) is x + δ up to normalize().
Linear has plain differences, so a weighted mean in it is the plain one; Periodic does not.
|
inlineconstexpr |
|
inlineconstexpr |
Whether S is linear: its values and its differences are both plain vectors.
Linear, and a Composite or Repeated of linear blocks, are linear; Periodic is not. Like hasPlainValues and hasPlainDifferences, it takes only a Space, so a type that is not one does not compile rather than counting as linear.
|
inlineconstexpr |
The largest valid value dimension of Space, or Eigen::Dynamic if it is unbounded.
|
inlineconstexpr |
The path TagPath<Tags...> as a value, for a call that takes its paths as arguments rather than as template arguments: reads(path<Position>, path<Ownship, Velocity>).
A bare tag's own value, Position{}, is a path of one tag wherever a path value is taken (PathValue), since a tag is an empty type.
|
inlineconstexpr |
The value dimension of Space at compile time, or Eigen::Dynamic if it is resizable.