- Refurbish block implementation to support nested block
- Add missing extractors
This commit is contained in:
parent
3fff326db9
commit
93a1404d9a
24 changed files with 1205 additions and 630 deletions
|
|
@ -25,6 +25,8 @@ namespace rotgen
|
||||||
using value_type = typename T::value_type;
|
using value_type = typename T::value_type;
|
||||||
using rotgen_tag = void;
|
using rotgen_tag = void;
|
||||||
|
|
||||||
|
static constexpr int storage_order = T::storage_order;
|
||||||
|
|
||||||
using parent::operator();
|
using parent::operator();
|
||||||
using parent::rows;
|
using parent::rows;
|
||||||
using parent::cols;
|
using parent::cols;
|
||||||
|
|
@ -59,19 +61,19 @@ namespace rotgen
|
||||||
ref(matrix<S, R, C, O, MR, MC>& m)
|
ref(matrix<S, R, C, O, MR, MC>& m)
|
||||||
: parent(m.data(), m.rows(), m.cols(), strides(m))
|
: parent(m.data(), m.rows(), m.cols(), strides(m))
|
||||||
{
|
{
|
||||||
static_assert((O & 1) == Options, "ref: Incompatible storage layout");
|
static_assert((O & 1) == storage_order, "ref: Incompatible storage layout");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ref, int R, int C, bool I, int FS>
|
template<typename Ref, int R, int C, bool I>
|
||||||
ref(block<Ref,R,C,I,FS>& b) : parent(b.data(), b.rows(), b.cols(), stride_type{b.outerStride(),b.innerStride()})
|
ref(block<Ref,R,C,I>& b) : parent(b.data(), b.rows(), b.cols(), stride_type{b.outerStride(),b.innerStride()})
|
||||||
{
|
{
|
||||||
static_assert((Ref::Options & 1) == Options, "ref: Incompatible storage layout");
|
static_assert((Ref::storage_order & 1) == storage_order, "ref: Incompatible storage layout");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ref, int O, typename S>
|
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()})
|
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");
|
static_assert((Ref::storage_order & 1) == storage_order, "ref: Incompatible storage layout");
|
||||||
}
|
}
|
||||||
|
|
||||||
ref(parent& m) : parent(m.data(), m.rows(), m.cols()) {}
|
ref(parent& m) : parent(m.data(), m.rows(), m.cols()) {}
|
||||||
|
|
@ -89,7 +91,9 @@ namespace rotgen
|
||||||
public:
|
public:
|
||||||
using parent = map<const T, Options,Stride>;
|
using parent = map<const T, Options,Stride>;
|
||||||
using value_type = typename T::value_type;
|
using value_type = typename T::value_type;
|
||||||
using rotgen_tag = void;
|
using rotgen_tag = void;
|
||||||
|
|
||||||
|
static constexpr int storage_order = T::storage_order;
|
||||||
|
|
||||||
using parent::operator();
|
using parent::operator();
|
||||||
using parent::rows;
|
using parent::rows;
|
||||||
|
|
@ -125,19 +129,19 @@ namespace rotgen
|
||||||
ref(matrix<S, R, C, O, MR, MC> const& m)
|
ref(matrix<S, R, C, O, MR, MC> const& m)
|
||||||
: parent(m.data(), m.rows(), m.cols(), strides(m))
|
: parent(m.data(), m.rows(), m.cols(), strides(m))
|
||||||
{
|
{
|
||||||
static_assert((O & 1) == Options, "ref: Incompatible storage layout");
|
static_assert((O & 1) == storage_order, "ref: Incompatible storage layout");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ref, int R, int C, bool I, int FS>
|
template<typename Ref, int R, int C, bool I>
|
||||||
ref(block<Ref,R,C,I,FS> const& b) : parent(b.data(), b.rows(), b.cols(), stride_type{b.outerStride(),b.innerStride()})
|
ref(block<Ref,R,C,I> 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");
|
static_assert((Ref::storage_order & 1) == storage_order, "ref: Incompatible storage layout");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ref, int O, typename S>
|
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()})
|
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");
|
static_assert((Ref::storage_order & 1) == storage_order, "ref: Incompatible storage layout");
|
||||||
}
|
}
|
||||||
|
|
||||||
ref(parent const& m) : parent(m.data(), m.rows(), m.cols()) {}
|
ref(parent const& m) : parent(m.data(), m.rows(), m.cols()) {}
|
||||||
|
|
@ -151,14 +155,14 @@ namespace rotgen
|
||||||
template<typename S, int R, int C, int O, int MR, int MC>
|
template<typename S, int R, int C, int O, int MR, int MC>
|
||||||
ref(matrix<S, R, C, O, MR, MC>&) -> ref<matrix<S>>;
|
ref(matrix<S, R, C, O, MR, MC>&) -> ref<matrix<S>>;
|
||||||
|
|
||||||
template<typename Ref, int R, int C, bool I, int FS>
|
template<typename Ref, int R, int C, bool I>
|
||||||
ref(block<Ref,R,C,I,FS>& b) -> ref<Ref>;
|
ref(block<Ref,R,C,I>& b) -> ref<Ref>;
|
||||||
|
|
||||||
template<typename S, int R, int C, int O, int MR, int MC>
|
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>;
|
ref(matrix<S, R, C, O, MR, MC> const&) -> ref<matrix<S> const>;
|
||||||
|
|
||||||
template<typename Ref, int R, int C, bool I, int FS>
|
template<typename Ref, int R, int C, bool I>
|
||||||
ref(block<Ref,R,C,I,FS> const& b) -> ref<Ref const>;
|
ref(block<Ref,R,C,I> const& b) -> ref<Ref const>;
|
||||||
|
|
||||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||||
bool operator==(ref<A,O,S> lhs, ref<B,P,T> rhs)
|
bool operator==(ref<A,O,S> lhs, ref<B,P,T> rhs)
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,8 @@ namespace rotgen::concepts
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept entity = requires(T const&)
|
concept entity = requires(T const&)
|
||||||
{
|
{
|
||||||
typename T::rotgen_tag;
|
typename std::remove_cvref_t<T>::rotgen_tag;
|
||||||
typename T::parent;
|
typename std::remove_cvref_t<T>::parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
//================================================================================================
|
//================================================================================================
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
namespace rotgen
|
namespace rotgen
|
||||||
{
|
{
|
||||||
template<typename Ref, int Rows = Dynamic, int Cols = Dynamic, bool Inner = false, int ForceStorageOrder = -1>
|
template<typename Ref, int Rows = Dynamic, int Cols = Dynamic, bool Inner = false>
|
||||||
class block : public find_block<Ref>
|
class block : public find_block<Ref>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -25,20 +25,24 @@ namespace rotgen
|
||||||
|
|
||||||
using parent = find_block<Ref>;
|
using parent = find_block<Ref>;
|
||||||
using rotgen_tag = void;
|
using rotgen_tag = void;
|
||||||
using value_type = typename Ref::value_type;
|
using rotgen_block_tag = void;
|
||||||
static constexpr int storage_order = (ForceStorageOrder == -1) ? Ref::storage_order : ForceStorageOrder;
|
using value_type = typename std::remove_const_t<Ref>::value_type;
|
||||||
|
|
||||||
|
static constexpr int storage_order = Ref::storage_order;
|
||||||
|
static constexpr bool is_immutable = std::is_const_v<Ref>;
|
||||||
using concrete_type = matrix<value_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>;
|
using concrete_dynamic_type = matrix<value_type,Dynamic,Dynamic,storage_order>;
|
||||||
|
|
||||||
static constexpr int RowsAtCompileTime = Rows;
|
static constexpr int RowsAtCompileTime = Rows;
|
||||||
static constexpr int ColsAtCompileTime = Cols;
|
static constexpr int ColsAtCompileTime = Cols;
|
||||||
static constexpr int Options = Ref::Options;
|
static constexpr int Options = Ref::Options;
|
||||||
|
static constexpr bool IsRowMajor = (storage_order & RowMajor) == RowMajor;
|
||||||
|
|
||||||
static constexpr bool is_defined_static = false;
|
static constexpr bool is_defined_static = false;
|
||||||
static constexpr bool has_static_storage = false;
|
static constexpr bool has_static_storage = false;
|
||||||
|
|
||||||
using parent::operator=;
|
using parent::operator=;
|
||||||
block& operator=(concepts::entity auto const& other)
|
block& operator=(concepts::entity auto const& other) requires(!is_immutable)
|
||||||
{
|
{
|
||||||
assert(parent::rows() == other.rows() && parent::cols() == other.cols());
|
assert(parent::rows() == other.rows() && parent::cols() == other.cols());
|
||||||
for (rotgen::Index r = 0; r < parent::rows(); ++r)
|
for (rotgen::Index r = 0; r < parent::rows(); ++r)
|
||||||
|
|
@ -48,26 +52,58 @@ namespace rotgen
|
||||||
return *this;
|
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)
|
block(Ref const& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
||||||
|
requires( !requires{typename Ref::rotgen_block_tag; } && is_immutable)
|
||||||
|
: parent(r,i0,j0,ni,nj)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
block(Ref& r, std::size_t i0, std::size_t j0) requires(Rows != -1 && Cols != -1)
|
block(Ref const& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
||||||
|
requires( requires{typename Ref::rotgen_block_tag; } && is_immutable)
|
||||||
|
: parent(*r.storage(),i0,j0,ni,nj)
|
||||||
|
{}
|
||||||
|
|
||||||
|
block(Ref const& r, std::size_t i0, std::size_t j0)
|
||||||
|
requires(!requires{typename Ref::rotgen_block_tag; } && Rows != -1 && Cols != -1 && is_immutable)
|
||||||
: parent(r,i0,j0,Rows,Cols)
|
: parent(r,i0,j0,Rows,Cols)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
block(Ref const& r, std::size_t i0, std::size_t j0)
|
||||||
|
requires(requires{typename Ref::rotgen_block_tag; } && Rows != -1 && Cols != -1 && is_immutable)
|
||||||
|
: parent(*r.storage(),i0,j0,Rows,Cols)
|
||||||
|
{}
|
||||||
|
|
||||||
|
block(Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
||||||
|
requires( !requires{typename Ref::rotgen_block_tag; } && !is_immutable)
|
||||||
|
: parent(r,i0,j0,ni,nj)
|
||||||
|
{}
|
||||||
|
|
||||||
|
block(Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
||||||
|
requires( requires{typename Ref::rotgen_block_tag; } && !is_immutable)
|
||||||
|
: parent(*r.storage(),i0,j0,ni,nj)
|
||||||
|
{}
|
||||||
|
|
||||||
|
block(Ref& r, std::size_t i0, std::size_t j0)
|
||||||
|
requires(!requires{typename Ref::rotgen_block_tag; } && Rows != -1 && Cols != -1 && !is_immutable)
|
||||||
|
: parent(r,i0,j0,Rows,Cols)
|
||||||
|
{}
|
||||||
|
|
||||||
|
block(Ref& r, std::size_t i0, std::size_t j0)
|
||||||
|
requires(requires{typename Ref::rotgen_block_tag; } && Rows != -1 && Cols != -1 && !is_immutable)
|
||||||
|
: parent(*r.storage(),i0,j0,Rows,Cols)
|
||||||
|
{}
|
||||||
|
|
||||||
block(parent const& base) : parent(base) {}
|
block(parent const& base) : parent(base) {}
|
||||||
|
|
||||||
bool is_contiguous_linear() const
|
bool is_contiguous_linear() const
|
||||||
{
|
{
|
||||||
if(parent::innerStride() != 1) return false;
|
if(parent::innerStride() != 1) return false;
|
||||||
// outer‐stride must equal the “inner‐dimension length”
|
|
||||||
if constexpr(storage_order) return parent::outerStride() == parent::cols();
|
if constexpr(storage_order) return parent::outerStride() == parent::cols();
|
||||||
else return parent::outerStride() == parent::rows();
|
else return parent::outerStride() == parent::rows();
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type& operator()(Index i, Index j) { return parent::operator()(i,j); }
|
value_type& operator()(Index i, Index j) requires(!is_immutable) { return parent::operator()(i,j); }
|
||||||
|
|
||||||
value_type& operator()(Index i)
|
value_type& operator()(Index i) requires(!is_immutable)
|
||||||
{
|
{
|
||||||
assert(is_contiguous_linear());
|
assert(is_contiguous_linear());
|
||||||
return parent::operator()(i);
|
return parent::operator()(i);
|
||||||
|
|
@ -96,22 +132,22 @@ namespace rotgen
|
||||||
return concrete_type(static_cast<parent const &>(*this).adjoint());
|
return concrete_type(static_cast<parent const &>(*this).adjoint());
|
||||||
}
|
}
|
||||||
|
|
||||||
void transposeInPlace() { parent::transposeInPlace(); }
|
void transposeInPlace() requires(!is_immutable) { parent::transposeInPlace(); }
|
||||||
|
|
||||||
void adjointInPlace() { parent::adjointInPlace(); }
|
void adjointInPlace() requires(!is_immutable) { parent::adjointInPlace(); }
|
||||||
|
|
||||||
friend bool operator==(block const& lhs, block const& rhs)
|
friend bool operator==(block const& lhs, block const& rhs)
|
||||||
{
|
{
|
||||||
return static_cast<parent const&>(lhs) == static_cast<parent const&>(rhs);
|
return static_cast<parent const&>(lhs) == static_cast<parent const&>(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator+=(block const& rhs)
|
block& operator+=(block const& rhs) requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() += static_cast<parent const&>(rhs);
|
base() += static_cast<parent const&>(rhs);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator-=(block const& rhs)
|
block& operator-=(block const& rhs) requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() -= static_cast<parent const&>(rhs);
|
base() -= static_cast<parent const&>(rhs);
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -122,19 +158,19 @@ namespace rotgen
|
||||||
return concrete_type(static_cast<parent const&>(*this).operator-());
|
return concrete_type(static_cast<parent const&>(*this).operator-());
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator*=(block const& rhs)
|
block& operator*=(block const& rhs) requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() *= static_cast<parent const&>(rhs);
|
base() *= static_cast<parent const&>(rhs);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator*=(value_type rhs)
|
block& operator*=(value_type rhs) requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() *= rhs;
|
base() *= rhs;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator/=(value_type rhs)
|
block& operator/=(value_type rhs) requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() /= rhs;
|
base() /= rhs;
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -205,31 +241,31 @@ namespace rotgen
|
||||||
return parent::Identity(rows, cols);
|
return parent::Identity(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setOnes()
|
block& setOnes() requires(!is_immutable)
|
||||||
{
|
{
|
||||||
parent::assign(parent::Ones(parent::rows(), parent::cols()));
|
parent::assign(parent::Ones(parent::rows(), parent::cols()));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setZero()
|
block& setZero() requires(!is_immutable)
|
||||||
{
|
{
|
||||||
parent::assign(parent::Zero(parent::rows(), parent::cols()));
|
parent::assign(parent::Zero(parent::rows(), parent::cols()));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setConstant(value_type value)
|
block& setConstant(value_type value) requires(!is_immutable)
|
||||||
{
|
{
|
||||||
parent::assign(parent::Constant(parent::rows(), parent::cols(), value));
|
parent::assign(parent::Constant(parent::rows(), parent::cols(), value));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setRandom()
|
block& setRandom() requires(!is_immutable)
|
||||||
{
|
{
|
||||||
parent::assign(parent::Random(parent::rows(), parent::cols()));
|
parent::assign(parent::Random(parent::rows(), parent::cols()));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setIdentity()
|
block& setIdentity() requires(!is_immutable)
|
||||||
{
|
{
|
||||||
parent::assign(parent::Identity(parent::rows(), parent::cols()));
|
parent::assign(parent::Identity(parent::rows(), parent::cols()));
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -246,45 +282,45 @@ namespace rotgen
|
||||||
parent const& base() const { return static_cast<parent const&>(*this); }
|
parent const& base() const { return static_cast<parent const&>(*this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Ref, int R, int C, bool I, int F>
|
template<typename Ref, int R, int C, bool I>
|
||||||
auto operator+(block<Ref, R, C, I, F> const& lhs, block<Ref, R, C, I, F> const& rhs)
|
auto operator+(block<Ref, R, C, I> const& lhs, block<Ref, R, C, I> const& rhs)
|
||||||
{
|
{
|
||||||
using concrete_type = typename block<Ref, R, C, I, F>::concrete_type;
|
using concrete_type = typename block<Ref, R, C, I>::concrete_type;
|
||||||
return concrete_type(lhs.base().add(rhs));
|
return concrete_type(lhs.base().add(rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ref, int R, int C, bool I, int F>
|
template<typename Ref, int R, int C, bool I>
|
||||||
auto operator-(block<Ref, R, C, I, F> const& lhs, block<Ref, R, C, I, F> const& rhs)
|
auto operator-(block<Ref, R, C, I> const& lhs, block<Ref, R, C, I> const& rhs)
|
||||||
{
|
{
|
||||||
using concrete_type = typename block<Ref, R, C, I, F>::concrete_type;
|
using concrete_type = typename block<Ref, R, C, I>::concrete_type;
|
||||||
return concrete_type(lhs.base().sub(rhs));
|
return concrete_type(lhs.base().sub(rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ref, int R, int C, bool I, int F>
|
template<typename Ref, int R, int C, bool I>
|
||||||
auto operator*(block<Ref, R, C, I, F> const& lhs, block<Ref, R, C, I, F> const& rhs)
|
auto operator*(block<Ref, R, C, I> const& lhs, block<Ref, R, C, I> const& rhs)
|
||||||
{
|
{
|
||||||
using concrete_type = typename block<Ref, R, C, I, F>::concrete_type;
|
using concrete_type = typename block<Ref, R, C, I>::concrete_type;
|
||||||
return concrete_type(lhs.base().mul(rhs));
|
return concrete_type(lhs.base().mul(rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ref, int R, int C, bool I, int F>
|
template<typename Ref, int R, int C, bool I>
|
||||||
auto operator*(block<Ref, R, C, I, F> const& lhs, double rhs)
|
auto operator*(block<Ref, R, C, I> const& lhs, double rhs)
|
||||||
{
|
{
|
||||||
using concrete_type = typename block<Ref, R, C, I, F>::concrete_type;
|
using concrete_type = typename block<Ref, R, C, I>::concrete_type;
|
||||||
return concrete_type(lhs.base().mul(rhs));
|
return concrete_type(lhs.base().mul(rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ref, int R, int C, bool I, int F>
|
template<typename Ref, int R, int C, bool I>
|
||||||
auto operator*(double lhs, block<Ref, R, C, I, F> const& rhs)
|
auto operator*(double lhs, block<Ref, R, C, I> const& rhs)
|
||||||
{
|
{
|
||||||
using concrete_type = typename block<Ref, R, C, I, F>::concrete_type;
|
using concrete_type = typename block<Ref, R, C, I>::concrete_type;
|
||||||
return concrete_type(rhs.base().mul(lhs));
|
return concrete_type(rhs.base().mul(lhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ref, int R, int C, bool I, int F>
|
template<typename Ref, int R, int C, bool I>
|
||||||
auto operator/(block<Ref, R, C, I, F> const& lhs, double rhs)
|
auto operator/(block<Ref, R, C, I> const& lhs, double rhs)
|
||||||
{
|
{
|
||||||
using concrete_type = typename block<Ref, R, C, I, F>::concrete_type;
|
using concrete_type = typename block<Ref, R, C, I>::concrete_type;
|
||||||
return concrete_type(lhs.base().div(rhs));
|
return concrete_type(lhs.base().div(rhs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -22,12 +22,14 @@ namespace rotgen
|
||||||
, "[ROTGEN][CRITICAL] - Map of non-rotgen type instanciated"
|
, "[ROTGEN][CRITICAL] - Map of non-rotgen type instanciated"
|
||||||
);
|
);
|
||||||
|
|
||||||
using parent = find_map<Ref>;
|
using parent = find_map<Ref>;
|
||||||
using rotgen_tag = void;
|
using rotgen_tag = void;
|
||||||
using value_type = typename std::remove_const_t<Ref>::value_type;
|
using value_type = typename std::remove_const_t<Ref>::value_type;
|
||||||
using concrete_type = typename std::remove_const_t<Ref>::concrete_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 IsRowMajor = Ref::IsRowMajor;
|
||||||
|
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_immutable = std::is_const_v<Ref>;
|
||||||
static constexpr bool is_defined_static = false;
|
static constexpr bool is_defined_static = false;
|
||||||
|
|
|
||||||
|
|
@ -21,17 +21,18 @@ namespace rotgen
|
||||||
class matrix : public find_matrix<Scalar,Opts>
|
class matrix : public find_matrix<Scalar,Opts>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using parent = find_matrix<Scalar,Opts>;
|
using parent = find_matrix<Scalar,Opts>;
|
||||||
using rotgen_tag = void;
|
using rotgen_tag = void;
|
||||||
using concrete_type = matrix;
|
using concrete_type = matrix;
|
||||||
using value_type = Scalar;
|
using value_type = Scalar;
|
||||||
static constexpr auto storage_order = Opts & 1;
|
|
||||||
|
|
||||||
static constexpr int RowsAtCompileTime = Rows;
|
static constexpr auto storage_order = Opts & 1;
|
||||||
static constexpr int ColsAtCompileTime = Cols;
|
static constexpr int RowsAtCompileTime = Rows;
|
||||||
static constexpr int Options = Opts;
|
static constexpr int ColsAtCompileTime = Cols;
|
||||||
static constexpr bool is_defined_static = false;
|
static constexpr int Options = Opts;
|
||||||
static constexpr bool has_static_storage = false;
|
static constexpr bool IsRowMajor = (Opts & RowMajor) == RowMajor;
|
||||||
|
static constexpr bool is_defined_static = false;
|
||||||
|
static constexpr bool has_static_storage = false;
|
||||||
|
|
||||||
matrix() : parent(Rows==-1?0:Rows,Cols==-1?0:Cols) {}
|
matrix() : parent(Rows==-1?0:Rows,Cols==-1?0:Cols) {}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,224 +9,233 @@
|
||||||
|
|
||||||
namespace rotgen
|
namespace rotgen
|
||||||
{
|
{
|
||||||
template< typename S, int R , int C
|
namespace detail
|
||||||
, int Opts , int MaxR, int MaxC
|
|
||||||
>
|
|
||||||
auto extract(matrix<S,R,C,Opts,MaxR,MaxC>& m, int i0, int j0,int ni, int nj)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
template<concepts::entity Entity>
|
||||||
return block<base>(m, i0,j0,ni,nj);
|
void validate_extract ( [[maybe_unused]] Entity& e
|
||||||
|
, [[maybe_unused]] Index i0, [[maybe_unused]] Index j0
|
||||||
|
, [[maybe_unused]] Index ni, [[maybe_unused]] Index nj
|
||||||
|
)
|
||||||
|
{
|
||||||
|
assert(i0 >= 0 && "block extraction uses negative row index.");
|
||||||
|
assert(j0 >= 0 && "block extraction uses negative col index.");
|
||||||
|
assert(i0 + ni <= e.rows() && "block extraction rows is out of range.");
|
||||||
|
assert(j0 + nj <= e.cols() && "block extraction cols is out of range.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//======================== EXTRACT ========================
|
||||||
|
template<concepts::entity Entity>
|
||||||
|
auto extract(Entity& e, Index i0, Index j0, Index ni, Index nj)
|
||||||
|
{
|
||||||
|
detail::validate_extract(e,i0,j0,ni,nj);
|
||||||
|
return block<Entity>(e, i0, j0, ni, nj);
|
||||||
}
|
}
|
||||||
|
|
||||||
template< int NI, int NJ
|
template<Index NI, Index NJ, concepts::entity Entity>
|
||||||
, typename S, int R , int C
|
requires(NI!=-1 && NJ!=-1)
|
||||||
, int Opts , int MaxR, int MaxC
|
auto extract(Entity& e, Index i0, Index j0)
|
||||||
>
|
|
||||||
auto extract(matrix<S,R,C,Opts,MaxR,MaxC>& m, int i0, int j0)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
detail::validate_extract(e,i0,j0,NI,NJ);
|
||||||
return block<base,NI,NJ>(m,i0,j0);
|
return block<Entity,NI,NJ>(e, i0, j0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename S, int R , int C
|
template<Index NI, Index NJ, concepts::entity Entity>
|
||||||
, int Opts , int MaxR, int MaxC
|
requires((NI!=-1) != (NJ!=-1))
|
||||||
>
|
auto extract(Entity& e, Index i0, Index j0, Index ni, Index nj)
|
||||||
auto topLeftCorner(matrix<S,R,C,Opts,MaxR,MaxC>& m, int ni, int nj)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
detail::validate_extract(e,i0,j0,ni,nj);
|
||||||
return block<base>(m,0,0,ni,nj);
|
return block<Entity,NI,NJ>(e, i0, j0, ni, nj);
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename S, int R , int C
|
//======================== TOP LEFT CORNER ========================
|
||||||
, int Opts , int MaxR, int MaxC
|
template<concepts::entity Entity>
|
||||||
>
|
auto topLeftCorner(Entity& e, Index ni, Index nj)
|
||||||
auto topRightCorner(matrix<S,R,C,Opts,MaxR,MaxC>& m, int ni, int nj)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract(e, 0, 0, ni, nj);
|
||||||
return block<base>(m,0,m.cols()-nj,ni,nj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename S, int R , int C
|
template<Index NI, Index NJ, concepts::entity Entity>
|
||||||
, int Opts , int MaxR, int MaxC
|
auto topLeftCorner(Entity& e)
|
||||||
>
|
|
||||||
auto bottomLeftCorner(matrix<S,R,C,Opts,MaxR,MaxC>& m, int ni, int nj)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract<NI,NJ>(e, 0, 0);
|
||||||
return block<base>(m,m.rows()-ni,0,ni,nj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename S, int R , int C
|
//======================== TOP RIGHT CORNER ========================
|
||||||
, int Opts , int MaxR, int MaxC
|
template<concepts::entity Entity>
|
||||||
>
|
auto topRightCorner(Entity& e, Index ni, Index nj)
|
||||||
auto bottomRightCorner(matrix<S,R,C,Opts,MaxR,MaxC>& m, int ni, int nj)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract(e, 0, e.cols() - nj, ni, nj);
|
||||||
return block<base>(m,m.rows()-ni,m.cols()-nj,ni,nj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename S, int R , int C
|
template<Index NI, Index NJ, concepts::entity Entity>
|
||||||
, int Opts , int MaxR, int MaxC
|
auto topRightCorner(Entity& e)
|
||||||
>
|
|
||||||
auto topRows(matrix<S,R,C,Opts,MaxR,MaxC>& m, int ni)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract<NI,NJ>(e, 0, e.cols()-NJ);
|
||||||
return block<base>(m,0,0,ni,m.cols());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename S, int R , int C,
|
//======================== BOTTOM LEFT CORNER ========================
|
||||||
int Opts , int MaxR, int MaxC
|
template<concepts::entity Entity>
|
||||||
>
|
auto bottomLeftCorner(Entity& e, Index ni, Index nj)
|
||||||
auto middleRows(matrix<S,R,C,Opts,MaxR,MaxC>& m, int i0, int ni)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract(e, e.rows() - ni, 0, ni, nj);
|
||||||
return block<base>(m,i0,0,ni,m.cols());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename S, int R , int C
|
template<Index NI, Index NJ, concepts::entity Entity>
|
||||||
, int Opts , int MaxR, int MaxC
|
auto bottomLeftCorner(Entity& e)
|
||||||
>
|
|
||||||
auto bottomRows(matrix<S,R,C,Opts,MaxR,MaxC>& m, int ni)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract<NI,NJ>(e, e.rows()-NI, 0);
|
||||||
return block<base>(m,m.rows()-ni,0,ni,m.cols());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename S, int R , int C
|
//======================== BOTTOM RIGHT CORNER ========================
|
||||||
, int Opts , int MaxR, int MaxC
|
template<concepts::entity Entity>
|
||||||
>
|
auto bottomRightCorner(Entity& e, Index ni, Index nj)
|
||||||
auto leftCols(matrix<S,R,C,Opts,MaxR,MaxC>& m, int nj)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract(e, e.rows() - ni, e.cols() - nj, ni, nj);
|
||||||
return block<base>(m,0,0,m.rows(),nj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename S, int R , int C,
|
template<Index NI, Index NJ, concepts::entity Entity>
|
||||||
int Opts , int MaxR, int MaxC
|
auto bottomRightCorner(Entity& e)
|
||||||
>
|
|
||||||
auto middleCols(matrix<S,R,C,Opts,MaxR,MaxC>& m, int j0, int nj)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract<NI,NJ>(e, e.rows()-NI, e.cols()-NJ);
|
||||||
return block<base>(m,0,j0,m.rows(),nj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename S, int R , int C
|
//======================== TOP ROWS ========================
|
||||||
, int Opts , int MaxR, int MaxC
|
template<concepts::entity Entity>
|
||||||
>
|
auto topRows(Entity& e, Index ni)
|
||||||
auto rightCols(matrix<S,R,C,Opts,MaxR,MaxC>& m, int nj)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract(e, 0, 0, ni, e.cols());
|
||||||
return block<base>(m,0,m.cols()-nj,m.rows(),nj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename S, int R, int C
|
template<Index NI, concepts::entity Entity>
|
||||||
, int Opts , int MaxR, int MaxC
|
auto topRows(Entity& e)
|
||||||
>
|
|
||||||
auto row(matrix<S,R,C,Opts,MaxR,MaxC>& m, int i0)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract<NI,-1>(e, 0, 0, NI,e.cols());
|
||||||
return block<base,1, -1, false, 1>(m,i0,0, 1, m.cols());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename S, int R, int C
|
//======================== MIDDLE ROWS ========================
|
||||||
, int Opts , int MaxR, int MaxC
|
template<concepts::entity Entity>
|
||||||
>
|
auto middleRows(Entity& e, Index i0, Index ni)
|
||||||
auto col(matrix<S,R,C,Opts,MaxR,MaxC>& m, int j0)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract(e, i0, 0, ni, e.cols());
|
||||||
return block<base,-1,1, false, 0>(m,0,j0, m.rows(), 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< int NI, typename S, int R, int C,
|
template<Index NI, concepts::entity Entity>
|
||||||
int Opts, int MaxR, int MaxC
|
auto middleRows(Entity& e, Index i0)
|
||||||
>
|
|
||||||
auto topRows(matrix<S,R,C,Opts,MaxR,MaxC>& m)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract<NI,-1>(e, i0, 0,NI,e.cols());
|
||||||
return block<base,NI,-1>(m,0,0, NI, m.cols());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< int NI, typename S, int R, int C,
|
//======================== BOTTOM ROWS ========================
|
||||||
int Opts, int MaxR, int MaxC
|
template<concepts::entity Entity>
|
||||||
>
|
auto bottomRows(Entity& e, Index ni)
|
||||||
auto bottomRows(matrix<S,R,C,Opts,MaxR,MaxC>& m)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract(e, e.rows() - ni, 0, ni, e.cols());
|
||||||
return block<base,NI,-1>(m,m.rows()-NI,0, NI, m.cols());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< int NI, typename S, int R, int C,
|
template<Index NI, concepts::entity Entity>
|
||||||
int Opts , int MaxR, int MaxC
|
auto bottomRows(Entity& e)
|
||||||
>
|
|
||||||
auto middleRows(matrix<S,R,C,Opts,MaxR,MaxC>& m, int i0)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract<NI,-1>(e, e.rows()-NI, 0,NI,e.cols());
|
||||||
return block<base,NI,-1>(m,i0,0, NI, m.cols());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< int NJ, typename S, int R, int C,
|
//======================== LEFT COLS ========================
|
||||||
int Opts, int MaxR, int MaxC
|
template<concepts::entity Entity>
|
||||||
>
|
auto leftCols(Entity& e, Index nj)
|
||||||
auto leftCols(matrix<S,R,C,Opts,MaxR,MaxC>& m)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract(e, 0, 0, e.rows(), nj);
|
||||||
return block<base,-1,NJ>(m,0,0, m.rows(), NJ);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< int NJ, typename S, int R, int C,
|
template<Index NJ, concepts::entity Entity>
|
||||||
int Opts, int MaxR, int MaxC
|
auto leftCols(Entity& e)
|
||||||
>
|
|
||||||
auto rightCols(matrix<S,R,C,Opts,MaxR,MaxC>& m)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract<-1,NJ>(e, 0, 0,e.rows(),NJ);
|
||||||
return block<base,-1,NJ>(m,0,m.cols()-NJ, m.rows(), NJ);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< int NJ, typename S, int R, int C,
|
//======================== MIDDLE COLS ========================
|
||||||
int Opts , int MaxR, int MaxC
|
template<concepts::entity Entity>
|
||||||
>
|
auto middleCols(Entity& e, Index j0, Index nj)
|
||||||
auto middleCols(matrix<S,R,C,Opts,MaxR,MaxC>& m, int j0)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract(e, 0, j0, e.rows(), nj);
|
||||||
return block<base,-1,NJ>(m,0,j0, m.rows(), NJ);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< int NI, int NJ
|
template<Index NJ, concepts::entity Entity>
|
||||||
, typename S, int R , int C
|
auto middleCols(Entity& e, Index j0)
|
||||||
, int Opts , int MaxR, int MaxC
|
|
||||||
>
|
|
||||||
auto topLeftCorner(matrix<S,R,C,Opts,MaxR,MaxC>& m)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract<-1,NJ>(e, 0, j0,e.rows(),NJ);
|
||||||
return block<base,NI,NJ>(m,0,0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< int NI, int NJ
|
//======================== RIGHT COLS ========================
|
||||||
, typename S, int R , int C
|
template<concepts::entity Entity>
|
||||||
, int Opts , int MaxR, int MaxC
|
auto rightCols(Entity& e, Index nj)
|
||||||
>
|
|
||||||
auto topRightCorner(matrix<S,R,C,Opts,MaxR,MaxC>& m)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract(e, 0, e.cols() - nj, e.rows(), nj);
|
||||||
return block<base,NI,NJ>(m,0,m.cols()-NJ);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< int NI, int NJ
|
template<Index NJ, concepts::entity Entity>
|
||||||
, typename S, int R , int C
|
auto rightCols(Entity& e)
|
||||||
, int Opts , int MaxR, int MaxC
|
|
||||||
>
|
|
||||||
auto bottomLeftCorner(matrix<S,R,C,Opts,MaxR,MaxC>& m)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract<-1,NJ>(e, 0, e.cols()-NJ,e.rows(),NJ);
|
||||||
return block<base,NI,NJ>(m,m.rows()-NI,0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< int NI, int NJ
|
//======================== ROW ========================
|
||||||
, typename S, int R , int C
|
template<concepts::entity Entity>
|
||||||
, int Opts , int MaxR, int MaxC
|
auto row(Entity& e, Index i0)
|
||||||
>
|
|
||||||
auto bottomRightCorner(matrix<S,R,C,Opts,MaxR,MaxC>& m)
|
|
||||||
{
|
{
|
||||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
return extract<1,-1>(e, i0, 0, 1, e.cols());
|
||||||
return block<base,NI,NJ>(m,m.rows()-NI,m.cols()-NJ);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
//======================== COL ========================
|
||||||
|
template<concepts::entity Entity>
|
||||||
|
auto col(Entity& e, Index j0)
|
||||||
|
{
|
||||||
|
return extract<-1,1>(e, 0, j0, e.rows(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//======================== VECTOR HEAD ========================
|
||||||
|
template<concepts::entity Entity>
|
||||||
|
auto head(Entity& e, Index n)
|
||||||
|
requires(Entity::RowsAtCompileTime==1 || Entity::ColsAtCompileTime==1)
|
||||||
|
{
|
||||||
|
if constexpr(Entity::RowsAtCompileTime==1) return extract<1,Dynamic>(e,0,0,1,n);
|
||||||
|
else if constexpr(Entity::ColsAtCompileTime==1) return extract<Dynamic,1>(e,0,0,n,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<Index N, concepts::entity Entity>
|
||||||
|
auto head(Entity& e) requires(Entity::RowsAtCompileTime==1 || Entity::ColsAtCompileTime==1)
|
||||||
|
{
|
||||||
|
if constexpr(Entity::RowsAtCompileTime==1) return extract<1,N>(e,0,0);
|
||||||
|
else if constexpr(Entity::ColsAtCompileTime==1) return extract<N,1>(e,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//======================== VECTOR TAIL ========================
|
||||||
|
template<concepts::entity Entity>
|
||||||
|
auto tail(Entity& e, Index n)
|
||||||
|
requires(Entity::RowsAtCompileTime==1 || Entity::ColsAtCompileTime==1)
|
||||||
|
{
|
||||||
|
if constexpr(Entity::RowsAtCompileTime==1) return extract<1,Dynamic>(e,0,e.cols()-n,1,n);
|
||||||
|
else if constexpr(Entity::ColsAtCompileTime==1) return extract<Dynamic,1>(e,e.rows()-n,0,n,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<Index N, concepts::entity Entity>
|
||||||
|
auto tail(Entity& e) requires(Entity::RowsAtCompileTime==1 || Entity::ColsAtCompileTime==1)
|
||||||
|
{
|
||||||
|
if constexpr(Entity::RowsAtCompileTime==1) return extract<1,N>(e,0,e.cols()-N);
|
||||||
|
else if constexpr(Entity::ColsAtCompileTime==1) return extract<N,1>(e,e.rows()-N,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//======================== VECTOR SEGMENT ========================
|
||||||
|
template<concepts::entity Entity>
|
||||||
|
auto segment(Entity& e, Index s, Index n)
|
||||||
|
requires(Entity::RowsAtCompileTime==1 || Entity::ColsAtCompileTime==1)
|
||||||
|
{
|
||||||
|
if constexpr(Entity::RowsAtCompileTime==1) return extract<1,Dynamic>(e,0,s,1,n);
|
||||||
|
else if constexpr(Entity::ColsAtCompileTime==1) return extract<Dynamic,1>(e,s,0,n,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<Index N, concepts::entity Entity>
|
||||||
|
auto segment(Entity& e, Index s) requires(Entity::RowsAtCompileTime==1 || Entity::ColsAtCompileTime==1)
|
||||||
|
{
|
||||||
|
if constexpr(Entity::RowsAtCompileTime==1) return extract<1,N>(e,0,s);
|
||||||
|
else if constexpr(Entity::ColsAtCompileTime==1) return extract<N,1>(e,s,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,30 +14,43 @@ namespace rotgen
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template<typename Ref, int Rows, int Cols, bool Inner>
|
template<typename Ref, int Rows, int Cols, bool Inner, bool IsConst>
|
||||||
using block_type = std::conditional_t < storage_status<Rows,Cols,Rows,Cols>
|
struct compute_block_type
|
||||||
, Eigen::Block<typename Ref::parent, Rows, Cols, Inner>
|
{
|
||||||
, Eigen::Block<typename Ref::parent, Eigen::Dynamic, Eigen::Dynamic, Inner>
|
using ref_t = std::conditional_t<IsConst, typename Ref::parent const, typename Ref::parent>;
|
||||||
>;
|
|
||||||
|
using type = std::conditional_t < storage_status<Rows,Cols,Rows,Cols>
|
||||||
|
, Eigen::Block<ref_t, Rows, Cols, Inner>
|
||||||
|
, Eigen::Block<ref_t, Eigen::Dynamic, Eigen::Dynamic, Inner>
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Ref, int Rows, int Cols, bool Inner, bool IsConst>
|
||||||
|
using block_type = typename compute_block_type<Ref,Rows,Cols,Inner,IsConst>::type;
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename Ref
|
template< typename Ref
|
||||||
, int Rows = Dynamic, int Cols = Dynamic
|
, int Rows = Dynamic, int Cols = Dynamic
|
||||||
, bool Inner = false , int ForceStorageOrder = -1
|
, bool Inner = false , int ForceStorageOrder = -1
|
||||||
>
|
>
|
||||||
class block : private detail::block_type<Ref, Rows, Cols, Inner>
|
class block : private detail::block_type<std::remove_const_t<Ref>, Rows, Cols, Inner,std::is_const_v<Ref> >
|
||||||
{
|
{
|
||||||
static_assert ( concepts::entity<Ref>
|
static_assert ( concepts::entity<Ref>
|
||||||
, "[ROTGEN][CRITICAL] - Block of non-rotgen type instanciated"
|
, "[ROTGEN][CRITICAL] - Block of non-rotgen type instanciated"
|
||||||
);
|
);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using rotgen_tag = void;
|
using rotgen_tag = void;
|
||||||
using parent = detail::block_type<Ref, Rows, Cols, Inner>;
|
using rotgen_block_tag = void;
|
||||||
using value_type = typename parent::value_type;
|
using parent = detail::block_type<std::remove_const_t<Ref>, Rows, Cols, Inner,std::is_const_v<Ref>>;
|
||||||
using Index = typename parent::Index;
|
using value_type = typename parent::value_type;
|
||||||
|
using Index = typename parent::Index;
|
||||||
|
|
||||||
|
static constexpr int storage_order = (ForceStorageOrder == -1) ? Ref::storage_order : ForceStorageOrder;
|
||||||
|
static constexpr bool is_immutable = std::is_const_v<Ref>;
|
||||||
|
|
||||||
|
static constexpr bool IsRowMajor = parent::IsRowMajor;
|
||||||
|
|
||||||
static constexpr int storage_order = (ForceStorageOrder == -1) ? Ref::storage_order : ForceStorageOrder;
|
|
||||||
using concrete_type = matrix<value_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>;
|
using concrete_dynamic_type = matrix<value_type,Dynamic,Dynamic,storage_order>;
|
||||||
|
|
||||||
|
|
@ -58,10 +71,23 @@ namespace rotgen
|
||||||
block& operator=(const block&) = default;
|
block& operator=(const block&) = default;
|
||||||
block& operator=(block&&) = default;
|
block& operator=(block&&) = default;
|
||||||
|
|
||||||
block(Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj) : parent(r.base(),i0,j0,ni,nj)
|
block(Ref const& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
||||||
|
requires(is_immutable)
|
||||||
|
: parent(r.base(),i0,j0,ni,nj)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
block(Ref& r, std::size_t i0, std::size_t j0) requires(Rows != -1 && Cols != -1)
|
block(Ref const& r, std::size_t i0, std::size_t j0)
|
||||||
|
requires(Rows != -1 && Cols != -1 && is_immutable)
|
||||||
|
: parent(r.base(),i0,j0,Rows,Cols)
|
||||||
|
{}
|
||||||
|
|
||||||
|
block(Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
||||||
|
requires(!is_immutable)
|
||||||
|
: parent(r.base(),i0,j0,ni,nj)
|
||||||
|
{}
|
||||||
|
|
||||||
|
block(Ref& r, std::size_t i0, std::size_t j0)
|
||||||
|
requires(Rows != -1 && Cols != -1 && !is_immutable)
|
||||||
: parent(r.base(),i0,j0,Rows,Cols)
|
: parent(r.base(),i0,j0,Rows,Cols)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
@ -111,8 +137,8 @@ namespace rotgen
|
||||||
return as_concrete_type<decltype(res)>(res);
|
return as_concrete_type<decltype(res)>(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
void transposeInPlace() { parent::transposeInPlace(); }
|
void transposeInPlace() requires(!is_immutable) { parent::transposeInPlace(); }
|
||||||
void adjointInPlace() { parent::adjointInPlace(); }
|
void adjointInPlace() requires(!is_immutable) { parent::adjointInPlace(); }
|
||||||
|
|
||||||
static concrete_type Constant(value_type value) requires (Rows != -1 && Cols != -1)
|
static concrete_type Constant(value_type value) requires (Rows != -1 && Cols != -1)
|
||||||
{
|
{
|
||||||
|
|
@ -174,61 +200,61 @@ namespace rotgen
|
||||||
return parent::Random(rows, cols);
|
return parent::Random(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setOnes()
|
block& setOnes() requires(!is_immutable)
|
||||||
{
|
{
|
||||||
*this = parent::Ones(rows(), cols());
|
*this = parent::Ones(rows(), cols());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setOnes(int r, int c)
|
block& setOnes(int r, int c) requires(!is_immutable)
|
||||||
{
|
{
|
||||||
*this = parent::Ones(r, c);
|
*this = parent::Ones(r, c);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setZero()
|
block& setZero() requires(!is_immutable)
|
||||||
{
|
{
|
||||||
*this = parent::Zero(rows(), cols());
|
*this = parent::Zero(rows(), cols());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setZero(int r, int c)
|
block& setZero(int r, int c) requires(!is_immutable)
|
||||||
{
|
{
|
||||||
*this = parent::Zero(r,c);
|
*this = parent::Zero(r,c);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setConstant(value_type value)
|
block& setConstant(value_type value) requires(!is_immutable)
|
||||||
{
|
{
|
||||||
*this = parent::Constant(rows(), cols(), value);
|
*this = parent::Constant(rows(), cols(), value);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setConstant(int r, int c, value_type value)
|
block& setConstant(int r, int c, value_type value) requires(!is_immutable)
|
||||||
{
|
{
|
||||||
*this = parent::Constant(r,c, value);
|
*this = parent::Constant(r,c, value);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setRandom()
|
block& setRandom() requires(!is_immutable)
|
||||||
{
|
{
|
||||||
*this = parent::Random(rows(),cols());
|
*this = parent::Random(rows(),cols());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setRandom(int r, int c)
|
block& setRandom(int r, int c) requires(!is_immutable)
|
||||||
{
|
{
|
||||||
*this = parent::Random(r,c);
|
*this = parent::Random(r,c);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setIdentity()
|
block& setIdentity() requires(!is_immutable)
|
||||||
{
|
{
|
||||||
*this = parent::Identity(rows(),cols());
|
*this = parent::Identity(rows(),cols());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& setIdentity(int r, int c)
|
block& setIdentity(int r, int c) requires(!is_immutable)
|
||||||
{
|
{
|
||||||
*this = parent::Identity(r,c);
|
*this = parent::Identity(r,c);
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -249,10 +275,10 @@ namespace rotgen
|
||||||
else return parent::outerStride() == parent::rows();
|
else return parent::outerStride() == parent::rows();
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type& operator()(Index i, Index j) { return base()(i,j); }
|
value_type& operator()(Index i, Index j) requires(!is_immutable) { return base()(i,j); }
|
||||||
value_type operator()(Index i, Index j) const { return base()(i,j); }
|
value_type operator()(Index i, Index j) const { return base()(i,j); }
|
||||||
|
|
||||||
value_type& operator()(Index i)
|
value_type& operator()(Index i) requires(!is_immutable)
|
||||||
{
|
{
|
||||||
assert(is_contiguous_linear());
|
assert(is_contiguous_linear());
|
||||||
return base().data()[i];
|
return base().data()[i];
|
||||||
|
|
@ -279,13 +305,16 @@ namespace rotgen
|
||||||
using parent::sum;
|
using parent::sum;
|
||||||
using parent::data;
|
using parent::data;
|
||||||
|
|
||||||
block& operator+=(block const& rhs)
|
Index startRow() const { return base().startRow(); }
|
||||||
|
Index startCol() const { return base().startCol(); }
|
||||||
|
|
||||||
|
block& operator+=(block const& rhs) requires(!is_immutable)
|
||||||
{
|
{
|
||||||
static_cast<parent&>(*this) += static_cast<parent const&>(rhs);
|
static_cast<parent&>(*this) += static_cast<parent const&>(rhs);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator-=(block const& rhs)
|
block& operator-=(block const& rhs) requires(!is_immutable)
|
||||||
{
|
{
|
||||||
static_cast<parent&>(*this) -= static_cast<parent const&>(rhs);
|
static_cast<parent&>(*this) -= static_cast<parent const&>(rhs);
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -296,19 +325,19 @@ namespace rotgen
|
||||||
return concrete_type(static_cast<parent const&>(*this).operator-());
|
return concrete_type(static_cast<parent const&>(*this).operator-());
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator*=(block const& rhs)
|
block& operator*=(block const& rhs) requires(!is_immutable)
|
||||||
{
|
{
|
||||||
static_cast<parent&>(*this) *= static_cast<parent const&>(rhs);
|
static_cast<parent&>(*this) *= static_cast<parent const&>(rhs);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator*=(value_type rhs)
|
block& operator*=(value_type rhs) requires(!is_immutable)
|
||||||
{
|
{
|
||||||
static_cast<parent&>(*this) *= rhs;
|
static_cast<parent&>(*this) *= rhs;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator/=(value_type rhs)
|
block& operator/=(value_type rhs) requires(!is_immutable)
|
||||||
{
|
{
|
||||||
static_cast<parent&>(*this) /= rhs;
|
static_cast<parent&>(*this) /= rhs;
|
||||||
return *this;
|
return *this;
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ namespace rotgen
|
||||||
static constexpr int RowsAtCompileTime = Rows;
|
static constexpr int RowsAtCompileTime = Rows;
|
||||||
static constexpr int ColsAtCompileTime = Cols;
|
static constexpr int ColsAtCompileTime = Cols;
|
||||||
static constexpr int Options = parent::Options;
|
static constexpr int Options = parent::Options;
|
||||||
|
static constexpr bool IsRowMajor = parent::IsRowMajor;
|
||||||
|
|
||||||
template<typename ET>
|
template<typename ET>
|
||||||
using as_concrete_type = as_concrete_t<ET, matrix>;
|
using as_concrete_type = as_concrete_t<ET, matrix>;
|
||||||
|
|
|
||||||
|
|
@ -9,55 +9,47 @@
|
||||||
|
|
||||||
#include <rotgen/detail/generators.hpp>
|
#include <rotgen/detail/generators.hpp>
|
||||||
#include <rotgen/impl/matrix.hpp>
|
#include <rotgen/impl/matrix.hpp>
|
||||||
|
#include <rotgen/impl/map.hpp>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace rotgen
|
namespace rotgen
|
||||||
{
|
{
|
||||||
#define SIZE 64
|
class matrix_impl64_row;
|
||||||
#define TYPE double
|
class matrix_impl64_col;
|
||||||
|
class matrix_impl32_row;
|
||||||
|
class matrix_impl32_col;
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(block_impl,SIZE,_col)
|
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
|
||||||
#include <rotgen/impl/block_model.hpp>
|
|
||||||
#undef CLASSNAME
|
|
||||||
#undef SOURCENAME
|
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(block_impl,SIZE,_row)
|
#define USE_CONST
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
#define CONST const
|
||||||
#include <rotgen/impl/block_model.hpp>
|
#define BASENAME block_const_impl
|
||||||
#undef CLASSNAME
|
#include <rotgen/impl/block_indirect.hpp>
|
||||||
#undef SOURCENAME
|
#undef BASENAME
|
||||||
|
#undef CONST
|
||||||
|
#undef USE_CONST
|
||||||
|
|
||||||
#undef SIZE
|
#define CONST
|
||||||
#undef TYPE
|
#define BASENAME block_impl
|
||||||
|
#include <rotgen/impl/block_indirect.hpp>
|
||||||
|
#undef BASENAME
|
||||||
|
#undef CONST
|
||||||
|
|
||||||
#define SIZE 32
|
template<typename Scalar,int Options, bool isConst> struct find_block_impl;
|
||||||
#define TYPE float
|
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(block_impl,SIZE,_col)
|
template<> struct find_block_impl<float , ColMajor, true> { using type = block_const_impl32_col; };
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
template<> struct find_block_impl<float , RowMajor, true> { using type = block_const_impl32_row; };
|
||||||
#include <rotgen/impl/block_model.hpp>
|
template<> struct find_block_impl<double, ColMajor, true> { using type = block_const_impl64_col; };
|
||||||
#undef CLASSNAME
|
template<> struct find_block_impl<double, RowMajor, true> { using type = block_const_impl64_row; };
|
||||||
#undef SOURCENAME
|
template<> struct find_block_impl<float , ColMajor, false> { using type = block_impl32_col; };
|
||||||
|
template<> struct find_block_impl<float , RowMajor, false> { using type = block_impl32_row; };
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(block_impl,SIZE,_row)
|
template<> struct find_block_impl<double, ColMajor, false> { using type = block_impl64_col; };
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
template<> struct find_block_impl<double, RowMajor, false> { using type = block_impl64_row; };
|
||||||
#include <rotgen/impl/block_model.hpp>
|
|
||||||
#undef CLASSNAME
|
|
||||||
#undef SOURCENAME
|
|
||||||
|
|
||||||
#undef SIZE
|
|
||||||
#undef TYPE
|
|
||||||
|
|
||||||
template<typename Scalar,int Options> struct find_block_impl;
|
|
||||||
|
|
||||||
template<> struct find_block_impl<float , ColMajor> { using type = block_impl32_col; };
|
|
||||||
template<> struct find_block_impl<float , RowMajor> { using type = block_impl32_row; };
|
|
||||||
template<> struct find_block_impl<double, ColMajor> { using type = block_impl64_col; };
|
|
||||||
template<> struct find_block_impl<double, RowMajor> { using type = block_impl64_row; };
|
|
||||||
|
|
||||||
template<typename Ref>
|
template<typename Ref>
|
||||||
using find_block = typename find_block_impl<typename Ref::value_type, Ref::storage_order>::type;
|
using find_block = typename find_block_impl < typename std::remove_const_t<Ref>::value_type
|
||||||
|
, Ref::storage_order
|
||||||
|
, std::is_const_v<Ref>
|
||||||
|
>::type;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
43
include/rotgen/impl/block_indirect.hpp
Normal file
43
include/rotgen/impl/block_indirect.hpp
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
#define SIZE 64
|
||||||
|
#define TYPE double
|
||||||
|
|
||||||
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,SIZE,_col)
|
||||||
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
||||||
|
#define MAPNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_col)
|
||||||
|
#include <rotgen/impl/block_model.hpp>
|
||||||
|
#undef CLASSNAME
|
||||||
|
#undef SOURCENAME
|
||||||
|
#undef MAPNAME
|
||||||
|
|
||||||
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,SIZE,_row)
|
||||||
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
||||||
|
#define MAPNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_row)
|
||||||
|
#include <rotgen/impl/block_model.hpp>
|
||||||
|
#undef CLASSNAME
|
||||||
|
#undef SOURCENAME
|
||||||
|
#undef MAPNAME
|
||||||
|
|
||||||
|
#undef SIZE
|
||||||
|
#undef TYPE
|
||||||
|
|
||||||
|
#define SIZE 32
|
||||||
|
#define TYPE float
|
||||||
|
|
||||||
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,SIZE,_col)
|
||||||
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
||||||
|
#define MAPNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_col)
|
||||||
|
#include <rotgen/impl/block_model.hpp>
|
||||||
|
#undef CLASSNAME
|
||||||
|
#undef SOURCENAME
|
||||||
|
#undef MAPNAME
|
||||||
|
|
||||||
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,SIZE,_row)
|
||||||
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
||||||
|
#define MAPNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_row)
|
||||||
|
#include <rotgen/impl/block_model.hpp>
|
||||||
|
#undef CLASSNAME
|
||||||
|
#undef SOURCENAME
|
||||||
|
#undef MAPNAME
|
||||||
|
|
||||||
|
#undef SIZE
|
||||||
|
#undef TYPE
|
||||||
|
|
@ -13,18 +13,28 @@
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
class ROTGEN_EXPORT CLASSNAME
|
class ROTGEN_EXPORT CLASSNAME
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
struct payload;
|
||||||
|
std::unique_ptr<payload> storage_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CLASSNAME(SOURCENAME& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj);
|
CLASSNAME(SOURCENAME CONST& r , Index i0, Index j0, Index ni, Index nj);
|
||||||
|
CLASSNAME(MAPNAME CONST& r, Index i0, Index j0, Index ni, Index nj);
|
||||||
|
CLASSNAME(payload const& r, Index i0, Index j0, Index ni, Index nj);
|
||||||
|
|
||||||
CLASSNAME(CLASSNAME const& other);
|
CLASSNAME(CLASSNAME const& other);
|
||||||
CLASSNAME(CLASSNAME&&) noexcept;
|
CLASSNAME(CLASSNAME&&) noexcept;
|
||||||
|
|
||||||
|
#if !defined(USE_CONST)
|
||||||
CLASSNAME& operator=(CLASSNAME const& other);
|
CLASSNAME& operator=(CLASSNAME const& other);
|
||||||
CLASSNAME& operator=(CLASSNAME&&) noexcept;
|
CLASSNAME& operator=(CLASSNAME&&) noexcept;
|
||||||
|
#endif
|
||||||
|
|
||||||
~CLASSNAME();
|
~CLASSNAME();
|
||||||
|
|
||||||
|
#if !defined(USE_CONST)
|
||||||
void assign(SOURCENAME const&);
|
void assign(SOURCENAME const&);
|
||||||
|
#endif
|
||||||
|
|
||||||
Index rows() const;
|
Index rows() const;
|
||||||
Index cols() const;
|
Index cols() const;
|
||||||
|
|
@ -33,12 +43,17 @@ class ROTGEN_EXPORT CLASSNAME
|
||||||
Index innerStride() const;
|
Index innerStride() const;
|
||||||
Index outerStride() const;
|
Index outerStride() const;
|
||||||
|
|
||||||
|
Index startRow() const;
|
||||||
|
Index startCol() const;
|
||||||
|
|
||||||
SOURCENAME transpose() const;
|
SOURCENAME transpose() const;
|
||||||
SOURCENAME conjugate() const;
|
SOURCENAME conjugate() const;
|
||||||
SOURCENAME adjoint() const;
|
SOURCENAME adjoint() const;
|
||||||
|
|
||||||
|
#if !defined(USE_CONST)
|
||||||
void transposeInPlace();
|
void transposeInPlace();
|
||||||
void adjointInPlace();
|
void adjointInPlace();
|
||||||
|
#endif
|
||||||
|
|
||||||
TYPE sum() const;
|
TYPE sum() const;
|
||||||
TYPE prod() const;
|
TYPE prod() const;
|
||||||
|
|
@ -53,18 +68,19 @@ class ROTGEN_EXPORT CLASSNAME
|
||||||
TYPE norm() const;
|
TYPE norm() const;
|
||||||
TYPE lpNorm(int p) const;
|
TYPE lpNorm(int p) const;
|
||||||
|
|
||||||
TYPE& operator()(std::size_t i, std::size_t j);
|
#if !defined(USE_CONST)
|
||||||
TYPE const& operator()(std::size_t i, std::size_t j) const;
|
TYPE& operator()(Index i, Index j);
|
||||||
|
TYPE& operator()(Index index);
|
||||||
TYPE& operator()(std::size_t index);
|
|
||||||
TYPE const& operator()(std::size_t index) const;
|
|
||||||
|
|
||||||
CLASSNAME& operator+=(CLASSNAME const& rhs);
|
CLASSNAME& operator+=(CLASSNAME const& rhs);
|
||||||
CLASSNAME& operator-=(CLASSNAME const& rhs);
|
CLASSNAME& operator-=(CLASSNAME const& rhs);
|
||||||
SOURCENAME operator-() const;
|
|
||||||
CLASSNAME& operator*=(CLASSNAME const& rhs);
|
CLASSNAME& operator*=(CLASSNAME const& rhs);
|
||||||
CLASSNAME& operator*=(TYPE d);
|
CLASSNAME& operator*=(TYPE d);
|
||||||
CLASSNAME& operator/=(TYPE d);
|
CLASSNAME& operator/=(TYPE d);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TYPE operator()(Index i, Index j) const;
|
||||||
|
TYPE operator()(Index index) const;
|
||||||
|
SOURCENAME operator-() const;
|
||||||
|
|
||||||
SOURCENAME add(CLASSNAME const& rhs) const;
|
SOURCENAME add(CLASSNAME const& rhs) const;
|
||||||
SOURCENAME sub(CLASSNAME const& rhs) const;
|
SOURCENAME sub(CLASSNAME const& rhs) const;
|
||||||
|
|
@ -76,20 +92,21 @@ class ROTGEN_EXPORT CLASSNAME
|
||||||
friend ROTGEN_EXPORT bool operator==(CLASSNAME const& lhs, CLASSNAME const& rhs);
|
friend ROTGEN_EXPORT bool operator==(CLASSNAME const& lhs, CLASSNAME const& rhs);
|
||||||
friend ROTGEN_EXPORT bool operator!=(CLASSNAME const& lhs, CLASSNAME const& rhs);
|
friend ROTGEN_EXPORT bool operator!=(CLASSNAME const& lhs, CLASSNAME const& rhs);
|
||||||
|
|
||||||
const TYPE* data() const;
|
#if !defined(USE_CONST)
|
||||||
TYPE* data();
|
TYPE* data();
|
||||||
|
#endif
|
||||||
|
const TYPE* data() const;
|
||||||
|
|
||||||
static SOURCENAME Zero(std::size_t r, std::size_t c) { return SOURCENAME::Zero(r,c); }
|
static SOURCENAME Zero(Index r, Index c) { return SOURCENAME::Zero(r,c); }
|
||||||
static SOURCENAME Ones(std::size_t r, std::size_t c) { return SOURCENAME::Ones(r,c); }
|
static SOURCENAME Ones(Index r, Index 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 Constant(Index r, Index 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 Random(Index r, Index c) { return SOURCENAME::Random(r,c); }
|
||||||
static SOURCENAME Identity(std::size_t r, std::size_t c) { return SOURCENAME::Identity(r,c); }
|
static SOURCENAME Identity(Index r, Index c) { return SOURCENAME::Identity(r,c); }
|
||||||
|
|
||||||
private:
|
|
||||||
struct payload;
|
|
||||||
std::unique_ptr<payload> storage_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
#if !defined(USE_CONST)
|
||||||
std::unique_ptr<payload>& storage() { return storage_; }
|
std::unique_ptr<payload>& storage() { return storage_; }
|
||||||
|
#endif
|
||||||
|
|
||||||
std::unique_ptr<payload> const& storage() const { return storage_; }
|
std::unique_ptr<payload> const& storage() const { return storage_; }
|
||||||
};
|
};
|
||||||
|
|
@ -18,82 +18,19 @@ namespace rotgen
|
||||||
{
|
{
|
||||||
#define USE_CONST
|
#define USE_CONST
|
||||||
#define CONST const
|
#define CONST const
|
||||||
#define SIZE 64
|
#define BASENAME map_const_impl
|
||||||
#define TYPE double
|
#include <rotgen/impl/map_indirect.hpp>
|
||||||
|
#undef BASENAME
|
||||||
#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 CONST
|
||||||
#undef USE_CONST
|
#undef USE_CONST
|
||||||
|
|
||||||
#define SIZE 64
|
|
||||||
#define TYPE double
|
|
||||||
#define CONST
|
#define CONST
|
||||||
|
#define BASENAME map_impl
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_col)
|
#include <rotgen/impl/map_indirect.hpp>
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
#undef BASENAME
|
||||||
#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
|
#undef CONST
|
||||||
|
|
||||||
|
|
||||||
template<typename Scalar,int Options, bool isConst> struct find_map_impl;
|
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 , ColMajor, true> { using type = map_const_impl32_col; };
|
||||||
|
|
|
||||||
35
include/rotgen/impl/map_indirect.hpp
Normal file
35
include/rotgen/impl/map_indirect.hpp
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
#define SIZE 64
|
||||||
|
#define TYPE double
|
||||||
|
|
||||||
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,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(BASENAME,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(BASENAME,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(BASENAME,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
|
||||||
|
|
@ -9,50 +9,21 @@
|
||||||
#include <rotgen/impl/block.hpp>
|
#include <rotgen/impl/block.hpp>
|
||||||
#include <rotgen/impl/payload.hpp>
|
#include <rotgen/impl/payload.hpp>
|
||||||
#include <Eigen/Dense>
|
#include <Eigen/Dense>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
namespace rotgen
|
namespace rotgen
|
||||||
{
|
{
|
||||||
#define SIZE 64
|
#define USE_CONST
|
||||||
#define TYPE double
|
#define CONST const
|
||||||
#define STORAGE_ORDER Eigen::ColMajor
|
#define BASENAME block_const_impl
|
||||||
|
#include "block_indirect.cpp"
|
||||||
|
#undef BASENAME
|
||||||
|
#undef USE_CONST
|
||||||
|
#undef CONST
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(block_impl,SIZE,_col)
|
#define CONST
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
#define BASENAME block_impl
|
||||||
#include "block_model.cpp"
|
#include "block_indirect.cpp"
|
||||||
#undef CLASSNAME
|
#undef BASENAME
|
||||||
#undef SOURCENAME
|
#undef CONST
|
||||||
#undef STORAGE_ORDER
|
|
||||||
|
|
||||||
#define STORAGE_ORDER Eigen::RowMajor
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(block_impl,SIZE,_row)
|
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
|
||||||
#include "block_model.cpp"
|
|
||||||
#undef CLASSNAME
|
|
||||||
#undef SOURCENAME
|
|
||||||
#undef STORAGE_ORDER
|
|
||||||
|
|
||||||
#undef SIZE
|
|
||||||
#undef TYPE
|
|
||||||
|
|
||||||
#define SIZE 32
|
|
||||||
#define TYPE float
|
|
||||||
#define STORAGE_ORDER Eigen::ColMajor
|
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(block_impl,SIZE,_col)
|
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
|
||||||
#include "block_model.cpp"
|
|
||||||
#undef CLASSNAME
|
|
||||||
#undef SOURCENAME
|
|
||||||
#undef STORAGE_ORDER
|
|
||||||
|
|
||||||
#define STORAGE_ORDER Eigen::RowMajor
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(block_impl,SIZE,_row)
|
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
|
||||||
#include "block_model.cpp"
|
|
||||||
#undef CLASSNAME
|
|
||||||
#undef SOURCENAME
|
|
||||||
#undef STORAGE_ORDER
|
|
||||||
|
|
||||||
#undef SIZE
|
|
||||||
#undef TYPE
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
51
src/block_indirect.cpp
Normal file
51
src/block_indirect.cpp
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
#define SIZE 64
|
||||||
|
#define TYPE double
|
||||||
|
#define STORAGE_ORDER Eigen::ColMajor
|
||||||
|
|
||||||
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,SIZE,_col)
|
||||||
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
||||||
|
#define MAPNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_col)
|
||||||
|
#include "block_model.cpp"
|
||||||
|
#undef CLASSNAME
|
||||||
|
#undef SOURCENAME
|
||||||
|
#undef MAPNAME
|
||||||
|
#undef STORAGE_ORDER
|
||||||
|
|
||||||
|
#define STORAGE_ORDER Eigen::RowMajor
|
||||||
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,SIZE,_row)
|
||||||
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
||||||
|
#define MAPNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_row)
|
||||||
|
#include "block_model.cpp"
|
||||||
|
#undef CLASSNAME
|
||||||
|
#undef SOURCENAME
|
||||||
|
#undef MAPNAME
|
||||||
|
#undef STORAGE_ORDER
|
||||||
|
|
||||||
|
#undef SIZE
|
||||||
|
#undef TYPE
|
||||||
|
|
||||||
|
#define SIZE 32
|
||||||
|
#define TYPE float
|
||||||
|
#define STORAGE_ORDER Eigen::ColMajor
|
||||||
|
|
||||||
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,SIZE,_col)
|
||||||
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
||||||
|
#define MAPNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_col)
|
||||||
|
#include "block_model.cpp"
|
||||||
|
#undef CLASSNAME
|
||||||
|
#undef SOURCENAME
|
||||||
|
#undef MAPNAME
|
||||||
|
#undef STORAGE_ORDER
|
||||||
|
|
||||||
|
#define STORAGE_ORDER Eigen::RowMajor
|
||||||
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,SIZE,_row)
|
||||||
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
||||||
|
#define MAPNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_row)
|
||||||
|
#include "block_model.cpp"
|
||||||
|
#undef CLASSNAME
|
||||||
|
#undef SOURCENAME
|
||||||
|
#undef MAPNAME
|
||||||
|
#undef STORAGE_ORDER
|
||||||
|
|
||||||
|
#undef SIZE
|
||||||
|
#undef TYPE
|
||||||
|
|
@ -11,204 +11,476 @@
|
||||||
This file is a X-File to generate various block_impl_* definitions variant
|
This file is a X-File to generate various block_impl_* definitions variant
|
||||||
*/
|
*/
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
|
#define STR(text) STR_I(text)
|
||||||
|
#define STR_I(...) #__VA_ARGS__
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// Internal payload
|
// Internal payload
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
struct CLASSNAME::payload
|
struct CLASSNAME::payload
|
||||||
{
|
{
|
||||||
using base_type = Eigen::Matrix<TYPE,Eigen::Dynamic,Eigen::Dynamic,STORAGE_ORDER>;
|
using stride_type = Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic>;
|
||||||
using data_type = Eigen::Block<base_type>;
|
using matrix_type = Eigen::Matrix<TYPE,Eigen::Dynamic,Eigen::Dynamic,STORAGE_ORDER>;
|
||||||
|
using matrix_block_type = Eigen::Block<matrix_type CONST>;
|
||||||
|
using matrix_storage_t = std::pair<matrix_block_type, matrix_type CONST*>;
|
||||||
|
using map_type = Eigen::Map<matrix_type,Eigen::Unaligned,stride_type>;
|
||||||
|
using map_block_type = Eigen::Block<map_type CONST>;
|
||||||
|
using map_storage_t = std::pair<map_block_type, map_type CONST*>;
|
||||||
|
using data_type = std::variant<matrix_storage_t, map_storage_t>;
|
||||||
|
|
||||||
data_type data;
|
data_type data;
|
||||||
|
rotgen::Index abs_i0 = 0; // absolute start row in original matrix
|
||||||
|
rotgen::Index abs_j0 = 0; // absolute start col in original matrix
|
||||||
|
rotgen::Index rel_i0 = 0; // relative start row in original matrix
|
||||||
|
rotgen::Index rel_j0 = 0; // relative start col in original matrix
|
||||||
|
|
||||||
|
template <typename Func>
|
||||||
|
void apply(Func f) { std::visit([&](auto& blk) { return f(blk.first); }, data); }
|
||||||
|
|
||||||
|
template <typename Func>
|
||||||
|
void apply(Func f) const { std::visit([&](auto const& blk) { return f(blk.first); }, data); }
|
||||||
|
|
||||||
payload (data_type const& o) : data(o) {}
|
payload (data_type const& o) : data(o) {}
|
||||||
|
|
||||||
payload (base_type& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
payload (SOURCENAME CONST& o, rotgen::Index i0, rotgen::Index j0, rotgen::Index ni, rotgen::Index nj)
|
||||||
: data(r,i0,j0,ni,nj)
|
: data(matrix_storage_t{matrix_block_type{o.storage()->data,i0,j0,ni,nj},&o.storage()->data})
|
||||||
|
, abs_i0(i0), abs_j0(j0), rel_i0(i0), rel_j0(j0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
payload (MAPNAME CONST& o, rotgen::Index i0, rotgen::Index j0, rotgen::Index ni, rotgen::Index nj)
|
||||||
|
: data(map_storage_t{map_block_type{o.storage()->data,i0,j0,ni,nj},&o.storage()->data})
|
||||||
|
, abs_i0(i0), abs_j0(j0), rel_i0(i0), rel_j0(j0)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// Constructors & Special Members
|
// Constructors & Special Members
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
CLASSNAME::CLASSNAME(SOURCENAME& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
CLASSNAME::CLASSNAME(SOURCENAME CONST& r, Index i0, Index j0, Index ni, Index nj)
|
||||||
: storage_(std::make_unique<payload>(r.storage()->data,i0,j0,ni,nj))
|
: storage_(std::make_unique<payload>(r, i0,j0,ni,nj))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
CLASSNAME::CLASSNAME(CLASSNAME const& o) : storage_(std::make_unique<payload>(o.storage_->data))
|
CLASSNAME::CLASSNAME(MAPNAME CONST& r, Index i0, Index j0, Index ni, Index nj)
|
||||||
|
: storage_(std::make_unique<payload>(r, i0,j0,ni,nj))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
// We're building a block from a block - So we have to dig around the internals
|
||||||
|
CLASSNAME::CLASSNAME(payload const& o, Index i0, Index j0, Index ni, Index nj)
|
||||||
|
{
|
||||||
|
// Compute absolute indices from the parent stored block
|
||||||
|
Index abs_i0 = 0;
|
||||||
|
Index abs_j0 = 0;
|
||||||
|
std::visit( [&](auto const& blk)
|
||||||
|
{
|
||||||
|
abs_i0 = blk.first.startRow() + i0;
|
||||||
|
abs_j0 = blk.first.startCol() + j0;
|
||||||
|
}
|
||||||
|
, o.data
|
||||||
|
);
|
||||||
|
|
||||||
|
// Build a payload::data_type that holds the child block using absolute indices
|
||||||
|
payload::data_type new_data =
|
||||||
|
std::visit([&]<typename T>(T const& blk) -> payload::data_type
|
||||||
|
{
|
||||||
|
auto& [parent_block, ref] = blk;
|
||||||
|
using block_type = typename T::first_type;
|
||||||
|
return T{ block_type{ *ref, abs_i0, abs_j0, ni, nj }, ref };
|
||||||
|
}, o.data);
|
||||||
|
|
||||||
|
storage_ = std::make_unique<payload>(new_data);
|
||||||
|
storage_->abs_i0 = abs_i0;
|
||||||
|
storage_->abs_j0 = abs_j0;
|
||||||
|
storage_->rel_i0 = i0;
|
||||||
|
storage_->rel_j0 = j0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLASSNAME::CLASSNAME(CLASSNAME const& o)
|
||||||
|
: storage_(std::make_unique<payload>(o.storage_->data))
|
||||||
|
{}
|
||||||
|
|
||||||
|
CLASSNAME::CLASSNAME(CLASSNAME&&) noexcept = default;
|
||||||
|
|
||||||
|
#if !defined(USE_CONST)
|
||||||
CLASSNAME& CLASSNAME::operator=(CLASSNAME const& o)
|
CLASSNAME& CLASSNAME::operator=(CLASSNAME const& o)
|
||||||
{
|
{
|
||||||
if (this != &o) storage_->data = o.storage_->data;
|
if (this != &o) { storage_->data = o.storage_->data; }
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLASSNAME::CLASSNAME(CLASSNAME&&) noexcept = default;
|
|
||||||
CLASSNAME& CLASSNAME::operator=(CLASSNAME&&) noexcept = default;
|
CLASSNAME& CLASSNAME::operator=(CLASSNAME&&) noexcept = default;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
CLASSNAME::~CLASSNAME() = default;
|
CLASSNAME::~CLASSNAME() = default;
|
||||||
|
|
||||||
|
#if !defined(USE_CONST)
|
||||||
void CLASSNAME::assign(SOURCENAME const& m)
|
void CLASSNAME::assign(SOURCENAME const& m)
|
||||||
{
|
{
|
||||||
storage_->data = m.storage()->data;
|
storage_->apply([&](auto& blk)
|
||||||
|
{
|
||||||
|
blk = m.storage()->data;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// Matrix API
|
// Matrix API
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
rotgen::Index CLASSNAME::rows() const { return storage_->data.rows(); }
|
rotgen::Index CLASSNAME::rows() const
|
||||||
rotgen::Index CLASSNAME::cols() const { return storage_->data.cols(); }
|
{
|
||||||
rotgen::Index CLASSNAME::size() const { return storage_->data.size(); }
|
rotgen::Index that;
|
||||||
rotgen::Index CLASSNAME::innerStride() const { return storage_->data.innerStride(); }
|
storage_->apply([&](const auto& blk) { that = blk.rows(); });
|
||||||
rotgen::Index CLASSNAME::outerStride() const { return storage_->data.outerStride(); }
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
TYPE& CLASSNAME::operator()(std::size_t i, std::size_t j) { return storage_->data(i,j); }
|
rotgen::Index CLASSNAME::cols() const
|
||||||
TYPE const& CLASSNAME::operator()(std::size_t i, std::size_t j) const { return storage_->data(i,j); }
|
{
|
||||||
|
rotgen::Index that;
|
||||||
|
storage_->apply([&](const auto& blk) { that = blk.cols(); });
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
TYPE& CLASSNAME::operator()(std::size_t index) { return storage_->data.data()[index]; }
|
rotgen::Index CLASSNAME::size() const
|
||||||
TYPE const& CLASSNAME::operator()(std::size_t index) const { return storage_->data.data()[index]; }
|
{
|
||||||
|
rotgen::Index that;
|
||||||
|
storage_->apply([&](const auto& blk) { that = blk.size(); });
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
TYPE* CLASSNAME::data() { return storage_->data.data(); }
|
rotgen::Index CLASSNAME::innerStride() const
|
||||||
const TYPE* CLASSNAME::data() const { return storage_->data.data(); }
|
{
|
||||||
|
rotgen::Index that;
|
||||||
|
storage_->apply([&](const auto& blk) { that = blk.innerStride(); });
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
rotgen::Index CLASSNAME::outerStride() const
|
||||||
|
{
|
||||||
|
rotgen::Index that;
|
||||||
|
storage_->apply([&](const auto& blk) { that = blk.outerStride(); });
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
rotgen::Index CLASSNAME::startRow() const
|
||||||
|
{
|
||||||
|
return storage_->rel_i0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rotgen::Index CLASSNAME::startCol() const
|
||||||
|
{
|
||||||
|
return storage_->rel_j0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Element access by (i,j)
|
||||||
|
#if !defined(USE_CONST)
|
||||||
|
TYPE& CLASSNAME::operator()(Index i, Index j)
|
||||||
|
{
|
||||||
|
TYPE* ptr = nullptr;
|
||||||
|
storage_->apply([&](auto& blk) { ptr = &blk(i,j); });
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TYPE CLASSNAME::operator()(Index i, Index j) const
|
||||||
|
{
|
||||||
|
TYPE ptr;
|
||||||
|
storage_->apply([&](auto const& blk) { ptr = blk(i,j); });
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Element access by linear index
|
||||||
|
#if !defined(USE_CONST)
|
||||||
|
TYPE& CLASSNAME::operator()(Index index)
|
||||||
|
{
|
||||||
|
TYPE* ptr = nullptr;
|
||||||
|
storage_->apply([&](auto& blk) { ptr = blk.data() + index; });
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TYPE CLASSNAME::operator()(Index index) const
|
||||||
|
{
|
||||||
|
TYPE ptr;
|
||||||
|
storage_->apply([&](auto const& blk) { ptr = *(blk.data() + index); });
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Raw pointer access
|
||||||
|
#if !defined(USE_CONST)
|
||||||
|
TYPE* CLASSNAME::data()
|
||||||
|
{
|
||||||
|
TYPE* ptr = nullptr;
|
||||||
|
storage_->apply([&](auto& blk) { ptr = blk.data(); });
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TYPE const* CLASSNAME::data() const
|
||||||
|
{
|
||||||
|
TYPE const* ptr = nullptr;
|
||||||
|
storage_->apply([&](auto const& blk) { ptr = blk.data(); });
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
// Matrix operations
|
||||||
|
//==================================================================================================
|
||||||
SOURCENAME CLASSNAME::transpose() const
|
SOURCENAME CLASSNAME::transpose() const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
result.storage()->assign(storage_->data.transpose().eval());
|
storage_->apply([&](const auto& blk) { result.storage()->assign(blk.transpose().eval()); });
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::conjugate() const {
|
SOURCENAME CLASSNAME::conjugate() const
|
||||||
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
result.storage()->assign(storage_->data.conjugate().eval());
|
storage_->apply([&](const auto& blk) { result.storage()->assign(blk.conjugate().eval()); });
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::adjoint() const {
|
SOURCENAME CLASSNAME::adjoint() const
|
||||||
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
result.storage()->assign(storage_->data.adjoint().eval());
|
storage_->apply([&](const auto& blk) { result.storage()->assign(blk.adjoint().eval()); });
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(USE_CONST)
|
||||||
void CLASSNAME::transposeInPlace()
|
void CLASSNAME::transposeInPlace()
|
||||||
{
|
{
|
||||||
storage_->data.transposeInPlace();
|
storage_->apply([](auto& blk) { blk.transposeInPlace(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLASSNAME::adjointInPlace()
|
void CLASSNAME::adjointInPlace()
|
||||||
{
|
{
|
||||||
storage_->data.adjointInPlace();
|
storage_->apply([](auto& blk) { blk.adjointInPlace(); });
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//==================================================================================================
|
||||||
|
// Reductions
|
||||||
|
//==================================================================================================
|
||||||
|
TYPE CLASSNAME::sum() const
|
||||||
|
{
|
||||||
|
TYPE val{};
|
||||||
|
storage_->apply([&](const auto& blk) { val = blk.sum(); });
|
||||||
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::sum() const { return storage_->data.sum(); }
|
TYPE CLASSNAME::prod() const
|
||||||
TYPE CLASSNAME::prod() const { return storage_->data.prod(); }
|
{
|
||||||
TYPE CLASSNAME::mean() const { return storage_->data.mean(); }
|
TYPE val{};
|
||||||
TYPE CLASSNAME::trace() const { return storage_->data.trace(); }
|
storage_->apply([&](const auto& blk) { val = blk.prod(); });
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::minCoeff() const { return storage_->data.minCoeff(); }
|
TYPE CLASSNAME::mean() const
|
||||||
TYPE CLASSNAME::maxCoeff() const { return storage_->data.maxCoeff(); }
|
{
|
||||||
|
TYPE val{};
|
||||||
|
storage_->apply([&](const auto& blk) { val = blk.mean(); });
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::minCoeff(std::ptrdiff_t* row, std::ptrdiff_t* col) const { return storage_->data.minCoeff(row, col); }
|
TYPE CLASSNAME::trace() const
|
||||||
TYPE CLASSNAME::maxCoeff(std::ptrdiff_t* row, std::ptrdiff_t* col) const { return storage_->data.maxCoeff(row, col); }
|
{
|
||||||
|
TYPE val{};
|
||||||
|
storage_->apply([&](const auto& blk) { val = blk.trace(); });
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::squaredNorm() const { return storage_->data.squaredNorm(); }
|
TYPE CLASSNAME::minCoeff() const
|
||||||
TYPE CLASSNAME::norm() const { return storage_->data.norm(); }
|
{
|
||||||
|
TYPE val{};
|
||||||
|
storage_->apply([&](const auto& blk) { val = blk.minCoeff(); });
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE CLASSNAME::maxCoeff() const
|
||||||
|
{
|
||||||
|
TYPE val{};
|
||||||
|
storage_->apply([&](const auto& blk) { val = blk.maxCoeff(); });
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE CLASSNAME::minCoeff(std::ptrdiff_t* row, std::ptrdiff_t* col) const
|
||||||
|
{
|
||||||
|
TYPE val{};
|
||||||
|
storage_->apply([&](const auto& blk) { val = blk.minCoeff(row, col); });
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE CLASSNAME::maxCoeff(std::ptrdiff_t* row, std::ptrdiff_t* col) const
|
||||||
|
{
|
||||||
|
TYPE val{};
|
||||||
|
storage_->apply([&](const auto& blk) { val = blk.maxCoeff(row, col); });
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE CLASSNAME::squaredNorm() const
|
||||||
|
{
|
||||||
|
TYPE val{};
|
||||||
|
storage_->apply([&](const auto& blk) { val = blk.squaredNorm(); });
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPE CLASSNAME::norm() const
|
||||||
|
{
|
||||||
|
TYPE val{};
|
||||||
|
storage_->apply([&](const auto& blk) { val = blk.norm(); });
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
TYPE CLASSNAME::lpNorm(int p) const
|
TYPE CLASSNAME::lpNorm(int p) const
|
||||||
{
|
{
|
||||||
if (p == 1) return storage_->data.lpNorm<1>();
|
TYPE val{};
|
||||||
else if (p == 2) return storage_->data.lpNorm<2>();
|
storage_->apply([&](const auto& blk)
|
||||||
else return storage_->data.lpNorm<Eigen::Infinity>();
|
{
|
||||||
|
if (p == 1) val = blk.template lpNorm<1>();
|
||||||
|
else if (p == 2) val = blk.template lpNorm<2>();
|
||||||
|
else val = blk.template lpNorm<Eigen::Infinity>();
|
||||||
|
});
|
||||||
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// Operators
|
// Operators
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
ROTGEN_EXPORT std::ostream& operator<<(std::ostream& os,CLASSNAME const& m)
|
ROTGEN_EXPORT std::ostream& operator<<(std::ostream& os, CLASSNAME const& m)
|
||||||
{
|
{
|
||||||
return os << m.storage_->data;
|
m.storage_->apply([&](const auto& blk) { os << blk; });
|
||||||
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
ROTGEN_EXPORT bool operator==(CLASSNAME const& lhs, CLASSNAME const& rhs)
|
ROTGEN_EXPORT bool operator==(CLASSNAME const& lhs, CLASSNAME const& rhs)
|
||||||
{
|
{
|
||||||
return lhs.storage_->data == rhs.storage_->data;
|
return std::visit ( [](auto const& lhs_blk, auto const& rhs_blk) { return lhs_blk.first == rhs_blk.first; }
|
||||||
|
, lhs.storage_->data
|
||||||
|
, rhs.storage_->data
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ROTGEN_EXPORT bool operator!=(CLASSNAME const& lhs, CLASSNAME const& rhs)
|
ROTGEN_EXPORT bool operator!=(CLASSNAME const& lhs, CLASSNAME const& rhs)
|
||||||
{
|
{
|
||||||
return lhs.storage_->data != rhs.storage_->data;
|
return std::visit ( [](auto const& lhs_blk, auto const& rhs_blk) { return lhs_blk.first != rhs_blk.first; }
|
||||||
|
, lhs.storage_->data
|
||||||
|
, rhs.storage_->data
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SOURCENAME CLASSNAME::operator-() const
|
||||||
|
{
|
||||||
|
SOURCENAME result;
|
||||||
|
storage_->apply([&](const auto& blk) { result.storage()->assign(blk); });
|
||||||
|
return -result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(USE_CONST)
|
||||||
CLASSNAME& CLASSNAME::operator+=(CLASSNAME const& rhs)
|
CLASSNAME& CLASSNAME::operator+=(CLASSNAME const& rhs)
|
||||||
{
|
{
|
||||||
storage_->data += rhs.storage_->data;
|
std::visit( [](auto& lhs_blk, auto const& rhs_blk) { lhs_blk.first += rhs_blk.first; }
|
||||||
|
, storage_->data
|
||||||
|
, rhs.storage_->data
|
||||||
|
);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLASSNAME& CLASSNAME::operator-=(CLASSNAME const& rhs)
|
CLASSNAME& CLASSNAME::operator-=(CLASSNAME const& rhs)
|
||||||
{
|
{
|
||||||
storage_->data -= rhs.storage_->data;
|
std::visit( [](auto& lhs_blk, auto const& rhs_blk) { lhs_blk.first -= rhs_blk.first; }
|
||||||
|
, storage_->data
|
||||||
|
, rhs.storage_->data
|
||||||
|
);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::operator-() const
|
|
||||||
{
|
|
||||||
SOURCENAME result;
|
|
||||||
result.storage()->assign(storage_->data);
|
|
||||||
return -result;
|
|
||||||
}
|
|
||||||
|
|
||||||
CLASSNAME& CLASSNAME::operator*=(CLASSNAME const& rhs)
|
CLASSNAME& CLASSNAME::operator*=(CLASSNAME const& rhs)
|
||||||
{
|
{
|
||||||
storage_->data *= rhs.storage_->data;
|
std::visit( [](auto& lhs_blk, auto const& rhs_blk) { lhs_blk.first *= rhs_blk.first; }
|
||||||
|
, storage_->data
|
||||||
|
, rhs.storage_->data
|
||||||
|
);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLASSNAME& CLASSNAME::operator*=(TYPE s)
|
CLASSNAME& CLASSNAME::operator*=(TYPE s)
|
||||||
{
|
{
|
||||||
storage_->data *= s;
|
storage_->apply([&](auto& blk) { blk *= s; });
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLASSNAME& CLASSNAME::operator/=(TYPE s)
|
CLASSNAME& CLASSNAME::operator/=(TYPE s)
|
||||||
{
|
{
|
||||||
storage_->data /= s;
|
storage_->apply([&](auto& blk) { blk /= s; });
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::add(CLASSNAME const& rhs) const
|
SOURCENAME CLASSNAME::add(CLASSNAME const& rhs) const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
result.storage()->assign(storage_->data + rhs.storage_->data);
|
result.storage()->assign( std::visit( [](auto const& lhs_blk, auto const& rhs_blk)
|
||||||
|
{
|
||||||
|
return (lhs_blk.first + rhs_blk.first).eval();
|
||||||
|
}
|
||||||
|
, storage_->data
|
||||||
|
, rhs.storage_->data
|
||||||
|
)
|
||||||
|
);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::sub(CLASSNAME const& rhs) const
|
SOURCENAME CLASSNAME::sub(CLASSNAME const& rhs) const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
result.storage()->assign(storage_->data - rhs.storage_->data);
|
result.storage()->assign( std::visit( [](auto const& lhs_blk, auto const& rhs_blk)
|
||||||
|
{
|
||||||
|
return (lhs_blk.first - rhs_blk.first).eval();
|
||||||
|
}
|
||||||
|
, storage_->data
|
||||||
|
, rhs.storage_->data
|
||||||
|
)
|
||||||
|
);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::mul(CLASSNAME const& rhs) const
|
SOURCENAME CLASSNAME::mul(CLASSNAME const& rhs) const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
result.storage()->assign(storage_->data * rhs.storage_->data);
|
result.storage()->assign( std::visit( [](auto const& lhs_blk, auto const& rhs_blk)
|
||||||
|
{
|
||||||
|
return (lhs_blk.first * rhs_blk.first).eval();
|
||||||
|
}
|
||||||
|
, storage_->data
|
||||||
|
, rhs.storage_->data
|
||||||
|
)
|
||||||
|
);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::mul(TYPE s) const
|
SOURCENAME CLASSNAME::mul(TYPE s) const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
result.storage()->assign(storage_->data * s);
|
result.storage()->assign( std::visit( [s](auto const& lhs_blk)
|
||||||
|
{
|
||||||
|
return (lhs_blk.first * s).eval();
|
||||||
|
}
|
||||||
|
, storage_->data
|
||||||
|
)
|
||||||
|
);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SOURCENAME CLASSNAME::div(TYPE s) const
|
SOURCENAME CLASSNAME::div(TYPE s) const
|
||||||
{
|
{
|
||||||
SOURCENAME result;
|
SOURCENAME result;
|
||||||
result.storage()->assign(storage_->data / s);
|
result.storage()->assign( std::visit( [s](auto const& lhs_blk)
|
||||||
|
{
|
||||||
|
return (lhs_blk.first / s).eval();
|
||||||
|
}
|
||||||
|
, storage_->data
|
||||||
|
)
|
||||||
|
);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
96
src/map.cpp
96
src/map.cpp
|
|
@ -14,97 +14,15 @@ namespace rotgen
|
||||||
{
|
{
|
||||||
#define USE_CONST
|
#define USE_CONST
|
||||||
#define CONST const
|
#define CONST const
|
||||||
|
#define BASENAME map_const_impl
|
||||||
#define SIZE 64
|
#include "map_indirect.cpp"
|
||||||
#define TYPE double
|
#undef BASENAME
|
||||||
#define STORAGE_ORDER Eigen::ColMajor
|
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(map_const_impl,SIZE,_col)
|
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
|
||||||
#include "map_model.cpp"
|
|
||||||
#undef CLASSNAME
|
|
||||||
#undef SOURCENAME
|
|
||||||
#undef STORAGE_ORDER
|
|
||||||
|
|
||||||
#define STORAGE_ORDER Eigen::RowMajor
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(map_const_impl,SIZE,_row)
|
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
|
||||||
#include "map_model.cpp"
|
|
||||||
#undef CLASSNAME
|
|
||||||
#undef SOURCENAME
|
|
||||||
#undef STORAGE_ORDER
|
|
||||||
|
|
||||||
#undef SIZE
|
|
||||||
#undef TYPE
|
|
||||||
|
|
||||||
#define SIZE 32
|
|
||||||
#define TYPE float
|
|
||||||
#define STORAGE_ORDER Eigen::ColMajor
|
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(map_const_impl,SIZE,_col)
|
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
|
||||||
#include "map_model.cpp"
|
|
||||||
#undef CLASSNAME
|
|
||||||
#undef SOURCENAME
|
|
||||||
#undef STORAGE_ORDER
|
|
||||||
|
|
||||||
#define STORAGE_ORDER Eigen::RowMajor
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(map_const_impl,SIZE,_row)
|
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
|
||||||
#include "map_model.cpp"
|
|
||||||
#undef CLASSNAME
|
|
||||||
#undef SOURCENAME
|
|
||||||
#undef STORAGE_ORDER
|
|
||||||
|
|
||||||
#undef SIZE
|
|
||||||
#undef TYPE
|
|
||||||
|
|
||||||
#undef USE_CONST
|
#undef USE_CONST
|
||||||
#undef CONST
|
#undef CONST
|
||||||
|
|
||||||
#define CONST
|
#define CONST
|
||||||
|
#define BASENAME map_impl
|
||||||
#define SIZE 64
|
#include "map_indirect.cpp"
|
||||||
#define TYPE double
|
#undef BASENAME
|
||||||
#define STORAGE_ORDER Eigen::ColMajor
|
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_col)
|
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
|
||||||
#include "map_model.cpp"
|
|
||||||
#undef CLASSNAME
|
|
||||||
#undef SOURCENAME
|
|
||||||
#undef STORAGE_ORDER
|
|
||||||
|
|
||||||
#define STORAGE_ORDER Eigen::RowMajor
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_row)
|
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
|
||||||
#include "map_model.cpp"
|
|
||||||
#undef CLASSNAME
|
|
||||||
#undef SOURCENAME
|
|
||||||
#undef STORAGE_ORDER
|
|
||||||
|
|
||||||
#undef SIZE
|
|
||||||
#undef TYPE
|
|
||||||
|
|
||||||
#define SIZE 32
|
|
||||||
#define TYPE float
|
|
||||||
#define STORAGE_ORDER Eigen::ColMajor
|
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_col)
|
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
|
||||||
#include "map_model.cpp"
|
|
||||||
#undef CLASSNAME
|
|
||||||
#undef SOURCENAME
|
|
||||||
#undef STORAGE_ORDER
|
|
||||||
|
|
||||||
#define STORAGE_ORDER Eigen::RowMajor
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(map_impl,SIZE,_row)
|
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
|
||||||
#include "map_model.cpp"
|
|
||||||
#undef CLASSNAME
|
|
||||||
#undef SOURCENAME
|
|
||||||
#undef STORAGE_ORDER
|
|
||||||
|
|
||||||
#undef SIZE
|
|
||||||
#undef TYPE
|
|
||||||
#undef CONST
|
#undef CONST
|
||||||
}
|
}
|
||||||
|
|
|
||||||
43
src/map_indirect.cpp
Normal file
43
src/map_indirect.cpp
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
#define SIZE 64
|
||||||
|
#define TYPE double
|
||||||
|
#define STORAGE_ORDER Eigen::ColMajor
|
||||||
|
|
||||||
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,SIZE,_col)
|
||||||
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
||||||
|
#include "map_model.cpp"
|
||||||
|
#undef CLASSNAME
|
||||||
|
#undef SOURCENAME
|
||||||
|
#undef STORAGE_ORDER
|
||||||
|
|
||||||
|
#define STORAGE_ORDER Eigen::RowMajor
|
||||||
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,SIZE,_row)
|
||||||
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
||||||
|
#include "map_model.cpp"
|
||||||
|
#undef CLASSNAME
|
||||||
|
#undef SOURCENAME
|
||||||
|
#undef STORAGE_ORDER
|
||||||
|
|
||||||
|
#undef SIZE
|
||||||
|
#undef TYPE
|
||||||
|
|
||||||
|
#define SIZE 32
|
||||||
|
#define TYPE float
|
||||||
|
#define STORAGE_ORDER Eigen::ColMajor
|
||||||
|
|
||||||
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,SIZE,_col)
|
||||||
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
||||||
|
#include "map_model.cpp"
|
||||||
|
#undef CLASSNAME
|
||||||
|
#undef SOURCENAME
|
||||||
|
#undef STORAGE_ORDER
|
||||||
|
|
||||||
|
#define STORAGE_ORDER Eigen::RowMajor
|
||||||
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME,SIZE,_row)
|
||||||
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
||||||
|
#include "map_model.cpp"
|
||||||
|
#undef CLASSNAME
|
||||||
|
#undef SOURCENAME
|
||||||
|
#undef STORAGE_ORDER
|
||||||
|
|
||||||
|
#undef SIZE
|
||||||
|
#undef TYPE
|
||||||
|
|
@ -48,7 +48,6 @@
|
||||||
rotgen::Index CLASSNAME::rows() const { return storage_->data.rows(); }
|
rotgen::Index CLASSNAME::rows() const { return storage_->data.rows(); }
|
||||||
rotgen::Index CLASSNAME::cols() const { return storage_->data.cols(); }
|
rotgen::Index CLASSNAME::cols() const { return storage_->data.cols(); }
|
||||||
rotgen::Index CLASSNAME::size() const { return storage_->data.size(); }
|
rotgen::Index CLASSNAME::size() const { return storage_->data.size(); }
|
||||||
|
|
||||||
rotgen::Index CLASSNAME::innerStride() const { return storage_->data.innerStride(); }
|
rotgen::Index CLASSNAME::innerStride() const { return storage_->data.innerStride(); }
|
||||||
rotgen::Index CLASSNAME::outerStride() const { return storage_->data.outerStride(); }
|
rotgen::Index CLASSNAME::outerStride() const { return storage_->data.outerStride(); }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,9 +51,9 @@ CLASSNAME::~CLASSNAME() = default;
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
// Matrix API
|
// Matrix API
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
rotgen::Index CLASSNAME::rows() const { return storage_->data.rows(); }
|
rotgen::Index CLASSNAME::rows() const { return storage_->data.rows(); }
|
||||||
rotgen::Index CLASSNAME::cols() const { return storage_->data.cols(); }
|
rotgen::Index CLASSNAME::cols() const { return storage_->data.cols(); }
|
||||||
rotgen::Index CLASSNAME::size() const { return storage_->data.size(); }
|
rotgen::Index CLASSNAME::size() const { return storage_->data.size(); }
|
||||||
|
|
||||||
void CLASSNAME::resize(std::size_t new_rows, std::size_t new_cols)
|
void CLASSNAME::resize(std::size_t new_rows, std::size_t new_cols)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -21,3 +21,8 @@ rotgen_glob_unit(QUIET PATTERN "unit/*.cpp" INTERFACE rotgen_test)
|
||||||
rotgen_glob_unit(QUIET PATTERN "unit/matrix/*.cpp" INTERFACE rotgen_test)
|
rotgen_glob_unit(QUIET PATTERN "unit/matrix/*.cpp" INTERFACE rotgen_test)
|
||||||
rotgen_glob_unit(QUIET PATTERN "unit/block/*.cpp" INTERFACE rotgen_test)
|
rotgen_glob_unit(QUIET PATTERN "unit/block/*.cpp" INTERFACE rotgen_test)
|
||||||
rotgen_glob_unit(QUIET PATTERN "unit/map/*.cpp" INTERFACE rotgen_test)
|
rotgen_glob_unit(QUIET PATTERN "unit/map/*.cpp" INTERFACE rotgen_test)
|
||||||
|
|
||||||
|
##======================================================================================================================
|
||||||
|
## Integrations Tests registration
|
||||||
|
##======================================================================================================================
|
||||||
|
rotgen_glob_unit(QUIET PATTERN "integration/*.cpp" INTERFACE rotgen_test)
|
||||||
|
|
|
||||||
51
test/integration/extract.cpp
Normal file
51
test/integration/extract.cpp
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
//==================================================================================================
|
||||||
|
/*
|
||||||
|
ROTGEN - Runtime Overlay for Eigen
|
||||||
|
Copyright : CODE RECKONS
|
||||||
|
SPDX-License-Identifier: BSL-1.0
|
||||||
|
*/
|
||||||
|
//==================================================================================================
|
||||||
|
#include "unit/tests.hpp"
|
||||||
|
#include <rotgen/rotgen.hpp>
|
||||||
|
|
||||||
|
TTS_CASE_TPL("Chains of extraction", rotgen::tests::types)
|
||||||
|
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
||||||
|
{
|
||||||
|
constexpr int N = 8;
|
||||||
|
auto a = rotgen::matrix<T,N,N,O::value>::Random();
|
||||||
|
|
||||||
|
auto b = topLeftCorner(a,5,5);
|
||||||
|
TTS_EQUAL(b.startRow(), 0);
|
||||||
|
TTS_EQUAL(b.startCol(), 0);
|
||||||
|
b.setConstant(-7);
|
||||||
|
|
||||||
|
for(rotgen::Index r=0;r<5;r++)
|
||||||
|
for(rotgen::Index c=0;c<5;c++)
|
||||||
|
TTS_EQUAL(a(r,c), -7);
|
||||||
|
|
||||||
|
auto bb = bottomRightCorner(b,3,3);
|
||||||
|
TTS_EQUAL(bb.startRow(), 2);
|
||||||
|
TTS_EQUAL(bb.startCol(), 2);
|
||||||
|
bb.setConstant(42);
|
||||||
|
|
||||||
|
for(rotgen::Index r=2;r<5;r++)
|
||||||
|
for(rotgen::Index c=2;c<5;c++)
|
||||||
|
TTS_EQUAL(a(r,c), 42);
|
||||||
|
|
||||||
|
auto bbb = row(bb,1);
|
||||||
|
TTS_EQUAL(bbb.startRow(), 1);
|
||||||
|
TTS_EQUAL(bbb.startCol(), 0);
|
||||||
|
bbb.setConstant(99.5);
|
||||||
|
|
||||||
|
for(rotgen::Index c=3;c<5;c++)
|
||||||
|
TTS_EQUAL(a(3,c), 99.5);
|
||||||
|
|
||||||
|
auto bbbb = col(bbb,1);
|
||||||
|
TTS_EQUAL(bbbb.startRow(), 0);
|
||||||
|
TTS_EQUAL(bbbb.startCol(), 1);
|
||||||
|
bbbb.setConstant(0.125);
|
||||||
|
|
||||||
|
TTS_EQUAL(a(3,3), 0.125);
|
||||||
|
|
||||||
|
std::cout << "a: \n" << a << std::endl;
|
||||||
|
};
|
||||||
|
|
@ -21,19 +21,19 @@ TTS_CASE_TPL("Function size", rotgen::tests::types)
|
||||||
// 1x12 dynamic block at (0,0)
|
// 1x12 dynamic block at (0,0)
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> dm(1,12);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> dm(1,12);
|
||||||
fill(dm,1,12);
|
fill(dm,1,12);
|
||||||
auto b1 = rotgen::block<decltype(dm), rotgen::Dynamic, rotgen::Dynamic, false, O::value>(dm, 0,0,1,12);
|
auto b1 = rotgen::block<decltype(dm), rotgen::Dynamic, rotgen::Dynamic>(dm, 0,0,1,12);
|
||||||
TTS_EQUAL(b1.rows(), rotgen::Index{1});
|
TTS_EQUAL(b1.rows(), rotgen::Index{1});
|
||||||
TTS_EQUAL(b1.cols(), rotgen::Index{12});
|
TTS_EQUAL(b1.cols(), rotgen::Index{12});
|
||||||
|
|
||||||
// 1x5 dynamic block at (0,2)
|
// 1x5 dynamic block at (0,2)
|
||||||
auto b2 = rotgen::block<decltype(dm), rotgen::Dynamic, rotgen::Dynamic, false, O::value>(dm, 0,2,1,5);
|
auto b2 = rotgen::block<decltype(dm), rotgen::Dynamic, rotgen::Dynamic>(dm, 0,2,1,5);
|
||||||
TTS_EQUAL(b2.rows(), rotgen::Index{1});
|
TTS_EQUAL(b2.rows(), rotgen::Index{1});
|
||||||
TTS_EQUAL(b2.cols(), rotgen::Index{5});
|
TTS_EQUAL(b2.cols(), rotgen::Index{5});
|
||||||
|
|
||||||
// 3x2 dynamic block at (1,4) in 4x6
|
// 3x2 dynamic block at (1,4) in 4x6
|
||||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> dm2(4,6);
|
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> dm2(4,6);
|
||||||
fill(dm2,4,6);
|
fill(dm2,4,6);
|
||||||
auto b3 = rotgen::block<decltype(dm2), rotgen::Dynamic, rotgen::Dynamic, false, O::value>(dm2, 1,4,3,2);
|
auto b3 = rotgen::block<decltype(dm2), rotgen::Dynamic, rotgen::Dynamic>(dm2, 1,4,3,2);
|
||||||
TTS_EQUAL(b3.rows(), rotgen::Index{3});
|
TTS_EQUAL(b3.rows(), rotgen::Index{3});
|
||||||
TTS_EQUAL(b3.cols(), rotgen::Index{2});
|
TTS_EQUAL(b3.cols(), rotgen::Index{2});
|
||||||
TTS_EQUAL(b3.size(), rotgen::Index{6});
|
TTS_EQUAL(b3.size(), rotgen::Index{6});
|
||||||
|
|
@ -41,7 +41,7 @@ TTS_CASE_TPL("Function size", rotgen::tests::types)
|
||||||
// 3x4 static block
|
// 3x4 static block
|
||||||
rotgen::matrix<T,3,4,O::value> sm;
|
rotgen::matrix<T,3,4,O::value> sm;
|
||||||
fill(sm,3,4);
|
fill(sm,3,4);
|
||||||
auto b4 = rotgen::block<decltype(sm), 3, 4, false, O::value>(sm, 0,0);
|
auto b4 = rotgen::block<decltype(sm), 3, 4>(sm, 0,0);
|
||||||
TTS_EQUAL(b4.rows(), rotgen::Index{3});
|
TTS_EQUAL(b4.rows(), rotgen::Index{3});
|
||||||
TTS_EQUAL(b4.cols(), rotgen::Index{4});
|
TTS_EQUAL(b4.cols(), rotgen::Index{4});
|
||||||
TTS_EQUAL(b4.size(), rotgen::Index{12});
|
TTS_EQUAL(b4.size(), rotgen::Index{12});
|
||||||
|
|
@ -49,7 +49,7 @@ TTS_CASE_TPL("Function size", rotgen::tests::types)
|
||||||
// 6x2 static block
|
// 6x2 static block
|
||||||
rotgen::matrix<T,6,2,O::value> sm2;
|
rotgen::matrix<T,6,2,O::value> sm2;
|
||||||
fill(sm2,6,2);
|
fill(sm2,6,2);
|
||||||
auto b5 = rotgen::block<decltype(sm2), 6, 2, false, O::value>(sm2, 0,0);
|
auto b5 = rotgen::block<decltype(sm2), 6, 2>(sm2, 0,0);
|
||||||
TTS_EQUAL(b5.rows(), rotgen::Index{6});
|
TTS_EQUAL(b5.rows(), rotgen::Index{6});
|
||||||
TTS_EQUAL(b5.cols(), rotgen::Index{2});
|
TTS_EQUAL(b5.cols(), rotgen::Index{2});
|
||||||
TTS_EQUAL(b5.size(), rotgen::Index{12});
|
TTS_EQUAL(b5.size(), rotgen::Index{12});
|
||||||
|
|
@ -64,7 +64,7 @@ TTS_CASE_TPL("Test coefficient accessors", rotgen::tests::types)
|
||||||
base mat(4,3);
|
base mat(4,3);
|
||||||
for(int k=0;k<12;++k) mat.data()[k] = data[k];
|
for(int k=0;k<12;++k) mat.data()[k] = data[k];
|
||||||
|
|
||||||
auto b = rotgen::block<base,rotgen::Dynamic,rotgen::Dynamic,false,O::value>(mat, 0, 0, 4, 3);
|
auto b = rotgen::block<base,rotgen::Dynamic,rotgen::Dynamic>(mat, 0, 0, 4, 3);
|
||||||
for(rotgen::Index i=0;i<4;i++)
|
for(rotgen::Index i=0;i<4;i++)
|
||||||
{
|
{
|
||||||
for(rotgen::Index j=0;j<3;j++)
|
for(rotgen::Index j=0;j<3;j++)
|
||||||
|
|
@ -91,7 +91,7 @@ TTS_CASE_TPL("Test one index coefficient accessors", rotgen::tests::types)
|
||||||
base mat(4,3);
|
base mat(4,3);
|
||||||
for(int k=0;k<12;++k) mat.data()[k] = data[k];
|
for(int k=0;k<12;++k) mat.data()[k] = data[k];
|
||||||
|
|
||||||
auto b = rotgen::block<base,rotgen::Dynamic,rotgen::Dynamic,false,O::value>(mat, 0, 0, 4, 3);
|
auto b = rotgen::block<base,rotgen::Dynamic,rotgen::Dynamic>(mat, 0, 0, 4, 3);
|
||||||
for(rotgen::Index i=0;i<b.size();i++)
|
for(rotgen::Index i=0;i<b.size();i++)
|
||||||
TTS_EQUAL(b(i), data[i]) << "Index: " << i << "\n";
|
TTS_EQUAL(b(i), data[i]) << "Index: " << i << "\n";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,11 +39,12 @@ MatrixType make_initialized_matrix(rotgen::tests::matrix_block_test_case<MatrixT
|
||||||
return matrix;
|
return matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename MatrixType, typename BlockType, typename T>
|
template<typename MatrixType, typename BlockType>
|
||||||
void validate_block_behavior(MatrixType& matrix, BlockType& block,
|
void validate_block_behavior(MatrixType& matrix, BlockType& block,
|
||||||
rotgen::Index i0, rotgen::Index j0,
|
rotgen::Index i0, rotgen::Index j0,
|
||||||
rotgen::Index ni, rotgen::Index nj)
|
rotgen::Index ni, rotgen::Index nj)
|
||||||
{
|
{
|
||||||
|
using T = typename MatrixType::value_type;
|
||||||
TTS_EQUAL(block.rows(), ni);
|
TTS_EQUAL(block.rows(), ni);
|
||||||
TTS_EQUAL(block.cols(), nj);
|
TTS_EQUAL(block.cols(), nj);
|
||||||
TTS_EQUAL(block.size(), ni * nj);
|
TTS_EQUAL(block.size(), ni * nj);
|
||||||
|
|
@ -53,24 +54,27 @@ void validate_block_behavior(MatrixType& matrix, BlockType& block,
|
||||||
TTS_EQUAL(val, matrix(i0 + i, j0 + j));
|
TTS_EQUAL(val, matrix(i0 + i, j0 + j));
|
||||||
});
|
});
|
||||||
|
|
||||||
// test aliasing
|
// test aliasing if non immutable
|
||||||
T value = 1;
|
if constexpr(!BlockType::is_immutable)
|
||||||
for_each_element(block, [&](auto i, auto j, auto&) {
|
{
|
||||||
block(i, j) = value++;
|
T value = 1;
|
||||||
});
|
for_each_element(block, [&](auto i, auto j, auto&) {
|
||||||
|
block(i, j) = value++;
|
||||||
|
});
|
||||||
|
|
||||||
value = 1;
|
value = 1;
|
||||||
for_each_element(block, [&](auto i, auto j, auto&) {
|
for_each_element(block, [&](auto i, auto j, auto&) {
|
||||||
TTS_EQUAL(matrix(i0 + i, j0 + j), value++);
|
TTS_EQUAL(matrix(i0 + i, j0 + j), value++);
|
||||||
});
|
});
|
||||||
|
|
||||||
for_each_element(block, [&](auto i, auto j, auto&) {
|
for_each_element(block, [&](auto i, auto j, auto&) {
|
||||||
matrix(i0 + i, j0 + j) = T(42);
|
matrix(i0 + i, j0 + j) = T(42);
|
||||||
});
|
});
|
||||||
|
|
||||||
for_each_element(block, [&](auto&, auto&, auto val) {
|
for_each_element(block, [&](auto&, auto&, auto val) {
|
||||||
TTS_EQUAL(val, T(42));
|
TTS_EQUAL(val, T(42));
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename MatrixType, typename T>
|
template<typename MatrixType, typename T>
|
||||||
|
|
@ -78,6 +82,23 @@ void test_dynamic_block_extraction(rotgen::tests::matrix_block_test_case<MatrixT
|
||||||
{
|
{
|
||||||
MatrixType matrix = make_initialized_matrix<MatrixType, T>(matrix_construct);
|
MatrixType matrix = make_initialized_matrix<MatrixType, T>(matrix_construct);
|
||||||
|
|
||||||
|
MatrixType const c_matrix = matrix;
|
||||||
|
|
||||||
|
auto c_block_main = rotgen::extract(c_matrix, matrix_construct.i0, matrix_construct.j0,
|
||||||
|
matrix_construct.ni, matrix_construct.nj);
|
||||||
|
auto c_block_top_left_corner = rotgen::topLeftCorner(c_matrix, matrix_construct.ni, matrix_construct.nj);
|
||||||
|
auto c_block_top_right_corner = rotgen::topRightCorner(c_matrix, matrix_construct.ni, matrix_construct.nj);
|
||||||
|
auto c_block_bottom_left_corner = rotgen::bottomLeftCorner(c_matrix, matrix_construct.ni, matrix_construct.nj);
|
||||||
|
auto c_block_bottom_right_corner = rotgen::bottomRightCorner(c_matrix, matrix_construct.ni, matrix_construct.nj);
|
||||||
|
|
||||||
|
auto c_block_top_rows = rotgen::topRows(c_matrix, matrix_construct.ni);
|
||||||
|
auto c_block_middle_rows = rotgen::middleRows(c_matrix, matrix_construct.i0, matrix_construct.ni);
|
||||||
|
auto c_block_bottom_rows = rotgen::bottomRows(c_matrix, matrix_construct.ni);
|
||||||
|
|
||||||
|
auto c_block_left_cols = rotgen::leftCols(c_matrix, matrix_construct.nj);
|
||||||
|
auto c_block_middle_cols = rotgen::middleCols(c_matrix, matrix_construct.j0, matrix_construct.nj);
|
||||||
|
auto c_block_right_cols = rotgen::rightCols(c_matrix, matrix_construct.nj);
|
||||||
|
|
||||||
auto block_main = rotgen::extract(matrix, matrix_construct.i0, matrix_construct.j0,
|
auto block_main = rotgen::extract(matrix, matrix_construct.i0, matrix_construct.j0,
|
||||||
matrix_construct.ni, matrix_construct.nj);
|
matrix_construct.ni, matrix_construct.nj);
|
||||||
auto block_top_left_corner = rotgen::topLeftCorner(matrix, matrix_construct.ni, matrix_construct.nj);
|
auto block_top_left_corner = rotgen::topLeftCorner(matrix, matrix_construct.ni, matrix_construct.nj);
|
||||||
|
|
@ -94,6 +115,22 @@ void test_dynamic_block_extraction(rotgen::tests::matrix_block_test_case<MatrixT
|
||||||
auto block_right_cols = rotgen::rightCols(matrix, matrix_construct.nj);
|
auto block_right_cols = rotgen::rightCols(matrix, matrix_construct.nj);
|
||||||
|
|
||||||
auto blocks = std::make_tuple(
|
auto blocks = std::make_tuple(
|
||||||
|
// --- CONST TESTS
|
||||||
|
std::make_tuple(c_block_main, matrix_construct.i0, matrix_construct.j0, matrix_construct.ni, matrix_construct.nj),
|
||||||
|
std::make_tuple(c_block_top_left_corner, 0, 0, matrix_construct.ni, matrix_construct.nj),
|
||||||
|
std::make_tuple(c_block_top_right_corner, 0, matrix.cols() - matrix_construct.nj, matrix_construct.ni, matrix_construct.nj),
|
||||||
|
std::make_tuple(c_block_bottom_left_corner, matrix.rows() - matrix_construct.ni, 0, matrix_construct.ni, matrix_construct.nj),
|
||||||
|
std::make_tuple(c_block_bottom_right_corner, matrix.rows() - matrix_construct.ni, matrix.cols() - matrix_construct.nj,
|
||||||
|
matrix_construct.ni, matrix_construct.nj),
|
||||||
|
|
||||||
|
std::make_tuple(c_block_top_rows, 0, 0, matrix_construct.ni, matrix.cols()),
|
||||||
|
std::make_tuple(c_block_middle_rows, matrix_construct.i0, 0, matrix_construct.ni, matrix.cols()),
|
||||||
|
std::make_tuple(c_block_bottom_rows, matrix.rows() - matrix_construct.ni, 0, matrix_construct.ni, matrix.cols()),
|
||||||
|
|
||||||
|
std::make_tuple(c_block_left_cols, 0, 0, matrix.rows(), matrix_construct.nj),
|
||||||
|
std::make_tuple(c_block_middle_cols, 0, matrix_construct.j0, matrix.rows(), matrix_construct.nj),
|
||||||
|
std::make_tuple(c_block_right_cols, 0, matrix.cols() - matrix_construct.nj, matrix.rows(), matrix_construct.nj),
|
||||||
|
// --- REGULAR TESTS
|
||||||
std::make_tuple(block_main, matrix_construct.i0, matrix_construct.j0, matrix_construct.ni, matrix_construct.nj),
|
std::make_tuple(block_main, matrix_construct.i0, matrix_construct.j0, matrix_construct.ni, matrix_construct.nj),
|
||||||
std::make_tuple(block_top_left_corner, 0, 0, matrix_construct.ni, matrix_construct.nj),
|
std::make_tuple(block_top_left_corner, 0, 0, matrix_construct.ni, matrix_construct.nj),
|
||||||
std::make_tuple(block_top_right_corner, 0, matrix.cols() - matrix_construct.nj, matrix_construct.ni, matrix_construct.nj),
|
std::make_tuple(block_top_right_corner, 0, matrix.cols() - matrix_construct.nj, matrix_construct.ni, matrix_construct.nj),
|
||||||
|
|
@ -121,7 +158,7 @@ void test_dynamic_block_extraction(rotgen::tests::matrix_block_test_case<MatrixT
|
||||||
TTS_EQUAL(block_t::ColsAtCompileTime, rotgen::Dynamic);
|
TTS_EQUAL(block_t::ColsAtCompileTime, rotgen::Dynamic);
|
||||||
TTS_EQUAL(block_t::storage_order, MatrixType::storage_order);
|
TTS_EQUAL(block_t::storage_order, MatrixType::storage_order);
|
||||||
|
|
||||||
validate_block_behavior<MatrixType, block_t, T>(matrix, block, i_offset, j_offset, ni, nj);
|
validate_block_behavior(matrix, block, i_offset, j_offset, ni, nj);
|
||||||
})(), ...);
|
})(), ...);
|
||||||
}, blocks);
|
}, blocks);
|
||||||
|
|
||||||
|
|
@ -139,68 +176,109 @@ void test_static_block_extraction(rotgen::tests::static_matrix_block_test_case<M
|
||||||
for (rotgen::Index j = 0; j < c; ++j)
|
for (rotgen::Index j = 0; j < c; ++j)
|
||||||
matrix(i, j) = static_cast<T>(fn(i, j));
|
matrix(i, j) = static_cast<T>(fn(i, j));
|
||||||
|
|
||||||
|
MatrixType const c_matrix = matrix;
|
||||||
|
|
||||||
|
auto c_block_main = rotgen::extract<NI, NJ>(c_matrix, i0, j0);
|
||||||
|
auto c_block_top_left_corner = rotgen::topLeftCorner<NI, NJ>(c_matrix);
|
||||||
|
auto c_block_top_right_corner = rotgen::topRightCorner<NI, NJ>(c_matrix);
|
||||||
|
auto c_block_bottom_left_corner = rotgen::bottomLeftCorner<NI, NJ>(c_matrix);
|
||||||
|
auto c_block_bottom_right_corner = rotgen::bottomRightCorner<NI, NJ>(c_matrix);
|
||||||
|
auto c_block_top_rows = rotgen::topRows<NI>(c_matrix);
|
||||||
|
auto c_block_middle_rows = rotgen::middleRows<NI>(c_matrix, i0);
|
||||||
|
auto c_block_bottom_rows = rotgen::bottomRows<NI>(c_matrix);
|
||||||
|
auto c_block_left_cols = rotgen::leftCols<NJ>(c_matrix);
|
||||||
|
auto c_block_middle_cols = rotgen::middleCols<NJ>(c_matrix, j0);
|
||||||
|
auto c_block_right_cols = rotgen::rightCols<NJ>(c_matrix);
|
||||||
|
auto c_block_row = rotgen::row(c_matrix, i0);
|
||||||
|
auto c_block_col = rotgen::col(c_matrix, j0);
|
||||||
|
|
||||||
auto block_main = rotgen::extract<NI, NJ>(matrix, i0, j0);
|
auto block_main = rotgen::extract<NI, NJ>(matrix, i0, j0);
|
||||||
auto block_top_left_corner = rotgen::topLeftCorner<NI, NJ>(matrix);
|
auto block_top_left_corner = rotgen::topLeftCorner<NI, NJ>(matrix);
|
||||||
auto block_top_right_corner = rotgen::topRightCorner<NI, NJ>(matrix);
|
auto block_top_right_corner = rotgen::topRightCorner<NI, NJ>(matrix);
|
||||||
auto block_bottom_left_corner = rotgen::bottomLeftCorner<NI, NJ>(matrix);
|
auto block_bottom_left_corner = rotgen::bottomLeftCorner<NI, NJ>(matrix);
|
||||||
auto block_bottom_right_corner = rotgen::bottomRightCorner<NI, NJ>(matrix);
|
auto block_bottom_right_corner = rotgen::bottomRightCorner<NI, NJ>(matrix);
|
||||||
|
|
||||||
auto block_top_rows = rotgen::topRows<NI>(matrix);
|
auto block_top_rows = rotgen::topRows<NI>(matrix);
|
||||||
auto block_middle_rows = rotgen::middleRows<NI>(matrix, i0);
|
auto block_middle_rows = rotgen::middleRows<NI>(matrix, i0);
|
||||||
auto block_bottom_rows = rotgen::bottomRows<NI>(matrix);
|
auto block_bottom_rows = rotgen::bottomRows<NI>(matrix);
|
||||||
|
|
||||||
auto block_left_cols = rotgen::leftCols<NJ>(matrix);
|
auto block_left_cols = rotgen::leftCols<NJ>(matrix);
|
||||||
auto block_middle_cols = rotgen::middleCols<NJ>(matrix, j0);
|
auto block_middle_cols = rotgen::middleCols<NJ>(matrix, j0);
|
||||||
auto block_right_cols = rotgen::rightCols<NJ>(matrix);
|
auto block_right_cols = rotgen::rightCols<NJ>(matrix);
|
||||||
|
|
||||||
auto block_row = rotgen::row(matrix, i0);
|
auto block_row = rotgen::row(matrix, i0);
|
||||||
auto block_col = rotgen::col(matrix, j0);
|
auto block_col = rotgen::col(matrix, j0);
|
||||||
|
|
||||||
auto blocks = std::make_tuple(
|
auto blocks = std::make_tuple(
|
||||||
|
|
||||||
|
// ----- TEST ON BLOCK FROM CONST MATRIX
|
||||||
|
std::make_tuple(c_block_main, i0, j0,
|
||||||
|
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ)),
|
||||||
|
std::make_tuple(c_block_top_left_corner, 0, 0,
|
||||||
|
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ)),
|
||||||
|
std::make_tuple(c_block_top_right_corner, 0, matrix.cols() - matrix_construct.nj,
|
||||||
|
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ)),
|
||||||
|
std::make_tuple(c_block_bottom_left_corner, matrix.rows() - matrix_construct.ni, 0,
|
||||||
|
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ)),
|
||||||
|
std::make_tuple(c_block_bottom_right_corner, matrix.rows() - matrix_construct.ni,
|
||||||
|
matrix.cols() - matrix_construct.nj, matrix_construct.ni,
|
||||||
|
matrix_construct.nj, int(NI), int(NJ)),
|
||||||
|
|
||||||
|
std::make_tuple(c_block_top_rows, 0, 0, matrix_construct.ni, matrix.cols(), int(NI), rotgen::Dynamic),
|
||||||
|
std::make_tuple(c_block_middle_rows, i0, 0, matrix_construct.ni,
|
||||||
|
matrix.cols(), int(NI), rotgen::Dynamic),
|
||||||
|
std::make_tuple(c_block_bottom_rows, matrix.rows() - matrix_construct.ni,
|
||||||
|
0, matrix_construct.ni, matrix.cols(), int(NI), rotgen::Dynamic),
|
||||||
|
|
||||||
|
std::make_tuple(c_block_left_cols, 0, 0, matrix.rows(), matrix_construct.nj, rotgen::Dynamic, int(NJ)),
|
||||||
|
std::make_tuple(c_block_middle_cols, 0, j0,
|
||||||
|
matrix.rows(), matrix_construct.nj, rotgen::Dynamic, int(NJ)),
|
||||||
|
std::make_tuple(c_block_right_cols, 0, matrix.cols() - matrix_construct.nj,
|
||||||
|
matrix.rows(), matrix_construct.nj, rotgen::Dynamic, int(NJ)),
|
||||||
|
|
||||||
|
std::make_tuple(c_block_row, i0, 0,
|
||||||
|
1, matrix.cols(), 1, rotgen::Dynamic),
|
||||||
|
std::make_tuple(c_block_col, 0, j0,
|
||||||
|
matrix.rows(), 1, rotgen::Dynamic, 1),
|
||||||
|
// -- Block to NON CONST
|
||||||
std::make_tuple(block_main, i0, j0,
|
std::make_tuple(block_main, i0, j0,
|
||||||
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ), -1),
|
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ)),
|
||||||
std::make_tuple(block_top_left_corner, 0, 0,
|
std::make_tuple(block_top_left_corner, 0, 0,
|
||||||
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ), -1),
|
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ)),
|
||||||
std::make_tuple(block_top_right_corner, 0, matrix.cols() - matrix_construct.nj,
|
std::make_tuple(block_top_right_corner, 0, matrix.cols() - matrix_construct.nj,
|
||||||
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ), -1),
|
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ)),
|
||||||
std::make_tuple(block_bottom_left_corner, matrix.rows() - matrix_construct.ni, 0,
|
std::make_tuple(block_bottom_left_corner, matrix.rows() - matrix_construct.ni, 0,
|
||||||
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ), -1),
|
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ)),
|
||||||
std::make_tuple(block_bottom_right_corner, matrix.rows() - matrix_construct.ni,
|
std::make_tuple(block_bottom_right_corner, matrix.rows() - matrix_construct.ni,
|
||||||
matrix.cols() - matrix_construct.nj, matrix_construct.ni,
|
matrix.cols() - matrix_construct.nj, matrix_construct.ni,
|
||||||
matrix_construct.nj, int(NI), int(NJ), -1),
|
matrix_construct.nj, int(NI), int(NJ)),
|
||||||
|
|
||||||
std::make_tuple(block_top_rows, 0, 0, matrix_construct.ni, matrix.cols(), int(NI), rotgen::Dynamic, -1),
|
std::make_tuple(block_top_rows, 0, 0, matrix_construct.ni, matrix.cols(), int(NI), rotgen::Dynamic),
|
||||||
std::make_tuple(block_middle_rows, i0, 0, matrix_construct.ni,
|
std::make_tuple(block_middle_rows, i0, 0, matrix_construct.ni,
|
||||||
matrix.cols(), int(NI), rotgen::Dynamic, -1),
|
matrix.cols(), int(NI), rotgen::Dynamic),
|
||||||
std::make_tuple(block_bottom_rows, matrix.rows() - matrix_construct.ni,
|
std::make_tuple(block_bottom_rows, matrix.rows() - matrix_construct.ni,
|
||||||
0, matrix_construct.ni, matrix.cols(), int(NI), rotgen::Dynamic, -1),
|
0, matrix_construct.ni, matrix.cols(), int(NI), rotgen::Dynamic),
|
||||||
|
|
||||||
std::make_tuple(block_left_cols, 0, 0, matrix.rows(), matrix_construct.nj, rotgen::Dynamic, int(NJ), -1),
|
std::make_tuple(block_left_cols, 0, 0, matrix.rows(), matrix_construct.nj, rotgen::Dynamic, int(NJ)),
|
||||||
std::make_tuple(block_middle_cols, 0, j0,
|
std::make_tuple(block_middle_cols, 0, j0,
|
||||||
matrix.rows(), matrix_construct.nj, rotgen::Dynamic, int(NJ), -1),
|
matrix.rows(), matrix_construct.nj, rotgen::Dynamic, int(NJ)),
|
||||||
std::make_tuple(block_right_cols, 0, matrix.cols() - matrix_construct.nj,
|
std::make_tuple(block_right_cols, 0, matrix.cols() - matrix_construct.nj,
|
||||||
matrix.rows(), matrix_construct.nj, rotgen::Dynamic, int(NJ), -1),
|
matrix.rows(), matrix_construct.nj, rotgen::Dynamic, int(NJ)),
|
||||||
|
|
||||||
std::make_tuple(block_row, i0, 0,
|
std::make_tuple(block_row, i0, 0,
|
||||||
1, matrix.cols(), 1, rotgen::Dynamic, 1),
|
1, matrix.cols(), 1, rotgen::Dynamic),
|
||||||
std::make_tuple(block_col, 0, j0,
|
std::make_tuple(block_col, 0, j0,
|
||||||
matrix.rows(), 1, rotgen::Dynamic, 1, 0)
|
matrix.rows(), 1, rotgen::Dynamic, 1)
|
||||||
);
|
);
|
||||||
|
|
||||||
std::apply([&](auto&&... block_entries)
|
std::apply([&](auto&&... block_entries)
|
||||||
{
|
{
|
||||||
(([&]
|
(([&]
|
||||||
{
|
{
|
||||||
auto&& [block, i_offset, j_offset, ni, nj, rows_ct, cols_ct, storage_order] = block_entries;
|
auto&& [block, i_offset, j_offset, ni, nj, rows_ct, cols_ct] = block_entries;
|
||||||
using block_t = std::remove_reference_t<decltype(block)>;
|
using block_t = std::remove_reference_t<decltype(block)>;
|
||||||
|
|
||||||
TTS_EQUAL(block_t::RowsAtCompileTime, rows_ct);
|
TTS_EQUAL(block_t::RowsAtCompileTime, rows_ct);
|
||||||
TTS_EQUAL(block_t::ColsAtCompileTime, cols_ct);
|
TTS_EQUAL(block_t::ColsAtCompileTime, cols_ct);
|
||||||
|
|
||||||
auto expected_storage_order = (storage_order == -1) ? MatrixType::storage_order : storage_order;
|
validate_block_behavior(matrix, block, i_offset, j_offset, ni, nj);
|
||||||
TTS_EQUAL(block_t::storage_order, expected_storage_order);
|
|
||||||
|
|
||||||
validate_block_behavior<MatrixType, block_t, T>(matrix, block, i_offset, j_offset, ni, nj);
|
|
||||||
})(), ...);
|
})(), ...);
|
||||||
}, blocks);
|
}, blocks);
|
||||||
}
|
}
|
||||||
|
|
@ -242,7 +320,7 @@ TTS_CASE_TPL("Check all dynamic block extractions on a static column-major matri
|
||||||
TTS_CASE_TPL("Check all static block extractions", rotgen::tests::types)
|
TTS_CASE_TPL("Check all static block extractions", rotgen::tests::types)
|
||||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
||||||
{
|
{
|
||||||
using mat_t = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value, 1>;
|
using mat_t = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>;
|
||||||
|
|
||||||
test_static_block_extraction<mat_t, T, 1, 2>(
|
test_static_block_extraction<mat_t, T, 1, 2>(
|
||||||
rotgen::tests::static_matrix_block_test_case<mat_t, 1, 2>{
|
rotgen::tests::static_matrix_block_test_case<mat_t, 1, 2>{
|
||||||
|
|
@ -264,4 +342,85 @@ TTS_CASE_TPL("Check all static block extractions", rotgen::tests::types)
|
||||||
0, 0
|
0, 0
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
TTS_CASE_TPL("Check vector-only extractions", rotgen::tests::types)
|
||||||
|
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
||||||
|
{
|
||||||
|
auto refs = []()
|
||||||
|
{
|
||||||
|
if constexpr(O::value == rotgen::RowMajor)
|
||||||
|
{
|
||||||
|
using mat_t = rotgen::matrix<T,1,rotgen::Dynamic,O::value>;
|
||||||
|
mat_t m(1,11);
|
||||||
|
|
||||||
|
for(rotgen::Index i=0;i<11;++i) m(i) = 1 + i;
|
||||||
|
|
||||||
|
return std::make_tuple( m,
|
||||||
|
std::make_tuple
|
||||||
|
(
|
||||||
|
std::make_tuple(head(m, 1), 0, 0, 1, 1, 1, rotgen::Dynamic)
|
||||||
|
, std::make_tuple(head(m, 5), 0, 0, 1, 5, 1, rotgen::Dynamic)
|
||||||
|
, std::make_tuple(head(m,11), 0, 0, 1,11, 1, rotgen::Dynamic)
|
||||||
|
, std::make_tuple(head<1>(m), 0, 0, 1, 1, 1, 1)
|
||||||
|
, std::make_tuple(head<4>(m), 0, 0, 1, 4, 1, 4)
|
||||||
|
, std::make_tuple(head<9>(m), 0, 0, 1, 9, 1, 9)
|
||||||
|
, std::make_tuple(tail(m, 1), 0,10, 1, 1, 1, rotgen::Dynamic)
|
||||||
|
, std::make_tuple(tail(m, 5), 0, 6, 1, 5, 1, rotgen::Dynamic)
|
||||||
|
, std::make_tuple(tail(m,11), 0, 0, 1,11, 1, rotgen::Dynamic)
|
||||||
|
, std::make_tuple(tail<1>(m), 0,10, 1, 1, 1, 1)
|
||||||
|
, std::make_tuple(tail<4>(m), 0, 7, 1, 4, 1, 4)
|
||||||
|
, std::make_tuple(tail<9>(m), 0, 2, 1, 9, 1, 9)
|
||||||
|
, std::make_tuple(segment(m,0,11), 0, 0, 1, 11, 1, rotgen::Dynamic)
|
||||||
|
, std::make_tuple(segment(m,0, 7), 0, 0, 1, 7, 1, rotgen::Dynamic)
|
||||||
|
, std::make_tuple(segment(m,5, 6), 0, 5, 1, 6, 1, rotgen::Dynamic)
|
||||||
|
, std::make_tuple(segment<11>(m,0), 0, 0, 1, 11, 1, 11)
|
||||||
|
, std::make_tuple(segment< 7>(m,0), 0, 0, 1, 7, 1, 7)
|
||||||
|
, std::make_tuple(segment< 6>(m,5), 0, 5, 1, 6, 1, 6)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
using mat_t = rotgen::matrix<T,rotgen::Dynamic,1,O::value>;
|
||||||
|
mat_t m(11,1);
|
||||||
|
|
||||||
|
for(rotgen::Index i=0;i<11;++i) m(i) = 1 + i;
|
||||||
|
|
||||||
|
return std::make_tuple( m,
|
||||||
|
std::make_tuple
|
||||||
|
(
|
||||||
|
std::make_tuple(head(m, 1), 0, 0, 1, 1, rotgen::Dynamic, 1)
|
||||||
|
, std::make_tuple(head(m, 5), 0, 0, 5, 1, rotgen::Dynamic, 1)
|
||||||
|
, std::make_tuple(head(m,11), 0, 0,11, 1, rotgen::Dynamic, 1)
|
||||||
|
, std::make_tuple(head<1>(m), 0, 0, 1, 1, 1, 1)
|
||||||
|
, std::make_tuple(head<4>(m), 0, 0, 4, 1, 4, 1)
|
||||||
|
, std::make_tuple(head<9>(m), 0, 0, 9, 1, 9, 1)
|
||||||
|
, std::make_tuple(tail(m, 1),10, 0, 1, 1, rotgen::Dynamic, 1)
|
||||||
|
, std::make_tuple(tail(m, 5), 6, 0, 5, 1, rotgen::Dynamic, 1)
|
||||||
|
, std::make_tuple(tail(m,11), 0, 0,11, 1, rotgen::Dynamic, 1)
|
||||||
|
, std::make_tuple(tail<1>(m),10, 0, 1, 1, 1, 1)
|
||||||
|
, std::make_tuple(tail<4>(m), 7, 0, 4, 1, 4, 1)
|
||||||
|
, std::make_tuple(tail<9>(m), 2, 0, 9, 1, 9, 1)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
|
auto matrix = std::get<0>(refs);
|
||||||
|
auto blocks = std::get<1>(refs);
|
||||||
|
|
||||||
|
std::apply([&](auto&&... block_entries)
|
||||||
|
{
|
||||||
|
(([&]
|
||||||
|
{
|
||||||
|
auto&& [block, i_offset, j_offset, ni, nj, rows_ct, cols_ct] = block_entries;
|
||||||
|
using block_t = std::remove_reference_t<decltype(block)>;
|
||||||
|
|
||||||
|
TTS_EQUAL(block_t::RowsAtCompileTime, rows_ct);
|
||||||
|
TTS_EQUAL(block_t::ColsAtCompileTime, cols_ct);
|
||||||
|
|
||||||
|
validate_block_behavior(matrix, block, i_offset, j_offset, ni, nj);
|
||||||
|
})(), ...);
|
||||||
|
}, blocks);
|
||||||
};
|
};
|
||||||
Loading…
Add table
Add a link
Reference in a new issue