- Refurbish block implementation to support nested block

- Add missing extractors
This commit is contained in:
Joel Falcou 2025-09-02 19:52:22 +02:00
parent 3fff326db9
commit 93a1404d9a
24 changed files with 1205 additions and 630 deletions

View file

@ -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)

View file

@ -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;
}; };
//================================================================================================ //================================================================================================

View file

@ -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;
// outerstride must equal the “innerdimension 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));
} }
} }

View file

@ -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;

View file

@ -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) {}

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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>;

View file

@ -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;
} }

View 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

View file

@ -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_; }
}; };

View file

@ -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; };

View 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

View file

@ -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
View 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

View file

@ -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;
} }

View file

@ -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
View 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

View file

@ -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(); }

View file

@ -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)
{ {

View file

@ -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)

View 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;
};

View file

@ -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";

View file

@ -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);
}; };