Skip to content

Commit 1c5a5bb

Browse files
[operation] specialize operations support for 1-by-N filters (#54)
1 parent d4eb20c commit 1c5a5bb

File tree

7 files changed

+177
-112
lines changed

7 files changed

+177
-112
lines changed

.github/workflows/verify_code_style_format.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,6 @@ jobs:
1515
- name: Update
1616
run: sudo apt update
1717
- name: Install
18-
run: sudo apt install clang-format-12
18+
run: sudo apt install clang-format-14
1919
- name: Format
20-
run: find . -iname *.hpp -o -iname *.cpp | xargs clang-format-12 --Werror --dry-run --verbose -style=file
20+
run: find . -iname *.hpp -o -iname *.cpp | xargs clang-format-14 --Werror --dry-run --verbose -style=file

include/fcarouge/internal/kalman.hpp

+21
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,27 @@ For more information, please refer to <https://unlicense.org> */
4747

4848
namespace fcarouge::internal
4949
{
50+
51+
//! @brief Function object for providing an identity matrix.
52+
//!
53+
//! @todo Could we remove this for a standard facility? Perhaps a form of
54+
//! std::integral_constant?
55+
//!
56+
//! @note Could this function object template be a variable template as proposed
57+
//! in paper P2008R0 entitled "Enabling variable template template parameters"?
58+
struct identity_matrix {
59+
//! @brief Returns `1`, the 1-by-1 identity matrix equivalent.
60+
//!
61+
//! @tparam Type The type template parameter of the value.
62+
//!
63+
//! @return The value `1`.
64+
template <typename Type>
65+
[[nodiscard]] inline constexpr auto operator()() const noexcept
66+
{
67+
return Type{ 1 };
68+
}
69+
};
70+
5071
template <typename State, typename Output, typename Input, typename Transpose,
5172
typename Symmetrize, typename Divide, typename Identity,
5273
typename UpdateArguments, typename PredictionArguments>

include/fcarouge/internal/kalman_eigen_operator.hpp include/fcarouge/internal/kalman_eigen.hpp

+99-12
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,30 @@ OTHER DEALINGS IN THE SOFTWARE.
3636
3737
For more information, please refer to <https://unlicense.org> */
3838

39-
#ifndef FCAROUGE_INTERNAL_KALMAN_EIGEN_OPERATOR_HPP
40-
#define FCAROUGE_INTERNAL_KALMAN_EIGEN_OPERATOR_HPP
39+
#ifndef FCAROUGE_INTERNAL_KALMAN_EIGEN_HPP
40+
#define FCAROUGE_INTERNAL_KALMAN_EIGEN_HPP
4141

4242
//! @file
4343
//! @brief Kalman operation for Eigen 3 types.
4444
//!
45-
//! @details Default customization point objects (CPO) for Eigen 3 types.
45+
//! @details Default customization point objects (CPO).
4646

47-
#include "kalman.hpp"
47+
#include "fcarouge/kalman.hpp"
4848

4949
#include <Eigen/Eigen>
5050

51+
#include <concepts>
52+
#include <cstddef>
53+
#include <functional>
5154
#include <type_traits>
5255

5356
namespace fcarouge::eigen::internal
5457
{
58+
59+
//! @brief Arithmetic concept.
60+
template <typename Type>
61+
concept arithmetic = std::integral<Type> || std::floating_point<Type>;
62+
5563
//! @brief Function object for performing Eigen matrix transposition.
5664
//!
5765
//! @details Implemented with the Eigen linear algebra library matrices with
@@ -78,7 +86,7 @@ struct transpose {
7886
//! @details Implemented with the Eigen linear algebra library matrices with
7987
//! sizes fixed at compile-time.
8088
struct symmetrize {
81-
//! @brief Returns the symmetrised `value`.
89+
//! @brief Returns the symmetrized `value`.
8290
//!
8391
//! @param value Value to compute the symmetry of.
8492
//!
@@ -101,7 +109,7 @@ struct divide {
101109
//! @param numerator The dividend matrix of the division. N: m x n
102110
//! @param denominator The divisor matrix of the division. D: o x n
103111
//!
104-
//! @return The quotien matrix. Q: m x o
112+
//! @return The quotient matrix. Q: m x o
105113
//!
106114
//! @exception May throw implementation-defined exceptions.
107115
//!
@@ -119,18 +127,77 @@ struct divide {
119127
.solve(numerator.transpose())
120128
.transpose();
121129
}
130+
131+
//! @brief Returns the quotient of `numerator` and `denominator`.
132+
//!
133+
//! @param numerator The dividend matrix of the division. N: m x 1
134+
//! @param denominator The divisor value of the division.
135+
//!
136+
//! @return The quotient column vector. Q: m x 1
137+
//!
138+
//! @exception May throw implementation-defined exceptions.
139+
//!
140+
//! @todo Simplify implementation.
141+
[[nodiscard]] inline constexpr auto
142+
operator()(const auto &numerator, const arithmetic auto &denominator) const ->
143+
typename Eigen::Vector<
144+
typename std::decay_t<decltype(numerator)>::Scalar,
145+
std::decay_t<decltype(numerator)>::RowsAtCompileTime>
146+
{
147+
return Eigen::Matrix<typename std::decay_t<decltype(numerator)>::Scalar, 1,
148+
1>{ denominator }
149+
.transpose()
150+
.fullPivHouseholderQr()
151+
.solve(numerator.transpose())
152+
.transpose();
153+
}
154+
155+
//! @brief Returns the quotient of `numerator` and `denominator`.
156+
//!
157+
//! @param numerator The dividend value of the division.
158+
//! @param denominator The divisor matrix of the division. D: o x 1
159+
//!
160+
//! @return The quotient row vector. Q: 1 x o
161+
//!
162+
//! @exception May throw implementation-defined exceptions.
163+
//!
164+
//! @todo Simplify implementation.
165+
[[nodiscard]] inline constexpr auto
166+
operator()(const arithmetic auto &numerator, const auto &denominator) const ->
167+
typename Eigen::RowVector<
168+
typename std::decay_t<decltype(denominator)>::Scalar,
169+
std::decay_t<decltype(denominator)>::RowsAtCompileTime>
170+
{
171+
return denominator.transpose()
172+
.fullPivHouseholderQr()
173+
.solve(Eigen::Matrix<typename std::decay_t<decltype(numerator)>::Scalar,
174+
1, 1>{ numerator })
175+
.transpose();
176+
}
177+
178+
//! @brief Returns the quotient of `numerator` and `denominator`.
179+
//!
180+
//! @param numerator The dividend value of the division.
181+
//! @param denominator The divisor value of the division.
182+
//!
183+
//! @return The quotient value.
184+
[[nodiscard]] inline constexpr auto
185+
operator()(const arithmetic auto &numerator,
186+
const arithmetic auto &denominator) const
187+
{
188+
return numerator / denominator;
189+
}
122190
};
123191

124192
//! @brief Function object for providing an Eigen identity matrix.
125193
//!
126194
//! @details Implemented with the Eigen linear algebra library matrices with
127195
//! sizes fixed at compile-time.
128196
//!
129-
//! @note Could this function object template be replaced by a variable
130-
//! template? Proposed in paper P2008R0 entitled "Enabling variable template
131-
//! template parameters".
132-
struct identity {
133-
//! @brief Returns the identity maxtrix.
197+
//! @note Could this function object template be a variable template as proposed
198+
//! in paper P2008R0 entitled "Enabling variable template template parameters"?
199+
struct identity_matrix {
200+
//! @brief Returns the identity matrix.
134201
//!
135202
//! @tparam Type The type template parameter of the matrix.
136203
//!
@@ -142,8 +209,28 @@ struct identity {
142209
{
143210
return Type::Identity();
144211
}
212+
213+
//! @brief Returns `1`, the 1-by-1 identity matrix equivalent.
214+
//!
215+
//! @tparam Type The type template parameter of the value.
216+
//!
217+
//! @return The value `1`.
218+
template <arithmetic Type>
219+
[[nodiscard]] inline constexpr auto operator()() const noexcept
220+
{
221+
return Type{ 1 };
222+
}
145223
};
146224

225+
template <typename Type = double, std::size_t State = 1, std::size_t Output = 1,
226+
std::size_t Input = 1, typename UpdateArguments = std::tuple<>,
227+
typename PredictionArguments = std::tuple<>>
228+
using kalman = fcarouge::kalman<
229+
Type, std::conditional_t<State == 1, Type, Eigen::Vector<Type, State>>,
230+
std::conditional_t<Output == 1, Type, Eigen::Vector<Type, Output>>,
231+
std::conditional_t<Input == 1, Type, Eigen::Vector<Type, Input>>, transpose,
232+
symmetrize, divide, identity_matrix, UpdateArguments, PredictionArguments>;
233+
147234
} // namespace fcarouge::eigen::internal
148235

149-
#endif // FCAROUGE_INTERNAL_KALMAN_EIGEN_OPERATOR_HPP
236+
#endif // FCAROUGE_INTERNAL_KALMAN_EIGEN_HPP

include/fcarouge/internal/kalman_operator.hpp

-68
This file was deleted.

include/fcarouge/kalman.hpp

+22-12
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ For more information, please refer to <https://unlicense.org> */
4343
//! @brief The main Kalman filter class.
4444

4545
#include "internal/kalman.hpp"
46-
#include "internal/kalman_operator.hpp"
4746

4847
#include <concepts>
4948
#include <functional>
@@ -53,23 +52,26 @@ For more information, please refer to <https://unlicense.org> */
5352

5453
namespace fcarouge
5554
{
55+
//! @brief Function object for providing an identity matrix.
56+
using identity_matrix = internal::identity_matrix;
57+
5658
//! @brief Kalman filter.
5759
//!
5860
//! @details A Bayesian filter that uses multivariate Gaussians.
5961
//! Applicable for unimodal and uncorrelated uncertainties. Kalman filters
6062
//! assume white noise, propagation and measurement functions are
6163
//! differentiable, and that the uncertainty stays centered on the state
6264
//! estimate. The filter updates estimates by multiplying Gaussians and predicts
63-
//! estimates by adding Gaussians. Design the state (x, P), the process (F, Q),
64-
//! the measurement (z, R), the measurement function H, and if the system has
65-
//! control inputs (u, B). Designing a filter is as much art as science.
65+
//! estimates by adding Gaussians. Design the state (X, P), the process (F, Q),
66+
//! the measurement (Z, R), the measurement function H, and if the system has
67+
//! control inputs (U, B). Designing a filter is as much art as science.
6668
//!
6769
//! @tparam Type The type template parameter of the value type of the filter.
68-
//! @tparam State The type template parameter of the state vector x. State
70+
//! @tparam State The type template parameter of the state vector X. State
6971
//! variables can be observed (measured), or hidden variables (inferred). This
7072
//! is the the mean of the multivariate Gaussian.
71-
//! @tparam Output The type template parameter of the measurement vector z.
72-
//! @tparam Input The type template parameter of the control u.
73+
//! @tparam Output The type template parameter of the measurement vector Z.
74+
//! @tparam Input The type template parameter of the control U.
7375
//! @tparam Transpose The customization point object template parameter of the
7476
//! matrix transpose functor.
7577
//! @tparam Symmetrize The customization point object template parameter of the
@@ -78,11 +80,18 @@ namespace fcarouge
7880
//! matrix division functor.
7981
//! @tparam Identity The customization point object template parameter of the
8082
//! matrix identity functor.
83+
//! @tparam UpdateArguments The variadic type template parameter for additional
84+
//! update function parameters. Parameters such as delta times, variances, or
85+
//! linearized values. The parameters are propagated to the function objects
86+
//! used to compute the state observation H and the observation noise R
87+
//! matrices. The parameters are also propagated to the state observation
88+
//! function object h.
8189
//! @tparam PredictionArguments The variadic type template parameter for
82-
//! additional prediction function parameters. Time, or a delta thereof, is
83-
//! often a prediction parameter. The parameters are propagated to the function
84-
//! objects used to compute the process noise Q, the state transition F, and the
85-
//! control transition G matrices.
90+
//! additional prediction function parameters. Parameters such as delta times,
91+
//! variances, or linearized values. The parameters are propagated to the
92+
//! function objects used to compute the process noise Q, the state transition
93+
//! F, and the control transition G matrices. The parameters are also propagated
94+
//! to the state transition function object f.
8695
//!
8796
//! @note This class could be usable in constant expressions if `std::function`
8897
//! could too. The polymorphic function wrapper was used in place of function
@@ -118,11 +127,12 @@ namespace fcarouge
118127
//! characteristics?
119128
//! @todo Consider additional constructors?
120129
//! @todo Consider additional characteristics method overloads?
130+
//! @todo Could we do away with std::tuple, replaced by a template template?
121131
template <
122132
typename Type = double, typename State = Type, typename Output = State,
123133
typename Input = State, typename Transpose = std::identity,
124134
typename Symmetrize = std::identity, typename Divide = std::divides<void>,
125-
typename Identity = internal::identity,
135+
typename Identity = identity_matrix,
126136
typename UpdateArguments = std::tuple<>,
127137
typename PredictionArguments = std::tuple<>>
128138
class kalman

0 commit comments

Comments
 (0)