Merge branch 'fix/various-manta' into 'main'
More specific fixes See merge request oss/rotgen!47
This commit is contained in:
commit
987d71cc35
34 changed files with 1171 additions and 416 deletions
|
|
@ -25,20 +25,20 @@ namespace rotgen
|
|||
|
||||
int rank() const { return parent::rank(); }
|
||||
|
||||
m_type U() const { return parent::U(); }
|
||||
m_type matrixU() const { return parent::U(); }
|
||||
|
||||
m_type D() const { return parent::D(); }
|
||||
m_type matrixD() const { return parent::D(); }
|
||||
|
||||
m_type V() const { return parent::V(); }
|
||||
m_type matrixV() const { return parent::V(); }
|
||||
|
||||
d_type singular_values() const { return parent::singular_values(); }
|
||||
d_type singularValues() const { return parent::singular_values(); }
|
||||
|
||||
m_type U(int r) const { return parent::U(r); }
|
||||
m_type matrixU(int r) const { return parent::U(r); }
|
||||
|
||||
m_type D(int r) const { return parent::D(r); }
|
||||
m_type matrixD(int r) const { return parent::D(r); }
|
||||
|
||||
m_type V(int r) const { return parent::V(r); }
|
||||
m_type matrixV(int r) const { return parent::V(r); }
|
||||
|
||||
m_type singular_values(int r) const { return parent::singular_values(r); }
|
||||
m_type singularValues(int r) const { return parent::singular_values(r); }
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,28 +31,28 @@ namespace rotgen
|
|||
|
||||
int rank() const { return svd_.rank(); }
|
||||
|
||||
auto singular_values() const
|
||||
auto singularValues() const
|
||||
{
|
||||
if constexpr (!use_expression_templates)
|
||||
return detail::as_concrete_t<d_type, matrix>{svd_.singularValues()};
|
||||
else return svd_.singularValues();
|
||||
}
|
||||
|
||||
auto U() const
|
||||
auto matrixU() const
|
||||
{
|
||||
if constexpr (!use_expression_templates)
|
||||
return detail::as_concrete_t<u_type, matrix>{svd_.matrixU()};
|
||||
else return svd_.matrixU();
|
||||
}
|
||||
|
||||
auto V() const
|
||||
auto matrixV() const
|
||||
{
|
||||
if constexpr (!use_expression_templates)
|
||||
return detail::as_concrete_t<v_type, matrix>{svd_.matrixV()};
|
||||
else return svd_.matrixV();
|
||||
}
|
||||
|
||||
auto D() const
|
||||
auto matrixD() const
|
||||
{
|
||||
auto d = svd_.singularValues().asDiagonal();
|
||||
if constexpr (!use_expression_templates)
|
||||
|
|
@ -61,7 +61,7 @@ namespace rotgen
|
|||
else return d;
|
||||
}
|
||||
|
||||
auto singular_values(int r) const
|
||||
auto singularValues(int r) const
|
||||
{
|
||||
auto that = svd_.singularValues().head(r);
|
||||
if constexpr (!use_expression_templates)
|
||||
|
|
@ -69,7 +69,7 @@ namespace rotgen
|
|||
else return svd_.singularValues();
|
||||
}
|
||||
|
||||
auto U(int r) const
|
||||
auto matrixU(int r) const
|
||||
{
|
||||
auto that = svd_.matrixU().leftCols(r);
|
||||
if constexpr (!use_expression_templates)
|
||||
|
|
@ -77,7 +77,7 @@ namespace rotgen
|
|||
else return that;
|
||||
}
|
||||
|
||||
auto V(int r) const
|
||||
auto matrixV(int r) const
|
||||
{
|
||||
auto that = svd_.matrixV().leftCols(r);
|
||||
if constexpr (!use_expression_templates)
|
||||
|
|
@ -85,7 +85,7 @@ namespace rotgen
|
|||
else return that;
|
||||
}
|
||||
|
||||
auto D(int r) const
|
||||
auto matrixD(int r) const
|
||||
{
|
||||
auto d = svd_.singularValues().head(r).asDiagonal();
|
||||
if constexpr (!use_expression_templates)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,26 @@
|
|||
|
||||
namespace rotgen::concepts
|
||||
{
|
||||
//================================================================================================
|
||||
//! @brief Check if a type is a Rotgen block.
|
||||
//================================================================================================
|
||||
template<typename T>
|
||||
concept block =
|
||||
requires { typename std::remove_cvref_t<T>::rotgen_block_tag; };
|
||||
|
||||
//================================================================================================
|
||||
//! @brief Check if a type is a Rotgen matrix.
|
||||
//================================================================================================
|
||||
template<typename T>
|
||||
concept matrix =
|
||||
requires { typename std::remove_cvref_t<T>::rotgen_matrix_tag; };
|
||||
|
||||
//================================================================================================
|
||||
//! @brief Check if a type is a Rotgen map.
|
||||
//================================================================================================
|
||||
template<typename T>
|
||||
concept map = requires { typename std::remove_cvref_t<T>::rotgen_map_tag; };
|
||||
|
||||
//================================================================================================
|
||||
//! @brief Check if a type is a Rotgen reference.
|
||||
//================================================================================================
|
||||
|
|
@ -36,10 +56,8 @@ namespace rotgen::concepts
|
|||
//! @brief Check if a type is a ROTGEN type.
|
||||
//================================================================================================
|
||||
template<typename T>
|
||||
concept entity = requires(T const&) {
|
||||
typename std::remove_cvref_t<T>::rotgen_tag;
|
||||
typename std::remove_cvref_t<T>::parent;
|
||||
};
|
||||
concept entity =
|
||||
requires(T const&) { typename std::remove_cvref_t<T>::rotgen_tag; };
|
||||
|
||||
//================================================================================================
|
||||
//! @brief Check if a type is an EIGEN type.
|
||||
|
|
|
|||
|
|
@ -7,11 +7,12 @@
|
|||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/detail/assert.hpp>
|
||||
|
||||
#include <rotgen/concepts.hpp>
|
||||
#include <rotgen/container/block/dynamic/impl.hpp>
|
||||
#include <rotgen/container/matrix/dynamic.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <initializer_list>
|
||||
|
||||
namespace rotgen
|
||||
|
|
@ -76,14 +77,37 @@ namespace rotgen
|
|||
|
||||
using parent::operator=;
|
||||
|
||||
block& operator=(concepts::entity auto const& other)
|
||||
template<concepts::entity Src>
|
||||
block& operator=(Src const& other)
|
||||
requires(!is_immutable)
|
||||
{
|
||||
assert(parent::rows() == other.rows() && parent::cols() == other.cols());
|
||||
for (rotgen::Index r = 0; r < parent::rows(); ++r)
|
||||
for (rotgen::Index c = 0; c < parent::cols(); ++c)
|
||||
(*this)(r, c) = other(r, c);
|
||||
if constexpr (IsVectorAtCompileTime && Src::IsVectorAtCompileTime)
|
||||
{
|
||||
ROTGEN_ASSERT(parent::size() == other.size(),
|
||||
"Block assignment from 1D source doesn't match size");
|
||||
for (rotgen::Index i = 0; i < parent::size(); ++i)
|
||||
(*this)[i] = other[i];
|
||||
}
|
||||
else if constexpr (IsVectorAtCompileTime && !Src::IsVectorAtCompileTime)
|
||||
{
|
||||
auto r = other.rows();
|
||||
auto c = other.cols();
|
||||
|
||||
ROTGEN_ASSERT((r == 1 || c == 1), "Block assignment from dynamic sized "
|
||||
"source doesn't match static size");
|
||||
|
||||
for (rotgen::Index i = 0; i < parent::size(); ++i)
|
||||
(*this)[i] = other(r == 1 ? 0 : i, c == 1 ? 0 : i);
|
||||
}
|
||||
else
|
||||
{
|
||||
ROTGEN_ASSERT(parent::rows() == other.rows() &&
|
||||
parent::cols() == other.cols(),
|
||||
"Block assignment size mismatch");
|
||||
for (rotgen::Index r = 0; r < parent::rows(); ++r)
|
||||
for (rotgen::Index c = 0; c < parent::cols(); ++c)
|
||||
(*this)(r, c) = other(r, c);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -167,13 +191,6 @@ namespace rotgen
|
|||
|
||||
block(parent const& base) : parent(base) {}
|
||||
|
||||
bool is_contiguous_linear() const
|
||||
{
|
||||
if (parent::innerStride() != 1) return false;
|
||||
if constexpr (IsRowMajor) return parent::outerStride() == parent::cols();
|
||||
else return parent::outerStride() == parent::rows();
|
||||
}
|
||||
|
||||
value_type& operator()(Index i, Index j)
|
||||
requires(!is_immutable)
|
||||
{
|
||||
|
|
@ -183,7 +200,6 @@ namespace rotgen
|
|||
value_type& operator()(Index i)
|
||||
requires(!is_immutable && IsVectorAtCompileTime)
|
||||
{
|
||||
assert(is_contiguous_linear());
|
||||
return parent::operator()(i);
|
||||
}
|
||||
|
||||
|
|
@ -201,7 +217,6 @@ namespace rotgen
|
|||
value_type operator()(Index i) const
|
||||
requires(IsVectorAtCompileTime)
|
||||
{
|
||||
assert(is_contiguous_linear());
|
||||
return parent::operator()(i);
|
||||
}
|
||||
|
||||
|
|
@ -211,7 +226,7 @@ namespace rotgen
|
|||
return (*this)(i);
|
||||
}
|
||||
|
||||
auto evaluate() const { return *this; }
|
||||
concrete_type evaluate() const { return concrete_type{*this}; }
|
||||
|
||||
decltype(auto) noalias() const { return *this; }
|
||||
|
||||
|
|
@ -278,17 +293,19 @@ namespace rotgen
|
|||
return static_cast<parent const&>(lhs) == static_cast<parent const&>(rhs);
|
||||
}
|
||||
|
||||
block& operator+=(block const& rhs)
|
||||
template<concepts::entity E>
|
||||
block& operator+=(E const& rhs)
|
||||
requires(!is_immutable)
|
||||
{
|
||||
base() += static_cast<parent const&>(rhs);
|
||||
base() += rhs.base();
|
||||
return *this;
|
||||
}
|
||||
|
||||
block& operator-=(block const& rhs)
|
||||
template<concepts::entity E>
|
||||
block& operator-=(E const& rhs)
|
||||
requires(!is_immutable)
|
||||
{
|
||||
base() -= static_cast<parent const&>(rhs);
|
||||
base() -= rhs.base();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -297,10 +314,11 @@ namespace rotgen
|
|||
return concrete_type(static_cast<parent const&>(*this).operator-());
|
||||
}
|
||||
|
||||
block& operator*=(block const& rhs)
|
||||
template<concepts::entity E>
|
||||
block& operator*=(E const& rhs)
|
||||
requires(!is_immutable)
|
||||
{
|
||||
base() *= static_cast<parent const&>(rhs);
|
||||
base() *= rhs.base();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -351,11 +369,11 @@ namespace rotgen
|
|||
static concrete_type Zero(int rows, int cols)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(rows == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(rows == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(cols == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(cols == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
return parent::Zero(rows, cols);
|
||||
}
|
||||
|
||||
|
|
@ -368,11 +386,11 @@ namespace rotgen
|
|||
static concrete_type Ones(int rows, int cols)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(rows == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(rows == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(cols == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(cols == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
return parent::Ones(rows, cols);
|
||||
}
|
||||
|
||||
|
|
@ -385,11 +403,11 @@ namespace rotgen
|
|||
static concrete_type Constant(int rows, int cols, value_type value)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(rows == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(rows == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(cols == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(cols == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
return parent::Constant(rows, cols, static_cast<double>(value));
|
||||
}
|
||||
|
||||
|
|
@ -402,11 +420,11 @@ namespace rotgen
|
|||
static concrete_type Random(int rows, int cols)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(rows == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(rows == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(cols == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(cols == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
return parent::Random(rows, cols);
|
||||
}
|
||||
|
||||
|
|
@ -419,11 +437,11 @@ namespace rotgen
|
|||
static concrete_type Identity(int rows, int cols)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(rows == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(rows == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(cols == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(cols == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
return parent::Identity(rows, cols);
|
||||
}
|
||||
|
||||
|
|
@ -464,7 +482,7 @@ namespace rotgen
|
|||
|
||||
template<int P> value_type lpNorm() const
|
||||
{
|
||||
assert(P == 1 || P == 2 || P == Infinity);
|
||||
static_assert(P == 1 || P == 2 || P == Infinity);
|
||||
return parent::lpNorm(P);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,28 +2,36 @@
|
|||
#define TYPE double
|
||||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _col)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
||||
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
||||
#include <rotgen/container/block/dynamic/model.hpp>
|
||||
#undef CLASSNAME
|
||||
#undef CLASSCONSTNAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef TRANSNAME
|
||||
#undef SOURCENAME
|
||||
#undef MAPNAME
|
||||
#undef TRANSMAPNAME
|
||||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _row)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
||||
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
||||
#include <rotgen/container/block/dynamic/model.hpp>
|
||||
#undef CLASSNAME
|
||||
#undef CLASSCONSTNAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef TRANSNAME
|
||||
#undef SOURCENAME
|
||||
#undef MAPNAME
|
||||
#undef TRANSMAPNAME
|
||||
|
||||
#undef SIZE
|
||||
#undef TYPE
|
||||
|
|
@ -32,28 +40,36 @@
|
|||
#define TYPE float
|
||||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _col)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
||||
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
||||
#include <rotgen/container/block/dynamic/model.hpp>
|
||||
#undef CLASSNAME
|
||||
#undef CLASSCONSTNAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef TRANSNAME
|
||||
#undef SOURCENAME
|
||||
#undef MAPNAME
|
||||
#undef TRANSMAPNAME
|
||||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _row)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
||||
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
||||
#include <rotgen/container/block/dynamic/model.hpp>
|
||||
#undef CLASSNAME
|
||||
#undef CLASSCONSTNAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef TRANSNAME
|
||||
#undef SOURCENAME
|
||||
#undef MAPNAME
|
||||
#undef TRANSMAPNAME
|
||||
|
||||
#undef SIZE
|
||||
#undef TYPE
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ public:
|
|||
CLASSNAME(MAPNAME CONST& r, Index i0, Index j0, Index ni, Index nj);
|
||||
CLASSNAME(CLASSNAME CONST& r, Index i0, Index j0, Index ni, Index nj);
|
||||
CLASSNAME(TRANSCLASSNAME CONST& r, Index i0, Index j0, Index ni, Index nj);
|
||||
CLASSNAME(TRANSMAPNAME CONST& r, Index i0, Index j0, Index ni, Index nj);
|
||||
|
||||
CLASSNAME(CLASSNAME const& other);
|
||||
CLASSNAME(CLASSNAME&&) noexcept;
|
||||
|
|
@ -81,8 +82,17 @@ public:
|
|||
TYPE& operator()(Index i, Index j);
|
||||
TYPE& operator()(Index index);
|
||||
CLASSNAME& operator+=(CLASSNAME const& rhs);
|
||||
CLASSNAME& operator+=(CLASSCONSTNAME const& rhs);
|
||||
CLASSNAME& operator+=(SOURCENAME const& rhs);
|
||||
CLASSNAME& operator+=(TRANSNAME const& rhs);
|
||||
CLASSNAME& operator-=(CLASSNAME const& rhs);
|
||||
CLASSNAME& operator-=(CLASSCONSTNAME const& rhs);
|
||||
CLASSNAME& operator-=(SOURCENAME const& rhs);
|
||||
CLASSNAME& operator-=(TRANSNAME const& rhs);
|
||||
CLASSNAME& operator*=(CLASSNAME const& rhs);
|
||||
CLASSNAME& operator*=(CLASSCONSTNAME const& rhs);
|
||||
CLASSNAME& operator*=(SOURCENAME const& rhs);
|
||||
CLASSNAME& operator*=(TRANSNAME const& rhs);
|
||||
CLASSNAME& operator*=(TYPE d);
|
||||
CLASSNAME& operator/=(TYPE d);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -193,11 +193,7 @@ namespace rotgen
|
|||
|
||||
parent const& base() const { return static_cast<parent const&>(*this); }
|
||||
|
||||
auto evaluate() const
|
||||
{
|
||||
auto res = base().eval();
|
||||
return as_concrete_type<decltype(res)>(res);
|
||||
}
|
||||
auto evaluate() const { return concrete_type(base().eval()); }
|
||||
|
||||
decltype(auto) noalias() const
|
||||
{
|
||||
|
|
@ -298,11 +294,11 @@ namespace rotgen
|
|||
static concrete_type Constant(int rows, int cols, value_type value)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(rows == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(rows == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(cols == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(cols == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
return parent::Constant(rows, cols, static_cast<value_type>(value));
|
||||
}
|
||||
|
||||
|
|
@ -315,11 +311,11 @@ namespace rotgen
|
|||
static concrete_type Identity(int rows, int cols)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(rows == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(rows == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(cols == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(cols == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
return parent::Identity(rows, cols);
|
||||
}
|
||||
|
||||
|
|
@ -332,11 +328,11 @@ namespace rotgen
|
|||
static concrete_type Zero(int rows, int cols)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(rows == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(rows == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(cols == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(cols == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
return parent::Zero(rows, cols);
|
||||
}
|
||||
|
||||
|
|
@ -349,11 +345,11 @@ namespace rotgen
|
|||
static concrete_type Ones(int rows, int cols)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(rows == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(rows == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(cols == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(cols == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
return parent::Ones(rows, cols);
|
||||
}
|
||||
|
||||
|
|
@ -366,11 +362,11 @@ namespace rotgen
|
|||
static concrete_type Random(int rows, int cols)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(rows == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(rows == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(cols == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(cols == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
return parent::Random(rows, cols);
|
||||
}
|
||||
|
||||
|
|
@ -523,17 +519,19 @@ namespace rotgen
|
|||
|
||||
Index startCol() const { return base().startCol(); }
|
||||
|
||||
block& operator+=(block const& rhs)
|
||||
template<concepts::entity E>
|
||||
block& operator+=(E const& rhs)
|
||||
requires(!is_immutable)
|
||||
{
|
||||
static_cast<parent&>(*this) += static_cast<parent const&>(rhs);
|
||||
base() += rhs.base();
|
||||
return *this;
|
||||
}
|
||||
|
||||
block& operator-=(block const& rhs)
|
||||
template<concepts::entity E>
|
||||
block& operator-=(E const& rhs)
|
||||
requires(!is_immutable)
|
||||
{
|
||||
static_cast<parent&>(*this) -= static_cast<parent const&>(rhs);
|
||||
base() -= rhs.base();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -542,10 +540,11 @@ namespace rotgen
|
|||
return concrete_type(static_cast<parent const&>(*this).operator-());
|
||||
}
|
||||
|
||||
block& operator*=(block const& rhs)
|
||||
template<concepts::entity E>
|
||||
block& operator*=(E const& rhs)
|
||||
requires(!is_immutable)
|
||||
{
|
||||
static_cast<parent&>(*this) *= static_cast<parent const&>(rhs);
|
||||
base() *= rhs.base();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,14 +7,14 @@
|
|||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/detail/assert.hpp>
|
||||
#include <rotgen/detail/helpers.hpp>
|
||||
#include <rotgen/detail/product.hpp>
|
||||
|
||||
#include <rotgen/concepts.hpp>
|
||||
#include <rotgen/container/map/dynamic/impl.hpp>
|
||||
#include <rotgen/container/matrix.hpp>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
namespace detail
|
||||
|
|
@ -35,6 +35,7 @@ namespace rotgen
|
|||
|
||||
using parent = find_map<Ref>;
|
||||
using rotgen_tag = void;
|
||||
using rotgen_map_tag = void;
|
||||
using value_type = typename std::remove_const_t<Ref>::value_type;
|
||||
using concrete_type = typename std::remove_const_t<Ref>::concrete_type;
|
||||
|
||||
|
|
@ -52,6 +53,7 @@ namespace rotgen
|
|||
static constexpr int ColsAtCompileTime = Ref::ColsAtCompileTime;
|
||||
static constexpr int MaxRowsAtCompileTime = Ref::MaxRowsAtCompileTime;
|
||||
static constexpr int MaxColsAtCompileTime = Ref::MaxColsAtCompileTime;
|
||||
static constexpr int SizeAtCompileTime = Ref::SizeAtCompileTime;
|
||||
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
|
||||
static constexpr bool is_defined_static =
|
||||
RowsAtCompileTime != -1 && ColsAtCompileTime != -1;
|
||||
|
|
@ -75,12 +77,12 @@ namespace rotgen
|
|||
: parent(ptr, r, c, strides<storage_order>(s, r, c))
|
||||
{
|
||||
if constexpr (RowsAtCompileTime != -1)
|
||||
assert(r == RowsAtCompileTime &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(r == RowsAtCompileTime,
|
||||
"Mismatched between dynamic and static row size");
|
||||
|
||||
if constexpr (ColsAtCompileTime != -1)
|
||||
assert(c == ColsAtCompileTime &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(c == ColsAtCompileTime,
|
||||
"Mismatched between dynamic and static column size");
|
||||
}
|
||||
|
||||
// Used to properly delay ref dynamic construction
|
||||
|
|
@ -135,24 +137,50 @@ namespace rotgen
|
|||
|
||||
map(map const& other) : parent(other) {}
|
||||
|
||||
map(map&& other) : parent(std::move(other)) {}
|
||||
|
||||
map& operator=(map const& other)
|
||||
requires(!is_immutable)
|
||||
{
|
||||
base() = static_cast<parent const&>(other);
|
||||
base() = other.base();
|
||||
return *this;
|
||||
}
|
||||
|
||||
map& operator=(concepts::entity auto const& other)
|
||||
map& operator=(map&& other)
|
||||
requires(!is_immutable)
|
||||
{
|
||||
assert(parent::rows() == other.rows() && parent::cols() == other.cols());
|
||||
if constexpr (IsVectorAtCompileTime)
|
||||
base() = std::move(other.base());
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<concepts::entity Src>
|
||||
map& operator=(Src const& other)
|
||||
requires(!is_immutable)
|
||||
{
|
||||
if constexpr (IsVectorAtCompileTime && Src::IsVectorAtCompileTime)
|
||||
{
|
||||
ROTGEN_ASSERT(parent::size() == other.size(),
|
||||
"Map assignment from 1D source doesn't match size");
|
||||
for (rotgen::Index i = 0; i < parent::size(); ++i)
|
||||
(*this)(i) = other(i);
|
||||
(*this)[i] = other[i];
|
||||
}
|
||||
else if constexpr (IsVectorAtCompileTime && !Src::IsVectorAtCompileTime)
|
||||
{
|
||||
auto r = other.rows();
|
||||
auto c = other.cols();
|
||||
|
||||
ROTGEN_ASSERT(
|
||||
(r == 1 || c == 1),
|
||||
"Map assignment from dynamic sized source doesn't match static size");
|
||||
|
||||
for (rotgen::Index i = 0; i < parent::size(); ++i)
|
||||
(*this)[i] = other(r == 1 ? 0 : i, c == 1 ? 0 : i);
|
||||
}
|
||||
else
|
||||
{
|
||||
ROTGEN_ASSERT(parent::rows() == other.rows() &&
|
||||
parent::cols() == other.cols(),
|
||||
"Map assignment size mismatch");
|
||||
for (rotgen::Index r = 0; r < parent::rows(); ++r)
|
||||
for (rotgen::Index c = 0; c < parent::cols(); ++c)
|
||||
(*this)(r, c) = other(r, c);
|
||||
|
|
@ -196,7 +224,7 @@ namespace rotgen
|
|||
return (*this)(i);
|
||||
}
|
||||
|
||||
auto evaluate() const { return *this; }
|
||||
concrete_type evaluate() const { return concrete_type{*this}; }
|
||||
|
||||
decltype(auto) noalias() const { return *this; }
|
||||
|
||||
|
|
@ -275,7 +303,7 @@ namespace rotgen
|
|||
concrete_type cross(map const& other) const
|
||||
{
|
||||
concrete_type that;
|
||||
if constexpr (RowsAtCompileTime == -1)
|
||||
if constexpr (ColsAtCompileTime == 1)
|
||||
{
|
||||
that(0, 0) = (*this)(1, 0) * other(2, 0) - (*this)(2, 0) * other(1, 0);
|
||||
that(1, 0) = (*this)(2, 0) * other(0, 0) - (*this)(0, 0) * other(2, 0);
|
||||
|
|
@ -312,6 +340,7 @@ namespace rotgen
|
|||
map& operator+=(map<R2, O2, S2> const& rhs)
|
||||
requires(!is_immutable)
|
||||
{
|
||||
validate_compound_operator(rhs);
|
||||
base() += rhs.base();
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -320,6 +349,7 @@ namespace rotgen
|
|||
map& operator-=(map<R2, O2, S2> const& rhs)
|
||||
requires(!is_immutable)
|
||||
{
|
||||
validate_compound_operator(rhs);
|
||||
base() -= rhs.base();
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -333,6 +363,9 @@ namespace rotgen
|
|||
map& operator*=(map<R2, O2, S2> const& rhs)
|
||||
requires(!is_immutable)
|
||||
{
|
||||
ROTGEN_ASSERT(parent::cols() == rhs.rows() &&
|
||||
parent::cols() == rhs.cols(),
|
||||
"Incompatible dimensions for compound matrix-product");
|
||||
base() *= rhs.base();
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -464,7 +497,7 @@ namespace rotgen
|
|||
|
||||
template<int P> value_type lpNorm() const
|
||||
{
|
||||
assert(P == 1 || P == 2 || P == Infinity);
|
||||
static_assert(P == 1 || P == 2 || P == Infinity);
|
||||
return parent::lpNorm(P);
|
||||
}
|
||||
|
||||
|
|
@ -476,6 +509,32 @@ namespace rotgen
|
|||
{
|
||||
return concrete_type(base().qr_solve(rhs.base()));
|
||||
};
|
||||
|
||||
template<typename R2, int O2, typename S2>
|
||||
void validate_compound_operator(map<R2, O2, S2> const& rhs)
|
||||
{
|
||||
if constexpr (IsVectorAtCompileTime && R2::IsVectorAtCompileTime)
|
||||
{
|
||||
if constexpr (is_defined_static && R2::is_defined_static)
|
||||
{
|
||||
static_assert(
|
||||
SizeAtCompileTime == R2::SizeAtCompileTime,
|
||||
"Compile-time size mismatch in compound assignment operator");
|
||||
}
|
||||
else
|
||||
{
|
||||
ROTGEN_ASSERT(parent::size() == rhs.size(),
|
||||
"Size mismatch in compound assignment operator");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ROTGEN_ASSERT(parent::rows() == rhs.rows(),
|
||||
"Mismatched rows count in compound assignment operator");
|
||||
ROTGEN_ASSERT(parent::cols() == rhs.cols(),
|
||||
"Mismatched cols count in compound assignment operator");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
|
||||
|
|
@ -499,18 +558,20 @@ namespace rotgen
|
|||
}
|
||||
|
||||
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
|
||||
matrix<typename R1::value_type,
|
||||
R1::RowsAtCompileTime,
|
||||
R2::ColsAtCompileTime,
|
||||
R1::storage_order>
|
||||
operator*(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
|
||||
auto operator*(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
|
||||
{
|
||||
using map1_type = map<R1 const, O1, S1>;
|
||||
using map2_type = map<R2 const, O2, S2>;
|
||||
using concrete_type = matrix<typename R1::value_type, R1::RowsAtCompileTime,
|
||||
R2::ColsAtCompileTime, R1::storage_order>;
|
||||
|
||||
return concrete_type(map1_type(lhs).base().mul(map2_type(rhs).base()));
|
||||
if constexpr (concrete_type::SizeAtCompileTime == 0) return concrete_type{};
|
||||
else
|
||||
{
|
||||
auto p = concrete_type(map1_type(lhs).base().mul(map2_type(rhs).base()));
|
||||
if constexpr (concrete_type::SizeAtCompileTime == 1) return product{p};
|
||||
else return p;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename R, int O, typename S>
|
||||
|
|
|
|||
|
|
@ -3,27 +3,39 @@
|
|||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
|
||||
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
|
||||
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
|
||||
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
|
||||
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#include <rotgen/container/map/dynamic/model.hpp>
|
||||
#undef CLASSNAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef TRANSCLASSCONSTNAME
|
||||
#undef TRANSCLASSNONCONSTNAME
|
||||
#undef TRANSSOURCENAME
|
||||
#undef SOURCENAME
|
||||
#undef CLASSCONSTNAME
|
||||
#undef CLASSNONCONSTNAME
|
||||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
|
||||
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
|
||||
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
|
||||
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
|
||||
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#include <rotgen/container/map/dynamic/model.hpp>
|
||||
#undef CLASSNAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef TRANSCLASSCONSTNAME
|
||||
#undef TRANSCLASSNONCONSTNAME
|
||||
#undef TRANSSOURCENAME
|
||||
#undef SOURCENAME
|
||||
#undef CLASSCONSTNAME
|
||||
#undef CLASSNONCONSTNAME
|
||||
|
||||
#undef SIZE
|
||||
#undef TYPE
|
||||
|
|
@ -33,27 +45,39 @@
|
|||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
|
||||
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
|
||||
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
|
||||
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
|
||||
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#include <rotgen/container/map/dynamic/model.hpp>
|
||||
#undef CLASSNAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef TRANSCLASSCONSTNAME
|
||||
#undef TRANSCLASSNONCONSTNAME
|
||||
#undef TRANSSOURCENAME
|
||||
#undef SOURCENAME
|
||||
#undef CLASSCONSTNAME
|
||||
#undef CLASSNONCONSTNAME
|
||||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
|
||||
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
|
||||
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
|
||||
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
|
||||
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#include <rotgen/container/map/dynamic/model.hpp>
|
||||
#undef CLASSNAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef TRANSCLASSCONSTNAME
|
||||
#undef TRANSCLASSNONCONSTNAME
|
||||
#undef TRANSSOURCENAME
|
||||
#undef SOURCENAME
|
||||
#undef CLASSCONSTNAME
|
||||
#undef CLASSNONCONSTNAME
|
||||
|
||||
#undef SIZE
|
||||
#undef TYPE
|
||||
|
|
|
|||
|
|
@ -66,8 +66,10 @@ public:
|
|||
TYPE minCoeff() const;
|
||||
TYPE maxCoeff(Index*, Index*) const;
|
||||
TYPE minCoeff(Index*, Index*) const;
|
||||
TYPE dot(CLASSNAME const&) const;
|
||||
TYPE dot(TRANSCLASSNAME const&) const;
|
||||
TYPE dot(CLASSNONCONSTNAME const&) const;
|
||||
TYPE dot(CLASSCONSTNAME const&) const;
|
||||
TYPE dot(TRANSCLASSCONSTNAME const&) const;
|
||||
TYPE dot(TRANSCLASSNONCONSTNAME const&) const;
|
||||
|
||||
TYPE squaredNorm() const;
|
||||
TYPE norm() const;
|
||||
|
|
@ -86,10 +88,16 @@ public:
|
|||
#if !defined(USE_CONST)
|
||||
CLASSNAME& operator+=(CLASSNAME const& rhs);
|
||||
CLASSNAME& operator+=(CLASSCONSTNAME const& rhs);
|
||||
CLASSNAME& operator+=(TRANSCLASSCONSTNAME const& rhs);
|
||||
CLASSNAME& operator+=(TRANSCLASSNONCONSTNAME const& rhs);
|
||||
CLASSNAME& operator-=(CLASSNAME const& rhs);
|
||||
CLASSNAME& operator-=(CLASSCONSTNAME const& rhs);
|
||||
CLASSNAME& operator-=(TRANSCLASSCONSTNAME const& rhs);
|
||||
CLASSNAME& operator-=(TRANSCLASSNONCONSTNAME const& rhs);
|
||||
CLASSNAME& operator*=(CLASSNAME const& rhs);
|
||||
CLASSNAME& operator*=(CLASSCONSTNAME const& rhs);
|
||||
CLASSNAME& operator*=(TRANSCLASSCONSTNAME const& rhs);
|
||||
CLASSNAME& operator*=(TRANSCLASSNONCONSTNAME const& rhs);
|
||||
CLASSNAME& operator*=(TYPE d);
|
||||
CLASSNAME& operator/=(TYPE d);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/detail/product.hpp>
|
||||
|
||||
#include <Eigen/Dense>
|
||||
#include <iostream>
|
||||
|
||||
|
|
@ -41,6 +43,7 @@ namespace rotgen
|
|||
{
|
||||
public:
|
||||
using rotgen_tag = void;
|
||||
using rotgen_map_tag = void;
|
||||
using parent = detail::
|
||||
map_type<std::remove_const_t<Ref>, Options, std::is_const_v<Ref>, Stride>;
|
||||
using value_type = typename std::remove_const_t<Ref>::value_type;
|
||||
|
|
@ -50,6 +53,7 @@ namespace rotgen
|
|||
static constexpr int ColsAtCompileTime = Ref::ColsAtCompileTime;
|
||||
static constexpr int MaxRowsAtCompileTime = Ref::MaxRowsAtCompileTime;
|
||||
static constexpr int MaxColsAtCompileTime = Ref::MaxColsAtCompileTime;
|
||||
static constexpr int SizeAtCompileTime = Ref::SizeAtCompileTime;
|
||||
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
|
||||
static constexpr bool has_static_storage = Ref::has_static_storage;
|
||||
static constexpr bool IsRowMajor = Ref::IsRowMajor;
|
||||
|
|
@ -112,21 +116,25 @@ namespace rotgen
|
|||
return *this;
|
||||
}
|
||||
|
||||
template<typename OtherDerived>
|
||||
map& operator=(Eigen::MatrixBase<OtherDerived> const& other)
|
||||
{
|
||||
parent::operator=(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename OtherDerived>
|
||||
map& operator=(Eigen::EigenBase<OtherDerived> const& other)
|
||||
{
|
||||
parent::operator=(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
parent& base() { return static_cast<parent&>(*this); }
|
||||
|
||||
parent const& base() const { return static_cast<parent const&>(*this); }
|
||||
|
||||
auto evaluate() const
|
||||
{
|
||||
auto res = static_cast<parent const&>(*this).eval();
|
||||
return as_concrete_type<decltype(res)>(res);
|
||||
}
|
||||
|
||||
auto evaluate()
|
||||
{
|
||||
auto res = static_cast<parent&>(*this).eval();
|
||||
return as_concrete_type<decltype(res)>(res);
|
||||
}
|
||||
auto evaluate() const { return concrete_type(base().eval()); }
|
||||
|
||||
decltype(auto) noalias() const
|
||||
{
|
||||
|
|
@ -176,6 +184,7 @@ namespace rotgen
|
|||
map& operator+=(map<R2, O2, S2> const& rhs)
|
||||
requires(!is_immutable)
|
||||
{
|
||||
validate_compound_operator(rhs);
|
||||
base() += rhs.base();
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -184,6 +193,7 @@ namespace rotgen
|
|||
map& operator-=(map<R2, O2, S2> const& rhs)
|
||||
requires(!is_immutable)
|
||||
{
|
||||
validate_compound_operator(rhs);
|
||||
base() -= rhs.base();
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -192,6 +202,9 @@ namespace rotgen
|
|||
map& operator*=(map<R2, O2, S2> const& rhs)
|
||||
requires(!is_immutable)
|
||||
{
|
||||
ROTGEN_ASSERT(parent::cols() == rhs.rows() &&
|
||||
parent::cols() == rhs.cols(),
|
||||
"Incompatible dimensions for compound matrix-product");
|
||||
base() *= rhs.base();
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -463,6 +476,32 @@ namespace rotgen
|
|||
static_assert(P == 1 || P == 2 || P == Infinity);
|
||||
return parent::template lpNorm<P>();
|
||||
}
|
||||
|
||||
template<typename R2, int O2, typename S2>
|
||||
void validate_compound_operator(map<R2, O2, S2> const& rhs)
|
||||
{
|
||||
if constexpr (IsVectorAtCompileTime && R2::IsVectorAtCompileTime)
|
||||
{
|
||||
if constexpr (is_defined_static && R2::is_defined_static)
|
||||
{
|
||||
static_assert(
|
||||
SizeAtCompileTime == R2::SizeAtCompileTime,
|
||||
"Compile-time size mismatch in compound assignment operator");
|
||||
}
|
||||
else
|
||||
{
|
||||
ROTGEN_ASSERT(parent::size() == rhs.size(),
|
||||
"Size mismatch in compound assignment operator");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ROTGEN_ASSERT(parent::rows() == rhs.rows(),
|
||||
"Mismatched rows count in compound assignment operator");
|
||||
ROTGEN_ASSERT(parent::cols() == rhs.cols(),
|
||||
"Mismatched cols count in compound assignment operator");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
|
||||
|
|
@ -534,13 +573,14 @@ namespace rotgen
|
|||
}
|
||||
|
||||
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
|
||||
matrix<typename R1::value_type, R1::RowsAtCompileTime, R2::ColsAtCompileTime>
|
||||
operator*(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
|
||||
auto operator*(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
|
||||
{
|
||||
using concrete_type = matrix<typename R1::value_type, R1::RowsAtCompileTime,
|
||||
R2::ColsAtCompileTime>;
|
||||
auto p = lhs.base() * rhs.base();
|
||||
using concrete_type = detail::as_concrete_t<decltype(p), matrix>;
|
||||
|
||||
return concrete_type(lhs.base() * rhs.base());
|
||||
if constexpr (concrete_type::SizeAtCompileTime == 1)
|
||||
return product{concrete_type{p}};
|
||||
else return concrete_type{p};
|
||||
}
|
||||
|
||||
template<typename R, int O, typename S>
|
||||
|
|
|
|||
|
|
@ -7,11 +7,12 @@
|
|||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/detail/assert.hpp>
|
||||
#include <rotgen/detail/helpers.hpp>
|
||||
|
||||
#include <rotgen/concepts.hpp>
|
||||
#include <rotgen/container/matrix/dynamic/impl.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <initializer_list>
|
||||
|
||||
namespace rotgen
|
||||
|
|
@ -27,6 +28,7 @@ namespace rotgen
|
|||
public:
|
||||
using parent = find_matrix<Scalar, Opts>;
|
||||
using rotgen_tag = void;
|
||||
using rotgen_matrix_tag = void;
|
||||
using concrete_type = matrix;
|
||||
using value_type = Scalar;
|
||||
|
||||
|
|
@ -48,29 +50,40 @@ namespace rotgen
|
|||
static constexpr bool has_static_storage = false;
|
||||
static constexpr bool is_immutable = false;
|
||||
static constexpr int InnerStrideAtCompileTime = 1;
|
||||
static constexpr int OuterStrideAtCompileTime =
|
||||
IsRowMajor ? ColsAtCompileTime : RowsAtCompileTime;
|
||||
static constexpr int OuterStrideAtCompileTime = IsRowMajor ? Cols : Rows;
|
||||
|
||||
using transposed_type = matrix<value_type, Cols, Rows, storage_order>;
|
||||
|
||||
matrix() : parent(Rows == -1 ? 0 : Rows, Cols == -1 ? 0 : Cols) {}
|
||||
static constexpr int AllocatedRows =
|
||||
Rows == -1 ? (MaxRows == -1 ? 0 : MaxRows) : Rows;
|
||||
static constexpr int AllocatedCols =
|
||||
Cols == -1 ? (MaxCols == -1 ? 0 : MaxCols) : Cols;
|
||||
|
||||
matrix() : parent(AllocatedRows, AllocatedCols) {}
|
||||
|
||||
matrix(Index r, Index c) : parent(r, c)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(r == Rows && "Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(r == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(c == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(c == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
}
|
||||
|
||||
matrix(Index n)
|
||||
requires(IsVectorAtCompileTime && (Rows != 1 || Cols != 1))
|
||||
: parent(Rows != -1 ? 1 : n, Cols != -1 ? 1 : n)
|
||||
: parent(Rows != 1 ? n : 1, Cols != 1 ? n : 1)
|
||||
{
|
||||
if constexpr (Rows == 1 && Cols != -1)
|
||||
ROTGEN_ASSERT(Cols == n,
|
||||
"Mismatched between dynamic and static col size");
|
||||
if constexpr (Cols == 1 && Rows != -1)
|
||||
ROTGEN_ASSERT(Rows == n,
|
||||
"Mismatched between dynamic and static row size");
|
||||
}
|
||||
|
||||
matrix(Scalar v)
|
||||
explicit matrix(Scalar v)
|
||||
requires(Rows == 1 && Cols == 1)
|
||||
: parent(1, 1, {v})
|
||||
{
|
||||
|
|
@ -89,14 +102,14 @@ namespace rotgen
|
|||
: parent(init)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(init.size() == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(init.size() == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
{
|
||||
[[maybe_unused]] Index c = 0;
|
||||
if (init.size()) c = init.begin()->size();
|
||||
assert(c == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(c == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -106,31 +119,28 @@ namespace rotgen
|
|||
{
|
||||
}
|
||||
|
||||
matrix(concepts::entity auto const& e) : parent(e.rows(), e.cols())
|
||||
template<concepts::entity Src> matrix(Src const& other) : parent()
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(e.rows() == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(e.cols() == Cols &&
|
||||
"Mismatched between dynamic and static col size");
|
||||
for (rotgen::Index r = 0; r < e.rows(); ++r)
|
||||
for (rotgen::Index c = 0; c < e.cols(); ++c) (*this)(r, c) = e(r, c);
|
||||
if constexpr (IsVectorAtCompileTime && Src::IsVectorAtCompileTime)
|
||||
{
|
||||
resize(other.size());
|
||||
for (rotgen::Index i = 0; i < parent::size(); ++i)
|
||||
(*this)[i] = other[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
resize(other.rows(), other.cols());
|
||||
|
||||
for (rotgen::Index r = 0; r < parent::rows(); ++r)
|
||||
for (rotgen::Index c = 0; c < parent::cols(); ++c)
|
||||
(*this)(r, c) = other(r, c);
|
||||
}
|
||||
}
|
||||
|
||||
matrix& operator=(concepts::entity auto const& e)
|
||||
matrix& operator=(concepts::entity auto const& other)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(e.rows() == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(e.cols() == Cols &&
|
||||
"Mismatched between dynamic and static col size");
|
||||
resize(e.rows(), e.cols());
|
||||
|
||||
for (rotgen::Index r = 0; r < e.rows(); ++r)
|
||||
for (rotgen::Index c = 0; c < e.cols(); ++c) (*this)(r, c) = e(r, c);
|
||||
|
||||
matrix local(other);
|
||||
swap(local);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -146,6 +156,13 @@ namespace rotgen
|
|||
return (*this)(i);
|
||||
}
|
||||
|
||||
void swap(matrix& other)
|
||||
{
|
||||
// TODO: Swap elements per elements if statically defined to preserve
|
||||
// data location in memory as with actual statically defines matrix
|
||||
base().swap(other.base());
|
||||
}
|
||||
|
||||
auto evaluate() const { return *this; }
|
||||
|
||||
decltype(auto) noalias() const { return *this; }
|
||||
|
|
@ -156,17 +173,22 @@ namespace rotgen
|
|||
|
||||
Index outerStride() const noexcept
|
||||
{
|
||||
return IsVectorAtCompileTime ? this->size()
|
||||
: IsRowMajor ? this->cols()
|
||||
: this->rows();
|
||||
if constexpr (IsVectorAtCompileTime) return this->size();
|
||||
else
|
||||
{
|
||||
if constexpr (IsRowMajor) return this->cols();
|
||||
else return this->rows();
|
||||
}
|
||||
}
|
||||
|
||||
void resize(int r, int c)
|
||||
{
|
||||
if constexpr (Rows == 1)
|
||||
assert(c == Cols && "Mismatched between dynamic and static col size");
|
||||
if constexpr (Cols == 1)
|
||||
assert(r == Rows && "Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
ROTGEN_ASSERT(c == Cols,
|
||||
"Mismatched between dynamic and static col size");
|
||||
if constexpr (Rows != -1)
|
||||
ROTGEN_ASSERT(r == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
parent::resize(r, c);
|
||||
}
|
||||
|
||||
|
|
@ -179,10 +201,12 @@ namespace rotgen
|
|||
|
||||
void conservativeResize(int r, int c)
|
||||
{
|
||||
if constexpr (Rows == 1)
|
||||
assert(c == Cols && "Mismatched between dynamic and static col size");
|
||||
if constexpr (Cols == 1)
|
||||
assert(r == Rows && "Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
ROTGEN_ASSERT(c == Cols,
|
||||
"Mismatched between dynamic and static col size");
|
||||
if constexpr (Rows != -1)
|
||||
ROTGEN_ASSERT(r == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
parent::conservativeResize(r, c);
|
||||
}
|
||||
|
||||
|
|
@ -231,26 +255,26 @@ namespace rotgen
|
|||
|
||||
friend bool operator==(matrix const& lhs, matrix const& rhs)
|
||||
{
|
||||
return static_cast<parent const&>(lhs) == static_cast<parent const&>(rhs);
|
||||
return lhs.base() == rhs.base();
|
||||
}
|
||||
|
||||
matrix& operator+=(matrix const& rhs)
|
||||
{
|
||||
base() += static_cast<parent const&>(rhs);
|
||||
base() += rhs.base();
|
||||
return *this;
|
||||
}
|
||||
|
||||
matrix& operator-=(matrix const& rhs)
|
||||
{
|
||||
base() -= static_cast<parent const&>(rhs);
|
||||
base() -= rhs.base();
|
||||
return *this;
|
||||
}
|
||||
|
||||
matrix operator-() const { return matrix(base().operator-()); }
|
||||
matrix operator-() const { return -base(); }
|
||||
|
||||
matrix& operator*=(matrix const& rhs)
|
||||
{
|
||||
base() *= static_cast<parent const&>(rhs);
|
||||
base() *= rhs.base();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -299,11 +323,11 @@ namespace rotgen
|
|||
static matrix Ones(int rows, int cols)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(rows == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(rows == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(cols == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(cols == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
return parent::Ones(rows, cols);
|
||||
}
|
||||
|
||||
|
|
@ -316,11 +340,11 @@ namespace rotgen
|
|||
static matrix Zero(int rows, int cols)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(rows == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(rows == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(cols == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(cols == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
return parent::Zero(rows, cols);
|
||||
}
|
||||
|
||||
|
|
@ -333,11 +357,11 @@ namespace rotgen
|
|||
static matrix Constant(int rows, int cols, Scalar value)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(rows == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(rows == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(cols == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(cols == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
return parent::Constant(rows, cols, static_cast<Scalar>(value));
|
||||
}
|
||||
|
||||
|
|
@ -350,11 +374,11 @@ namespace rotgen
|
|||
static matrix Random(int rows, int cols)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(rows == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(rows == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(cols == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(cols == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
return parent::Random(rows, cols);
|
||||
}
|
||||
|
||||
|
|
@ -367,11 +391,11 @@ namespace rotgen
|
|||
static matrix Identity(int rows, int cols)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(rows == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(rows == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(cols == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(cols == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
return parent::Identity(rows, cols);
|
||||
}
|
||||
|
||||
|
|
@ -446,51 +470,4 @@ namespace rotgen
|
|||
|
||||
parent const& base() const { return static_cast<parent const&>(*this); }
|
||||
};
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
matrix<S, R, C, O, MR, MC> operator+(matrix<S, R, C, O, MR, MC> const& lhs,
|
||||
matrix<S, R, C, O, MR, MC> const& rhs)
|
||||
{
|
||||
matrix<S, R, C, O, MR, MC> that(lhs);
|
||||
return that += rhs;
|
||||
}
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
matrix<S, R, C, O, MR, MC> operator-(matrix<S, R, C, O, MR, MC> const& lhs,
|
||||
matrix<S, R, C, O, MR, MC> const& rhs)
|
||||
{
|
||||
matrix<S, R, C, O, MR, MC> that(lhs);
|
||||
return that -= rhs;
|
||||
}
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
matrix<S, R, C, O, MR, MC> operator*(matrix<S, R, C, O, MR, MC> const& lhs,
|
||||
matrix<S, R, C, O, MR, MC> const& rhs)
|
||||
{
|
||||
matrix<S, R, C, O, MR, MC> that(lhs);
|
||||
return that *= rhs;
|
||||
}
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
matrix<S, R, C, O, MR, MC> operator*(matrix<S, R, C, O, MR, MC> const& lhs,
|
||||
double rhs)
|
||||
{
|
||||
matrix<S, R, C, O, MR, MC> that(lhs);
|
||||
return that *= rhs;
|
||||
}
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
matrix<S, R, C, O, MR, MC> operator*(double lhs,
|
||||
matrix<S, R, C, O, MR, MC> const& rhs)
|
||||
{
|
||||
return rhs * lhs;
|
||||
}
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
matrix<S, R, C, O, MR, MC> operator/(matrix<S, R, C, O, MR, MC> const& lhs,
|
||||
double rhs)
|
||||
{
|
||||
matrix<S, R, C, O, MR, MC> that(lhs);
|
||||
return that /= rhs;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,6 +99,8 @@ public:
|
|||
void setRandom(Index rows, Index cols);
|
||||
void setIdentity(Index rows, Index cols);
|
||||
|
||||
void swap(CLASSNAME& other) { storage_.swap(other.storage_); }
|
||||
|
||||
private:
|
||||
struct payload;
|
||||
std::unique_ptr<payload> storage_;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/detail/assert.hpp>
|
||||
#include <rotgen/detail/helpers.hpp>
|
||||
|
||||
#include <rotgen/concepts.hpp>
|
||||
|
|
@ -40,6 +41,7 @@ namespace rotgen
|
|||
{
|
||||
public:
|
||||
using rotgen_tag = void;
|
||||
using rotgen_matrix_tag = void;
|
||||
using parent =
|
||||
detail::storage_type<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>;
|
||||
using value_type = Scalar;
|
||||
|
|
@ -49,6 +51,9 @@ namespace rotgen
|
|||
using concrete_type = matrix;
|
||||
using concrete_dynamic_type = matrix<value_type>;
|
||||
|
||||
using exact_base =
|
||||
Eigen::Matrix<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>;
|
||||
|
||||
static constexpr int RowsAtCompileTime = Rows;
|
||||
static constexpr int ColsAtCompileTime = Cols;
|
||||
static constexpr int SizeAtCompileTime = detail::static_size<matrix>();
|
||||
|
|
@ -75,6 +80,11 @@ namespace rotgen
|
|||
static constexpr bool has_static_storage =
|
||||
storage_status<Rows, Cols, MaxRows, MaxCols>;
|
||||
|
||||
static constexpr int AllocatedRows =
|
||||
Rows == -1 ? (MaxRows == -1 ? 0 : MaxRows) : Rows;
|
||||
static constexpr int AllocatedCols =
|
||||
Cols == -1 ? (MaxCols == -1 ? 0 : MaxCols) : Cols;
|
||||
|
||||
public:
|
||||
matrix()
|
||||
requires(has_static_storage)
|
||||
|
|
@ -83,19 +93,19 @@ namespace rotgen
|
|||
|
||||
matrix()
|
||||
requires(!has_static_storage)
|
||||
: parent(Rows > 0 ? Rows : 0, Cols > 0 ? Cols : 0)
|
||||
: parent(AllocatedRows, AllocatedCols)
|
||||
{
|
||||
}
|
||||
|
||||
matrix(Index r, Index c) : parent(r, c)
|
||||
{
|
||||
if constexpr (RowsAtCompileTime != -1)
|
||||
assert(r == RowsAtCompileTime &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(r == RowsAtCompileTime,
|
||||
"Mismatched between dynamic and static row size");
|
||||
|
||||
if constexpr (ColsAtCompileTime != -1)
|
||||
assert(c == ColsAtCompileTime &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(c == ColsAtCompileTime,
|
||||
"Mismatched between dynamic and static column size");
|
||||
}
|
||||
|
||||
matrix(matrix const& other) = default;
|
||||
|
|
@ -181,11 +191,7 @@ namespace rotgen
|
|||
|
||||
parent const& base() const { return static_cast<parent const&>(*this); }
|
||||
|
||||
auto evaluate() const
|
||||
{
|
||||
auto res = base().eval();
|
||||
return as_concrete_type<decltype(res)>(res);
|
||||
}
|
||||
auto evaluate() const { return *this; }
|
||||
|
||||
decltype(auto) noalias() const
|
||||
{
|
||||
|
|
@ -273,38 +279,36 @@ namespace rotgen
|
|||
void resize(int s)
|
||||
requires(IsVectorAtCompileTime)
|
||||
{
|
||||
if constexpr (Rows == 1)
|
||||
assert(s == Cols && "Mismatched between dynamic and static col size");
|
||||
if constexpr (Cols == 1)
|
||||
assert(s == Rows && "Mismatched between dynamic and static row size");
|
||||
parent::resize(s);
|
||||
if constexpr (Rows == 1) parent::resize(1, s);
|
||||
else parent::resize(s, 1);
|
||||
}
|
||||
|
||||
void resize(int r, int c)
|
||||
{
|
||||
if constexpr (Rows == 1)
|
||||
assert(c == Cols && "Mismatched between dynamic and static col size");
|
||||
if constexpr (Cols == 1)
|
||||
assert(r == Rows && "Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
ROTGEN_ASSERT(c == Cols,
|
||||
"Mismatched between dynamic and static col size");
|
||||
if constexpr (Rows != -1)
|
||||
ROTGEN_ASSERT(r == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
parent::resize(r, c);
|
||||
}
|
||||
|
||||
void conservativeResize(int s)
|
||||
requires(IsVectorAtCompileTime)
|
||||
{
|
||||
if constexpr (Rows == 1)
|
||||
assert(s == Cols && "Mismatched between dynamic and static col size");
|
||||
if constexpr (Cols == 1)
|
||||
assert(s == Rows && "Mismatched between dynamic and static row size");
|
||||
parent::conservativeResize(s);
|
||||
if constexpr (Rows == 1) parent::conservativeResize(1, s);
|
||||
else parent::conservativeResize(s, 1);
|
||||
}
|
||||
|
||||
void conservativeResize(int r, int c)
|
||||
{
|
||||
if constexpr (Rows == 1)
|
||||
assert(c == Cols && "Mismatched between dynamic and static col size");
|
||||
if constexpr (Cols == 1)
|
||||
assert(r == Rows && "Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
ROTGEN_ASSERT(c == Cols,
|
||||
"Mismatched between dynamic and static col size");
|
||||
if constexpr (Rows != -1)
|
||||
ROTGEN_ASSERT(r == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
parent::conservativeResize(r, c);
|
||||
}
|
||||
|
||||
|
|
@ -317,11 +321,11 @@ namespace rotgen
|
|||
static matrix Constant(int rows, int cols, Scalar value)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(rows == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(rows == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(cols == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(cols == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
return parent::Constant(rows, cols, static_cast<Scalar>(value));
|
||||
}
|
||||
|
||||
|
|
@ -334,11 +338,11 @@ namespace rotgen
|
|||
static matrix Identity(int rows, int cols)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(rows == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(rows == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(cols == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(cols == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
return parent::Identity(rows, cols);
|
||||
}
|
||||
|
||||
|
|
@ -351,11 +355,11 @@ namespace rotgen
|
|||
static matrix Ones(int rows, int cols)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(rows == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(rows == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(cols == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(cols == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
return parent::Ones(rows, cols);
|
||||
}
|
||||
|
||||
|
|
@ -368,11 +372,11 @@ namespace rotgen
|
|||
static matrix Zero(int rows, int cols)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(rows == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(rows == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(cols == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(cols == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
return parent::Zero(rows, cols);
|
||||
}
|
||||
|
||||
|
|
@ -385,11 +389,11 @@ namespace rotgen
|
|||
static matrix Random(int rows, int cols)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(rows == Rows &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
ROTGEN_ASSERT(rows == Rows,
|
||||
"Mismatched between dynamic and static row size");
|
||||
if constexpr (Cols != -1)
|
||||
assert(cols == Cols &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
ROTGEN_ASSERT(cols == Cols,
|
||||
"Mismatched between dynamic and static column size");
|
||||
return parent::Random(rows, cols);
|
||||
}
|
||||
|
||||
|
|
@ -519,7 +523,7 @@ namespace rotgen
|
|||
return *this;
|
||||
}
|
||||
|
||||
matrix operator-() const { return matrix(base()(*this).operator-()); }
|
||||
matrix operator-() const { return -base(); }
|
||||
|
||||
matrix& operator*=(matrix const& rhs)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,12 +7,13 @@
|
|||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/detail/assert.hpp>
|
||||
|
||||
#include <rotgen/config.hpp>
|
||||
#include <rotgen/container/block.hpp>
|
||||
#include <rotgen/container/map.hpp>
|
||||
#include <rotgen/format.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <type_traits>
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@
|
|||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <rotgen/detail/assert.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(ROTGEN_FORCE_DYNAMIC)
|
||||
|
|
@ -15,6 +16,7 @@
|
|||
#endif
|
||||
|
||||
#include <rotgen/detail/accept_as_ref.hpp>
|
||||
#include <rotgen/detail/product.hpp>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
|
|
@ -149,6 +151,7 @@ namespace rotgen
|
|||
using parent::Zero;
|
||||
|
||||
using parent::operator=;
|
||||
using parent::operator-;
|
||||
|
||||
template<typename RO, int OO, typename SO>
|
||||
auto qr_solve(ref<RO, OO, SO> rhs) const
|
||||
|
|
@ -166,12 +169,18 @@ namespace rotgen
|
|||
|
||||
parent& as_map() { return base(); }
|
||||
|
||||
template<typename M>
|
||||
requires(is_immutable)
|
||||
ref(product<M> const& m) : ref(m.storage_)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
requires(detail::accept_as_ref<ref, matrix<S, R, C, O, MR, MC>>)
|
||||
ref(matrix<S, R, C, O, MR, MC>& m) : parent(detail::postpone{})
|
||||
{
|
||||
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, m);
|
||||
assert(correct_ref_setup);
|
||||
ROTGEN_ASSERT(correct_ref_setup, "Invalid reference binding");
|
||||
}
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
|
|
@ -202,7 +211,7 @@ namespace rotgen
|
|||
ref(block<Ref, R, C, I>&& b) : parent(detail::postpone{})
|
||||
{
|
||||
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
|
||||
assert(correct_ref_setup);
|
||||
ROTGEN_ASSERT(correct_ref_setup, "Invalid reference binding");
|
||||
}
|
||||
|
||||
template<typename Ref, int R, int C, bool I>
|
||||
|
|
@ -210,7 +219,7 @@ namespace rotgen
|
|||
ref(block<Ref, R, C, I>& b) : parent(detail::postpone{})
|
||||
{
|
||||
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
|
||||
assert(correct_ref_setup);
|
||||
ROTGEN_ASSERT(correct_ref_setup, "Invalid reference binding");
|
||||
}
|
||||
|
||||
template<typename Ref, int R, int C, bool I>
|
||||
|
|
@ -229,7 +238,7 @@ namespace rotgen
|
|||
ref(map<Ref, O, S>& b) : parent(detail::postpone{})
|
||||
{
|
||||
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
|
||||
assert(correct_ref_setup);
|
||||
ROTGEN_ASSERT(correct_ref_setup, "Invalid reference binding");
|
||||
}
|
||||
|
||||
template<typename Ref, int O, typename S>
|
||||
|
|
@ -259,15 +268,15 @@ namespace rotgen
|
|||
ref(ref<TT, OO, SS>& b) : parent(detail::postpone{})
|
||||
{
|
||||
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
|
||||
assert(correct_ref_setup);
|
||||
ROTGEN_ASSERT(correct_ref_setup, "Invalid reference binding");
|
||||
}
|
||||
|
||||
template<typename TT, int OO, typename SS>
|
||||
requires(detail::same_scalar<ref, ref<TT, OO, SS>>)
|
||||
requires(detail::accept_as_ref<ref, ref<TT, OO, SS>>)
|
||||
ref(ref<TT, OO, SS> const& b) : parent(detail::postpone{})
|
||||
{
|
||||
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
|
||||
assert(correct_ref_setup);
|
||||
ROTGEN_ASSERT(correct_ref_setup, "Invalid reference binding");
|
||||
}
|
||||
|
||||
ref(parent& m) : parent(m.data(), m.rows(), m.cols()) {}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <rotgen/detail/helpers.hpp>
|
||||
#include <rotgen/detail/product.hpp>
|
||||
|
||||
#include <Eigen/Dense>
|
||||
#include <type_traits>
|
||||
|
|
@ -52,6 +53,9 @@ namespace rotgen
|
|||
|
||||
template<typename T, int Options, typename Stride>
|
||||
using compile_ref_t = typename compile_ref<T, Options, Stride>::type;
|
||||
|
||||
template<typename T, int Options, typename Stride>
|
||||
using compile_base_t = typename compile_ref<T, Options, Stride>::base;
|
||||
}
|
||||
|
||||
template<typename T, int Options, typename Stride>
|
||||
|
|
@ -59,6 +63,7 @@ namespace rotgen
|
|||
{
|
||||
public:
|
||||
using parent = detail::compile_ref_t<T, Options, Stride>;
|
||||
using exact_base = detail::compile_base_t<T, Options, Stride>;
|
||||
using referee = std::remove_const_t<T>;
|
||||
using value_type = typename referee::value_type;
|
||||
using rotgen_tag = void;
|
||||
|
|
@ -91,17 +96,7 @@ namespace rotgen
|
|||
using parent::size;
|
||||
|
||||
// Aliasing handling
|
||||
auto evaluate() const
|
||||
{
|
||||
auto res = static_cast<parent const&>(*this).eval();
|
||||
return as_concrete_type<decltype(res)>(res);
|
||||
}
|
||||
|
||||
auto evaluate()
|
||||
{
|
||||
auto res = static_cast<parent&>(*this).eval();
|
||||
return as_concrete_type<decltype(res)>(res);
|
||||
}
|
||||
auto evaluate() const { return T(base().eval()); }
|
||||
|
||||
decltype(auto) noalias() const
|
||||
{
|
||||
|
|
@ -116,10 +111,27 @@ namespace rotgen
|
|||
}
|
||||
|
||||
// Numeric functions
|
||||
using parent::cwiseAbs;
|
||||
using parent::cwiseAbs2;
|
||||
using parent::cwiseInverse;
|
||||
using parent::cwiseSqrt;
|
||||
auto operator-() const { return detail::concretize<matrix>(-base()); }
|
||||
|
||||
auto cwiseAbs() const
|
||||
{
|
||||
return detail::concretize<matrix>(base().cwiseAbs());
|
||||
}
|
||||
|
||||
auto cwiseAbs2() const
|
||||
{
|
||||
return detail::concretize<matrix>(base().cwiseAbs2());
|
||||
}
|
||||
|
||||
auto cwiseInverse() const
|
||||
{
|
||||
return detail::concretize<matrix>(base().cwiseInverse());
|
||||
}
|
||||
|
||||
auto cwiseSqrt() const
|
||||
{
|
||||
return detail::concretize<matrix>(base().cwiseSqrt());
|
||||
}
|
||||
|
||||
// Reductions
|
||||
using parent::lpNorm;
|
||||
|
|
@ -172,10 +184,26 @@ namespace rotgen
|
|||
}
|
||||
|
||||
// Shape modifications
|
||||
using parent::adjoint;
|
||||
using parent::conjugate;
|
||||
using parent::normalized;
|
||||
using parent::transpose;
|
||||
auto normalized() const
|
||||
requires(IsVectorAtCompileTime)
|
||||
{
|
||||
return detail::concretize<matrix>(base().normalized());
|
||||
}
|
||||
|
||||
auto transpose() const
|
||||
{
|
||||
return detail::concretize<matrix>(base().transpose());
|
||||
}
|
||||
|
||||
auto adjoint() const
|
||||
{
|
||||
return detail::concretize<matrix>(base().adjoint());
|
||||
}
|
||||
|
||||
auto conjugate() const
|
||||
{
|
||||
return detail::concretize<matrix>(base().conjugate());
|
||||
}
|
||||
|
||||
// In-place Shape modifications
|
||||
using parent::adjointInPlace;
|
||||
|
|
@ -183,16 +211,79 @@ namespace rotgen
|
|||
using parent::transposeInPlace;
|
||||
|
||||
// Generators
|
||||
using parent::Constant;
|
||||
using parent::Identity;
|
||||
using parent::Ones;
|
||||
using parent::Random;
|
||||
using parent::setConstant;
|
||||
using parent::setIdentity;
|
||||
using parent::setOnes;
|
||||
using parent::setRandom;
|
||||
using parent::setZero;
|
||||
using parent::Zero;
|
||||
static auto Zero() { return detail::concretize<matrix>(parent::Zero()); }
|
||||
|
||||
static auto Zero(int rows, int cols)
|
||||
{
|
||||
return detail::concretize<matrix>(parent::Zero(rows, cols));
|
||||
}
|
||||
|
||||
static auto Ones() { return detail::concretize<matrix>(parent::Ones()); }
|
||||
|
||||
static auto Ones(int rows, int cols)
|
||||
{
|
||||
return detail::concretize<matrix>(parent::Ones(rows, cols));
|
||||
}
|
||||
|
||||
static auto Constant(value_type value)
|
||||
{
|
||||
return detail::concretize<matrix>(parent::Constant(value));
|
||||
}
|
||||
|
||||
static auto Constant(int rows, int cols, value_type value)
|
||||
{
|
||||
return detail::concretize<matrix>(parent::Constant(rows, cols, value));
|
||||
}
|
||||
|
||||
static auto Random()
|
||||
{
|
||||
return detail::concretize<matrix>(parent::Random());
|
||||
}
|
||||
|
||||
static auto Random(int rows, int cols)
|
||||
{
|
||||
return detail::concretize<matrix>(parent::Random(rows, cols));
|
||||
}
|
||||
|
||||
static auto Identity()
|
||||
{
|
||||
return detail::concretize<matrix>(parent::Identity());
|
||||
}
|
||||
|
||||
static auto Identity(int rows, int cols)
|
||||
{
|
||||
return detail::concretize<matrix>(parent::Identity(rows, cols));
|
||||
}
|
||||
|
||||
ref& setOnes()
|
||||
{
|
||||
base() = parent::Ones(base().rows(), base().cols());
|
||||
return *this;
|
||||
}
|
||||
|
||||
ref& setZero()
|
||||
{
|
||||
base() = parent::Zero(base().rows(), base().cols());
|
||||
return *this;
|
||||
}
|
||||
|
||||
ref& setConstant(value_type value)
|
||||
{
|
||||
base() = parent::Constant(base().rows(), base().cols(), value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ref& setRandom()
|
||||
{
|
||||
base() = parent::Random(base().rows(), base().cols());
|
||||
return *this;
|
||||
}
|
||||
|
||||
ref& setIdentity()
|
||||
{
|
||||
base() = parent::Identity(base().rows(), base().cols());
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto qr_solve(auto const& rhs) const
|
||||
{
|
||||
|
|
@ -212,6 +303,12 @@ namespace rotgen
|
|||
|
||||
parent& base() { return static_cast<parent&>(*this); }
|
||||
|
||||
template<typename M>
|
||||
requires(is_immutable)
|
||||
ref(product<M> const& m) : ref(m.storage_)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
ref(matrix<S, R, C, O, MR, MC>& m)
|
||||
requires(requires { parent(m.base()); })
|
||||
|
|
@ -307,13 +404,14 @@ namespace rotgen
|
|||
// Deduction Guides
|
||||
//============================================================================
|
||||
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, R, C, O, MR, MC>>;
|
||||
|
||||
template<typename Ref, int R, int C, bool I>
|
||||
ref(block<Ref, R, C, I>& b) -> ref<Ref>;
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
ref(matrix<S, R, C, O, MR, MC> const&) -> ref<matrix<S> const>;
|
||||
ref(matrix<S, R, C, O, MR, MC> const&)
|
||||
-> ref<matrix<S, R, C, O, MR, MC> const>;
|
||||
|
||||
template<typename Ref, int R, int C, bool I>
|
||||
ref(block<Ref, R, C, I> const& b) -> ref<Ref const>;
|
||||
|
|
@ -336,7 +434,14 @@ namespace rotgen
|
|||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto operator*(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
return detail::concretize<matrix>(lhs.base() * rhs.base());
|
||||
auto p = lhs.base() * rhs.base();
|
||||
using concrete_type = detail::as_concrete_t<decltype(p), matrix>;
|
||||
|
||||
if constexpr (concrete_type::SizeAtCompileTime == 1)
|
||||
return product{concrete_type{p}};
|
||||
else if constexpr (concrete_type::SizeAtCompileTime == 0)
|
||||
return concrete_type{};
|
||||
else return concrete_type{p};
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
|
|
@ -411,7 +516,6 @@ namespace rotgen
|
|||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto cross(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
-> decltype(lhs.base().cross(rhs.base()))
|
||||
{
|
||||
return detail::concretize<matrix>(lhs.base().cross(rhs.base()));
|
||||
}
|
||||
|
|
@ -432,13 +536,8 @@ namespace rotgen
|
|||
using type = std::conditional_t<is_const, ref<base const>, ref<base>>;
|
||||
};
|
||||
|
||||
template<concepts::eigen_compatible T> auto const& base_of(T const& a)
|
||||
template<concepts::eigen_compatible T> decltype(auto) base_of(T&& a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
template<concepts::eigen_compatible T> auto& base_of(T& a)
|
||||
{
|
||||
return a;
|
||||
return ROTGEN_FWD(a);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,46 +12,49 @@
|
|||
namespace rotgen
|
||||
{
|
||||
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> const& lhs, ref<B, P, T> const& rhs)
|
||||
{
|
||||
return lhs.base() == rhs.base();
|
||||
}
|
||||
|
||||
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> const& lhs, ref<B, P, T> const& rhs)
|
||||
{
|
||||
return lhs.base() != rhs.base();
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto operator*(std::convertible_to<typename A::value_type> auto s,
|
||||
ref<A, O, S> rhs)
|
||||
ref<A, O, S> const& rhs)
|
||||
{
|
||||
// void* _ = rhs;
|
||||
return rhs * s;
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto dot(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
auto dot(ref<A, O, S> const& lhs, ref<B, P, T> const& rhs)
|
||||
{
|
||||
return lhs.base().dot(rhs.base());
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto mul(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
|
||||
auto mul(ref<A, O, S> const& lhs,
|
||||
std::convertible_to<typename A::value_type> auto s)
|
||||
-> decltype(lhs * s)
|
||||
{
|
||||
return lhs * s;
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto mul(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs)
|
||||
-> decltype(s * rhs)
|
||||
auto mul(std::convertible_to<typename A::value_type> auto s,
|
||||
ref<A, O, S> const& rhs) -> decltype(s * rhs)
|
||||
{
|
||||
return s * rhs;
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto div(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
|
||||
auto div(ref<A, O, S> const& lhs,
|
||||
std::convertible_to<typename A::value_type> auto s)
|
||||
-> decltype(lhs / s)
|
||||
{
|
||||
return lhs / s;
|
||||
|
|
|
|||
|
|
@ -32,11 +32,12 @@ namespace rotgen
|
|||
|
||||
template<concepts::entity T> struct generalize<T>
|
||||
{
|
||||
static constexpr bool is_const = std::is_const_v<T>;
|
||||
using base = matrix<typename T::value_type,
|
||||
T::RowsAtCompileTime,
|
||||
T::ColsAtCompileTime,
|
||||
T::storage_order>;
|
||||
static constexpr bool is_const =
|
||||
std::is_const_v<std::remove_reference_t<T>>;
|
||||
using base = matrix<typename std::remove_cvref_t<T>::value_type,
|
||||
std::remove_cvref_t<T>::RowsAtCompileTime,
|
||||
std::remove_cvref_t<T>::ColsAtCompileTime,
|
||||
std::remove_cvref_t<T>::storage_order>;
|
||||
using type = std::conditional_t<is_const, ref<base const>, ref<base>>;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@
|
|||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <rotgen/detail/assert.hpp>
|
||||
|
||||
#include <concepts>
|
||||
|
||||
namespace rotgen::detail
|
||||
|
|
@ -77,22 +78,26 @@ namespace rotgen::detail
|
|||
|
||||
if (Ref::RowsAtCompileTime == 1)
|
||||
{
|
||||
assert(in.rows() == 1 || in.cols() == 1);
|
||||
ROTGEN_ASSERT(in.rows() == 1 || in.cols() == 1,
|
||||
"Incompatible rows/cols in ref binding");
|
||||
rows = 1;
|
||||
cols = in.size();
|
||||
}
|
||||
else if (Ref::ColsAtCompileTime == 1)
|
||||
{
|
||||
assert(in.rows() == 1 || in.cols() == 1);
|
||||
ROTGEN_ASSERT(in.rows() == 1 || in.cols() == 1,
|
||||
"Incompatible rows/cols in ref binding");
|
||||
rows = in.size();
|
||||
cols = 1;
|
||||
}
|
||||
|
||||
// Verify that the sizes are valid.
|
||||
assert((Ref::RowsAtCompileTime == Dynamic) ||
|
||||
(Ref::RowsAtCompileTime == rows));
|
||||
assert((Ref::ColsAtCompileTime == Dynamic) ||
|
||||
(Ref::ColsAtCompileTime == cols));
|
||||
ROTGEN_ASSERT((Ref::RowsAtCompileTime == Dynamic) ||
|
||||
(Ref::RowsAtCompileTime == rows),
|
||||
"Incompatible static rows/cols in ref binding");
|
||||
ROTGEN_ASSERT((Ref::ColsAtCompileTime == Dynamic) ||
|
||||
(Ref::ColsAtCompileTime == cols),
|
||||
"Incompatible static rows/cols in ref binding");
|
||||
|
||||
// Swap stride if we are a vector and we changed rows as such
|
||||
bool transpose = Ref::IsVectorAtCompileTime && (rows != in.rows());
|
||||
|
|
|
|||
22
include/rotgen/detail/assert.hpp
Normal file
22
include/rotgen/detail/assert.hpp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#if defined(ROTGEN_USE_LIBASSERT)
|
||||
#include <libassert/assert.hpp>
|
||||
#define ROTGEN_ASSERT(COND, ...) DEBUG_ASSERT(COND, __VA_ARGS__)
|
||||
|
||||
#else
|
||||
#include <cassert>
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#define ROTGEN_ASSERT(COND, MSG, ...) assert((COND) && (MSG))
|
||||
#else
|
||||
#define ROTGEN_ASSERT(COND, ...) (void)(COND)
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -31,7 +31,7 @@ namespace rotgen::detail
|
|||
using type = Wrapper<typename EigenType::value_type,
|
||||
EigenType::RowsAtCompileTime,
|
||||
EigenType::ColsAtCompileTime,
|
||||
EigenType::Flags & 1,
|
||||
EigenType::IsRowMajor ? RowMajor : ColMajor,
|
||||
EigenType::MaxRowsAtCompileTime,
|
||||
EigenType::MaxColsAtCompileTime>;
|
||||
};
|
||||
|
|
|
|||
57
include/rotgen/detail/product.hpp
Normal file
57
include/rotgen/detail/product.hpp
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/detail/helpers.hpp>
|
||||
|
||||
#include <rotgen/container/matrix.hpp>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
// Emulate EIGEN 1x1 pseudo product type
|
||||
template<typename M> struct product
|
||||
{
|
||||
using rotgen_tag = void;
|
||||
|
||||
using value_type = typename M::value_type;
|
||||
using concrete_type = matrix<value_type, 1, 1>;
|
||||
|
||||
static constexpr auto storage_order = concrete_type::storage_order;
|
||||
static constexpr int RowsAtCompileTime = 1;
|
||||
static constexpr int ColsAtCompileTime = 1;
|
||||
static constexpr int SizeAtCompileTime = 1;
|
||||
static constexpr int MaxRowsAtCompileTime = 1;
|
||||
static constexpr int MaxColsAtCompileTime = 1;
|
||||
static constexpr bool IsVectorAtCompileTime =
|
||||
concrete_type::IsVectorAtCompileTime;
|
||||
|
||||
product(M const& m) : storage_(m) {}
|
||||
|
||||
auto size() const { return storage_.size(); }
|
||||
|
||||
auto rows() const { return storage_.rows(); }
|
||||
|
||||
auto cols() const { return storage_.cols(); }
|
||||
|
||||
auto operator()(int i) const { return storage_(i); }
|
||||
|
||||
auto operator[](int i) const { return storage_(i); }
|
||||
|
||||
auto operator()(int r, int c) const { return storage_(r, c); }
|
||||
|
||||
auto sum() const { return storage_.sum(); }
|
||||
|
||||
auto const& base() const { return storage_.base(); }
|
||||
|
||||
operator value_type const() const { return storage_(0); }
|
||||
|
||||
operator concrete_type() const { return storage_; }
|
||||
|
||||
concrete_type storage_;
|
||||
};
|
||||
}
|
||||
|
|
@ -21,10 +21,12 @@ namespace rotgen
|
|||
[[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.");
|
||||
ROTGEN_ASSERT(i0 >= 0, "block extraction uses negative row index.");
|
||||
ROTGEN_ASSERT(j0 >= 0, "block extraction uses negative col index.");
|
||||
ROTGEN_ASSERT(i0 + ni <= e.rows(),
|
||||
"block extraction rows is out of range.");
|
||||
ROTGEN_ASSERT(j0 + nj <= e.cols(),
|
||||
"block extraction cols is out of range.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,10 +7,24 @@
|
|||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/detail/assert.hpp>
|
||||
#include <rotgen/detail/helpers.hpp>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
template<typename T, typename... Args> void initialize_with(T&& m, Args... v)
|
||||
{
|
||||
using type = typename std::remove_cvref_t<T>::value_type;
|
||||
using map_t = rotgen::map<rotgen::matrix<type, -1, -1, rotgen::RowMajor>>;
|
||||
|
||||
ROTGEN_ASSERT(sizeof...(v) == m.size(),
|
||||
"Incorrect quantity of coefficients for initialization");
|
||||
type data[] = {static_cast<type>(v)...};
|
||||
m = map_t(data, m.rows(), m.cols());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
// Generators
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -7,9 +7,10 @@
|
|||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/detail/product.hpp>
|
||||
|
||||
#include <rotgen/concepts.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <iosfwd>
|
||||
|
||||
namespace rotgen
|
||||
|
|
@ -80,30 +81,27 @@ namespace rotgen
|
|||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
// Compounds operators across types
|
||||
template<typename A, typename B>
|
||||
auto operator+=(A& a, B const& b)
|
||||
requires(concepts::entity<A> && concepts::entity<B>)
|
||||
template<concepts::entity A, concepts::entity B>
|
||||
decltype(auto) operator+=(A&& a, B const& b)
|
||||
requires(!concepts::block<A>)
|
||||
{
|
||||
if constexpr (!use_expression_templates)
|
||||
return generalize_t<A>(a) += generalize_t<B const>(b);
|
||||
else return base_of(a) += base_of(b);
|
||||
generalize_t<A>(ROTGEN_FWD(a)) += generalize_t<B const>(b);
|
||||
return ROTGEN_FWD(a);
|
||||
}
|
||||
|
||||
template<typename A, typename B>
|
||||
auto operator-=(A& a, B const& b)
|
||||
requires(concepts::entity<A> && concepts::entity<B>)
|
||||
template<concepts::entity A, concepts::entity B>
|
||||
decltype(auto) operator-=(A&& a, B const& b)
|
||||
requires(!concepts::block<A>)
|
||||
{
|
||||
if constexpr (!use_expression_templates)
|
||||
return generalize_t<A>(a) -= generalize_t<B const>(b);
|
||||
else return base_of(a) -= base_of(b);
|
||||
generalize_t<A>(ROTGEN_FWD(a)) -= generalize_t<B const>(b);
|
||||
return ROTGEN_FWD(a);
|
||||
}
|
||||
|
||||
template<typename A, typename B>
|
||||
auto operator*=(A& a, B const& b)
|
||||
requires(concepts::entity<A> && concepts::entity<B>)
|
||||
template<concepts::entity A, concepts::entity B>
|
||||
decltype(auto) operator*=(A&& a, B const& b)
|
||||
requires(!concepts::block<A>)
|
||||
{
|
||||
if constexpr (!use_expression_templates)
|
||||
return generalize_t<A>(a) *= generalize_t<B const>(b);
|
||||
else return base_of(a) *= base_of(b);
|
||||
generalize_t<A>(ROTGEN_FWD(a)) *= generalize_t<B const>(b);
|
||||
return ROTGEN_FWD(a);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,30 +10,38 @@
|
|||
#define STORAGE_ORDER Eigen::ColMajor
|
||||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _col)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
||||
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
||||
#include "model.cpp"
|
||||
#undef CLASSNAME
|
||||
#undef CLASSCONSTNAME
|
||||
#undef TRANSNAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef SOURCENAME
|
||||
#undef MAPNAME
|
||||
#undef TRANSMAPNAME
|
||||
#undef STORAGE_ORDER
|
||||
|
||||
#define STORAGE_ORDER Eigen::RowMajor
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _row)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
||||
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
||||
#include "model.cpp"
|
||||
#undef CLASSNAME
|
||||
#undef CLASSCONSTNAME
|
||||
#undef TRANSNAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef SOURCENAME
|
||||
#undef MAPNAME
|
||||
#undef TRANSMAPNAME
|
||||
#undef STORAGE_ORDER
|
||||
|
||||
#undef SIZE
|
||||
|
|
@ -44,30 +52,38 @@
|
|||
#define STORAGE_ORDER Eigen::ColMajor
|
||||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _col)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
||||
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
||||
#include "model.cpp"
|
||||
#undef CLASSNAME
|
||||
#undef CLASSCONSTNAME
|
||||
#undef TRANSNAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef SOURCENAME
|
||||
#undef MAPNAME
|
||||
#undef TRANSMAPNAME
|
||||
#undef STORAGE_ORDER
|
||||
|
||||
#define STORAGE_ORDER Eigen::RowMajor
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _row)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
||||
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
||||
#include "model.cpp"
|
||||
#undef CLASSNAME
|
||||
#undef CLASSCONSTNAME
|
||||
#undef TRANSNAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef SOURCENAME
|
||||
#undef MAPNAME
|
||||
#undef TRANSMAPNAME
|
||||
#undef STORAGE_ORDER
|
||||
|
||||
#undef SIZE
|
||||
|
|
|
|||
|
|
@ -33,6 +33,12 @@ CLASSNAME::CLASSNAME(MAPNAME CONST& r, Index i0, Index j0, Index ni, Index nj)
|
|||
{
|
||||
}
|
||||
|
||||
CLASSNAME::CLASSNAME(
|
||||
TRANSMAPNAME CONST& r, Index i0, Index j0, Index ni, Index nj)
|
||||
: storage_(std::make_unique<payload>(r, i0, j0, ni, nj, map_t{}, trans_t{}))
|
||||
{
|
||||
}
|
||||
|
||||
// We're building a block from a block - So we have to dig around the internals
|
||||
CLASSNAME::CLASSNAME(
|
||||
TRANSCLASSNAME CONST& p, Index i0, Index j0, Index ni, Index nj)
|
||||
|
|
@ -197,17 +203,17 @@ TYPE CLASSNAME::operator()(Index i, Index j) const
|
|||
#if !defined(USE_CONST)
|
||||
TYPE& CLASSNAME::operator()(Index index)
|
||||
{
|
||||
TYPE* ptr = nullptr;
|
||||
storage_->apply([&](auto& blk) { ptr = blk.data() + index; });
|
||||
return *ptr;
|
||||
auto r = rows() == 1 ? 0 : index;
|
||||
auto c = cols() == 1 ? 0 : index;
|
||||
return (*this)(r, c);
|
||||
}
|
||||
#endif
|
||||
|
||||
TYPE CLASSNAME::operator()(Index index) const
|
||||
{
|
||||
TYPE ptr;
|
||||
storage_->apply([&](auto const& blk) { ptr = *(blk.data() + index); });
|
||||
return ptr;
|
||||
auto r = rows() == 1 ? 0 : index;
|
||||
auto c = cols() == 1 ? 0 : index;
|
||||
return (*this)(r, c);
|
||||
}
|
||||
|
||||
// Raw pointer access
|
||||
|
|
@ -448,6 +454,28 @@ CLASSNAME& CLASSNAME::operator+=(CLASSNAME const& rhs)
|
|||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator+=(CLASSCONSTNAME const& rhs)
|
||||
{
|
||||
std::visit(
|
||||
[](auto& lhs_blk, auto const& rhs_blk) { lhs_blk.first += rhs_blk.first; },
|
||||
storage_->data, rhs.storage()->data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator+=(SOURCENAME const& rhs)
|
||||
{
|
||||
std::visit([&](auto& lhs_blk) { lhs_blk.first += rhs.storage()->data; },
|
||||
storage_->data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator+=(TRANSNAME const& rhs)
|
||||
{
|
||||
std::visit([&](auto& lhs_blk) { lhs_blk.first += rhs.storage()->data; },
|
||||
storage_->data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator-=(CLASSNAME const& rhs)
|
||||
{
|
||||
std::visit(
|
||||
|
|
@ -456,6 +484,28 @@ CLASSNAME& CLASSNAME::operator-=(CLASSNAME const& rhs)
|
|||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator-=(CLASSCONSTNAME const& rhs)
|
||||
{
|
||||
std::visit(
|
||||
[](auto& lhs_blk, auto const& rhs_blk) { lhs_blk.first -= rhs_blk.first; },
|
||||
storage_->data, rhs.storage()->data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator-=(SOURCENAME const& rhs)
|
||||
{
|
||||
std::visit([&](auto& lhs_blk) { lhs_blk.first -= rhs.storage()->data; },
|
||||
storage_->data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator-=(TRANSNAME const& rhs)
|
||||
{
|
||||
std::visit([&](auto& lhs_blk) { lhs_blk.first -= rhs.storage()->data; },
|
||||
storage_->data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator*=(CLASSNAME const& rhs)
|
||||
{
|
||||
std::visit(
|
||||
|
|
@ -464,6 +514,28 @@ CLASSNAME& CLASSNAME::operator*=(CLASSNAME const& rhs)
|
|||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator*=(CLASSCONSTNAME const& rhs)
|
||||
{
|
||||
std::visit(
|
||||
[](auto& lhs_blk, auto const& rhs_blk) { lhs_blk.first *= rhs_blk.first; },
|
||||
storage_->data, rhs.storage()->data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator*=(SOURCENAME const& rhs)
|
||||
{
|
||||
std::visit([&](auto& lhs_blk) { lhs_blk.first *= rhs.storage()->data; },
|
||||
storage_->data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator*=(TRANSNAME const& rhs)
|
||||
{
|
||||
std::visit([&](auto& lhs_blk) { lhs_blk.first *= rhs.storage()->data; },
|
||||
storage_->data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator*=(TYPE s)
|
||||
{
|
||||
storage_->apply([&](auto& blk) { blk *= s; });
|
||||
|
|
|
|||
|
|
@ -11,29 +11,41 @@
|
|||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
|
||||
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
|
||||
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
|
||||
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#include "model.cpp"
|
||||
#undef CLASSNAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef TRANSCLASSCONSTNAME
|
||||
#undef TRANSCLASSNONCONSTNAME
|
||||
#undef TRANSSOURCENAME
|
||||
#undef CLASSCONSTNAME
|
||||
#undef CLASSNONCONSTNAME
|
||||
#undef SOURCENAME
|
||||
#undef STORAGE_ORDER
|
||||
|
||||
#define STORAGE_ORDER Eigen::RowMajor
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
|
||||
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
|
||||
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
|
||||
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#include "model.cpp"
|
||||
#undef CLASSNAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef TRANSCLASSCONSTNAME
|
||||
#undef TRANSCLASSNONCONSTNAME
|
||||
#undef TRANSSOURCENAME
|
||||
#undef SOURCENAME
|
||||
#undef CLASSCONSTNAME
|
||||
#undef CLASSNONCONSTNAME
|
||||
#undef STORAGE_ORDER
|
||||
|
||||
#undef SIZE
|
||||
|
|
@ -45,28 +57,40 @@
|
|||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
|
||||
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
|
||||
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
|
||||
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#include "model.cpp"
|
||||
#undef CLASSNAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef TRANSCLASSCONSTNAME
|
||||
#undef TRANSCLASSNONCONSTNAME
|
||||
#undef TRANSSOURCENAME
|
||||
#undef CLASSCONSTNAME
|
||||
#undef CLASSNONCONSTNAME
|
||||
#undef SOURCENAME
|
||||
#undef STORAGE_ORDER
|
||||
|
||||
#define STORAGE_ORDER Eigen::RowMajor
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
|
||||
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
|
||||
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
|
||||
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#include "model.cpp"
|
||||
#undef CLASSNAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef TRANSCLASSCONSTNAME
|
||||
#undef TRANSCLASSNONCONSTNAME
|
||||
#undef TRANSSOURCENAME
|
||||
#undef CLASSCONSTNAME
|
||||
#undef CLASSNONCONSTNAME
|
||||
#undef SOURCENAME
|
||||
#undef STORAGE_ORDER
|
||||
|
||||
|
|
|
|||
|
|
@ -239,12 +239,22 @@ void CLASSNAME::adjointInPlace()
|
|||
}
|
||||
#endif
|
||||
|
||||
TYPE CLASSNAME::dot(CLASSNAME const& rhs) const
|
||||
TYPE CLASSNAME::dot(CLASSNONCONSTNAME const& rhs) const
|
||||
{
|
||||
return storage_->data.reshaped().dot(rhs.storage()->data.reshaped());
|
||||
}
|
||||
|
||||
TYPE CLASSNAME::dot(TRANSCLASSNAME const& rhs) const
|
||||
TYPE CLASSNAME::dot(CLASSCONSTNAME const& rhs) const
|
||||
{
|
||||
return storage_->data.reshaped().dot(rhs.storage()->data.reshaped());
|
||||
}
|
||||
|
||||
TYPE CLASSNAME::dot(TRANSCLASSNONCONSTNAME const& rhs) const
|
||||
{
|
||||
return storage_->data.reshaped().dot(rhs.storage()->data.reshaped());
|
||||
}
|
||||
|
||||
TYPE CLASSNAME::dot(TRANSCLASSCONSTNAME const& rhs) const
|
||||
{
|
||||
return storage_->data.reshaped().dot(rhs.storage()->data.reshaped());
|
||||
}
|
||||
|
|
@ -378,7 +388,7 @@ SOURCENAME CLASSNAME::operator-() const
|
|||
#if !defined(USE_CONST)
|
||||
CLASSNAME& CLASSNAME::operator+=(CLASSNAME const& rhs)
|
||||
{
|
||||
storage_->data += rhs.storage_->data;
|
||||
storage_->data += rhs.storage()->data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -388,9 +398,21 @@ CLASSNAME& CLASSNAME::operator+=(CLASSCONSTNAME const& rhs)
|
|||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator+=(TRANSCLASSNONCONSTNAME const& rhs)
|
||||
{
|
||||
storage_->data.reshaped() += rhs.storage()->data.reshaped();
|
||||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator+=(TRANSCLASSCONSTNAME const& rhs)
|
||||
{
|
||||
storage_->data.reshaped() += rhs.storage()->data.reshaped();
|
||||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator-=(CLASSNAME const& rhs)
|
||||
{
|
||||
storage_->data -= rhs.storage_->data;
|
||||
storage_->data -= rhs.storage()->data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -400,9 +422,21 @@ CLASSNAME& CLASSNAME::operator-=(CLASSCONSTNAME const& rhs)
|
|||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator-=(TRANSCLASSNONCONSTNAME const& rhs)
|
||||
{
|
||||
storage_->data.reshaped() -= rhs.storage()->data.reshaped();
|
||||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator-=(TRANSCLASSCONSTNAME const& rhs)
|
||||
{
|
||||
storage_->data.reshaped() -= rhs.storage()->data.reshaped();
|
||||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator*=(CLASSNAME const& rhs)
|
||||
{
|
||||
storage_->data *= rhs.storage_->data;
|
||||
storage_->data *= rhs.storage()->data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -412,6 +446,18 @@ CLASSNAME& CLASSNAME::operator*=(CLASSCONSTNAME const& rhs)
|
|||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator*=(TRANSCLASSNONCONSTNAME const& rhs)
|
||||
{
|
||||
storage_->data *= rhs.storage()->data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator*=(TRANSCLASSCONSTNAME const& rhs)
|
||||
{
|
||||
storage_->data *= rhs.storage()->data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator*=(TYPE s)
|
||||
{
|
||||
storage_->data *= s;
|
||||
|
|
|
|||
|
|
@ -77,3 +77,39 @@ TTS_CASE("Extraction of ref/ref const")
|
|||
for (rotgen::Index r = 0; r < 4; r++)
|
||||
for (rotgen::Index c = 0; c < 3; c++) TTS_EQUAL(sliced(r, c), 5.f);
|
||||
};
|
||||
|
||||
void process_col(rotgen::matrix<float, 3, 4>& m,
|
||||
rotgen::matrix<float, 3, 1> const& n,
|
||||
int c)
|
||||
{
|
||||
col(m, c) += n;
|
||||
}
|
||||
|
||||
TTS_CASE("Compound operators on extractions")
|
||||
{
|
||||
rotgen::matrix<float, 3, 4> m;
|
||||
rotgen::matrix<float, 3, 4> reference;
|
||||
rotgen::matrix<float, 3, 1> n;
|
||||
setZero(m);
|
||||
setConstant(n, 10);
|
||||
setConstant(reference, 10);
|
||||
|
||||
for (int i = 0; i < m.cols(); i++) process_col(m, n, i);
|
||||
|
||||
TTS_EQUAL(m, reference);
|
||||
};
|
||||
|
||||
TTS_CASE("Compatibility of 1D blocks")
|
||||
{
|
||||
rotgen::matrix<float, 4, 2> V;
|
||||
setConstant(V, 99);
|
||||
rotgen::matrix<float, 3, 1> C{12, 34, 56};
|
||||
|
||||
extract<1, 2>(V, 0, 0) = segment<2>(C, 0);
|
||||
extract<2, 1>(V, 1, 0) = segment<2>(C, 1);
|
||||
|
||||
TTS_EQUAL(V(0, 0), C(0));
|
||||
TTS_EQUAL(V(0, 1), C(1));
|
||||
TTS_EQUAL(V(1, 0), C(1));
|
||||
TTS_EQUAL(V(2, 0), C(2));
|
||||
};
|
||||
|
|
|
|||
123
test/integration/initialize_with.cpp
Normal file
123
test/integration/initialize_with.cpp
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#include <rotgen/rotgen.hpp>
|
||||
|
||||
#include "unit/tests.hpp"
|
||||
#include <Eigen/Core>
|
||||
|
||||
TTS_CASE_TPL("Initialize a matrix with a list of scalars", rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
using eigen_t = Eigen::Matrix<T, -1, -1, O::value>;
|
||||
using rotgen_t = rotgen::matrix<T, -1, -1, O::value>;
|
||||
|
||||
eigen_t reference(3, 3);
|
||||
reference << 1, 2, 3, 4, 5, 6, 7, 8, 9;
|
||||
|
||||
rotgen_t values(3, 3);
|
||||
initialize_with(values, 1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||
|
||||
for (int r = 0; r < 3; r++)
|
||||
for (int c = 0; c < 3; c++) TTS_EQUAL(values(r, c), reference(r, c));
|
||||
};
|
||||
|
||||
TTS_CASE_TPL("Initialize a sub-matrix with a list of scalars",
|
||||
rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
using eigen_t = Eigen::Matrix<T, -1, -1, O::value>;
|
||||
using rotgen_t = rotgen::matrix<T, -1, -1, O::value>;
|
||||
|
||||
eigen_t reference(6, 6);
|
||||
reference.block(1, 1, 3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9;
|
||||
|
||||
rotgen_t values(6, 6);
|
||||
initialize_with(extract(values, 1, 1, 3, 3), 1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||
|
||||
for (int r = 0; r < 3; r++)
|
||||
for (int c = 0; c < 3; c++)
|
||||
TTS_EQUAL(values(r + 1, c + 1), reference(r + 1, c + 1));
|
||||
};
|
||||
|
||||
TTS_CASE_TPL("Initialize a map with a list of scalars", rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
using eigen_t = Eigen::Matrix<T, -1, -1, O::value>;
|
||||
using rotgen_t = rotgen::matrix<T, -1, -1, O::value>;
|
||||
|
||||
T eigen_data[9] = {};
|
||||
T rotgen_data[9] = {};
|
||||
|
||||
Eigen::Map<eigen_t> reference(eigen_data, 3, 3);
|
||||
reference << 1, 2, 3, 4, 5, 6, 7, 8, 9;
|
||||
|
||||
rotgen::map<rotgen_t> values(rotgen_data, 3, 3);
|
||||
initialize_with(values, 1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||
|
||||
for (int i = 0; i < 9; i++) TTS_EQUAL(eigen_data[i], rotgen_data[i]);
|
||||
};
|
||||
|
||||
TTS_CASE_TPL("Initialize a sub-map with a list of scalars",
|
||||
rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
using eigen_t = Eigen::Matrix<T, -1, -1, O::value>;
|
||||
using rotgen_t = rotgen::matrix<T, -1, -1, O::value>;
|
||||
|
||||
T eigen_data[36] = {};
|
||||
T rotgen_data[36] = {};
|
||||
|
||||
Eigen::Map<eigen_t> reference(eigen_data, 6, 6);
|
||||
reference.block(1, 1, 3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9;
|
||||
|
||||
rotgen::map<rotgen_t> values(rotgen_data, 6, 6);
|
||||
initialize_with(extract(values, 1, 1, 3, 3), 1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||
|
||||
for (int i = 0; i < 9; i++) TTS_EQUAL(eigen_data[i], rotgen_data[i]);
|
||||
};
|
||||
|
||||
void process(rotgen::ref<rotgen::matrixXf> r)
|
||||
{
|
||||
rotgen::initialize_with(r, 1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||
}
|
||||
|
||||
void process(rotgen::ref<rotgen::matrixXd> r)
|
||||
{
|
||||
rotgen::initialize_with(r, 1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||
}
|
||||
|
||||
void process(rotgen::ref<rotgen::matrix<float, -1, -1, rotgen::RowMajor>> r)
|
||||
{
|
||||
rotgen::initialize_with(r, 1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||
}
|
||||
|
||||
void process(rotgen::ref<rotgen::matrix<double, -1, -1, rotgen::RowMajor>> r)
|
||||
{
|
||||
rotgen::initialize_with(r, 1, 2, 3, 4, 5, 6, 7, 8, 9);
|
||||
}
|
||||
|
||||
TTS_CASE_TPL("Initialize a ref with a list of scalars", rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
using eigen_t = Eigen::Matrix<T, -1, -1, O::value>;
|
||||
using rotgen_t = rotgen::matrix<T, -1, -1, O::value>;
|
||||
|
||||
eigen_t reference(3, 3);
|
||||
reference << 1, 2, 3, 4, 5, 6, 7, 8, 9;
|
||||
|
||||
rotgen_t values(3, 3);
|
||||
process(values);
|
||||
|
||||
for (int r = 0; r < 3; r++)
|
||||
for (int c = 0; c < 3; c++) TTS_EQUAL(values(r, c), reference(r, c));
|
||||
};
|
||||
50
test/integration/specifics.cpp
Normal file
50
test/integration/specifics.cpp
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#include <rotgen/rotgen.hpp>
|
||||
|
||||
#include "unit/tests.hpp"
|
||||
|
||||
bool categorize_as_scalar(double)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool categorize_as_scalar(rotgen::ref<rotgen::matrix<double, 1, 1>>)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TTS_CASE("Matrix product of 1xN by Nx1 yields a scalar-convertible object")
|
||||
{
|
||||
rotgen::matrix<double, 1, 2> a = {1, 2};
|
||||
rotgen::matrix<double, 2, 1> b = {10, 20};
|
||||
|
||||
double n = a * b;
|
||||
|
||||
TTS_EQUAL(n, 50);
|
||||
TTS_EXPECT(categorize_as_scalar(a * b));
|
||||
};
|
||||
|
||||
TTS_CASE_TPL("Static 1x1 matrix-like objects can be assigned as-if",
|
||||
rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
rotgen::matrix<T, 1, 2> a = {1, 2};
|
||||
rotgen::matrix<T, 2, 1> b = {10, 20};
|
||||
|
||||
rotgen::matrix<T, -1, -1, O::value> big(10, 10);
|
||||
auto bk = extract<1, 1>(big, 2, 2);
|
||||
bk = a * b;
|
||||
TTS_EQUAL(big(2, 2), 50);
|
||||
|
||||
rotgen::map<rotgen::matrix<T, 1, 1, O::value>> big_map(big.data(), 1, 1);
|
||||
|
||||
big_map = a * b;
|
||||
TTS_EQUAL(big(0, 0), 50);
|
||||
};
|
||||
|
|
@ -9,9 +9,9 @@
|
|||
|
||||
#include "unit/tests.hpp"
|
||||
|
||||
TTS_CASE_TPL("SVD decomposition - Dynamic case",
|
||||
rotgen::tests::types)<typename T, typename O>(
|
||||
tts::type<tts::types<T, O>>)
|
||||
TTS_CASE_TPL("SVD decomposition - Dynamic case", rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
int rank, i = 5;
|
||||
auto eps = std::numeric_limits<T>::epsilon();
|
||||
|
|
@ -24,10 +24,10 @@ TTS_CASE_TPL("SVD decomposition - Dynamic case",
|
|||
{
|
||||
rank = decomp.rank();
|
||||
|
||||
auto u = decomp.U(rank);
|
||||
auto d = decomp.singular_values(rank);
|
||||
auto dd = decomp.D(rank);
|
||||
auto v = decomp.V(rank);
|
||||
auto u = decomp.matrixU(rank);
|
||||
auto d = decomp.singularValues(rank);
|
||||
auto dd = decomp.matrixD(rank);
|
||||
auto v = decomp.matrixV(rank);
|
||||
|
||||
TTS_EQUAL(rank, i);
|
||||
|
||||
|
|
@ -48,9 +48,9 @@ TTS_CASE_TPL("SVD decomposition - Dynamic case",
|
|||
} while (rank != 1);
|
||||
};
|
||||
|
||||
TTS_CASE_TPL("SVD decomposition - Static case",
|
||||
rotgen::tests::types)<typename T, typename O>(
|
||||
tts::type<tts::types<T, O>>)
|
||||
TTS_CASE_TPL("SVD decomposition - Static case", rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
int rank, i = 5;
|
||||
auto eps = std::numeric_limits<T>::epsilon();
|
||||
|
|
@ -62,10 +62,10 @@ TTS_CASE_TPL("SVD decomposition - Static case",
|
|||
{
|
||||
rank = decomp.rank();
|
||||
|
||||
auto u = decomp.U(rank);
|
||||
auto d = decomp.singular_values(rank);
|
||||
auto dd = decomp.D(rank);
|
||||
auto v = decomp.V(rank);
|
||||
auto u = decomp.matrixU(rank);
|
||||
auto d = decomp.singularValues(rank);
|
||||
auto dd = decomp.matrixD(rank);
|
||||
auto v = decomp.matrixV(rank);
|
||||
|
||||
TTS_EQUAL(rank, i);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue