Skip to content

Commit

Permalink
[filter] array and span API
Browse files Browse the repository at this point in the history
  • Loading branch information
FrancoisCarouge committed Aug 7, 2022
1 parent 9c94afd commit a642bac
Show file tree
Hide file tree
Showing 8 changed files with 164 additions and 203 deletions.
140 changes: 40 additions & 100 deletions include/fcarouge/internal/eigen.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,23 @@ namespace fcarouge::eigen::internal
template <typename Type>
concept arithmetic = std::integral<Type> || std::floating_point<Type>;

[[nodiscard]] inline constexpr auto matrix(const auto &value)
{
return value;
}

[[nodiscard]] inline constexpr auto matrix(const arithmetic auto &value)
{
using type = std::decay_t<decltype(value)>;
return Eigen::Matrix<type, 1, 1>{ value };
}

template <typename Type, std::size_t Size>
[[nodiscard]] inline constexpr auto matrix(const std::array<Type, Size> &value)
{
return Eigen::Matrix<Type, Size, 1>{ value.data() };
}

//! @brief Function object for performing Eigen matrix transposition.
//!
//! @details Implemented with the Eigen linear algebra library matrices with
Expand All @@ -70,23 +87,19 @@ struct transpose {
//! @param value Value to compute the transpose of.
//!
//! @exception May throw implementation-defined exceptions.
[[nodiscard]] inline constexpr auto operator()(const auto &value) const
[[nodiscard]] inline constexpr auto operator()(const auto &value) const ->
typename Eigen::Matrix<typename std::decay_t<decltype(value)>::Scalar,
std::decay_t<decltype(value)>::ColsAtCompileTime,
std::decay_t<decltype(value)>::RowsAtCompileTime>
{
using type = std::decay_t<decltype(value)>;
using result_type =
typename Eigen::Matrix<typename type::Scalar, type::ColsAtCompileTime,
type::RowsAtCompileTime>;

return result_type{ value.transpose() };
return value.transpose();
}

//! @brief Returns the transpose of `value`.
//!
//! @param value Value to compute the transpose of.
//!
//! @todo Can this be optimized?
[[nodiscard]] inline constexpr auto
operator()(const arithmetic auto &value) const
operator()(const arithmetic auto &value) const noexcept -> const auto &
{
return value;
}
Expand All @@ -102,22 +115,20 @@ struct symmetrize {
//! @param value Value to compute the symmetry of.
//!
//! @exception May throw implementation-defined exceptions.
//!
//! @todo Should overflow be protected?
[[nodiscard]] inline constexpr auto operator()(const auto &value) const
{
using result_type = std::decay_t<decltype(value)>;

return result_type{ (value + value.transpose()) / 2 };
return (value + value.transpose()) / 2;
}

//! @brief Returns the symmetrized `value`.
//!
//! @param value Value to compute the symmetry of.
//!
//! @todo Can this be optimized?
[[nodiscard]] inline constexpr auto
operator()(const arithmetic auto &value) const
operator()(arithmetic auto &&value) const noexcept -> auto &&
{
return value;
return std::forward(value);
}
};

Expand All @@ -134,83 +145,17 @@ struct divide {
//! @return The quotient matrix. Q: m x o
//!
//! @exception May throw implementation-defined exceptions.
//!
//! @todo Why compilation fails if we specify the return type in the body of
//! the function?
template <typename Numerator, typename Denominator>
[[nodiscard]] inline constexpr auto
operator()(const Numerator &numerator, const Denominator &denominator) const
-> typename Eigen::Matrix<typename std::decay_t<Numerator>::Scalar,
std::decay_t<Numerator>::RowsAtCompileTime,
std::decay_t<Denominator>::RowsAtCompileTime>
{
return denominator.transpose()
.fullPivHouseholderQr()
.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.
template <typename Numerator>
[[nodiscard]] inline constexpr auto
operator()(const Numerator &numerator,
const arithmetic auto &denominator) const ->
typename Eigen::Vector<typename std::decay_t<Numerator>::Scalar,
std::decay_t<Numerator>::RowsAtCompileTime>
{
return Eigen::Matrix<typename std::decay_t<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.
template <typename Denominator>
[[nodiscard]] inline constexpr auto
operator()(const arithmetic auto &numerator,
const Denominator &denominator) const ->
typename Eigen::RowVector<typename std::decay_t<Denominator>::Scalar,
std::decay_t<Denominator>::RowsAtCompileTime>
{
return denominator.transpose()
.fullPivHouseholderQr()
.solve(Eigen::Matrix<typename std::decay_t<decltype(numerator)>::Scalar,
1, 1>{ numerator })
.transpose();
}
auto result{ matrix(denominator)
.transpose()
.fullPivHouseholderQr()
.solve(matrix(numerator).transpose())
.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;
return typename decltype(result)::PlainMatrix{ result };
}
};

Expand All @@ -230,7 +175,7 @@ struct identity_matrix {
//!
//! @exception May throw implementation-defined exceptions.
template <typename Type>
[[nodiscard]] inline constexpr auto operator()() const
[[nodiscard]] inline constexpr auto operator()() const -> Type
{
return Type::Identity();
}
Expand All @@ -241,9 +186,9 @@ struct identity_matrix {
//!
//! @return The value `1`.
template <arithmetic Type>
[[nodiscard]] inline constexpr auto operator()() const noexcept
[[nodiscard]] inline constexpr auto operator()() const noexcept -> Type
{
return Type{ 1 };
return 1;
}
};

Expand All @@ -254,14 +199,9 @@ template <typename Type = double, std::size_t State = 1, std::size_t Output = 1,
std::size_t Input = 1,
typename UpdateTypes = fcarouge::internal::empty_pack_t,
typename PredictionTypes = fcarouge::internal::empty_pack_t>
using kalman = fcarouge::kalman<
std::conditional_t<State == 1, Type, Eigen::Vector<Type, State>>,
std::conditional_t<Output == 1, Type, Eigen::Vector<Type, Output>>,
std::conditional_t<
Input == 0, void,
std::conditional_t<Input == 1, Type, Eigen::Vector<Type, Input>>>,
transpose, symmetrize, divide, identity_matrix, UpdateTypes,
PredictionTypes>;
using kalman =
fcarouge::kalman<Type, State, Output, Input, transpose, symmetrize, divide,
identity_matrix, UpdateTypes, PredictionTypes>;

} // namespace fcarouge::eigen::internal

Expand Down
18 changes: 10 additions & 8 deletions include/fcarouge/internal/format.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,19 @@ For more information, please refer to <https://unlicense.org> */

namespace fcarouge
{
template <typename State, typename Output, typename Input, typename Transpose,
typename Symmetrize, typename Divide, typename Identity,
typename UpdateTypes, typename PredictionTypes>
template <typename Type, std::size_t State, std::size_t Output,
std::size_t Input, typename Transpose, typename Symmetrize,
typename Divide, typename Identity, typename UpdateTypes,
typename PredictionTypes>
class kalman;
} // namespace fcarouge

template <typename State, typename Output, typename Input, typename Transpose,
typename Symmetrize, typename Divide, typename Identity,
typename UpdateTypes, typename PredictionTypes, typename Char>
template <typename Type, std::size_t State, std::size_t Output,
std::size_t Input, typename Transpose, typename Symmetrize,
typename Divide, typename Identity, typename UpdateTypes,
typename PredictionTypes, typename Char>
struct std::formatter<
fcarouge::kalman<State, Output, Input, Transpose, Symmetrize, Divide,
fcarouge::kalman<Type, State, Output, Input, Transpose, Symmetrize, Divide,
Identity, UpdateTypes, PredictionTypes>,
Char> {
//! @todo Support parsing arguments.
Expand All @@ -64,7 +66,7 @@ struct std::formatter<

// @todo How to support different nested types?
template <typename OutputIt>
auto format(const fcarouge::kalman<State, Output, Input, Transpose,
auto format(const fcarouge::kalman<Type, State, Output, Input, Transpose,
Symmetrize, Divide, Identity, UpdateTypes,
PredictionTypes> &filter,
std::basic_format_context<OutputIt, Char> &format_context)
Expand Down
Loading

0 comments on commit a642bac

Please sign in to comment.