Skip to content

Commit

Permalink
[operation] specialize operations support for 1-by-N filters
Browse files Browse the repository at this point in the history
  • Loading branch information
FrancoisCarouge committed Jul 1, 2022
1 parent d4eb20c commit a084598
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 106 deletions.
21 changes: 21 additions & 0 deletions include/fcarouge/internal/kalman.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,27 @@ For more information, please refer to <https://unlicense.org> */

namespace fcarouge::internal
{

//! @brief Function object for providing an identity matrix.
//!
//! @todo Could we remove this for a standard facility? Perhaps a form of
//! std::integral_constant?
//!
//! @note Could this function object template be a variable template as proposed
//! in paper P2008R0 entitled "Enabling variable template template parameters"?
struct identity_matrix {
//! @brief Returns `1`, the 1-by-1 identity matrix equivalent.
//!
//! @tparam Type The type template parameter of the value.
//!
//! @return The value `1`.
template <typename Type>
[[nodiscard]] inline constexpr auto operator()() const noexcept
{
return Type{ 1 };
}
};

template <typename State, typename Output, typename Input, typename Transpose,
typename Symmetrize, typename Divide, typename Identity,
typename UpdateArguments, typename PredictionArguments>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,30 @@ OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <https://unlicense.org> */

#ifndef FCAROUGE_INTERNAL_KALMAN_EIGEN_OPERATOR_HPP
#define FCAROUGE_INTERNAL_KALMAN_EIGEN_OPERATOR_HPP
#ifndef FCAROUGE_INTERNAL_KALMAN_EIGEN_HPP
#define FCAROUGE_INTERNAL_KALMAN_EIGEN_HPP

//! @file
//! @brief Kalman operation for Eigen 3 types.
//!
//! @details Default customization point objects (CPO) for Eigen 3 types.
//! @details Default customization point objects (CPO).

#include "kalman.hpp"

#include <Eigen/Eigen>

#include <concepts>
#include <cstddef>
#include <functional>
#include <type_traits>

namespace fcarouge::eigen::internal
{

//! @brief Arithmetic concept.
template <typename Type>
concept arithmetic = std::integral<Type> || std::floating_point<Type>;

//! @brief Function object for performing Eigen matrix transposition.
//!
//! @details Implemented with the Eigen linear algebra library matrices with
Expand All @@ -78,7 +86,7 @@ struct transpose {
//! @details Implemented with the Eigen linear algebra library matrices with
//! sizes fixed at compile-time.
struct symmetrize {
//! @brief Returns the symmetrised `value`.
//! @brief Returns the symmetrized `value`.
//!
//! @param value Value to compute the symmetry of.
//!
Expand All @@ -101,7 +109,7 @@ struct divide {
//! @param numerator The dividend matrix of the division. N: m x n
//! @param denominator The divisor matrix of the division. D: o x n
//!
//! @return The quotien matrix. Q: m x o
//! @return The quotient matrix. Q: m x o
//!
//! @exception May throw implementation-defined exceptions.
//!
Expand All @@ -119,18 +127,77 @@ struct divide {
.solve(numerator.transpose())
.transpose();
}

//! @brief Returns the quotient of `numerator` and `denominator`.
//!
//! @param numerator The dividend matrix of the division. N: m x 1
//! @param denominator The divisor value of the division.
//!
//! @return The quotient column vector. Q: m x 1
//!
//! @exception May throw implementation-defined exceptions.
//!
//! @todo Simplify implementation.
[[nodiscard]] inline constexpr auto
operator()(const auto &numerator, const arithmetic auto &denominator) const ->
typename Eigen::Vector<
typename std::decay_t<decltype(numerator)>::Scalar,
std::decay_t<decltype(numerator)>::RowsAtCompileTime>
{
return Eigen::Matrix<typename std::decay_t<decltype(numerator)>::Scalar, 1,
1>{ denominator }
.transpose()
.fullPivHouseholderQr()
.solve(numerator.transpose())
.transpose();
}

//! @brief Returns the quotient of `numerator` and `denominator`.
//!
//! @param numerator The dividend value of the division.
//! @param denominator The divisor matrix of the division. D: o x 1
//!
//! @return The quotient row vector. Q: 1 x o
//!
//! @exception May throw implementation-defined exceptions.
//!
//! @todo Simplify implementation.
[[nodiscard]] inline constexpr auto
operator()(const arithmetic auto &numerator, const auto &denominator) const ->
typename Eigen::RowVector<
typename std::decay_t<decltype(denominator)>::Scalar,
std::decay_t<decltype(denominator)>::RowsAtCompileTime>
{
return denominator.transpose()
.fullPivHouseholderQr()
.solve(Eigen::Matrix<typename std::decay_t<decltype(numerator)>::Scalar,
1, 1>{ numerator })
.transpose();
}

//! @brief Returns the quotient of `numerator` and `denominator`.
//!
//! @param numerator The dividend value of the division.
//! @param denominator The divisor value of the division.
//!
//! @return The quotient value.
[[nodiscard]] inline constexpr auto
operator()(const arithmetic auto &numerator,
const arithmetic auto &denominator) const
{
return numerator / denominator;
}
};

//! @brief Function object for providing an Eigen identity matrix.
//!
//! @details Implemented with the Eigen linear algebra library matrices with
//! sizes fixed at compile-time.
//!
//! @note Could this function object template be replaced by a variable
//! template? Proposed in paper P2008R0 entitled "Enabling variable template
//! template parameters".
struct identity {
//! @brief Returns the identity maxtrix.
//! @note Could this function object template be a variable template as proposed
//! in paper P2008R0 entitled "Enabling variable template template parameters"?
struct identity_matrix {
//! @brief Returns the identity matrix.
//!
//! @tparam Type The type template parameter of the matrix.
//!
Expand All @@ -142,8 +209,28 @@ struct identity {
{
return Type::Identity();
}

//! @brief Returns `1`, the 1-by-1 identity matrix equivalent.
//!
//! @tparam Type The type template parameter of the value.
//!
//! @return The value `1`.
template <arithmetic Type>
[[nodiscard]] inline constexpr auto operator()() const noexcept
{
return Type{ 1 };
}
};

template <typename Type = double, std::size_t State = 1, std::size_t Output = 1,
std::size_t Input = 1, typename UpdateArguments = std::tuple<>,
typename PredictionArguments = std::tuple<>>
using kalman = fcarouge::kalman<
Type, std::conditional_t<State == 1, Type, Eigen::Vector<Type, State>>,
std::conditional_t<Output == 1, Type, Eigen::Vector<Type, Output>>,
std::conditional_t<Input == 1, Type, Eigen::Vector<Type, Input>>, transpose,
symmetrize, divide, identity_matrix, UpdateArguments, PredictionArguments>;

} // namespace fcarouge::eigen::internal

#endif // FCAROUGE_INTERNAL_KALMAN_EIGEN_OPERATOR_HPP
#endif // FCAROUGE_INTERNAL_KALMAN_EIGEN_HPP
68 changes: 0 additions & 68 deletions include/fcarouge/internal/kalman_operator.hpp

This file was deleted.

34 changes: 22 additions & 12 deletions include/fcarouge/kalman.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ For more information, please refer to <https://unlicense.org> */
//! @brief The main Kalman filter class.

#include "internal/kalman.hpp"
#include "internal/kalman_operator.hpp"

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

namespace fcarouge
{
//! @brief Function object for providing an identity matrix.
using identity_matrix = internal::identity_matrix;

//! @brief Kalman filter.
//!
//! @details A Bayesian filter that uses multivariate Gaussians.
//! Applicable for unimodal and uncorrelated uncertainties. Kalman filters
//! assume white noise, propagation and measurement functions are
//! differentiable, and that the uncertainty stays centered on the state
//! estimate. The filter updates estimates by multiplying Gaussians and predicts
//! estimates by adding Gaussians. Design the state (x, P), the process (F, Q),
//! the measurement (z, R), the measurement function H, and if the system has
//! control inputs (u, B). Designing a filter is as much art as science.
//! estimates by adding Gaussians. Design the state (X, P), the process (F, Q),
//! the measurement (Z, R), the measurement function H, and if the system has
//! control inputs (U, B). Designing a filter is as much art as science.
//!
//! @tparam Type The type template parameter of the value type of the filter.
//! @tparam State The type template parameter of the state vector x. State
//! @tparam State The type template parameter of the state vector X. State
//! variables can be observed (measured), or hidden variables (inferred). This
//! is the the mean of the multivariate Gaussian.
//! @tparam Output The type template parameter of the measurement vector z.
//! @tparam Input The type template parameter of the control u.
//! @tparam Output The type template parameter of the measurement vector Z.
//! @tparam Input The type template parameter of the control U.
//! @tparam Transpose The customization point object template parameter of the
//! matrix transpose functor.
//! @tparam Symmetrize The customization point object template parameter of the
Expand All @@ -78,11 +80,18 @@ namespace fcarouge
//! matrix division functor.
//! @tparam Identity The customization point object template parameter of the
//! matrix identity functor.
//! @tparam UpdateArguments The variadic type template parameter for additional
//! update function parameters. Parameters such as delta times, variances, or
//! linearized values. The parameters are propagated to the function objects
//! used to compute the state observation H and the observation noise R
//! matrices. The parameters are also propagated to the state observation
//! function object h.
//! @tparam PredictionArguments The variadic type template parameter for
//! additional prediction function parameters. Time, or a delta thereof, is
//! often a prediction parameter. The parameters are propagated to the function
//! objects used to compute the process noise Q, the state transition F, and the
//! control transition G matrices.
//! additional prediction function parameters. Parameters such as delta times,
//! variances, or linearized values. The parameters are propagated to the
//! function objects used to compute the process noise Q, the state transition
//! F, and the control transition G matrices. The parameters are also propagated
//! to the state transition function object f.
//!
//! @note This class could be usable in constant expressions if `std::function`
//! could too. The polymorphic function wrapper was used in place of function
Expand Down Expand Up @@ -118,11 +127,12 @@ namespace fcarouge
//! characteristics?
//! @todo Consider additional constructors?
//! @todo Consider additional characteristics method overloads?
//! @todo Could we do away with std::tuple, replaced by a template template?
template <
typename Type = double, typename State = Type, typename Output = State,
typename Input = State, typename Transpose = std::identity,
typename Symmetrize = std::identity, typename Divide = std::divides<void>,
typename Identity = internal::identity,
typename Identity = identity_matrix,
typename UpdateArguments = std::tuple<>,
typename PredictionArguments = std::tuple<>>
class kalman
Expand Down
Loading

0 comments on commit a084598

Please sign in to comment.