Implements map and ref for both static & dynamic mode

See merge request oss/rotgen!12
This commit is contained in:
Joel Falcou 2025-08-13 17:43:57 +02:00
parent aacae1cbb1
commit 6c2b260229
58 changed files with 4121 additions and 1205 deletions

40
include/rotgen/alias.hpp Normal file
View file

@ -0,0 +1,40 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
namespace rotgen
{
// matrix aliases (float and double, fixed and dynamic)
using matrix2f = rotgen::matrix<float, 2, 2>;
using matrix3f = rotgen::matrix<float, 3, 3>;
using matrix4f = rotgen::matrix<float, 4, 4>;
using matrix2d = rotgen::matrix<double, 2, 2>;
using matrix3d = rotgen::matrix<double, 3, 3>;
using matrix4d = rotgen::matrix<double, 4, 4>;
using matrixXf = rotgen::matrix<float, rotgen::Dynamic, rotgen::Dynamic>;
using matrixXd = rotgen::matrix<double, rotgen::Dynamic, rotgen::Dynamic>;
using matrixXi = rotgen::matrix<int, rotgen::Dynamic, rotgen::Dynamic>;
// Column vector aliases
using vector2f = rotgen::matrix<float, 2, 1>;
using vector3f = rotgen::matrix<float, 3, 1>;
using vector4f = rotgen::matrix<float, 4, 1>;
using vector2d = rotgen::matrix<double, 2, 1>;
using vector3d = rotgen::matrix<double, 3, 1>;
using vector4d = rotgen::matrix<double, 4, 1>;
using vectorXf = rotgen::matrix<float, rotgen::Dynamic, 1>;
using vectorXd = rotgen::matrix<double, rotgen::Dynamic, 1>;
// Row vector aliases
using row_vector2f = rotgen::matrix<float, 1, 2>;
using row_vector3f = rotgen::matrix<float, 1, 3>;
using row_vector4f = rotgen::matrix<float, 1, 4>;
using row_vector2d = rotgen::matrix<double, 1, 2>;
using row_vector3d = rotgen::matrix<double, 1, 3>;
using row_vector4d = rotgen::matrix<double, 1, 4>;
using row_vectorXf = rotgen::matrix<float, 1, rotgen::Dynamic>;
using row_vectorXd = rotgen::matrix<double, 1, rotgen::Dynamic>;
}

View file

@ -0,0 +1,284 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once
#include <type_traits>
#include <cassert>
#if !defined(ROTGEN_FORCE_DYNAMIC)
#include <Eigen/Dense>
#endif
namespace rotgen
{
// Primary template: mutable ref
template<typename T, int Options = T::storage_order>
class ref : private map<T, Options>
{
public:
using parent = map<T, Options>;
using value_type = typename T::value_type;
using rotgen_tag = void;
using parent::operator();
using parent::rows;
using parent::cols;
using parent::size;
using parent::data;
using parent::sum;
using parent::prod;
using parent::mean;
using parent::trace;
using parent::maxCoeff;
using parent::minCoeff;
using parent::norm;
using parent::squaredNorm;
using parent::lpNorm;
using parent::operator+=;
using parent::operator-=;
using parent::operator*=;
using parent::operator/=;
using parent::Zero;
using parent::Constant;
using parent::Random;
using parent::Identity;
using parent::operator=;
using stride_type = typename parent::stride_type;
parent const& base() const { return static_cast<parent const&>(*this); }
parent& base() { return static_cast<parent&>(*this); }
template<std::same_as<value_type> S, int R, int C, int O, int MR, int MC>
ref(matrix<S, R, C, O, MR, MC>& m)
: parent(m.data(), m.rows(), m.cols(), strides(m))
{
static_assert((O & 1) == Options, "ref: Incompatible storage layout");
}
template<typename Ref, int R, int C, bool I, int FS>
ref(block<Ref,R,C,I,FS>& b) : parent(b.data(), b.rows(), b.cols(), stride_type{b.outerStride(),b.innerStride()})
{
static_assert((Ref::Options & 1) == Options, "ref: Incompatible storage layout");
}
template<typename Ref, int O, typename S>
ref(map<Ref,O,S>& b) : parent(b.data(), b.rows(), b.cols(), stride_type{b.outerStride(),b.innerStride()})
{
static_assert((Ref::Options & 1) == Options, "ref: Incompatible storage layout");
}
// #if !defined(ROTGEN_FORCE_DYNAMIC)
// template<typename OtherDerived>
// ref(const Eigen::MatrixBase<OtherDerived>& b)
// : parent(b.data(), b.rows(), b.cols()/*, stride_type{b.outerStride(),b.innerStride()}*/)
// {
// using Str = typename parent::stride_type;
// std::cerr << "Stride compile-time: Outer=" << Str::OuterStrideAtCompileTime
// << " Inner=" << Str::InnerStrideAtCompileTime <<std::endl;
// std::cerr << "runtime: outer=" << b.outerStride() << " inner=" << b.innerStride() << std::endl;
// }
// #endif
ref(parent& m) : parent(m.data(), m.rows(), m.cols()) {}
friend std::ostream& operator<<(std::ostream& os, ref const& r)
{
return os << r.base() << "\n";
}
};
// Specialization for const matrix type
template<typename T, int Options>
class ref<const T, Options> : private map<const T, Options>
{
public:
using parent = map<const T, Options>;
using value_type = typename T::value_type;
using rotgen_tag = void;
using parent::operator();
using parent::rows;
using parent::cols;
using parent::size;
using parent::data;
using parent::sum;
using parent::prod;
using parent::mean;
using parent::trace;
using parent::maxCoeff;
using parent::minCoeff;
using parent::norm;
using parent::squaredNorm;
using parent::lpNorm;
using parent::operator+=;
using parent::operator-=;
using parent::operator*=;
using parent::operator/=;
using parent::Zero;
using parent::Constant;
using parent::Random;
using parent::Identity;
using parent::operator=;
using stride_type = typename parent::stride_type;
static constexpr bool has_static_storage = parent::has_static_storage;
parent const& base() const { return static_cast<parent const&>(*this); }
template<std::same_as<value_type> S, int R, int C, int O, int MR, int MC>
ref(matrix<S, R, C, O, MR, MC> const& m)
: parent(m.data(), m.rows(), m.cols(), strides(m))
{
static_assert((O & 1) == Options, "ref: Incompatible storage layout");
}
template<typename Ref, int R, int C, bool I, int FS>
ref(block<Ref,R,C,I,FS> const& b) : parent(b.data(), b.rows(), b.cols(), stride_type{b.outerStride(),b.innerStride()})
{
static_assert((Ref::Options & 1) == Options, "ref: Incompatible storage layout");
}
template<typename Ref, int O, typename S>
ref(map<Ref,O,S> const& b) : parent(b.data(), b.rows(), b.cols(), stride_type{b.outerStride(),b.innerStride()})
{
static_assert((Ref::Options & 1) == Options, "ref: Incompatible storage layout");
}
// #if !defined(ROTGEN_FORCE_DYNAMIC)
// template<typename OtherDerived>
// ref(const Eigen::MatrixBase<OtherDerived>& b)
// : parent(b.data(), b.rows(), b.cols())//, stride_type{b.outerStride(),b.innerStride()})
// {
// using Str = typename parent::stride_type;
// std::cerr << "Stride compile-time: Outer=" << Str::OuterStrideAtCompileTime
// << " Inner=" << Str::InnerStrideAtCompileTime <<std::endl;
// std::cerr << "runtime: outer=" << b.outerStride() << " inner=" << b.innerStride() << std::endl;
// }
// #endif
ref(parent const& m) : parent(m.data(), m.rows(), m.cols()) {}
// // From raw const buffer
// ref(value_type const* ptr, int r, int c) : parent(ptr, r, c) {}
friend std::ostream& operator<<(std::ostream& os, ref const& r)
{
return os << r.base() << "\n";
}
};
template<typename S, int R, int C, int O, int MR, int MC>
ref(matrix<S, R, C, O, MR, MC>&) -> ref<matrix<S>>;
template<typename Ref, int R, int C, bool I, int FS>
ref(block<Ref,R,C,I,FS>& b) -> ref<Ref>;
template<typename S, int R, int C, int O, int MR, int MC>
ref(matrix<S, R, C, O, MR, MC> const&) -> ref<matrix<S> const>;
template<typename Ref, int R, int C, bool I, int FS>
ref(block<Ref,R,C,I,FS> const& b) -> ref<Ref const>;
template<typename A, typename B>
bool operator==(ref<A> lhs, ref<B> rhs)
{
return lhs.base() == rhs.base();
}
template<typename A, typename B>
bool operator!=(ref<A> lhs, ref<B> rhs)
{
return lhs.base() != rhs.base();
}
template<typename A, typename B>
auto operator+(ref<A> lhs, ref<B> rhs) -> decltype(lhs.base() + rhs.base())
{
return lhs.base() + rhs.base();
}
template<typename A, typename B>
auto operator-(ref<A> lhs, ref<B> rhs)
{
return lhs.base() - rhs.base();
}
template<typename A, typename B>
auto operator*(ref<A> lhs, ref<B> rhs)
{
return lhs.base() * rhs.base();
}
template<typename A>
auto operator*(ref<A> lhs, std::convertible_to<typename A::value_type> auto s)
{
return lhs.base() * s;
}
template<typename A>
auto operator*(std::convertible_to<typename A::value_type> auto s, ref<A> rhs)
{
return s * rhs.base();
}
template<typename A>
auto operator/(ref<A> lhs, std::convertible_to<typename A::value_type> auto s)
{
return lhs.base() / s;
}
template<typename T> struct generalize;
template<typename T>
requires(std::is_arithmetic_v<std::remove_cvref_t<T>>)
struct generalize<T>
{
using type = std::remove_cvref_t<T>;
};
template<typename T>
using generalize_t = typename generalize<T>::type;
template<concepts::entity T> struct generalize<T>
{
static constexpr bool is_const = std::is_const_v<T>;
using base = matrix<typename T::value_type,Dynamic,Dynamic,T::storage_order>;
using type = std::conditional_t<is_const,ref<base const>, ref<base>>;
};
template<concepts::entity T>
typename T::parent const& base_of(T const& a)
{
return a.base();
}
template<typename T>
T base_of(T a) requires(std::is_arithmetic_v<T>)
{
return a;
}
#if !defined(ROTGEN_FORCE_DYNAMIC)
template<concepts::eigen_compatible T> struct generalize<T>
{
static constexpr bool is_const = std::is_const_v<T>;
using concrete_type = decltype(std::declval<T>().eval());
using base = matrix<typename T::Scalar,Dynamic,Dynamic,concrete_type::Options&1>;
using type = std::conditional_t<is_const,ref<base const>, ref<base>>;
};
template<concepts::eigen_compatible T>
T const& base_of(T const& a)
{
return a;
}
#endif
}

View file

@ -0,0 +1,37 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once
#include <rotgen/detail/static_info.hpp>
#include <rotgen/concepts.hpp>
#if !defined(ROTGEN_FORCE_DYNAMIC)
#include <Eigen/Dense>
#endif
namespace rotgen
{
#if !defined(ROTGEN_FORCE_DYNAMIC)
using stride = Eigen::Stride<-1,-1>;
#else
struct stride { Index outer, inner; };
#endif
template<int Order>
stride strides(Index r, Index c)
{
if constexpr (Order == RowMajor) return {c,1};
else return {r,1};
}
template<concepts::entity E>
auto strides(const E& e)
{
return strides<E::storage_order>(e.rows(), e.cols());
}
}

View file

@ -0,0 +1,28 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once
namespace rotgen
{
template< typename EigenType
, template<typename,int,int,int,int,int> typename Wrapper
>
struct as_concrete
{
using type = Wrapper< typename EigenType::value_type
, EigenType::RowsAtCompileTime, EigenType::ColsAtCompileTime
, EigenType::Flags & 1
, EigenType::MaxRowsAtCompileTime, EigenType::MaxColsAtCompileTime
>;
};
template<typename EigenType
, template<typename,int,int,int,int,int> typename Wrapper
>
using as_concrete_t = typename as_concrete<std::remove_cvref_t<EigenType>,Wrapper>::type;
}

View file

@ -9,10 +9,29 @@
namespace rotgen::concepts
{
//================================================================================================
//! @brief Check if a type is a ROTGEN type.
//================================================================================================
template<typename T>
concept entity = requires(T const&)
{
typename T::rotgen_tag;
typename T::parent;
};
//================================================================================================
//! @brief Check if a type is an EIGEN type.
//================================================================================================
template<typename T>
concept eigen_compatible = requires(T const& a)
{
typename T::Scalar;
{ T::RowsAtCompileTime } -> std::convertible_to<int>;
{ T::ColsAtCompileTime } -> std::convertible_to<int>;
{ T::MaxRowsAtCompileTime } -> std::convertible_to<int>;
{ T::MaxColsAtCompileTime } -> std::convertible_to<int>;
{ a.eval() };
};
}

View file

@ -8,15 +8,15 @@
#pragma once
#include <cstddef>
#include <iosfwd>
#include <iostream>
namespace rotgen
{
using Index = std::ptrdiff_t;
}
#if defined(ROTGEN_DISABLE_EXPRESSION_TEMPLATES)
#define ROTGEN_MAX_SIZE 0
#if !defined(ROTGEN_MAX_SIZE) && defined(ROTGEN_ENABLE_EXPRESSION_TEMPLATES)
#define ROTGEN_MAX_SIZE 0
#endif
#if !defined(ROTGEN_FORCE_DYNAMIC)
@ -33,10 +33,19 @@ namespace rotgen
namespace rotgen
{
#if defined(ROTGEN_ENABLE_EXPRESSION_TEMPLATES)
inline constexpr bool use_expression_templates = true;
#else
inline constexpr bool use_expression_templates = false;
#endif
inline constexpr bool has_static_limit = ROTGEN_HAS_STATIC_LIMIT;
inline constexpr bool is_forcing_dynamic_status = !has_static_limit;
std::ostream& setup_summary(std::ostream& os);
namespace detail
{
std::ostream& dynamic_info(std::ostream& os);
}
}
#if defined(ROTGEN_FORCE_DYNAMIC)
@ -51,12 +60,37 @@ namespace rotgen
namespace rotgen
{
inline constexpr Index max_static_size = ROTGEN_MAX_SIZE;
template<int Rows, int Cols>
inline constexpr bool storage_status = (Rows > 0 && Cols > 0) && ((Rows*Cols) <= max_static_size);
template<int Rows, int Cols, int MaxRows, int MaxCols>
inline constexpr bool storage_status =
[]()
{
// Actual static size
if(Rows > 0 && Cols > 0) return (Rows*Cols) <= max_static_size;
// Dynamic size but static Max Size
else if(MaxRows > 0 && MaxCols > 0) return (MaxRows*MaxCols) <= max_static_size;
// Everything dynamic already
else return false;
}();
}
#endif
namespace rotgen
{
inline constexpr bool use_expression_templates = max_static_size > 0;
}
inline std::ostream& setup_summary(std::ostream& os)
{
detail::dynamic_info(os);
if(!is_forcing_dynamic_status)
{
if constexpr(use_expression_templates)
os << "[ROTGEN] - Expression templates : Enabled." << std::endl;
else
os << "[ROTGEN] - Expression templates : Disabled." << std::endl;
if constexpr(rotgen::max_static_size)
os << "[ROTGEN] - Static/Dynamic mode with maximum size: " << rotgen::max_static_size << std::endl;
}
return os;
}
}

View file

@ -23,14 +23,30 @@ namespace rotgen
, "[ROTGEN][CRITICAL] - Block of non-rotgen type instanciated"
);
using parent = find_block<Ref>;
using parent = find_block<Ref>;
using rotgen_tag = void;
using scalar_type = typename Ref::scalar_type;
using value_type = typename Ref::value_type;
static constexpr int storage_order = (ForceStorageOrder == -1) ? Ref::storage_order : ForceStorageOrder;
using concrete_type = matrix<scalar_type,Rows,Cols,storage_order>;
using concrete_type = matrix<value_type,Rows,Cols,storage_order>;
using concrete_dynamic_type = matrix<value_type,Dynamic,Dynamic,storage_order>;
static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols;
static constexpr int Options = Ref::Options;
static constexpr bool is_defined_static = false;
static constexpr bool has_static_storage = false;
using parent::operator=;
block& operator=(concepts::entity auto const& other)
{
assert(parent::rows() == other.rows() && parent::cols() == other.cols());
for (rotgen::Index r = 0; r < parent::rows(); ++r)
for (rotgen::Index c = 0; c < parent::cols(); ++c)
(*this)(r, c) = other(r, c);
return *this;
}
block(Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj) : parent(r,i0,j0,ni,nj)
{}
@ -41,6 +57,30 @@ namespace rotgen
block(parent const& base) : parent(base) {}
bool is_contiguous_linear() const
{
if(parent::innerStride() != 1) return false;
// outerstride must equal the “innerdimension length”
if constexpr(storage_order) return parent::outerStride() == parent::cols();
else return parent::outerStride() == parent::rows();
}
value_type& operator()(Index i, Index j) { return parent::operator()(i,j); }
value_type& operator()(Index i)
{
assert(is_contiguous_linear());
return parent::operator()(i);
}
value_type operator()(Index i, Index j) const { return parent::operator()(i,j); }
value_type operator()(Index i) const
{
assert(is_contiguous_linear());
return parent::operator()(i);
}
concrete_type transpose() const
{
return concrete_type(static_cast<parent const &>(*this).transpose());
@ -67,13 +107,13 @@ namespace rotgen
block& operator+=(block const& rhs)
{
static_cast<parent&>(*this) += static_cast<parent const&>(rhs);
base() += static_cast<parent const&>(rhs);
return *this;
}
block& operator-=(block const& rhs)
{
static_cast<parent&>(*this) -= static_cast<parent const&>(rhs);
base() -= static_cast<parent const&>(rhs);
return *this;
}
@ -82,46 +122,21 @@ namespace rotgen
return concrete_type(static_cast<parent const&>(*this).operator-());
}
concrete_type matrix_addition(block const& rhs) const
{
return concrete_type(static_cast<parent const&>(*this).matrix_addition(rhs));
}
concrete_type matrix_subtraction(block const& rhs) const
{
return concrete_type(static_cast<parent const&>(*this).matrix_subtraction(rhs));
}
concrete_type matrix_multiplication(block const& rhs) const
{
return concrete_type(static_cast<parent const&>(*this).matrix_multiplication(rhs));
}
concrete_type matrix_multiplication(scalar_type rhs) const
{
return concrete_type(static_cast<parent const&>(*this).matrix_multiplication(rhs));
}
concrete_type matrix_division(scalar_type rhs) const
{
return concrete_type(static_cast<parent const&>(*this).matrix_division(rhs));
}
block& operator*=(block const& rhs)
{
static_cast<parent&>(*this) *= static_cast<parent const&>(rhs);
base() *= static_cast<parent const&>(rhs);
return *this;
}
block& operator*=(scalar_type rhs)
block& operator*=(value_type rhs)
{
static_cast<parent&>(*this) *= rhs;
base() *= rhs;
return *this;
}
block& operator/=(scalar_type rhs)
block& operator/=(value_type rhs)
{
static_cast<parent&>(*this) /= rhs;
base() /= rhs;
return *this;
}
@ -138,13 +153,26 @@ namespace rotgen
return parent::Zero(rows, cols);
}
static concrete_type Constant(scalar_type value)
static concrete_type Ones()
requires (Rows != -1 && Cols != -1)
{
return parent::Ones(Rows, Cols);
}
static concrete_type Ones(int rows, int cols)
{
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
return parent::Ones(rows, cols);
}
static concrete_type Constant(value_type value)
requires (Rows != -1 && Cols != -1)
{
return parent::Constant(Rows, Cols, static_cast<double>(value));
}
static concrete_type Constant(int rows, int cols, scalar_type value)
static concrete_type Constant(int rows, int cols, value_type value)
{
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
@ -177,47 +205,86 @@ namespace rotgen
return parent::Identity(rows, cols);
}
block& setOnes()
{
parent::assign(parent::Ones(parent::rows(), parent::cols()));
return *this;
}
block& setZero()
{
parent::assign(parent::Zero(parent::rows(), parent::cols()));
return *this;
}
block& setConstant(value_type value)
{
parent::assign(parent::Constant(parent::rows(), parent::cols(), value));
return *this;
}
block& setRandom()
{
parent::assign(parent::Random(parent::rows(), parent::cols()));
return *this;
}
block& setIdentity()
{
parent::assign(parent::Identity(parent::rows(), parent::cols()));
return *this;
}
template<int P>
double lpNorm() const
{
assert(P == 1 || P == 2 || P == Infinity);
return parent::lpNorm(P);
}
parent& base() { return static_cast<parent&>(*this); }
parent const& base() const { return static_cast<parent const&>(*this); }
};
template<typename Ref, int R, int C, bool I, int F>
typename block<Ref, R, C, I, F>::concrete_type operator+(block<Ref, R, C, I, F> const& lhs, block<Ref, R, C, I, F> const& rhs)
auto operator+(block<Ref, R, C, I, F> const& lhs, block<Ref, R, C, I, F> const& rhs)
{
return lhs.matrix_addition(rhs);
using concrete_type = typename block<Ref, R, C, I, F>::concrete_type;
return concrete_type(lhs.base().add(rhs));
}
template<typename Ref, int R, int C, bool I, int F>
typename block<Ref, R, C, I, F>::concrete_type operator-(block<Ref, R, C, I, F> const& lhs, block<Ref, R, C, I, F> const& rhs)
auto operator-(block<Ref, R, C, I, F> const& lhs, block<Ref, R, C, I, F> const& rhs)
{
return lhs.matrix_subtraction(rhs);
using concrete_type = typename block<Ref, R, C, I, F>::concrete_type;
return concrete_type(lhs.base().sub(rhs));
}
template<typename Ref, int R, int C, bool I, int F>
typename block<Ref, R, C, I, F>::concrete_type operator*(block<Ref, R, C, I, F> const& lhs, block<Ref, R, C, I, F> const& rhs)
auto operator*(block<Ref, R, C, I, F> const& lhs, block<Ref, R, C, I, F> const& rhs)
{
return lhs.matrix_multiplication(rhs);
using concrete_type = typename block<Ref, R, C, I, F>::concrete_type;
return concrete_type(lhs.base().mul(rhs));
}
template<typename Ref, int R, int C, bool I, int F>
typename block<Ref, R, C, I, F>::concrete_type operator*(block<Ref, R, C, I, F> const& lhs, double rhs)
auto operator*(block<Ref, R, C, I, F> const& lhs, double rhs)
{
return lhs.matrix_multiplication(rhs);
using concrete_type = typename block<Ref, R, C, I, F>::concrete_type;
return concrete_type(lhs.base().mul(rhs));
}
template<typename Ref, int R, int C, bool I, int F>
typename block<Ref, R, C, I, F>::concrete_type operator*(double lhs, block<Ref, R, C, I, F> const& rhs)
auto operator*(double lhs, block<Ref, R, C, I, F> const& rhs)
{
return rhs.matrix_multiplication(lhs);
using concrete_type = typename block<Ref, R, C, I, F>::concrete_type;
return concrete_type(rhs.base().mul(lhs));
}
template<typename Ref, int R, int C, bool I, int F>
typename block<Ref, R, C, I, F>::concrete_type operator/(block<Ref, R, C, I, F> const& lhs, double rhs)
auto operator/(block<Ref, R, C, I, F> const& lhs, double rhs)
{
return lhs.matrix_division(rhs);
using concrete_type = typename block<Ref, R, C, I, F>::concrete_type;
return concrete_type(lhs.base().div(rhs));
}
}

View file

@ -0,0 +1,280 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once
#include <rotgen/concepts.hpp>
#include <rotgen/impl/map.hpp>
#include <cassert>
namespace rotgen
{
template<typename Ref, int Options = ColMajor, typename = void>
class map : public find_map<Ref>
{
public:
static_assert ( concepts::entity<Ref>
, "[ROTGEN][CRITICAL] - Map of non-rotgen type instanciated"
);
using parent = find_map<Ref>;
using rotgen_tag = void;
using value_type = typename std::remove_const_t<Ref>::value_type;
using concrete_type = typename std::remove_const_t<Ref>::concrete_type;
static constexpr int storage_order = Ref::storage_order;
static constexpr bool has_static_storage = false;
static constexpr bool is_immutable = std::is_const_v<Ref>;
static constexpr bool is_defined_static = false;
using ptr_type = std::conditional_t<is_immutable, value_type const*, value_type*>;
using stride_type = stride;
static constexpr Index RowsAtCompileTime = Ref::RowsAtCompileTime;
static constexpr Index ColsAtCompileTime = Ref::ColsAtCompileTime;
map(ptr_type ptr, Index r, Index c, stride_type s) : parent(ptr, r, c,s) {}
map(ptr_type ptr, Index r, Index c) : map(ptr, r, c, strides<storage_order>(r,c)) {}
map(ptr_type ptr, stride_type s) requires(RowsAtCompileTime!=-1 && ColsAtCompileTime!=-1)
: parent(ptr,RowsAtCompileTime,ColsAtCompileTime, s)
{}
map(ptr_type ptr, Index size) requires(RowsAtCompileTime==1 || ColsAtCompileTime==1)
: map( ptr, RowsAtCompileTime==1?1:size, ColsAtCompileTime==1?1:size)
{}
map(ptr_type ptr) requires(RowsAtCompileTime!=-1 && ColsAtCompileTime!=-1)
: map( ptr, RowsAtCompileTime, ColsAtCompileTime )
{}
template<typename R2, int O2, typename S2>
map(map<R2,O2,S2> const& other) : map ( other.data(), other.rows(), other.cols()
, stride{other.outerStride(),other.innerStride()}
)
{}
map(parent const& base) : parent(base) {}
map(map const& other) : parent(other)
{}
map& operator=(map const& other) requires(!is_immutable)
{
base() = static_cast<parent const &>(*other);
return *this;
}
value_type& operator()(Index i, Index j) requires(!is_immutable) { return parent::operator()(i,j); }
value_type& operator()(Index i) requires(!is_immutable)
{
assert( parent::innerStride() == 1
&& parent::outerStride() ==(storage_order == RowMajor ? parent::cols() : parent::rows())
);
return parent::operator()(i);
}
value_type operator()(Index i, Index j) const { return parent::operator()(i,j); }
value_type operator()(Index i) const
{
assert( parent::innerStride() == 1
&& parent::outerStride() ==(storage_order == RowMajor ? parent::cols() : parent::rows())
);
return parent::operator()(i);
}
concrete_type transpose() const
{
return concrete_type(static_cast<parent const &>(*this).transpose());
}
concrete_type conjugate() const
{
return concrete_type(static_cast<parent const &>(*this).conjugate());
}
concrete_type adjoint() const
{
return concrete_type(static_cast<parent const &>(*this).adjoint());
}
void transposeInPlace() requires(!is_immutable) { parent::transposeInPlace(); }
void adjointInPlace() requires(!is_immutable) { parent::adjointInPlace(); }
map& operator+=(map const& rhs) requires(!is_immutable)
{
base() += static_cast<parent const&>(rhs);
return *this;
}
map& operator-=(map const& rhs) requires(!is_immutable)
{
base() -= static_cast<parent const&>(rhs);
return *this;
}
concrete_type operator-() const
{
return concrete_type(base().operator-());
}
map& operator*=(map const& rhs) requires(!is_immutable)
{
base() *= static_cast<parent const&>(rhs);
return *this;
}
map& operator*=(value_type rhs) requires(!is_immutable)
{
base() *= rhs;
return *this;
}
map& operator/=(value_type rhs) requires(!is_immutable)
{
base() /= rhs;
return *this;
}
static auto Zero() requires( requires {Ref::Zero();} )
{
return Ref::Zero();
}
static auto Zero(int rows, int cols)
{
return Ref::Zero(rows,cols);
}
static auto Constant(value_type value) requires( requires {Ref::Constant(value);} )
{
return Ref::Constant(value);
}
static auto Constant(int rows, int cols, value_type value)
{
return Ref::Constant(rows, cols, value);
}
static auto Random() requires( requires {Ref::Random();} )
{
return Ref::Random();
}
static auto Random(int rows, int cols)
{
return Ref::Random(rows, cols);
}
static auto Identity() requires( requires {Ref::Identity();} )
{
return Ref::Identity();
}
static auto Identity(int rows, int cols)
{
return Ref::Identity(rows, cols);
}
map& setZero() requires(!is_immutable)
{
parent::setZero();
return *this;
}
map& setOnes() requires(!is_immutable)
{
parent::setOnes();
return *this;
}
map& setIdentity() requires(!is_immutable)
{
parent::setIdentity();
return *this;
}
map& setRandom() requires(!is_immutable)
{
parent::setRandom();
return *this;
}
map& setConstant(value_type s) requires(!is_immutable)
{
parent::setConstant(s);
return *this;
}
template<int P>
double lpNorm() const
{
assert(P == 1 || P == 2 || P == Infinity);
return parent::lpNorm(P);
}
parent& base() { return static_cast<parent&>(*this); }
parent const& base() const { return static_cast<parent const&>(*this); }
};
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
typename map<R1,O1,S1>::concrete_type operator+(map<R1,O1,S1> const& lhs, map<R2,O2,S2> const& rhs)
{
using concrete_type = typename map<R1,O1,S1>::concrete_type;
return concrete_type(lhs.base().add(map<R1,O1,S1>(rhs)));
}
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
typename map<R1,O1,S1>::concrete_type operator-(map<R1,O1,S1> const& lhs, map<R2,O2,S2> const& rhs)
{
using concrete_type = typename map<R1,O1,S1>::concrete_type;
return concrete_type(lhs.base().sub(map<R1,O1,S1>(rhs)));
}
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
typename map<R1,O1,S1>::concrete_type operator*(map<R1,O1,S1> const& lhs, map<R2,O2,S2> const& rhs)
{
using concrete_type = typename map<R1,O1,S1>::concrete_type;
return concrete_type(lhs.base().mul(map<R1,O1,S1>(rhs)));
}
template<typename R, int O, typename S>
typename map<R,O,S>::concrete_type
operator*(map<R,O,S> const& lhs, std::convertible_to<typename R::value_type> auto s)
{
using concrete_type = typename map<R,O,S>::concrete_type;
return concrete_type(lhs.base().mul(s));
}
template<typename R, int O, typename S>
typename map<R,O,S>::concrete_type
operator*(std::convertible_to<typename R::value_type> auto s, map<R,O,S> const& rhs)
{
using concrete_type = typename map<R,O,S>::concrete_type;
return concrete_type(rhs.base().mul(s));
}
template<typename R, int O, typename S>
typename map<R,O,S>::concrete_type
operator/(map<R,O,S> const& lhs, std::convertible_to<typename R::value_type> auto s)
{
using concrete_type = typename map<R,O,S>::concrete_type;
return concrete_type(lhs.base().div(s));
}
template<typename R1, int O1, typename S1, typename R2, int O2, typename S2>
bool operator==(map<R1,O1,S1> const& lhs, map<R2,O2,S2> const& rhs)
{
return lhs.base() == rhs.base();
}
template<typename R1, int O1, typename S1, typename R2, int O2, typename S2>
bool operator!=(map<R1,O1,S1> const& lhs, map<R2,O2,S2> const& rhs)
{
return lhs.base() != rhs.base();
}
}

View file

@ -15,20 +15,23 @@ namespace rotgen
{
template< typename Scalar
, int Rows = Dynamic , int Cols = Dynamic
, int Options = ColMajor
, int Opts = ColMajor
, int MaxRows = Rows , int MaxCols = Cols
>
class matrix : public find_matrix<Scalar,Options>
class matrix : public find_matrix<Scalar,Opts>
{
public:
using parent = find_matrix<Scalar,Options>;
using parent = find_matrix<Scalar,Opts>;
using rotgen_tag = void;
using concrete_type = matrix;
using scalar_type = Scalar;
static constexpr auto storage_order = Options & 1;
using value_type = Scalar;
static constexpr auto storage_order = Opts & 1;
static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols;
static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols;
static constexpr int Options = Opts;
static constexpr bool is_defined_static = false;
static constexpr bool has_static_storage = false;
matrix() : parent(Rows==-1?0:Rows,Cols==-1?0:Cols) {}
@ -57,6 +60,15 @@ namespace rotgen
: parent(Rows, Cols, {s0,static_cast<Scalar>(init)...})
{}
matrix(concepts::entity auto const& e) : parent(e.rows(),e.cols())
{
if constexpr(Rows != -1) assert(e.rows() == Rows && "Mismatched between dynamic and static row size");
if constexpr(Cols != -1) assert(e.cols() == Cols && "Mismatched between dynamic and static col size");
for (rotgen::Index r = 0; r < e.rows(); ++r)
for (rotgen::Index c = 0; c < e.cols(); ++c)
(*this)(r, c) = e(r, c);
}
void resize(int new_rows, int new_cols) requires(Rows == -1 && Cols == -1)
{
parent::resize(new_rows, new_cols);
@ -69,17 +81,17 @@ namespace rotgen
matrix transpose() const
{
return matrix(static_cast<parent const&>(*this).transpose());
return matrix(base().transpose());
}
matrix conjugate() const
{
return matrix(static_cast<parent const&>(*this).conjugate());
return matrix(base().conjugate());
}
matrix adjoint() const
{
return matrix(static_cast<parent const&>(*this).adjoint());
return matrix(base().adjoint());
}
void transposeInPlace() { parent::transposeInPlace(); }
@ -92,39 +104,51 @@ namespace rotgen
matrix& operator+=(matrix const& rhs)
{
static_cast<parent&>(*this) += static_cast<parent const&>(rhs);
base() += static_cast<parent const&>(rhs);
return *this;
}
matrix& operator-=(matrix const& rhs)
{
static_cast<parent&>(*this) -= static_cast<parent const&>(rhs);
base() -= static_cast<parent const&>(rhs);
return *this;
}
matrix operator-() const
{
return matrix(static_cast<parent const&>(*this).operator-());
return matrix(base().operator-());
}
matrix& operator*=(matrix const& rhs)
{
static_cast<parent&>(*this) *= static_cast<parent const&>(rhs);
base() *= static_cast<parent const&>(rhs);
return *this;
}
matrix& operator*=(Scalar rhs)
{
static_cast<parent&>(*this) *= rhs;
base() *= rhs;
return *this;
}
matrix& operator/=(Scalar rhs)
{
static_cast<parent&>(*this) /= rhs;
base() /= rhs;
return *this;
}
static matrix Ones() requires (Rows != -1 && Cols != -1)
{
return parent::Ones(Rows, Cols);
}
static matrix Ones(int rows, int cols)
{
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
return parent::Ones(rows, cols);
}
static matrix Zero() requires (Rows != -1 && Cols != -1)
{
return parent::Zero(Rows, Cols);
@ -173,6 +197,66 @@ namespace rotgen
return parent::Identity(rows, cols);
}
matrix& setOnes()
{
*this = parent::Ones(Rows, Cols);
return *this;
}
matrix& setOnes(int rows, int cols)
{
*this = parent::Ones(rows, cols);
return *this;
}
matrix& setZero()
{
*this = parent::Zero(Rows, Cols);
return *this;
}
matrix& setZero(int rows, int cols)
{
*this = parent::Zero(rows, cols);
return *this;
}
matrix& setConstant(Scalar value)
{
*this = parent::Constant(Rows, Cols, static_cast<Scalar>(value));
return *this;
}
matrix& setConstant(int rows, int cols, Scalar value)
{
*this = parent::Constant(rows, cols, static_cast<Scalar>(value));
return *this;
}
matrix& setRandom()
{
*this = parent::Random(Rows, Cols);
return *this;
}
matrix& setRandom(int rows, int cols)
{
*this = parent::Random(rows, cols);
return *this;
}
matrix& setIdentity()
{
*this = parent::Identity(Rows, Cols);
return *this;
}
matrix& setIdentity(int rows, int cols)
{
*this = parent::Identity(rows, cols);
return *this;
}
template<int P>
Scalar lpNorm() const
{
@ -180,6 +264,8 @@ namespace rotgen
return parent::lp_norm(P);
}
parent& base() { return static_cast<parent&>(*this); }
parent const& base() const { return static_cast<parent const&>(*this);; }
};
template<typename S, int R, int C, int O, int MR, int MC>
@ -204,20 +290,20 @@ namespace rotgen
}
template<typename S, int R, int C, int O, int MR, int MC>
matrix<S,R,C,O,MR,MC> operator*(matrix<S,R,C,O,MR,MC> const& lhs, S rhs)
matrix<S,R,C,O,MR,MC> operator*(matrix<S,R,C,O,MR,MC> const& lhs, double rhs)
{
matrix<S,R,C,O,MR,MC> that(lhs);
return that *= rhs;
}
template<typename S, int R, int C, int O, int MR, int MC>
matrix<S,R,C,O,MR,MC> operator*(S lhs, matrix<S,R,C,O,MR,MC> const& rhs)
matrix<S,R,C,O,MR,MC> operator*(double lhs, matrix<S,R,C,O,MR,MC> const& rhs)
{
return rhs * lhs;
}
template<typename S, int R, int C, int O, int MR, int MC>
matrix<S,R,C,O,MR,MC> operator/(matrix<S,R,C,O,MR,MC> const& lhs, S rhs)
matrix<S,R,C,O,MR,MC> operator/(matrix<S,R,C,O,MR,MC> const& lhs, double rhs)
{
matrix<S,R,C,O,MR,MC> that(lhs);
return that /= rhs;

View file

@ -8,7 +8,6 @@
#pragma once
#include <rotgen/detail/static_info.hpp>
#include <rotgen/fixed/common.hpp>
#include <Eigen/Dense>
#include <iostream>
@ -17,15 +16,15 @@ namespace rotgen
namespace detail
{
template<typename Ref, int Rows, int Cols, bool Inner>
using block_type = std::conditional_t < storage_status<Rows,Cols>
using block_type = std::conditional_t < storage_status<Rows,Cols,Rows,Cols>
, Eigen::Block<typename Ref::parent, Rows, Cols, Inner>
, Eigen::Block<typename Ref::parent, Eigen::Dynamic, Eigen::Dynamic, Inner>
>;
}
template< typename Ref
, int Rows = Dynamic, int Cols = Dynamic
, bool Inner = false, int ForceStorageOrder = -1
, int Rows = Dynamic, int Cols = Dynamic
, bool Inner = false , int ForceStorageOrder = -1
>
class block : private detail::block_type<Ref, Rows, Cols, Inner>
{
@ -37,21 +36,21 @@ namespace rotgen
using rotgen_tag = void;
using parent = detail::block_type<Ref, Rows, Cols, Inner>;
using value_type = typename parent::value_type;
using scalar_type = typename parent::value_type;
using Index = typename parent::Index;
static constexpr int storage_order = (ForceStorageOrder == -1) ? Ref::storage_order : ForceStorageOrder;
using concrete_type = matrix<scalar_type,Rows,Cols,storage_order>;
using concrete_dynamic_type = matrix<scalar_type>;
using concrete_type = matrix<value_type,Rows,Cols,storage_order>;
using concrete_dynamic_type = matrix<value_type,Dynamic,Dynamic,storage_order>;
template<typename ET>
using as_concrete_type = as_concrete_t<ET, matrix>;
static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols;
private:
static constexpr bool has_static_storage = storage_status<Rows,Cols>;
static constexpr auto Flags = Ref::Flags;
static constexpr int Options = Ref::Options;
static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols;
static constexpr bool is_defined_static = Rows!=-1 && Cols!=-1;
static constexpr bool has_static_storage = storage_status<Rows,Cols,Rows,Cols>;
public:
@ -67,6 +66,10 @@ namespace rotgen
: parent(r.base(),i0,j0,Rows,Cols)
{}
template<typename B, int R, int C, bool I, int FS>
block(block<B,R,C,I,FS> const& other) : parent(other.base())
{}
template<typename OtherDerived>
block(const Eigen::MatrixBase<OtherDerived>& other) : parent(other) {}
@ -90,34 +93,38 @@ namespace rotgen
parent& base() { return static_cast<parent&>(*this); }
parent const& base() const { return static_cast<const parent&>(*this); }
concrete_type transpose() const
auto transpose() const
{
return concrete_type(static_cast<parent const &>(*this).transpose());
auto res = static_cast<parent const &>(*this).transpose();
return as_concrete_type<decltype(res)>(res);
}
concrete_type conjugate() const
auto conjugate() const
{
return concrete_type(static_cast<parent const &>(*this).conjugate());
auto res = static_cast<parent const &>(*this).conjugate();
return as_concrete_type<decltype(res)>(res);
}
concrete_type adjoint() const
auto adjoint() const
{
return concrete_type(static_cast<parent const &>(*this).adjoint());
auto res = static_cast<parent const &>(*this).adjoint();
return as_concrete_type<decltype(res)>(res);
}
void transposeInPlace() { parent::transposeInPlace(); }
void adjointInPlace() { parent::adjointInPlace(); }
static concrete_type Constant(scalar_type value) requires (Rows != -1 && Cols != -1)
static concrete_type Constant(value_type value) requires (Rows != -1 && Cols != -1)
{
return parent::Constant(Rows, Cols, static_cast<scalar_type>(value));
return parent::Constant(Rows, Cols, static_cast<value_type>(value));
}
static concrete_type Constant(int rows, int cols, scalar_type value)
static concrete_type Constant(int rows, int cols, value_type value)
{
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
return parent::Constant(rows, cols, static_cast<scalar_type>(value));
return parent::Constant(rows, cols, static_cast<value_type>(value));
}
static concrete_type Identity() requires (Rows != -1 && Cols != -1)
@ -144,6 +151,18 @@ namespace rotgen
return parent::Zero(rows, cols);
}
static concrete_type Ones() requires (Rows != -1 && Cols != -1)
{
return parent::Ones(Rows, Cols);
}
static concrete_type Ones(int rows, int cols)
{
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
return parent::Ones(rows, cols);
}
static concrete_type Random() requires (Rows != -1 && Cols != -1)
{
return parent::Random(Rows, Cols);
@ -156,14 +175,98 @@ namespace rotgen
return parent::Random(rows, cols);
}
block& setOnes()
{
*this = parent::Ones(rows(), cols());
return *this;
}
block& setOnes(int r, int c)
{
*this = parent::Ones(r, c);
return *this;
}
block& setZero()
{
*this = parent::Zero(rows(), cols());
return *this;
}
block& setZero(int r, int c)
{
*this = parent::Zero(r,c);
return *this;
}
block& setConstant(value_type value)
{
*this = parent::Constant(rows(), cols(), value);
return *this;
}
block& setConstant(int r, int c, value_type value)
{
*this = parent::Constant(r,c, value);
return *this;
}
block& setRandom()
{
*this = parent::Random(rows(),cols());
return *this;
}
block& setRandom(int r, int c)
{
*this = parent::Random(r,c);
return *this;
}
block& setIdentity()
{
*this = parent::Identity(rows(),cols());
return *this;
}
block& setIdentity(int r, int c)
{
*this = parent::Identity(r,c);
return *this;
}
template<int P>
scalar_type lpNorm() const
value_type lpNorm() const
{
static_assert(P == 1 || P == 2 || P == Infinity);
return parent::template lpNorm<P>();
}
using parent::operator();
bool is_contiguous_linear() const
{
if(parent::innerStride() != 1) return false;
// outerstride must equal the “innerdimension length”
if constexpr(storage_order) return parent::outerStride() == parent::cols();
else return parent::outerStride() == parent::rows();
}
value_type& operator()(Index i, Index j) { return base()(i,j); }
value_type operator()(Index i, Index j) const { return base()(i,j); }
value_type& operator()(Index i)
{
assert(is_contiguous_linear());
return base().data()[i];
}
value_type operator()(Index i) const
{
assert(is_contiguous_linear());
return base().data()[i];
}
using parent::innerStride;
using parent::outerStride;
using parent::rows;
using parent::cols;
using parent::size;
@ -200,25 +303,16 @@ namespace rotgen
return *this;
}
block& operator*=(scalar_type rhs)
block& operator*=(value_type rhs)
{
static_cast<parent&>(*this) *= rhs;
return *this;
}
block& operator/=(scalar_type rhs)
block& operator/=(value_type rhs)
{
static_cast<parent&>(*this) /= rhs;
return *this;
}
static void print_storage_info()
{
std::cout << "Block " << Rows << "x" << Cols
<< " - Storage: " << (has_static_storage ? "Static" : "Dynamic")
<< " (from: ";
Ref::print_storage_info();
std::cout << ")" << std::endl;
}
};
}

View file

@ -1,86 +0,0 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once
#include <rotgen/concepts.hpp>
#include <concepts>
#include <iosfwd>
namespace rotgen
{
template<typename EigenType
, template<typename,int,int,int,int,int> typename Wrapper
>
struct as_concrete
{
using type = Wrapper< typename EigenType::value_type
, EigenType::RowsAtCompileTime, EigenType::ColsAtCompileTime
, EigenType::Flags
, EigenType::MaxRowsAtCompileTime, EigenType::MaxColsAtCompileTime
>;
};
template<typename EigenType
, template<typename,int,int,int,int,int> typename Wrapper
>
using as_concrete_t = typename as_concrete<EigenType,Wrapper>::type;
template<concepts::entity E1, concepts::entity E2>
bool operator==(E1 const& lhs, E2 const& rhs)
{
return lhs.base() == rhs.base();
}
template<concepts::entity E>
std::ostream& operator<<(std::ostream& os, E const& arg)
{
return os << arg.base();
}
template<concepts::entity E1, concepts::entity E2>
auto operator+(E1 const& lhs, E2 const& rhs)
{
using type = E1::template as_concrete_type<decltype(lhs.base() + rhs.base())>;
return type(lhs.base() + rhs.base());
}
template<concepts::entity E1, concepts::entity E2>
auto operator-(E1 const& lhs, E2 const& rhs)
{
using type = E1::template as_concrete_type<decltype(lhs.base() - rhs.base())>;
return type(lhs.base() - rhs.base());
}
template<concepts::entity E1, concepts::entity E2>
auto operator*(E1 const& lhs, E2 const& rhs)
{
using type = typename E1::concrete_dynamic_type;
return type(lhs.base() * rhs.base());
}
template<concepts::entity E, std::convertible_to<typename E::scalar_type> S>
auto operator*(E const& lhs, S rhs)
{
using type = E::template as_concrete_type<decltype(lhs.base() * rhs)>;
return type(lhs.base() * rhs);
}
template<concepts::entity E, std::convertible_to<typename E::scalar_type> S>
auto operator*(S lhs, E const& rhs )
{
using type = E::template as_concrete_type<decltype(lhs * rhs.base())>;
return type(lhs * rhs.base());
}
template<concepts::entity E, std::convertible_to<typename E::scalar_type> S>
auto operator/(E const& lhs, S rhs)
{
using type = E::template as_concrete_type<decltype(lhs.base() / rhs)>;
return type(lhs.base() / rhs);
}
}

View file

@ -0,0 +1,328 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once
#include <rotgen/detail/static_info.hpp>
#include <Eigen/Dense>
#include <iostream>
namespace rotgen
{
namespace detail
{
template<typename Ref, int Options, bool isConst>
struct compute_map_type
{
using base = Eigen::Matrix< typename Ref::value_type
, Ref::RowsAtCompileTime, Ref::ColsAtCompileTime
, Ref::storage_order
>;
using ref_t = std::conditional_t<isConst, base const, base>;
using type = Eigen::Map<ref_t, Options, Eigen::Stride<-1,-1>>;
};
template<typename Ref, int Options, bool isConst>
using map_type = typename compute_map_type<Ref,Options,isConst>::type;
template<typename T> struct map_stride;
template<typename PlainObjectType, int MapOptions, typename Stride>
struct map_stride<Eigen::Map<PlainObjectType, MapOptions, Stride>>
{
using type = Stride;
};
}
template<typename Ref, int Options = ColMajor, typename = void>
class map : private detail::map_type<std::remove_const_t<Ref>, Options, std::is_const_v<Ref>>
{
public:
using rotgen_tag = void;
using parent = detail::map_type<std::remove_const_t<Ref>, Options, std::is_const_v<Ref>>;
using value_type = typename std::remove_const_t<Ref>::value_type;
using concrete_type = typename std::remove_const_t<Ref>::concrete_type;
static constexpr auto Flags = Ref::Flags;
static constexpr Index RowsAtCompileTime = Ref::RowsAtCompileTime;
static constexpr Index ColsAtCompileTime = Ref::ColsAtCompileTime;
static constexpr bool has_static_storage = Ref::has_static_storage;
static constexpr int storage_order = Ref::storage_order;
static constexpr bool is_immutable = std::is_const_v<Ref>;
static constexpr bool is_defined_static = Ref::is_defined_static;
template<typename ET>
using as_concrete_type = as_concrete_t<ET, matrix>;
using ptr_type = std::conditional_t<is_immutable, value_type const*, value_type*>;
using stride_type = typename detail::map_stride<parent>::type;
map(const map&) = default;
map(map&&) = default;
map& operator=(const map&) = default;
map& operator=(map&&) = default;
map(ptr_type ptr, Index r, Index c, stride_type s) : parent(ptr, r, c, s) {}
map(ptr_type ptr, Index r, Index c) : map(ptr, r, c, strides<storage_order>(r,c)) {}
map(ptr_type ptr, stride_type s) requires(RowsAtCompileTime!=-1 && ColsAtCompileTime!=-1)
: parent(ptr, s)
{}
map(ptr_type ptr, Index sz) requires(RowsAtCompileTime==1 || ColsAtCompileTime==1)
: map(ptr, RowsAtCompileTime==1?1:sz, ColsAtCompileTime==1?1:sz)
{}
map(ptr_type ptr) requires(RowsAtCompileTime!=-1 && ColsAtCompileTime!=-1)
: map( ptr, RowsAtCompileTime, ColsAtCompileTime )
{}
parent& base() { return static_cast<parent&>(*this); }
parent const& base() const { return static_cast<const parent&>(*this); }
value_type& operator()(Index i, Index j) { return base()(i, j); }
value_type operator()(Index i, Index j) const { return base()(i, j); }
value_type& operator()(Index i) requires(!is_immutable)
{
assert(is_contiguous_linear());
return base().data()[i];
}
value_type operator()(Index i) const
{
assert(is_contiguous_linear());
return base().data()[i];
}
map& operator+=(map const& rhs)
{
base() += rhs.base();
return *this;
}
map& operator-=(map const& rhs)
{
base() -= rhs.base();
return *this;
}
map& operator*=(map const& rhs)
{
base() *= rhs;
return *this;
}
map& operator*=(value_type rhs)
{
base() *= rhs;
return *this;
}
map& operator/=(value_type rhs)
{
base() /= rhs;
return *this;
}
auto transpose() const
{
if constexpr(use_expression_templates) return base().transpose();
else return as_concrete_type<decltype(base().transpose())>(base().transpose());
}
auto adjoint() const
{
if constexpr(use_expression_templates) return base().adjoint();
else return as_concrete_type<decltype(base().adjoint())>(base().adjoint());
}
auto conjugate() const
{
if constexpr(use_expression_templates) return base().conjugate();
else return as_concrete_type<decltype(base().conjugate())>(base().conjugate());
}
void transposeInPlace() { base().transposeInPlace(); }
void adjointInPlace() { base().adjointInPlace(); }
static auto Zero() requires( requires {Ref::Zero();} ) { return Ref::Zero(); }
static auto Zero(int rows, int cols) { return Ref::Zero(rows,cols); }
static auto Ones() requires( requires {Ref::Ones();} ) { return Ref::Ones(); }
static auto Ones(int rows, int cols) { return Ref::Ones(rows,cols); }
static auto Constant(value_type value) requires( requires {Ref::Constant(value);} )
{ return Ref::Constant(value); }
static auto Constant(int rows, int cols, value_type value) { return Ref::Constant(rows, cols, value); }
static auto Random() requires( requires {Ref::Random();} ) { return Ref::Random(); }
static auto Random(int rows, int cols) { return Ref::Random(rows, cols); }
static auto Identity() requires( requires {Ref::Identity();} ) { return Ref::Identity(); }
static auto Identity(int rows, int cols) { return Ref::Identity(rows, cols); }
map& setOnes()
{
base() = parent::Ones(base().rows(), base().cols());
return *this;
}
map& setZero()
{
base() = parent::Zero(base().rows(), base().cols());
return *this;
}
map& setConstant(value_type value)
{
base() = parent::Constant(base().rows(), base().cols(), value);
return *this;
}
map& setRandom()
{
base() = parent::Random(base().rows(), base().cols());
return *this;
}
map& setIdentity()
{
base() = parent::Identity(base().rows(), base().cols());
return *this;
}
bool is_contiguous_linear() const
{
if(base().innerStride() != 1) return false;
if constexpr(storage_order == rotgen::RowMajor) return base().outerStride() == base().cols();
else return base().outerStride() == base().rows();
}
using parent::innerStride;
using parent::outerStride;
using parent::rows;
using parent::cols;
using parent::size;
using parent::data;
using parent::sum;
using parent::mean;
using parent::prod;
using parent::trace;
using parent::maxCoeff;
using parent::minCoeff;
using parent::norm;
using parent::squaredNorm;
template<int P> value_type lpNorm() const
{
static_assert(P == 1 || P == 2 || P == Infinity);
return parent::template lpNorm<P>();
}
};
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
bool operator==(map<R1, O1, S1> const& lhs, map<R2,O2,S2> const& rhs)
{
return lhs.base() == rhs.base();
}
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
bool operator!=(map<R1, O1, S1> const& lhs, map<R2,O2,S2> const& rhs)
{
return lhs.base() != rhs.base();
}
#if defined(ROTGEN_ENABLE_EXPRESSION_TEMPLATES)
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
auto operator+(map<R1, O1, S1> const& lhs, map<R2,O2,S2> const& rhs)
{
return lhs.base() + rhs.base();
}
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
auto operator-(map<R1, O1, S1> const& lhs, map<R2,O2,S2> const& rhs)
{
return lhs.base() - rhs.base();
}
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
auto operator*(map<R1, O1, S1> const& lhs, map<R2,O2,S2> const& rhs)
{
return lhs.base() * rhs.base();
}
template<typename R, int O, typename S>
auto operator*( map<R, O, S> const& lhs, std::convertible_to<typename R::value_type> auto s)
{
return lhs.base() * s;
}
template<typename R, int O, typename S>
auto operator*(std::convertible_to<typename R::value_type> auto s, map<R, O, S> const& rhs)
{
return s * rhs.base();
}
template<typename R, int O, typename S>
auto operator/(map<R, O, S> const& lhs, std::convertible_to<typename R::value_type> auto s)
{
return lhs.base() / s;
}
#else
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
typename map<R1,O1,S1>::concrete_type operator+(map<R1, O1, S1> const& lhs, map<R2,O2,S2> const& rhs)
{
using concrete_type = typename map<R1,O1,S1>::concrete_type;
return concrete_type(lhs.base() + rhs.base());
}
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
typename map<R1,O1,S1>::concrete_type operator-(map<R1, O1, S1> const& lhs, map<R2,O2,S2> const& rhs)
{
using concrete_type = typename map<R1,O1,S1>::concrete_type;
return concrete_type(lhs.base() - rhs.base());
}
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
typename map<R1,O1,S1>::concrete_type operator*(map<R1, O1, S1> const& lhs, map<R2,O2,S2> const& rhs)
{
using concrete_type = typename map<R1,O1,S1>::concrete_type;
return concrete_type(lhs.base() * rhs.base());
}
template<typename R, int O, typename S>
typename map<R,O,S>::concrete_type operator*( map<R, O, S> const& lhs
, std::convertible_to<typename R::value_type> auto s
)
{
using concrete_type = typename map<R,O,S>::concrete_type;
return concrete_type(lhs.base() * s);
}
template<typename R, int O, typename S>
typename map<R,O,S>::concrete_type operator*( std::convertible_to<typename R::value_type> auto s
, map<R, O, S> const& rhs
)
{
using concrete_type = typename map<R,O,S>::concrete_type;
return concrete_type(rhs.base() * s);
}
template<typename R, int O, typename S>
typename map<R,O,S>::concrete_type operator/( map<R, O, S> const& lhs
, std::convertible_to<typename R::value_type> auto s
)
{
using concrete_type = typename map<R,O,S>::concrete_type;
return concrete_type(lhs.base() / s);
}
#endif
}

View file

@ -8,7 +8,6 @@
#pragma once
#include <rotgen/detail/static_info.hpp>
#include <rotgen/fixed/common.hpp>
#include <Eigen/Dense>
#include <iostream>
@ -17,7 +16,7 @@ namespace rotgen
namespace detail
{
template<typename Scalar, int Rows, int Cols, int Opts,int MaxRows, int MaxCols>
using storage_type = std::conditional_t < storage_status<Rows,Cols>
using storage_type = std::conditional_t < storage_status<Rows,Cols,MaxRows,MaxCols>
, Eigen::Matrix<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>
, Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Opts>
>;
@ -25,27 +24,31 @@ namespace rotgen
template< typename Scalar
, int Rows = Dynamic , int Cols = Dynamic
, int Options = ColMajor
, int Opts = ColMajor
, int MaxRows = Rows , int MaxCols = Cols
>
class matrix : private detail::storage_type<Scalar, Rows, Cols, Options, MaxRows, MaxCols>
class matrix : private detail::storage_type<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>
{
public:
using rotgen_tag = void;
using parent = detail::storage_type<Scalar, Rows, Cols, Options, MaxRows, MaxCols>;
using rotgen_tag = void;
using parent = detail::storage_type<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>;
using value_type = Scalar;
using scalar_type = Scalar;
using Index = typename parent::Index;
static constexpr auto storage_order = Options & 1;
static constexpr auto storage_order = Opts & 1;
using concrete_type = matrix;
using concrete_dynamic_type = matrix<scalar_type>;
using concrete_dynamic_type = matrix<value_type>;
static constexpr auto Flags = parent::Flags;
static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols;
static constexpr int Options = parent::Options;
template<typename ET>
using as_concrete_type = as_concrete_t<ET, matrix>;
private:
static constexpr bool has_static_storage = storage_status<Rows,Cols>;
static constexpr bool is_defined_static = Rows!=-1 && Cols!=-1;
static constexpr bool has_static_storage = storage_status<Rows,Cols,MaxRows,MaxCols>;
public:
@ -58,7 +61,6 @@ namespace rotgen
matrix& operator=(const matrix&) = default;
matrix& operator=(matrix&&) = default;
matrix(std::initializer_list<std::initializer_list<Scalar>> init) : parent(init)
{}
@ -82,10 +84,17 @@ namespace rotgen
}
}
matrix(concepts::entity auto const& other) : parent(other.base())
{}
template<typename OtherDerived>
matrix(const Eigen::MatrixBase<OtherDerived>& other) : parent(other)
{}
template<typename OtherDerived>
matrix(const Eigen::EigenBase<OtherDerived>& other) : parent(other)
{}
template<typename OtherDerived>
matrix& operator=(const Eigen::MatrixBase<OtherDerived>& other)
{
@ -100,22 +109,31 @@ namespace rotgen
return *this;
}
matrix& operator=(concepts::entity auto const& other)
{
parent::operator=(other.base());
return *this;
}
parent& base() { return static_cast<parent&>(*this); }
parent const& base() const { return static_cast<const parent&>(*this); }
concrete_type transpose() const
auto transpose() const
{
return concrete_type(static_cast<parent const &>(*this).transpose());
auto res = static_cast<parent const &>(*this).transpose();
return as_concrete_type<decltype(res)>(res);
}
concrete_type conjugate() const
auto conjugate() const
{
return concrete_type(static_cast<parent const &>(*this).conjugate());
auto res = static_cast<parent const &>(*this).conjugate();
return as_concrete_type<decltype(res)>(res);
}
concrete_type adjoint() const
auto adjoint() const
{
return concrete_type(static_cast<parent const &>(*this).adjoint());
auto res = static_cast<parent const &>(*this).adjoint();
return as_concrete_type<decltype(res)>(res);
}
void transposeInPlace() { parent::transposeInPlace(); }
@ -155,6 +173,18 @@ namespace rotgen
return parent::Identity(rows, cols);
}
static matrix Ones() requires (Rows != -1 && Cols != -1)
{
return parent::Ones(Rows, Cols);
}
static matrix Ones(int rows, int cols)
{
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
return parent::Ones(rows, cols);
}
static matrix Zero() requires (Rows != -1 && Cols != -1)
{
return parent::Zero(Rows, Cols);
@ -180,7 +210,7 @@ namespace rotgen
}
template<int P>
scalar_type lpNorm() const
value_type lpNorm() const
{
static_assert(P == 1 || P == 2 || P == Infinity);
return parent::template lpNorm<P>();
@ -200,6 +230,66 @@ namespace rotgen
using parent::sum;
using parent::data;
matrix& setOnes()
{
*this = parent::Ones(rows(),cols());
return *this;
}
matrix& setOnes(int r, int c)
{
*this = parent::Ones(r, c);
return *this;
}
matrix& setZero()
{
*this = parent::Zero(rows(),cols());
return *this;
}
matrix& setZero(int r, int c)
{
*this = parent::Zero(r, c);
return *this;
}
matrix& setConstant(Scalar value)
{
*this = parent::Constant(rows(),cols(), static_cast<Scalar>(value));
return *this;
}
matrix& setConstant(int r, int c, Scalar value)
{
*this = parent::Constant(r, c, static_cast<Scalar>(value));
return *this;
}
matrix& setRandom()
{
*this = parent::Random(rows(),cols());
return *this;
}
matrix& setRandom(int r, int c)
{
*this = parent::Random(r, c);
return *this;
}
matrix& setIdentity()
{
*this = parent::Identity(rows(),cols());
return *this;
}
matrix& setIdentity(int r, int c)
{
*this = parent::Identity(r, c);
return *this;
}
matrix& operator+=(matrix const& rhs)
{
static_cast<parent&>(*this) += static_cast<parent const&>(rhs);
@ -234,13 +324,5 @@ namespace rotgen
static_cast<parent&>(*this) /= rhs;
return *this;
}
static void print_storage_info()
{
std::cout << "Matrix " << Rows << "x" << Cols
<< " - Storage: " << (has_static_storage ? "Static" : "Dynamic")
<< " (Max. size=" << max_static_size << ")"
<< std::endl;
}
};
}

View file

@ -9,134 +9,52 @@
namespace rotgen
{
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
std::size_t rows(const rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix)
std::size_t rows(concepts::entity auto const& arg) { return arg.rows(); }
std::size_t cols(concepts::entity auto const& arg) { return arg.cols(); }
std::size_t size(concepts::entity auto const& arg) { return arg.size(); }
template<concepts::entity E>
void resize(E& arg, int new_rows, int new_cols)
requires(E::RowsAtCompileTime == -1 && E::ColsAtCompileTime == -1)
{
return matrix.rows();
arg.resize(new_rows, new_cols);
}
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
std::size_t cols(const rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix)
template<concepts::entity E>
void conservativeResize(E& arg, int new_rows, int new_cols)
requires(E::RowsAtCompileTime == -1 && E::ColsAtCompileTime == -1)
{
return matrix.cols();
arg.conservativeResize(new_rows, new_cols);
}
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
std::size_t size(const rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix)
decltype(auto) transpose(concepts::entity auto const& arg) { return arg.transpose(); }
decltype(auto) conjugate(concepts::entity auto const& arg) { return arg.conjugate(); }
decltype(auto) adjoint (concepts::entity auto const& arg) { return arg.adjoint(); }
void transposeInPlace(concepts::entity auto& arg) { arg.transposeInPlace(); }
void adjointInPlace(concepts::entity auto& arg) { arg.adjointInPlace(); }
auto trace(concepts::entity auto const& arg) { return arg.trace(); }
auto squaredNorm(concepts::entity auto const& arg) { return arg.squaredNorm(); }
auto norm(concepts::entity auto const& arg) { return arg.norm(); }
auto sum(concepts::entity auto const& arg) { return arg.sum(); }
auto prod(concepts::entity auto const& arg) { return arg.prod(); }
auto mean(concepts::entity auto const& arg) { return arg.mean(); }
auto maxCoeff(concepts::entity auto const& arg) { return arg.maxCoeff(); }
auto minCoeff(concepts::entity auto const& arg) { return arg.minCoeff(); }
auto maxCoeff(concepts::entity auto const& arg, Index* row, Index* col)
{
return matrix.size();
return arg.maxCoeff(row, col);
}
auto minCoeff(concepts::entity auto const& arg, Index* row, Index* col)
{
return arg.minCoeff(row, col);
}
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
void resize(rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix, int new_rows, int new_cols)
requires(Rows == -1 && Cols == -1)
{
matrix.resize(new_rows, new_cols);
}
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
void conservativeResize(rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix, int new_rows, int new_cols)
requires(Rows == -1 && Cols == -1)
{
matrix.conservativeResize(new_rows, new_cols);
}
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
rotgen::matrix<Scalar, Cols, Rows, Options, MaxCols, MaxRows> transpose(const rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix)
{
return matrix.transpose();
}
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> conjugate(const rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix)
{
return matrix.conjugate();
}
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
rotgen::matrix<Scalar, Cols, Rows, Options, MaxCols, MaxRows> adjoint(const rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix)
{
return matrix.adjoint();
}
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
void transposeInPlace(rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix)
{
matrix.transposeInPlace();
}
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
void adjointInPlace(rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix)
{
matrix.adjointInPlace();
}
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
double squaredNorm(const rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix)
{
return matrix.squaredNorm();
}
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
double norm(const rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix)
{
return matrix.norm();
}
template< int P, typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
double lpNorm(const rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix)
template<int P>
auto lpNorm(concepts::entity auto const& arg)
{
static_assert(P == 1 || P == 2 || P == Infinity);
return matrix.template lpNorm<P>();
return arg.template lpNorm<P>();
}
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
double sum(const rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix)
{
return matrix.sum();
}
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
double prod(const rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix)
{
return matrix.prod();
}
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
double mean(const rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix)
{
return matrix.mean();
}
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
double maxCoeff(const rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix)
{
return matrix.maxCoeff();
}
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
double maxCoeff(const rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix, std::ptrdiff_t* row, std::ptrdiff_t* col)
{
return matrix.maxCoeff(row, col);
}
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
double minCoeff(const rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix)
{
return matrix.minCoeff();
}
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
double minCoeff(const rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix, std::ptrdiff_t* row, std::ptrdiff_t* col)
{
return matrix.minCoeff(row, col);
}
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >
double trace(const rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix)
{
return matrix.trace();
}
}

View file

@ -8,7 +8,6 @@
#pragma once
#include <rotgen/detail/generators.hpp>
#include <rotgen/detail/static_info.hpp>
#include <rotgen/impl/matrix.hpp>
#include <initializer_list>
#include <cstddef>
@ -60,5 +59,5 @@ namespace rotgen
template<> struct find_block_impl<double, RowMajor> { using type = block_impl64_row; };
template<typename Ref>
using find_block = typename find_block_impl<typename Ref::scalar_type, Ref::storage_order>::type;
using find_block = typename find_block_impl<typename Ref::value_type, Ref::storage_order>::type;
}

View file

@ -24,10 +24,15 @@ class CLASSNAME
~CLASSNAME();
void assign(SOURCENAME const&);
Index rows() const;
Index cols() const;
Index size() const;
Index innerStride() const;
Index outerStride() const;
SOURCENAME transpose() const;
SOURCENAME conjugate() const;
SOURCENAME adjoint() const;
@ -51,8 +56,8 @@ class CLASSNAME
TYPE& operator()(std::size_t i, std::size_t j);
TYPE const& operator()(std::size_t i, std::size_t j) const;
// TYPE& operator()(std::size_t index);
// TYPE const& operator()(std::size_t index) const;
TYPE& operator()(std::size_t index);
TYPE const& operator()(std::size_t index) const;
CLASSNAME& operator+=(CLASSNAME const& rhs);
CLASSNAME& operator-=(CLASSNAME const& rhs);
@ -61,18 +66,21 @@ class CLASSNAME
CLASSNAME& operator*=(TYPE d);
CLASSNAME& operator/=(TYPE d);
SOURCENAME matrix_addition(CLASSNAME const& rhs) const;
SOURCENAME matrix_subtraction(CLASSNAME const& rhs) const;
SOURCENAME matrix_multiplication(CLASSNAME const& rhs) const;
SOURCENAME matrix_multiplication(TYPE s) const;
SOURCENAME matrix_division(TYPE s) const;
SOURCENAME add(CLASSNAME const& rhs) const;
SOURCENAME sub(CLASSNAME const& rhs) const;
SOURCENAME mul(CLASSNAME const& rhs) const;
SOURCENAME mul(TYPE s) const;
SOURCENAME div(TYPE s) const;
friend std::ostream& operator<<(std::ostream&,CLASSNAME const&);
friend bool operator==(CLASSNAME const& lhs, CLASSNAME const& rhs);
friend bool operator!=(CLASSNAME const& lhs, CLASSNAME const& rhs);
const TYPE* data() const;
TYPE* data();
static SOURCENAME Zero(std::size_t r, std::size_t c) { return SOURCENAME::Zero(r,c); }
static SOURCENAME Ones(std::size_t r, std::size_t c) { return SOURCENAME::Ones(r,c); }
static SOURCENAME Constant(std::size_t r, std::size_t c, TYPE v) { return SOURCENAME::Constant(r,c,v); }
static SOURCENAME Random(std::size_t r, std::size_t c) { return SOURCENAME::Random(r,c); }
static SOURCENAME Identity(std::size_t r, std::size_t c) { return SOURCENAME::Identity(r,c); }

115
include/rotgen/impl/map.hpp Normal file
View file

@ -0,0 +1,115 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once
#include <rotgen/detail/generators.hpp>
#include <rotgen/impl/matrix.hpp>
#include <rotgen/common/strides.hpp>
#include <initializer_list>
#include <cstddef>
#include <memory>
namespace rotgen
{
#define USE_CONST
#define CONST const
#define SIZE 64
#define TYPE double
#define CLASSNAME ROTGEN_MATRIX_NAME(map_const_impl,SIZE,_col)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
#include <rotgen/impl/map_model.hpp>
#undef CLASSNAME
#undef SOURCENAME
#define CLASSNAME ROTGEN_MATRIX_NAME(map_const_impl,SIZE,_row)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
#include <rotgen/impl/map_model.hpp>
#undef CLASSNAME
#undef SOURCENAME
#undef SIZE
#undef TYPE
#define SIZE 32
#define TYPE float
#define CLASSNAME ROTGEN_MATRIX_NAME(map_const_impl,SIZE,_col)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
#include <rotgen/impl/map_model.hpp>
#undef CLASSNAME
#undef SOURCENAME
#define CLASSNAME ROTGEN_MATRIX_NAME(map_const_impl,SIZE,_row)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
#include <rotgen/impl/map_model.hpp>
#undef CLASSNAME
#undef SOURCENAME
#undef SIZE
#undef TYPE
#undef CONST
#undef USE_CONST
#define SIZE 64
#define TYPE double
#define CONST
#define CLASSNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_col)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
#include <rotgen/impl/map_model.hpp>
#undef CLASSNAME
#undef SOURCENAME
#define CLASSNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_row)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
#include <rotgen/impl/map_model.hpp>
#undef CLASSNAME
#undef SOURCENAME
#undef SIZE
#undef TYPE
#define SIZE 32
#define TYPE float
#define CLASSNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_col)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
#include <rotgen/impl/map_model.hpp>
#undef CLASSNAME
#undef SOURCENAME
#define CLASSNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_row)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
#include <rotgen/impl/map_model.hpp>
#undef CLASSNAME
#undef SOURCENAME
#undef SIZE
#undef TYPE
#undef CONST
template<typename Scalar,int Options, bool isConst> struct find_map_impl;
template<> struct find_map_impl<float , ColMajor, true> { using type = map_const_impl32_col; };
template<> struct find_map_impl<float , RowMajor, true> { using type = map_const_impl32_row; };
template<> struct find_map_impl<double, ColMajor, true> { using type = map_const_impl64_col; };
template<> struct find_map_impl<double, RowMajor, true> { using type = map_const_impl64_row; };
template<> struct find_map_impl<float , ColMajor, false> { using type = map_impl32_col; };
template<> struct find_map_impl<float , RowMajor, false> { using type = map_impl32_row; };
template<> struct find_map_impl<double, ColMajor, false> { using type = map_impl64_col; };
template<> struct find_map_impl<double, RowMajor, false> { using type = map_impl64_row; };
template<typename Ref>
using find_map = typename find_map_impl < typename std::remove_const_t<Ref>::value_type
, Ref::storage_order
, std::is_const_v<Ref>
>::type;
}
#include <rotgen/impl/map_operators.hpp>

View file

@ -0,0 +1,106 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
//==================================================================================================
/*
This file is a X-File to generate various map_impl_* declarations variant
*/
//==================================================================================================
class CLASSNAME
{
public:
CLASSNAME(TYPE CONST* ptr, Index r, Index c);
CLASSNAME(TYPE CONST* ptr, Index r, Index c, stride s);
CLASSNAME(CLASSNAME const& other);
#if !defined(USE_CONST)
CLASSNAME& operator=(CLASSNAME const& other);
#endif
CLASSNAME(CLASSNAME&&) noexcept;
CLASSNAME& operator=(CLASSNAME&&) noexcept;
~CLASSNAME();
Index rows() const;
Index cols() const;
Index size() const;
Index innerStride() const;
Index outerStride() const;
SOURCENAME transpose() const;
SOURCENAME conjugate() const;
SOURCENAME adjoint() const;
#if !defined(USE_CONST)
void transposeInPlace();
void adjointInPlace();
#endif
TYPE sum() const;
TYPE prod() const;
TYPE mean() const;
TYPE trace() const;
TYPE maxCoeff() const;
TYPE minCoeff() const;
TYPE maxCoeff(Index* row, Index* col) const;
TYPE minCoeff(Index* row, Index* col) const;
TYPE squaredNorm() const;
TYPE norm() const;
TYPE lpNorm(int p) const;
#if !defined(USE_CONST)
TYPE& operator()(Index i, Index j);
TYPE& operator()(Index i);
#endif
TYPE operator()(Index i, Index j) const;
TYPE operator()(Index i) const;
#if !defined(USE_CONST)
CLASSNAME& operator+=(CLASSNAME const& rhs);
CLASSNAME& operator-=(CLASSNAME const& rhs);
CLASSNAME& operator*=(CLASSNAME const& rhs);
CLASSNAME& operator*=(TYPE d);
CLASSNAME& operator/=(TYPE d);
#endif
SOURCENAME operator-() const;
SOURCENAME add(CLASSNAME const& rhs) const;
SOURCENAME sub(CLASSNAME const& rhs) const;
SOURCENAME mul(CLASSNAME const& rhs) const;
SOURCENAME mul(TYPE s) const;
SOURCENAME div(TYPE s) const;
friend std::ostream& operator<<(std::ostream&,CLASSNAME const&);
const TYPE* data() const;
#if !defined(USE_CONST)
void setZero();
void setOnes();
void setRandom();
void setIdentity();
void setConstant(TYPE);
#endif
friend bool operator==(CLASSNAME const& lhs, CLASSNAME const& rhs);
friend bool operator!=(CLASSNAME const& lhs, CLASSNAME const& rhs);
private:
struct payload;
std::unique_ptr<payload> storage_;
public:
std::unique_ptr<payload>& storage() { return storage_; }
std::unique_ptr<payload> const& storage() const { return storage_; }
};

View file

@ -0,0 +1,39 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once
#define ROTGEN_DEF_RELOP_PAIR(OP, T1, T2) \
bool operator OP (T1 const&, T2 const&); \
inline bool operator OP (T2 const& a, T1 const& b) { return b OP a; } \
/**/
#define ROTGEN_DEF_RELOP(OP) \
ROTGEN_DEF_RELOP_PAIR(OP, map_const_impl32_col, map_impl32_col) \
ROTGEN_DEF_RELOP_PAIR(OP, map_const_impl32_col, map_impl32_row) \
ROTGEN_DEF_RELOP_PAIR(OP, map_const_impl32_col, map_const_impl32_row) \
ROTGEN_DEF_RELOP_PAIR(OP, map_const_impl32_row, map_impl32_row) \
ROTGEN_DEF_RELOP_PAIR(OP, map_const_impl32_row, map_impl32_col) \
ROTGEN_DEF_RELOP_PAIR(OP, map_impl32_col, map_impl32_row) \
ROTGEN_DEF_RELOP_PAIR(OP, map_const_impl64_col, map_impl64_col) \
ROTGEN_DEF_RELOP_PAIR(OP, map_const_impl64_col, map_impl64_row) \
ROTGEN_DEF_RELOP_PAIR(OP, map_const_impl64_col, map_const_impl64_row) \
ROTGEN_DEF_RELOP_PAIR(OP, map_const_impl64_row, map_impl64_row) \
ROTGEN_DEF_RELOP_PAIR(OP, map_const_impl64_row, map_impl64_col) \
ROTGEN_DEF_RELOP_PAIR(OP, map_impl64_col, map_impl64_row) \
/**/
namespace rotgen
{
ROTGEN_DEF_RELOP(==)
ROTGEN_DEF_RELOP(!=)
// ROTGEN_DEF_RELOP(+)
// ROTGEN_DEF_RELOP(-)
}
#undef ROTGEN_DEF_RELOP_PAIR
#undef ROTGEN_DEF_RELOP

View file

@ -69,10 +69,13 @@ class CLASSNAME
friend std::ostream& operator<<(std::ostream&,CLASSNAME const&);
friend bool operator==(CLASSNAME const& lhs, CLASSNAME const& rhs);
friend bool operator!=(CLASSNAME const& lhs, CLASSNAME const& rhs);
const TYPE* data() const;
TYPE* data();
static CLASSNAME Zero(std::size_t rows, std::size_t cols);
static CLASSNAME Ones(std::size_t rows, std::size_t cols);
static CLASSNAME Constant(std::size_t rows, std::size_t cols, TYPE value);
static CLASSNAME Random(std::size_t rows, std::size_t cols);
static CLASSNAME Identity(std::size_t rows, std::size_t cols);

View file

@ -10,12 +10,13 @@
#include <cstddef>
#include <memory>
#include <rotgen/impl/matrix.hpp>
#include <rotgen/impl/map.hpp>
#include <Eigen/Dense>
namespace rotgen
{
//==================================================================================================
// Internal payload - Requried for cross-referencing from block_impl*
// Internal payload - Required for cross-referencing from block_impl*
//==================================================================================================
struct matrix_impl64_col::payload
{
@ -72,4 +73,112 @@ namespace rotgen
void assign(data_type const& mat) { data = mat; }
void assign(data_type&& mat) { data = std::move(mat); }
};
//==================================================================================================
// Internal payload - Required for cross-referencing from mixed order on map operators
//==================================================================================================
struct map_const_impl32_col::payload
{
using stride_type = Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic>;
using base_type = Eigen::Matrix<float,Eigen::Dynamic,Eigen::Dynamic,Eigen::ColMajor>;
using data_type = Eigen::Map<base_type const,Eigen::ColMajor,stride_type>;
data_type data;
payload (data_type const& o) : data(o) {}
payload (float const* ptr, Index r, Index c) : data(ptr,r,c) {}
payload (float const* ptr, Index r, Index c, stride_type s) : data(ptr,r,c,s) {}
};
struct map_const_impl32_row::payload
{
using stride_type = Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic>;
using base_type = Eigen::Matrix<float,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor>;
using data_type = Eigen::Map<base_type const,Eigen::RowMajor,stride_type>;
data_type data;
payload (data_type const& o) : data(o) {}
payload (float const* ptr, Index r, Index c) : data(ptr,r,c) {}
payload (float const* ptr, Index r, Index c, stride_type s) : data(ptr,r,c,s) {}
};
struct map_impl32_col::payload
{
using stride_type = Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic>;
using base_type = Eigen::Matrix<float,Eigen::Dynamic,Eigen::Dynamic,Eigen::ColMajor>;
using data_type = Eigen::Map<base_type,Eigen::ColMajor,stride_type>;
data_type data;
payload (data_type const& o) : data(o) {}
payload (float* ptr, Index r, Index c) : data(ptr,r,c) {}
payload (float* ptr, Index r, Index c, stride_type s) : data(ptr,r,c,s) {}
};
struct map_impl32_row::payload
{
using stride_type = Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic>;
using base_type = Eigen::Matrix<float,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor>;
using data_type = Eigen::Map<base_type,Eigen::RowMajor,stride_type>;
data_type data;
payload (data_type const& o) : data(o) {}
payload (float* ptr, Index r, Index c) : data(ptr,r,c) {}
payload (float* ptr, Index r, Index c, stride_type s) : data(ptr,r,c,s) {}
};
struct map_const_impl64_col::payload
{
using stride_type = Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic>;
using base_type = Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,Eigen::ColMajor>;
using data_type = Eigen::Map<base_type const,Eigen::ColMajor,stride_type>;
data_type data;
payload (data_type const& o) : data(o) {}
payload (double const* ptr, Index r, Index c) : data(ptr,r,c) {}
payload (double const* ptr, Index r, Index c, stride_type s) : data(ptr,r,c,s) {}
};
struct map_const_impl64_row::payload
{
using stride_type = Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic>;
using base_type = Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor>;
using data_type = Eigen::Map<base_type const,Eigen::RowMajor,stride_type>;
data_type data;
payload (data_type const& o) : data(o) {}
payload (double const* ptr, Index r, Index c) : data(ptr,r,c) {}
payload (double const* ptr, Index r, Index c, stride_type s) : data(ptr,r,c,s) {}
};
struct map_impl64_col::payload
{
using stride_type = Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic>;
using base_type = Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,Eigen::ColMajor>;
using data_type = Eigen::Map<base_type,Eigen::ColMajor,stride_type>;
data_type data;
payload (data_type const& o) : data(o) {}
payload (double* ptr, Index r, Index c) : data(ptr,r,c) {}
payload (double* ptr, Index r, Index c, stride_type s) : data(ptr,r,c,s) {}
};
struct map_impl64_row::payload
{
using stride_type = Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic>;
using base_type = Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor>;
using data_type = Eigen::Map<base_type,Eigen::RowMajor,stride_type>;
data_type data;
payload (data_type const& o) : data(o) {}
payload (double* ptr, Index r, Index c) : data(ptr,r,c) {}
payload (double* ptr, Index r, Index c, stride_type s) : data(ptr,r,c,s) {}
};
}

View file

@ -0,0 +1,71 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once
#include <rotgen/concepts.hpp>
#include <cassert>
#include <iosfwd>
namespace rotgen
{
template<concepts::entity E>
std::ostream& operator<<(std::ostream& os, E const& arg)
{
return os << arg.base();
}
template<typename A, typename B>
constexpr bool operator==(A const& a, B const& b) noexcept
requires(concepts::entity<A> || concepts::entity<B>)
{
static_assert ( std::same_as<typename A::value_type,typename B::value_type>
, "[ROTGEN] Incompatible type in operator=="
);
if constexpr(!use_expression_templates) return generalize_t<A const>(a) == generalize_t<B const>(b);
else return base_of(a) == base_of(b);
}
template<typename A, typename B>
constexpr bool operator!=(A const& a, B const& b) noexcept
requires(concepts::entity<A> || concepts::entity<B>)
{
static_assert ( std::same_as<typename A::value_type,typename B::value_type>
, "[ROTGEN] Incompatible type in operator!="
);
if constexpr(!use_expression_templates) return generalize_t<A const>(a) != generalize_t<B const>(b);
else return base_of(a) != base_of(b);
}
template<typename A, typename B>
auto operator+(A const& a, B const& b) requires(concepts::entity<A> || concepts::entity<B>)
{
if constexpr(!use_expression_templates) return generalize_t<A const>(a) + generalize_t<B const>(b);
else return base_of(a) + base_of(b);
}
template<typename A, typename B>
auto operator-(A const& a, B const& b) requires(concepts::entity<A> || concepts::entity<B>)
{
if constexpr(!use_expression_templates) return generalize_t<A const>(a) - generalize_t<B const>(b);
else return base_of(a) - base_of(b);
}
template<typename A, typename B>
auto operator*(A const& a, B const& b) requires(concepts::entity<A> || concepts::entity<B>)
{
if constexpr(!use_expression_templates) return generalize_t<A const>(a) * generalize_t<B const>(b);
else return base_of(a) * base_of(b);
}
template<typename A, typename B>
auto operator/(A const& a, B const& b) requires(concepts::entity<A> && std::is_arithmetic_v<B>)
{
if constexpr(!use_expression_templates) return generalize_t<A const>(a) / b;
else return base_of(a) / b;
}
}

View file

@ -9,14 +9,21 @@
#include <rotgen/config.hpp>
#include <rotgen/concepts.hpp>
#include <rotgen/common/traits.hpp>
#include <rotgen/common/strides.hpp>
#if defined(ROTGEN_FORCE_DYNAMIC)
#include <rotgen/dynamic/matrix.hpp>
#include <rotgen/dynamic/block.hpp>
#include <rotgen/dynamic/map.hpp>
#else
#include <rotgen/fixed/matrix.hpp>
#include <rotgen/fixed/block.hpp>
#include <rotgen/fixed/map.hpp>
#endif
#include <rotgen/common/ref.hpp>
#include <rotgen/extract.hpp>
#include <rotgen/functions.hpp>
#include <rotgen/operators.hpp>
#include <rotgen/alias.hpp>