From a259ef756a844d2c596345ca549b82cb36945e2a Mon Sep 17 00:00:00 2001 From: FrancoisCarouge Date: Mon, 30 Dec 2024 18:05:29 -0800 Subject: [PATCH] [eigen] add eigen backend indirection --- support/eigen/CMakeLists.txt | 10 +- support/eigen/fcarouge/eigen.hpp | 188 ++++++++++++++++++++++++++++++ support/eigen/fcarouge/linalg.hpp | 151 +----------------------- 3 files changed, 198 insertions(+), 151 deletions(-) create mode 100644 support/eigen/fcarouge/eigen.hpp diff --git a/support/eigen/CMakeLists.txt b/support/eigen/CMakeLists.txt index de3b01309..71c6fa8bb 100644 --- a/support/eigen/CMakeLists.txt +++ b/support/eigen/CMakeLists.txt @@ -47,6 +47,12 @@ FetchContent_MakeAvailable(eigen) add_library(kalman_linalg_eigen INTERFACE) target_sources( - kalman_linalg_eigen INTERFACE FILE_SET "linalg_headers" TYPE "HEADERS" FILES - "fcarouge/linalg.hpp") + kalman_linalg_eigen + INTERFACE FILE_SET + "linalg_headers" + TYPE + "HEADERS" + FILES + "fcarouge/eigen.hpp" + "fcarouge/linalg.hpp") target_link_libraries(kalman_linalg_eigen INTERFACE Eigen3::Eigen kalman) diff --git a/support/eigen/fcarouge/eigen.hpp b/support/eigen/fcarouge/eigen.hpp new file mode 100644 index 000000000..c500fa052 --- /dev/null +++ b/support/eigen/fcarouge/eigen.hpp @@ -0,0 +1,188 @@ +/* __ _ __ __ _ _ +| |/ / /\ | | | \/ | /\ | \ | | +| ' / / \ | | | \ / | / \ | \| | +| < / /\ \ | | | |\/| | / /\ \ | . ` | +| . \ / ____ \| |____| | | |/ ____ \| |\ | +|_|\_\/_/ \_\______|_| |_/_/ \_\_| \_| + +Kalman Filter +Version 0.4.0 +https://github.com/FrancoisCarouge/Kalman + +SPDX-License-Identifier: Unlicense + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to */ + +#ifndef FCAROUGE_EIGEN_HPP +#define FCAROUGE_EIGEN_HPP + +//! @file +//! @brief Linear algebra facade for Eigen3 third party implementation. +//! +//! @details Supporting matrix, vectors, and named algebraic values. +//! +//! @note The Eigen3 linear algebra is not constexpr-compatible as of July 2023. + +#include "fcarouge/utility.hpp" + +#include +#include + +#include + +namespace fcarouge::eigen { +//! @name Concepts +//! @{ + +//! @brief An Eigen3 algebraic concept. +template +concept is_eigen = requires { typename Type::PlainMatrix; }; + +//! @} + +//! @name Types +//! @{ + +//! @brief Compile-time sized Eigen3 matrix. +//! +//! @details Facade for Eigen3 implementation compatibility. +//! +//! @tparam Type The matrix element type. +//! @tparam Row The number of rows of the matrix. +//! @tparam Column The number of columns of the matrix. +template +using matrix = Eigen::Matrix; + +//! @brief Compile-time sized Eigen3 row vector. +template +using row_vector = Eigen::RowVector; + +//! @brief Compile-time sized Eigen3 column vector. +template +using column_vector = Eigen::Vector; + +//! @} + +} // namespace fcarouge::eigen + +namespace fcarouge { +//! @brief Specialization of the evaluation type. +template struct evaluater { + [[nodiscard]] inline constexpr auto operator()() const -> + typename Type::PlainMatrix; +}; + +//! @brief Specialization of the division type. +template struct divider { + [[nodiscard]] inline constexpr auto operator()(const Lhs &lhs, const Rhs &rhs) + const -> eigen::matrix; +}; +} // namespace fcarouge + +namespace Eigen { +//! @brief Eigen matrix solution to division. +//! +//! @details Argument-dependent lookup (ADL) used for type definition orgering +//! dependencies. This demonstrator uses a householder rank-revealing QR +//! decomposition of a matrix with full pivoting. Other applications could +//! select a different solver. +template +constexpr auto operator/(const Numerator &lhs, const Denominator &rhs) + -> fcarouge::divide { + return rhs.transpose() + .fullPivHouseholderQr() + .solve(lhs.transpose()) + .transpose(); +} +} // namespace Eigen + +//! @brief Specialization of the standard formatter for the Eigen matrix. +template +struct std::formatter, Char> { + constexpr auto parse(std::basic_format_parse_context &parse_context) { + return parse_context.begin(); + } + + template + constexpr auto + format(const fcarouge::eigen::matrix &value, + std::basic_format_context &format_context) const + -> OutputIterator { + const Eigen::IOFormat output_format{Eigen::StreamPrecision, + Eigen::DontAlignCols, + ", ", + ", ", + "[", + "]", + "", + "", + ' '}; + + return std::format_to( + format_context.out(), "[{}]", + (std::stringstream{} << value.format(output_format)).str()); + } + + template + constexpr auto + format(const fcarouge::eigen::matrix &value, + std::basic_format_context &format_context) const + -> OutputIterator + requires(fcarouge::eigen::matrix::RowsAtCompileTime == + 1 && + fcarouge::eigen::matrix::ColsAtCompileTime != 1) + { + const Eigen::IOFormat output_format{Eigen::StreamPrecision, + Eigen::DontAlignCols, + ", ", + ", ", + "[", + "]", + "", + "", + ' '}; + + return std::format_to( + format_context.out(), "{}", + (std::stringstream{} << value.format(output_format)).str()); + } + + template + constexpr auto + format(const fcarouge::eigen::matrix &value, + std::basic_format_context &format_context) const + -> OutputIterator + requires(fcarouge::eigen::matrix::RowsAtCompileTime == + 1 && + fcarouge::eigen::matrix::ColsAtCompileTime == 1) + { + return std::format_to(format_context.out(), "{}", value.value()); + } +}; + +#endif // FCAROUGE_EIGEN_HPP diff --git a/support/eigen/fcarouge/linalg.hpp b/support/eigen/fcarouge/linalg.hpp index ca492cedf..22b0545c0 100644 --- a/support/eigen/fcarouge/linalg.hpp +++ b/support/eigen/fcarouge/linalg.hpp @@ -39,157 +39,10 @@ For more information, please refer to */ #ifndef FCAROUGE_LINALG_HPP #define FCAROUGE_LINALG_HPP -//! @file -//! @brief Linear algebra facade for Eigen3 third party implementation. -//! -//! @details Supporting matrix, vectors, and named algebraic values. -//! -//! @note The Eigen3 linear algebra is not constexpr-compatible as of July 2023. - -#include "fcarouge/utility.hpp" - -#include -#include - -#include +#include "eigen.hpp" namespace fcarouge { -//! @name Concepts -//! @{ - -//! @brief An Eigen3 algebraic concept. -template -concept eigen = requires { typename Type::PlainMatrix; }; - -//! @} - -//! @name Types -//! @{ - -//! @brief Compile-time sized Eigen3 matrix. -//! -//! @details Facade for Eigen3 implementation compatibility. -//! -//! @tparam Type The matrix element type. -//! @tparam Row The number of rows of the matrix. -//! @tparam Column The number of columns of the matrix. -template -using matrix = Eigen::Matrix; - -//! @brief Compile-time sized Eigen3 row vector. -template -using row_vector = Eigen::RowVector; - -//! @brief Compile-time sized Eigen3 column vector. -template -using column_vector = Eigen::Vector; - -//! @brief Specialization of the evaluation type. -//! -//! @note Implementation not needed. -template struct evaluater { - [[nodiscard]] inline constexpr auto operator()() const -> - typename Type::PlainMatrix; -}; - -//! @} - -template struct divider { - [[nodiscard]] inline constexpr auto operator()(const Lhs &lhs, const Rhs &rhs) - const -> matrix; -}; - -//! @brief A possible solution to the matrix division. -//! -//! @see fcarouge::operator/ declaration. -//! -//! @details The householder rank-revealing QR decomposition of a matrix with -//! full pivoting implementation provides a very prudent pivoting to achieve -//! optimal numerical stability. -template struct divider { - [[nodiscard]] inline constexpr auto - operator()(const Lhs &lhs, const Rhs &rhs) const -> decltype(lhs / rhs); -}; +using namespace eigen; } // namespace fcarouge -namespace Eigen { -//! @brief Eigen matrix solution to division. -//! -//! @details Argument-dependent lookup (ADL) used for type definition orgering -//! dependencies. This demonstrator uses a householder rank-revealing QR -//! decomposition of a matrix with full pivoting. Other applications could -//! select a different solver. -template -constexpr auto operator/(const Numerator &lhs, const Denominator &rhs) - -> fcarouge::divide { - return rhs.transpose() - .fullPivHouseholderQr() - .solve(lhs.transpose()) - .transpose(); -} -} // namespace Eigen - -//! @brief Specialization of the standard formatter for the Eigen matrix. -template -struct std::formatter, Char> { - constexpr auto parse(std::basic_format_parse_context &parse_context) { - return parse_context.begin(); - } - - template - constexpr auto - format(const fcarouge::matrix &value, - std::basic_format_context &format_context) const - -> OutputIterator { - const Eigen::IOFormat output_format{Eigen::StreamPrecision, - Eigen::DontAlignCols, - ", ", - ", ", - "[", - "]", - "", - "", - ' '}; - - return std::format_to( - format_context.out(), "[{}]", - (std::stringstream{} << value.format(output_format)).str()); - } - - template - constexpr auto - format(const fcarouge::matrix &value, - std::basic_format_context &format_context) const - -> OutputIterator - requires(fcarouge::matrix::RowsAtCompileTime == 1 && - fcarouge::matrix::ColsAtCompileTime != 1) - { - const Eigen::IOFormat output_format{Eigen::StreamPrecision, - Eigen::DontAlignCols, - ", ", - ", ", - "[", - "]", - "", - "", - ' '}; - - return std::format_to( - format_context.out(), "{}", - (std::stringstream{} << value.format(output_format)).str()); - } - - template - constexpr auto - format(const fcarouge::matrix &value, - std::basic_format_context &format_context) const - -> OutputIterator - requires(fcarouge::matrix::RowsAtCompileTime == 1 && - fcarouge::matrix::ColsAtCompileTime == 1) - { - return std::format_to(format_context.out(), "{}", value.value()); - } -}; - #endif // FCAROUGE_LINALG_HPP