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(); }
|
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(); }
|
int rank() const { return svd_.rank(); }
|
||||||
|
|
||||||
auto singular_values() const
|
auto singularValues() const
|
||||||
{
|
{
|
||||||
if constexpr (!use_expression_templates)
|
if constexpr (!use_expression_templates)
|
||||||
return detail::as_concrete_t<d_type, matrix>{svd_.singularValues()};
|
return detail::as_concrete_t<d_type, matrix>{svd_.singularValues()};
|
||||||
else return svd_.singularValues();
|
else return svd_.singularValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto U() const
|
auto matrixU() const
|
||||||
{
|
{
|
||||||
if constexpr (!use_expression_templates)
|
if constexpr (!use_expression_templates)
|
||||||
return detail::as_concrete_t<u_type, matrix>{svd_.matrixU()};
|
return detail::as_concrete_t<u_type, matrix>{svd_.matrixU()};
|
||||||
else return svd_.matrixU();
|
else return svd_.matrixU();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto V() const
|
auto matrixV() const
|
||||||
{
|
{
|
||||||
if constexpr (!use_expression_templates)
|
if constexpr (!use_expression_templates)
|
||||||
return detail::as_concrete_t<v_type, matrix>{svd_.matrixV()};
|
return detail::as_concrete_t<v_type, matrix>{svd_.matrixV()};
|
||||||
else return svd_.matrixV();
|
else return svd_.matrixV();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto D() const
|
auto matrixD() const
|
||||||
{
|
{
|
||||||
auto d = svd_.singularValues().asDiagonal();
|
auto d = svd_.singularValues().asDiagonal();
|
||||||
if constexpr (!use_expression_templates)
|
if constexpr (!use_expression_templates)
|
||||||
|
|
@ -61,7 +61,7 @@ namespace rotgen
|
||||||
else return d;
|
else return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto singular_values(int r) const
|
auto singularValues(int r) const
|
||||||
{
|
{
|
||||||
auto that = svd_.singularValues().head(r);
|
auto that = svd_.singularValues().head(r);
|
||||||
if constexpr (!use_expression_templates)
|
if constexpr (!use_expression_templates)
|
||||||
|
|
@ -69,7 +69,7 @@ namespace rotgen
|
||||||
else return svd_.singularValues();
|
else return svd_.singularValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto U(int r) const
|
auto matrixU(int r) const
|
||||||
{
|
{
|
||||||
auto that = svd_.matrixU().leftCols(r);
|
auto that = svd_.matrixU().leftCols(r);
|
||||||
if constexpr (!use_expression_templates)
|
if constexpr (!use_expression_templates)
|
||||||
|
|
@ -77,7 +77,7 @@ namespace rotgen
|
||||||
else return that;
|
else return that;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto V(int r) const
|
auto matrixV(int r) const
|
||||||
{
|
{
|
||||||
auto that = svd_.matrixV().leftCols(r);
|
auto that = svd_.matrixV().leftCols(r);
|
||||||
if constexpr (!use_expression_templates)
|
if constexpr (!use_expression_templates)
|
||||||
|
|
@ -85,7 +85,7 @@ namespace rotgen
|
||||||
else return that;
|
else return that;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto D(int r) const
|
auto matrixD(int r) const
|
||||||
{
|
{
|
||||||
auto d = svd_.singularValues().head(r).asDiagonal();
|
auto d = svd_.singularValues().head(r).asDiagonal();
|
||||||
if constexpr (!use_expression_templates)
|
if constexpr (!use_expression_templates)
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,26 @@
|
||||||
|
|
||||||
namespace rotgen::concepts
|
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.
|
//! @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.
|
//! @brief Check if a type is a ROTGEN type.
|
||||||
//================================================================================================
|
//================================================================================================
|
||||||
template<typename T>
|
template<typename T>
|
||||||
concept entity = requires(T const&) {
|
concept entity =
|
||||||
typename std::remove_cvref_t<T>::rotgen_tag;
|
requires(T const&) { typename std::remove_cvref_t<T>::rotgen_tag; };
|
||||||
typename std::remove_cvref_t<T>::parent;
|
|
||||||
};
|
|
||||||
|
|
||||||
//================================================================================================
|
//================================================================================================
|
||||||
//! @brief Check if a type is an EIGEN type.
|
//! @brief Check if a type is an EIGEN type.
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,12 @@
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <rotgen/detail/assert.hpp>
|
||||||
|
|
||||||
#include <rotgen/concepts.hpp>
|
#include <rotgen/concepts.hpp>
|
||||||
#include <rotgen/container/block/dynamic/impl.hpp>
|
#include <rotgen/container/block/dynamic/impl.hpp>
|
||||||
#include <rotgen/container/matrix/dynamic.hpp>
|
#include <rotgen/container/matrix/dynamic.hpp>
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
|
|
||||||
namespace rotgen
|
namespace rotgen
|
||||||
|
|
@ -76,14 +77,37 @@ namespace rotgen
|
||||||
|
|
||||||
using parent::operator=;
|
using parent::operator=;
|
||||||
|
|
||||||
block& operator=(concepts::entity auto const& other)
|
template<concepts::entity Src>
|
||||||
|
block& operator=(Src const& other)
|
||||||
requires(!is_immutable)
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
assert(parent::rows() == other.rows() && parent::cols() == other.cols());
|
if constexpr (IsVectorAtCompileTime && Src::IsVectorAtCompileTime)
|
||||||
for (rotgen::Index r = 0; r < parent::rows(); ++r)
|
{
|
||||||
for (rotgen::Index c = 0; c < parent::cols(); ++c)
|
ROTGEN_ASSERT(parent::size() == other.size(),
|
||||||
(*this)(r, c) = other(r, c);
|
"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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -167,13 +191,6 @@ namespace rotgen
|
||||||
|
|
||||||
block(parent const& base) : parent(base) {}
|
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)
|
value_type& operator()(Index i, Index j)
|
||||||
requires(!is_immutable)
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
|
|
@ -183,7 +200,6 @@ namespace rotgen
|
||||||
value_type& operator()(Index i)
|
value_type& operator()(Index i)
|
||||||
requires(!is_immutable && IsVectorAtCompileTime)
|
requires(!is_immutable && IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
assert(is_contiguous_linear());
|
|
||||||
return parent::operator()(i);
|
return parent::operator()(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -201,7 +217,6 @@ namespace rotgen
|
||||||
value_type operator()(Index i) const
|
value_type operator()(Index i) const
|
||||||
requires(IsVectorAtCompileTime)
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
assert(is_contiguous_linear());
|
|
||||||
return parent::operator()(i);
|
return parent::operator()(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,7 +226,7 @@ namespace rotgen
|
||||||
return (*this)(i);
|
return (*this)(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto evaluate() const { return *this; }
|
concrete_type evaluate() const { return concrete_type{*this}; }
|
||||||
|
|
||||||
decltype(auto) noalias() const { return *this; }
|
decltype(auto) noalias() const { return *this; }
|
||||||
|
|
||||||
|
|
@ -278,17 +293,19 @@ namespace rotgen
|
||||||
return static_cast<parent const&>(lhs) == static_cast<parent const&>(rhs);
|
return static_cast<parent const&>(lhs) == static_cast<parent const&>(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator+=(block const& rhs)
|
template<concepts::entity E>
|
||||||
|
block& operator+=(E const& rhs)
|
||||||
requires(!is_immutable)
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() += static_cast<parent const&>(rhs);
|
base() += rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator-=(block const& rhs)
|
template<concepts::entity E>
|
||||||
|
block& operator-=(E const& rhs)
|
||||||
requires(!is_immutable)
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() -= static_cast<parent const&>(rhs);
|
base() -= rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -297,10 +314,11 @@ namespace rotgen
|
||||||
return concrete_type(static_cast<parent const&>(*this).operator-());
|
return concrete_type(static_cast<parent const&>(*this).operator-());
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator*=(block const& rhs)
|
template<concepts::entity E>
|
||||||
|
block& operator*=(E const& rhs)
|
||||||
requires(!is_immutable)
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() *= static_cast<parent const&>(rhs);
|
base() *= rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -351,11 +369,11 @@ namespace rotgen
|
||||||
static concrete_type Zero(int rows, int cols)
|
static concrete_type Zero(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(rows == Rows &&
|
ROTGEN_ASSERT(rows == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
assert(cols == Cols &&
|
ROTGEN_ASSERT(cols == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Zero(rows, cols);
|
return parent::Zero(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -368,11 +386,11 @@ namespace rotgen
|
||||||
static concrete_type Ones(int rows, int cols)
|
static concrete_type Ones(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(rows == Rows &&
|
ROTGEN_ASSERT(rows == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
assert(cols == Cols &&
|
ROTGEN_ASSERT(cols == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Ones(rows, cols);
|
return parent::Ones(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -385,11 +403,11 @@ namespace rotgen
|
||||||
static concrete_type Constant(int rows, int cols, value_type value)
|
static concrete_type Constant(int rows, int cols, value_type value)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(rows == Rows &&
|
ROTGEN_ASSERT(rows == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
assert(cols == Cols &&
|
ROTGEN_ASSERT(cols == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Constant(rows, cols, static_cast<double>(value));
|
return parent::Constant(rows, cols, static_cast<double>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -402,11 +420,11 @@ namespace rotgen
|
||||||
static concrete_type Random(int rows, int cols)
|
static concrete_type Random(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(rows == Rows &&
|
ROTGEN_ASSERT(rows == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
assert(cols == Cols &&
|
ROTGEN_ASSERT(cols == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Random(rows, cols);
|
return parent::Random(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -419,11 +437,11 @@ namespace rotgen
|
||||||
static concrete_type Identity(int rows, int cols)
|
static concrete_type Identity(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(rows == Rows &&
|
ROTGEN_ASSERT(rows == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
assert(cols == Cols &&
|
ROTGEN_ASSERT(cols == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Identity(rows, cols);
|
return parent::Identity(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -464,7 +482,7 @@ namespace rotgen
|
||||||
|
|
||||||
template<int P> value_type lpNorm() const
|
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);
|
return parent::lpNorm(P);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,28 +2,36 @@
|
||||||
#define TYPE double
|
#define TYPE double
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
#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 TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
||||||
|
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
||||||
#include <rotgen/container/block/dynamic/model.hpp>
|
#include <rotgen/container/block/dynamic/model.hpp>
|
||||||
#undef CLASSNAME
|
#undef CLASSNAME
|
||||||
|
#undef CLASSCONSTNAME
|
||||||
#undef TRANSCLASSNAME
|
#undef TRANSCLASSNAME
|
||||||
#undef TRANSNAME
|
#undef TRANSNAME
|
||||||
#undef SOURCENAME
|
#undef SOURCENAME
|
||||||
#undef MAPNAME
|
#undef MAPNAME
|
||||||
|
#undef TRANSMAPNAME
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
#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 TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
||||||
|
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
||||||
#include <rotgen/container/block/dynamic/model.hpp>
|
#include <rotgen/container/block/dynamic/model.hpp>
|
||||||
#undef CLASSNAME
|
#undef CLASSNAME
|
||||||
|
#undef CLASSCONSTNAME
|
||||||
#undef TRANSCLASSNAME
|
#undef TRANSCLASSNAME
|
||||||
#undef TRANSNAME
|
#undef TRANSNAME
|
||||||
#undef SOURCENAME
|
#undef SOURCENAME
|
||||||
#undef MAPNAME
|
#undef MAPNAME
|
||||||
|
#undef TRANSMAPNAME
|
||||||
|
|
||||||
#undef SIZE
|
#undef SIZE
|
||||||
#undef TYPE
|
#undef TYPE
|
||||||
|
|
@ -32,28 +40,36 @@
|
||||||
#define TYPE float
|
#define TYPE float
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
#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 TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
||||||
|
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
||||||
#include <rotgen/container/block/dynamic/model.hpp>
|
#include <rotgen/container/block/dynamic/model.hpp>
|
||||||
#undef CLASSNAME
|
#undef CLASSNAME
|
||||||
|
#undef CLASSCONSTNAME
|
||||||
#undef TRANSCLASSNAME
|
#undef TRANSCLASSNAME
|
||||||
#undef TRANSNAME
|
#undef TRANSNAME
|
||||||
#undef SOURCENAME
|
#undef SOURCENAME
|
||||||
#undef MAPNAME
|
#undef MAPNAME
|
||||||
|
#undef TRANSMAPNAME
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
#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 TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
||||||
|
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
||||||
#include <rotgen/container/block/dynamic/model.hpp>
|
#include <rotgen/container/block/dynamic/model.hpp>
|
||||||
#undef CLASSNAME
|
#undef CLASSNAME
|
||||||
|
#undef CLASSCONSTNAME
|
||||||
#undef TRANSCLASSNAME
|
#undef TRANSCLASSNAME
|
||||||
#undef TRANSNAME
|
#undef TRANSNAME
|
||||||
#undef SOURCENAME
|
#undef SOURCENAME
|
||||||
#undef MAPNAME
|
#undef MAPNAME
|
||||||
|
#undef TRANSMAPNAME
|
||||||
|
|
||||||
#undef SIZE
|
#undef SIZE
|
||||||
#undef TYPE
|
#undef TYPE
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ public:
|
||||||
CLASSNAME(MAPNAME CONST& r, Index i0, Index j0, Index ni, Index nj);
|
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(CLASSNAME CONST& r, Index i0, Index j0, Index ni, Index nj);
|
||||||
CLASSNAME(TRANSCLASSNAME 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 const& other);
|
||||||
CLASSNAME(CLASSNAME&&) noexcept;
|
CLASSNAME(CLASSNAME&&) noexcept;
|
||||||
|
|
@ -81,8 +82,17 @@ public:
|
||||||
TYPE& operator()(Index i, Index j);
|
TYPE& operator()(Index i, Index j);
|
||||||
TYPE& operator()(Index index);
|
TYPE& operator()(Index index);
|
||||||
CLASSNAME& operator+=(CLASSNAME 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-=(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*=(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);
|
||||||
CLASSNAME& operator/=(TYPE d);
|
CLASSNAME& operator/=(TYPE d);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -193,11 +193,7 @@ namespace rotgen
|
||||||
|
|
||||||
parent const& base() const { return static_cast<parent const&>(*this); }
|
parent const& base() const { return static_cast<parent const&>(*this); }
|
||||||
|
|
||||||
auto evaluate() const
|
auto evaluate() const { return concrete_type(base().eval()); }
|
||||||
{
|
|
||||||
auto res = base().eval();
|
|
||||||
return as_concrete_type<decltype(res)>(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
decltype(auto) noalias() const
|
decltype(auto) noalias() const
|
||||||
{
|
{
|
||||||
|
|
@ -298,11 +294,11 @@ namespace rotgen
|
||||||
static concrete_type Constant(int rows, int cols, value_type value)
|
static concrete_type Constant(int rows, int cols, value_type value)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(rows == Rows &&
|
ROTGEN_ASSERT(rows == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
assert(cols == Cols &&
|
ROTGEN_ASSERT(cols == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Constant(rows, cols, static_cast<value_type>(value));
|
return parent::Constant(rows, cols, static_cast<value_type>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -315,11 +311,11 @@ namespace rotgen
|
||||||
static concrete_type Identity(int rows, int cols)
|
static concrete_type Identity(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(rows == Rows &&
|
ROTGEN_ASSERT(rows == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
assert(cols == Cols &&
|
ROTGEN_ASSERT(cols == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Identity(rows, cols);
|
return parent::Identity(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -332,11 +328,11 @@ namespace rotgen
|
||||||
static concrete_type Zero(int rows, int cols)
|
static concrete_type Zero(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(rows == Rows &&
|
ROTGEN_ASSERT(rows == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
assert(cols == Cols &&
|
ROTGEN_ASSERT(cols == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Zero(rows, cols);
|
return parent::Zero(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -349,11 +345,11 @@ namespace rotgen
|
||||||
static concrete_type Ones(int rows, int cols)
|
static concrete_type Ones(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(rows == Rows &&
|
ROTGEN_ASSERT(rows == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
assert(cols == Cols &&
|
ROTGEN_ASSERT(cols == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Ones(rows, cols);
|
return parent::Ones(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -366,11 +362,11 @@ namespace rotgen
|
||||||
static concrete_type Random(int rows, int cols)
|
static concrete_type Random(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(rows == Rows &&
|
ROTGEN_ASSERT(rows == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
assert(cols == Cols &&
|
ROTGEN_ASSERT(cols == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Random(rows, cols);
|
return parent::Random(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -523,17 +519,19 @@ namespace rotgen
|
||||||
|
|
||||||
Index startCol() const { return base().startCol(); }
|
Index startCol() const { return base().startCol(); }
|
||||||
|
|
||||||
block& operator+=(block const& rhs)
|
template<concepts::entity E>
|
||||||
|
block& operator+=(E const& rhs)
|
||||||
requires(!is_immutable)
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
static_cast<parent&>(*this) += static_cast<parent const&>(rhs);
|
base() += rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator-=(block const& rhs)
|
template<concepts::entity E>
|
||||||
|
block& operator-=(E const& rhs)
|
||||||
requires(!is_immutable)
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
static_cast<parent&>(*this) -= static_cast<parent const&>(rhs);
|
base() -= rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -542,10 +540,11 @@ namespace rotgen
|
||||||
return concrete_type(static_cast<parent const&>(*this).operator-());
|
return concrete_type(static_cast<parent const&>(*this).operator-());
|
||||||
}
|
}
|
||||||
|
|
||||||
block& operator*=(block const& rhs)
|
template<concepts::entity E>
|
||||||
|
block& operator*=(E const& rhs)
|
||||||
requires(!is_immutable)
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
static_cast<parent&>(*this) *= static_cast<parent const&>(rhs);
|
base() *= rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,14 @@
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <rotgen/detail/assert.hpp>
|
||||||
#include <rotgen/detail/helpers.hpp>
|
#include <rotgen/detail/helpers.hpp>
|
||||||
|
#include <rotgen/detail/product.hpp>
|
||||||
|
|
||||||
#include <rotgen/concepts.hpp>
|
#include <rotgen/concepts.hpp>
|
||||||
#include <rotgen/container/map/dynamic/impl.hpp>
|
#include <rotgen/container/map/dynamic/impl.hpp>
|
||||||
#include <rotgen/container/matrix.hpp>
|
#include <rotgen/container/matrix.hpp>
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
namespace rotgen
|
namespace rotgen
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
|
|
@ -35,6 +35,7 @@ namespace rotgen
|
||||||
|
|
||||||
using parent = find_map<Ref>;
|
using parent = find_map<Ref>;
|
||||||
using rotgen_tag = void;
|
using rotgen_tag = void;
|
||||||
|
using rotgen_map_tag = void;
|
||||||
using value_type = typename std::remove_const_t<Ref>::value_type;
|
using value_type = typename std::remove_const_t<Ref>::value_type;
|
||||||
using concrete_type = typename std::remove_const_t<Ref>::concrete_type;
|
using concrete_type = typename std::remove_const_t<Ref>::concrete_type;
|
||||||
|
|
||||||
|
|
@ -52,6 +53,7 @@ namespace rotgen
|
||||||
static constexpr int ColsAtCompileTime = Ref::ColsAtCompileTime;
|
static constexpr int ColsAtCompileTime = Ref::ColsAtCompileTime;
|
||||||
static constexpr int MaxRowsAtCompileTime = Ref::MaxRowsAtCompileTime;
|
static constexpr int MaxRowsAtCompileTime = Ref::MaxRowsAtCompileTime;
|
||||||
static constexpr int MaxColsAtCompileTime = Ref::MaxColsAtCompileTime;
|
static constexpr int MaxColsAtCompileTime = Ref::MaxColsAtCompileTime;
|
||||||
|
static constexpr int SizeAtCompileTime = Ref::SizeAtCompileTime;
|
||||||
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
|
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
|
||||||
static constexpr bool is_defined_static =
|
static constexpr bool is_defined_static =
|
||||||
RowsAtCompileTime != -1 && ColsAtCompileTime != -1;
|
RowsAtCompileTime != -1 && ColsAtCompileTime != -1;
|
||||||
|
|
@ -75,12 +77,12 @@ namespace rotgen
|
||||||
: parent(ptr, r, c, strides<storage_order>(s, r, c))
|
: parent(ptr, r, c, strides<storage_order>(s, r, c))
|
||||||
{
|
{
|
||||||
if constexpr (RowsAtCompileTime != -1)
|
if constexpr (RowsAtCompileTime != -1)
|
||||||
assert(r == RowsAtCompileTime &&
|
ROTGEN_ASSERT(r == RowsAtCompileTime,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
|
|
||||||
if constexpr (ColsAtCompileTime != -1)
|
if constexpr (ColsAtCompileTime != -1)
|
||||||
assert(c == ColsAtCompileTime &&
|
ROTGEN_ASSERT(c == ColsAtCompileTime,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used to properly delay ref dynamic construction
|
// Used to properly delay ref dynamic construction
|
||||||
|
|
@ -135,24 +137,50 @@ namespace rotgen
|
||||||
|
|
||||||
map(map const& other) : parent(other) {}
|
map(map const& other) : parent(other) {}
|
||||||
|
|
||||||
|
map(map&& other) : parent(std::move(other)) {}
|
||||||
|
|
||||||
map& operator=(map const& other)
|
map& operator=(map const& other)
|
||||||
requires(!is_immutable)
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
base() = static_cast<parent const&>(other);
|
base() = other.base();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
map& operator=(concepts::entity auto const& other)
|
map& operator=(map&& other)
|
||||||
requires(!is_immutable)
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
assert(parent::rows() == other.rows() && parent::cols() == other.cols());
|
base() = std::move(other.base());
|
||||||
if constexpr (IsVectorAtCompileTime)
|
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)
|
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
|
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 r = 0; r < parent::rows(); ++r)
|
||||||
for (rotgen::Index c = 0; c < parent::cols(); ++c)
|
for (rotgen::Index c = 0; c < parent::cols(); ++c)
|
||||||
(*this)(r, c) = other(r, c);
|
(*this)(r, c) = other(r, c);
|
||||||
|
|
@ -196,7 +224,7 @@ namespace rotgen
|
||||||
return (*this)(i);
|
return (*this)(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto evaluate() const { return *this; }
|
concrete_type evaluate() const { return concrete_type{*this}; }
|
||||||
|
|
||||||
decltype(auto) noalias() const { return *this; }
|
decltype(auto) noalias() const { return *this; }
|
||||||
|
|
||||||
|
|
@ -275,7 +303,7 @@ namespace rotgen
|
||||||
concrete_type cross(map const& other) const
|
concrete_type cross(map const& other) const
|
||||||
{
|
{
|
||||||
concrete_type that;
|
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(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);
|
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)
|
map& operator+=(map<R2, O2, S2> const& rhs)
|
||||||
requires(!is_immutable)
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
|
validate_compound_operator(rhs);
|
||||||
base() += rhs.base();
|
base() += rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -320,6 +349,7 @@ namespace rotgen
|
||||||
map& operator-=(map<R2, O2, S2> const& rhs)
|
map& operator-=(map<R2, O2, S2> const& rhs)
|
||||||
requires(!is_immutable)
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
|
validate_compound_operator(rhs);
|
||||||
base() -= rhs.base();
|
base() -= rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -333,6 +363,9 @@ namespace rotgen
|
||||||
map& operator*=(map<R2, O2, S2> const& rhs)
|
map& operator*=(map<R2, O2, S2> const& rhs)
|
||||||
requires(!is_immutable)
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
|
ROTGEN_ASSERT(parent::cols() == rhs.rows() &&
|
||||||
|
parent::cols() == rhs.cols(),
|
||||||
|
"Incompatible dimensions for compound matrix-product");
|
||||||
base() *= rhs.base();
|
base() *= rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -464,7 +497,7 @@ namespace rotgen
|
||||||
|
|
||||||
template<int P> value_type lpNorm() const
|
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);
|
return parent::lpNorm(P);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -476,6 +509,32 @@ namespace rotgen
|
||||||
{
|
{
|
||||||
return concrete_type(base().qr_solve(rhs.base()));
|
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>
|
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>
|
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
|
||||||
matrix<typename R1::value_type,
|
auto operator*(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
|
||||||
R1::RowsAtCompileTime,
|
|
||||||
R2::ColsAtCompileTime,
|
|
||||||
R1::storage_order>
|
|
||||||
operator*(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
|
|
||||||
{
|
{
|
||||||
using map1_type = map<R1 const, O1, S1>;
|
using map1_type = map<R1 const, O1, S1>;
|
||||||
using map2_type = map<R2 const, O2, S2>;
|
using map2_type = map<R2 const, O2, S2>;
|
||||||
using concrete_type = matrix<typename R1::value_type, R1::RowsAtCompileTime,
|
using concrete_type = matrix<typename R1::value_type, R1::RowsAtCompileTime,
|
||||||
R2::ColsAtCompileTime, R1::storage_order>;
|
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>
|
template<typename R, int O, typename S>
|
||||||
|
|
|
||||||
|
|
@ -3,27 +3,39 @@
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
#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 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 TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||||
#include <rotgen/container/map/dynamic/model.hpp>
|
#include <rotgen/container/map/dynamic/model.hpp>
|
||||||
#undef CLASSNAME
|
#undef CLASSNAME
|
||||||
#undef TRANSCLASSNAME
|
#undef TRANSCLASSNAME
|
||||||
|
#undef TRANSCLASSCONSTNAME
|
||||||
|
#undef TRANSCLASSNONCONSTNAME
|
||||||
#undef TRANSSOURCENAME
|
#undef TRANSSOURCENAME
|
||||||
#undef SOURCENAME
|
#undef SOURCENAME
|
||||||
#undef CLASSCONSTNAME
|
#undef CLASSCONSTNAME
|
||||||
|
#undef CLASSNONCONSTNAME
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
#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 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 TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||||
#include <rotgen/container/map/dynamic/model.hpp>
|
#include <rotgen/container/map/dynamic/model.hpp>
|
||||||
#undef CLASSNAME
|
#undef CLASSNAME
|
||||||
#undef TRANSCLASSNAME
|
#undef TRANSCLASSNAME
|
||||||
|
#undef TRANSCLASSCONSTNAME
|
||||||
|
#undef TRANSCLASSNONCONSTNAME
|
||||||
#undef TRANSSOURCENAME
|
#undef TRANSSOURCENAME
|
||||||
#undef SOURCENAME
|
#undef SOURCENAME
|
||||||
#undef CLASSCONSTNAME
|
#undef CLASSCONSTNAME
|
||||||
|
#undef CLASSNONCONSTNAME
|
||||||
|
|
||||||
#undef SIZE
|
#undef SIZE
|
||||||
#undef TYPE
|
#undef TYPE
|
||||||
|
|
@ -33,27 +45,39 @@
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
#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 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 TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||||
#include <rotgen/container/map/dynamic/model.hpp>
|
#include <rotgen/container/map/dynamic/model.hpp>
|
||||||
#undef CLASSNAME
|
#undef CLASSNAME
|
||||||
#undef TRANSCLASSNAME
|
#undef TRANSCLASSNAME
|
||||||
|
#undef TRANSCLASSCONSTNAME
|
||||||
|
#undef TRANSCLASSNONCONSTNAME
|
||||||
#undef TRANSSOURCENAME
|
#undef TRANSSOURCENAME
|
||||||
#undef SOURCENAME
|
#undef SOURCENAME
|
||||||
#undef CLASSCONSTNAME
|
#undef CLASSCONSTNAME
|
||||||
|
#undef CLASSNONCONSTNAME
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
#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 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 TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||||
#include <rotgen/container/map/dynamic/model.hpp>
|
#include <rotgen/container/map/dynamic/model.hpp>
|
||||||
#undef CLASSNAME
|
#undef CLASSNAME
|
||||||
#undef TRANSCLASSNAME
|
#undef TRANSCLASSNAME
|
||||||
|
#undef TRANSCLASSCONSTNAME
|
||||||
|
#undef TRANSCLASSNONCONSTNAME
|
||||||
#undef TRANSSOURCENAME
|
#undef TRANSSOURCENAME
|
||||||
#undef SOURCENAME
|
#undef SOURCENAME
|
||||||
#undef CLASSCONSTNAME
|
#undef CLASSCONSTNAME
|
||||||
|
#undef CLASSNONCONSTNAME
|
||||||
|
|
||||||
#undef SIZE
|
#undef SIZE
|
||||||
#undef TYPE
|
#undef TYPE
|
||||||
|
|
|
||||||
|
|
@ -66,8 +66,10 @@ public:
|
||||||
TYPE minCoeff() const;
|
TYPE minCoeff() const;
|
||||||
TYPE maxCoeff(Index*, Index*) const;
|
TYPE maxCoeff(Index*, Index*) const;
|
||||||
TYPE minCoeff(Index*, Index*) const;
|
TYPE minCoeff(Index*, Index*) const;
|
||||||
TYPE dot(CLASSNAME const&) const;
|
TYPE dot(CLASSNONCONSTNAME const&) const;
|
||||||
TYPE dot(TRANSCLASSNAME const&) const;
|
TYPE dot(CLASSCONSTNAME const&) const;
|
||||||
|
TYPE dot(TRANSCLASSCONSTNAME const&) const;
|
||||||
|
TYPE dot(TRANSCLASSNONCONSTNAME const&) const;
|
||||||
|
|
||||||
TYPE squaredNorm() const;
|
TYPE squaredNorm() const;
|
||||||
TYPE norm() const;
|
TYPE norm() const;
|
||||||
|
|
@ -86,10 +88,16 @@ public:
|
||||||
#if !defined(USE_CONST)
|
#if !defined(USE_CONST)
|
||||||
CLASSNAME& operator+=(CLASSNAME const& rhs);
|
CLASSNAME& operator+=(CLASSNAME const& rhs);
|
||||||
CLASSNAME& operator+=(CLASSCONSTNAME const& rhs);
|
CLASSNAME& operator+=(CLASSCONSTNAME const& rhs);
|
||||||
|
CLASSNAME& operator+=(TRANSCLASSCONSTNAME const& rhs);
|
||||||
|
CLASSNAME& operator+=(TRANSCLASSNONCONSTNAME const& rhs);
|
||||||
CLASSNAME& operator-=(CLASSNAME const& rhs);
|
CLASSNAME& operator-=(CLASSNAME const& rhs);
|
||||||
CLASSNAME& operator-=(CLASSCONSTNAME const& rhs);
|
CLASSNAME& operator-=(CLASSCONSTNAME const& rhs);
|
||||||
|
CLASSNAME& operator-=(TRANSCLASSCONSTNAME const& rhs);
|
||||||
|
CLASSNAME& operator-=(TRANSCLASSNONCONSTNAME const& rhs);
|
||||||
CLASSNAME& operator*=(CLASSNAME const& rhs);
|
CLASSNAME& operator*=(CLASSNAME const& rhs);
|
||||||
CLASSNAME& operator*=(CLASSCONSTNAME 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);
|
||||||
CLASSNAME& operator/=(TYPE d);
|
CLASSNAME& operator/=(TYPE d);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <rotgen/detail/product.hpp>
|
||||||
|
|
||||||
#include <Eigen/Dense>
|
#include <Eigen/Dense>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
@ -41,6 +43,7 @@ namespace rotgen
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using rotgen_tag = void;
|
using rotgen_tag = void;
|
||||||
|
using rotgen_map_tag = void;
|
||||||
using parent = detail::
|
using parent = detail::
|
||||||
map_type<std::remove_const_t<Ref>, Options, std::is_const_v<Ref>, Stride>;
|
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;
|
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 ColsAtCompileTime = Ref::ColsAtCompileTime;
|
||||||
static constexpr int MaxRowsAtCompileTime = Ref::MaxRowsAtCompileTime;
|
static constexpr int MaxRowsAtCompileTime = Ref::MaxRowsAtCompileTime;
|
||||||
static constexpr int MaxColsAtCompileTime = Ref::MaxColsAtCompileTime;
|
static constexpr int MaxColsAtCompileTime = Ref::MaxColsAtCompileTime;
|
||||||
|
static constexpr int SizeAtCompileTime = Ref::SizeAtCompileTime;
|
||||||
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
|
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
|
||||||
static constexpr bool has_static_storage = Ref::has_static_storage;
|
static constexpr bool has_static_storage = Ref::has_static_storage;
|
||||||
static constexpr bool IsRowMajor = Ref::IsRowMajor;
|
static constexpr bool IsRowMajor = Ref::IsRowMajor;
|
||||||
|
|
@ -112,21 +116,25 @@ namespace rotgen
|
||||||
return *this;
|
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& base() { return static_cast<parent&>(*this); }
|
||||||
|
|
||||||
parent const& base() const { return static_cast<parent const&>(*this); }
|
parent const& base() const { return static_cast<parent const&>(*this); }
|
||||||
|
|
||||||
auto evaluate() const
|
auto evaluate() const { return concrete_type(base().eval()); }
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
decltype(auto) noalias() const
|
decltype(auto) noalias() const
|
||||||
{
|
{
|
||||||
|
|
@ -176,6 +184,7 @@ namespace rotgen
|
||||||
map& operator+=(map<R2, O2, S2> const& rhs)
|
map& operator+=(map<R2, O2, S2> const& rhs)
|
||||||
requires(!is_immutable)
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
|
validate_compound_operator(rhs);
|
||||||
base() += rhs.base();
|
base() += rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -184,6 +193,7 @@ namespace rotgen
|
||||||
map& operator-=(map<R2, O2, S2> const& rhs)
|
map& operator-=(map<R2, O2, S2> const& rhs)
|
||||||
requires(!is_immutable)
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
|
validate_compound_operator(rhs);
|
||||||
base() -= rhs.base();
|
base() -= rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -192,6 +202,9 @@ namespace rotgen
|
||||||
map& operator*=(map<R2, O2, S2> const& rhs)
|
map& operator*=(map<R2, O2, S2> const& rhs)
|
||||||
requires(!is_immutable)
|
requires(!is_immutable)
|
||||||
{
|
{
|
||||||
|
ROTGEN_ASSERT(parent::cols() == rhs.rows() &&
|
||||||
|
parent::cols() == rhs.cols(),
|
||||||
|
"Incompatible dimensions for compound matrix-product");
|
||||||
base() *= rhs.base();
|
base() *= rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -463,6 +476,32 @@ namespace rotgen
|
||||||
static_assert(P == 1 || P == 2 || P == Infinity);
|
static_assert(P == 1 || P == 2 || P == Infinity);
|
||||||
return parent::template lpNorm<P>();
|
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>
|
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>
|
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
|
||||||
matrix<typename R1::value_type, R1::RowsAtCompileTime, R2::ColsAtCompileTime>
|
auto operator*(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
|
||||||
operator*(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
|
|
||||||
{
|
{
|
||||||
using concrete_type = matrix<typename R1::value_type, R1::RowsAtCompileTime,
|
auto p = lhs.base() * rhs.base();
|
||||||
R2::ColsAtCompileTime>;
|
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>
|
template<typename R, int O, typename S>
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,12 @@
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <rotgen/detail/assert.hpp>
|
||||||
#include <rotgen/detail/helpers.hpp>
|
#include <rotgen/detail/helpers.hpp>
|
||||||
|
|
||||||
#include <rotgen/concepts.hpp>
|
#include <rotgen/concepts.hpp>
|
||||||
#include <rotgen/container/matrix/dynamic/impl.hpp>
|
#include <rotgen/container/matrix/dynamic/impl.hpp>
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
|
|
||||||
namespace rotgen
|
namespace rotgen
|
||||||
|
|
@ -27,6 +28,7 @@ namespace rotgen
|
||||||
public:
|
public:
|
||||||
using parent = find_matrix<Scalar, Opts>;
|
using parent = find_matrix<Scalar, Opts>;
|
||||||
using rotgen_tag = void;
|
using rotgen_tag = void;
|
||||||
|
using rotgen_matrix_tag = void;
|
||||||
using concrete_type = matrix;
|
using concrete_type = matrix;
|
||||||
using value_type = Scalar;
|
using value_type = Scalar;
|
||||||
|
|
||||||
|
|
@ -48,29 +50,40 @@ namespace rotgen
|
||||||
static constexpr bool has_static_storage = false;
|
static constexpr bool has_static_storage = false;
|
||||||
static constexpr bool is_immutable = false;
|
static constexpr bool is_immutable = false;
|
||||||
static constexpr int InnerStrideAtCompileTime = 1;
|
static constexpr int InnerStrideAtCompileTime = 1;
|
||||||
static constexpr int OuterStrideAtCompileTime =
|
static constexpr int OuterStrideAtCompileTime = IsRowMajor ? Cols : Rows;
|
||||||
IsRowMajor ? ColsAtCompileTime : RowsAtCompileTime;
|
|
||||||
|
|
||||||
using transposed_type = matrix<value_type, Cols, Rows, storage_order>;
|
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)
|
matrix(Index r, Index c) : parent(r, c)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
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)
|
if constexpr (Cols != -1)
|
||||||
assert(c == Cols &&
|
ROTGEN_ASSERT(c == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix(Index n)
|
matrix(Index n)
|
||||||
requires(IsVectorAtCompileTime && (Rows != 1 || Cols != 1))
|
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)
|
requires(Rows == 1 && Cols == 1)
|
||||||
: parent(1, 1, {v})
|
: parent(1, 1, {v})
|
||||||
{
|
{
|
||||||
|
|
@ -89,14 +102,14 @@ namespace rotgen
|
||||||
: parent(init)
|
: parent(init)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(init.size() == Rows &&
|
ROTGEN_ASSERT(init.size() == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
{
|
{
|
||||||
[[maybe_unused]] Index c = 0;
|
[[maybe_unused]] Index c = 0;
|
||||||
if (init.size()) c = init.begin()->size();
|
if (init.size()) c = init.begin()->size();
|
||||||
assert(c == Cols &&
|
ROTGEN_ASSERT(c == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"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)
|
if constexpr (IsVectorAtCompileTime && Src::IsVectorAtCompileTime)
|
||||||
assert(e.rows() == Rows &&
|
{
|
||||||
"Mismatched between dynamic and static row size");
|
resize(other.size());
|
||||||
if constexpr (Cols != -1)
|
for (rotgen::Index i = 0; i < parent::size(); ++i)
|
||||||
assert(e.cols() == Cols &&
|
(*this)[i] = other[i];
|
||||||
"Mismatched between dynamic and static col size");
|
}
|
||||||
for (rotgen::Index r = 0; r < e.rows(); ++r)
|
else
|
||||||
for (rotgen::Index c = 0; c < e.cols(); ++c) (*this)(r, c) = e(r, c);
|
{
|
||||||
|
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)
|
matrix local(other);
|
||||||
assert(e.rows() == Rows &&
|
swap(local);
|
||||||
"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);
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,6 +156,13 @@ namespace rotgen
|
||||||
return (*this)(i);
|
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; }
|
auto evaluate() const { return *this; }
|
||||||
|
|
||||||
decltype(auto) noalias() const { return *this; }
|
decltype(auto) noalias() const { return *this; }
|
||||||
|
|
@ -156,17 +173,22 @@ namespace rotgen
|
||||||
|
|
||||||
Index outerStride() const noexcept
|
Index outerStride() const noexcept
|
||||||
{
|
{
|
||||||
return IsVectorAtCompileTime ? this->size()
|
if constexpr (IsVectorAtCompileTime) return this->size();
|
||||||
: IsRowMajor ? this->cols()
|
else
|
||||||
: this->rows();
|
{
|
||||||
|
if constexpr (IsRowMajor) return this->cols();
|
||||||
|
else return this->rows();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void resize(int r, int c)
|
void resize(int r, int c)
|
||||||
{
|
{
|
||||||
if constexpr (Rows == 1)
|
if constexpr (Cols != -1)
|
||||||
assert(c == Cols && "Mismatched between dynamic and static col size");
|
ROTGEN_ASSERT(c == Cols,
|
||||||
if constexpr (Cols == 1)
|
"Mismatched between dynamic and static col size");
|
||||||
assert(r == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
|
ROTGEN_ASSERT(r == Rows,
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
parent::resize(r, c);
|
parent::resize(r, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -179,10 +201,12 @@ namespace rotgen
|
||||||
|
|
||||||
void conservativeResize(int r, int c)
|
void conservativeResize(int r, int c)
|
||||||
{
|
{
|
||||||
if constexpr (Rows == 1)
|
if constexpr (Cols != -1)
|
||||||
assert(c == Cols && "Mismatched between dynamic and static col size");
|
ROTGEN_ASSERT(c == Cols,
|
||||||
if constexpr (Cols == 1)
|
"Mismatched between dynamic and static col size");
|
||||||
assert(r == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
|
ROTGEN_ASSERT(r == Rows,
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
parent::conservativeResize(r, c);
|
parent::conservativeResize(r, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -231,26 +255,26 @@ namespace rotgen
|
||||||
|
|
||||||
friend bool operator==(matrix const& lhs, matrix const& rhs)
|
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)
|
matrix& operator+=(matrix const& rhs)
|
||||||
{
|
{
|
||||||
base() += static_cast<parent const&>(rhs);
|
base() += rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix& operator-=(matrix const& rhs)
|
matrix& operator-=(matrix const& rhs)
|
||||||
{
|
{
|
||||||
base() -= static_cast<parent const&>(rhs);
|
base() -= rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix operator-() const { return matrix(base().operator-()); }
|
matrix operator-() const { return -base(); }
|
||||||
|
|
||||||
matrix& operator*=(matrix const& rhs)
|
matrix& operator*=(matrix const& rhs)
|
||||||
{
|
{
|
||||||
base() *= static_cast<parent const&>(rhs);
|
base() *= rhs.base();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -299,11 +323,11 @@ namespace rotgen
|
||||||
static matrix Ones(int rows, int cols)
|
static matrix Ones(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(rows == Rows &&
|
ROTGEN_ASSERT(rows == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
assert(cols == Cols &&
|
ROTGEN_ASSERT(cols == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Ones(rows, cols);
|
return parent::Ones(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -316,11 +340,11 @@ namespace rotgen
|
||||||
static matrix Zero(int rows, int cols)
|
static matrix Zero(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(rows == Rows &&
|
ROTGEN_ASSERT(rows == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
assert(cols == Cols &&
|
ROTGEN_ASSERT(cols == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Zero(rows, cols);
|
return parent::Zero(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -333,11 +357,11 @@ namespace rotgen
|
||||||
static matrix Constant(int rows, int cols, Scalar value)
|
static matrix Constant(int rows, int cols, Scalar value)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(rows == Rows &&
|
ROTGEN_ASSERT(rows == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
assert(cols == Cols &&
|
ROTGEN_ASSERT(cols == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Constant(rows, cols, static_cast<Scalar>(value));
|
return parent::Constant(rows, cols, static_cast<Scalar>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -350,11 +374,11 @@ namespace rotgen
|
||||||
static matrix Random(int rows, int cols)
|
static matrix Random(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(rows == Rows &&
|
ROTGEN_ASSERT(rows == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
assert(cols == Cols &&
|
ROTGEN_ASSERT(cols == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Random(rows, cols);
|
return parent::Random(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -367,11 +391,11 @@ namespace rotgen
|
||||||
static matrix Identity(int rows, int cols)
|
static matrix Identity(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(rows == Rows &&
|
ROTGEN_ASSERT(rows == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
assert(cols == Cols &&
|
ROTGEN_ASSERT(cols == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Identity(rows, cols);
|
return parent::Identity(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -446,51 +470,4 @@ namespace rotgen
|
||||||
|
|
||||||
parent const& base() const { return static_cast<parent const&>(*this); }
|
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 setRandom(Index rows, Index cols);
|
||||||
void setIdentity(Index rows, Index cols);
|
void setIdentity(Index rows, Index cols);
|
||||||
|
|
||||||
|
void swap(CLASSNAME& other) { storage_.swap(other.storage_); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct payload;
|
struct payload;
|
||||||
std::unique_ptr<payload> storage_;
|
std::unique_ptr<payload> storage_;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <rotgen/detail/assert.hpp>
|
||||||
#include <rotgen/detail/helpers.hpp>
|
#include <rotgen/detail/helpers.hpp>
|
||||||
|
|
||||||
#include <rotgen/concepts.hpp>
|
#include <rotgen/concepts.hpp>
|
||||||
|
|
@ -40,6 +41,7 @@ namespace rotgen
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using rotgen_tag = void;
|
using rotgen_tag = void;
|
||||||
|
using rotgen_matrix_tag = void;
|
||||||
using parent =
|
using parent =
|
||||||
detail::storage_type<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>;
|
detail::storage_type<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>;
|
||||||
using value_type = Scalar;
|
using value_type = Scalar;
|
||||||
|
|
@ -49,6 +51,9 @@ namespace rotgen
|
||||||
using concrete_type = matrix;
|
using concrete_type = matrix;
|
||||||
using concrete_dynamic_type = matrix<value_type>;
|
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 RowsAtCompileTime = Rows;
|
||||||
static constexpr int ColsAtCompileTime = Cols;
|
static constexpr int ColsAtCompileTime = Cols;
|
||||||
static constexpr int SizeAtCompileTime = detail::static_size<matrix>();
|
static constexpr int SizeAtCompileTime = detail::static_size<matrix>();
|
||||||
|
|
@ -75,6 +80,11 @@ namespace rotgen
|
||||||
static constexpr bool has_static_storage =
|
static constexpr bool has_static_storage =
|
||||||
storage_status<Rows, Cols, MaxRows, MaxCols>;
|
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:
|
public:
|
||||||
matrix()
|
matrix()
|
||||||
requires(has_static_storage)
|
requires(has_static_storage)
|
||||||
|
|
@ -83,19 +93,19 @@ namespace rotgen
|
||||||
|
|
||||||
matrix()
|
matrix()
|
||||||
requires(!has_static_storage)
|
requires(!has_static_storage)
|
||||||
: parent(Rows > 0 ? Rows : 0, Cols > 0 ? Cols : 0)
|
: parent(AllocatedRows, AllocatedCols)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix(Index r, Index c) : parent(r, c)
|
matrix(Index r, Index c) : parent(r, c)
|
||||||
{
|
{
|
||||||
if constexpr (RowsAtCompileTime != -1)
|
if constexpr (RowsAtCompileTime != -1)
|
||||||
assert(r == RowsAtCompileTime &&
|
ROTGEN_ASSERT(r == RowsAtCompileTime,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
|
|
||||||
if constexpr (ColsAtCompileTime != -1)
|
if constexpr (ColsAtCompileTime != -1)
|
||||||
assert(c == ColsAtCompileTime &&
|
ROTGEN_ASSERT(c == ColsAtCompileTime,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix(matrix const& other) = default;
|
matrix(matrix const& other) = default;
|
||||||
|
|
@ -181,11 +191,7 @@ namespace rotgen
|
||||||
|
|
||||||
parent const& base() const { return static_cast<parent const&>(*this); }
|
parent const& base() const { return static_cast<parent const&>(*this); }
|
||||||
|
|
||||||
auto evaluate() const
|
auto evaluate() const { return *this; }
|
||||||
{
|
|
||||||
auto res = base().eval();
|
|
||||||
return as_concrete_type<decltype(res)>(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
decltype(auto) noalias() const
|
decltype(auto) noalias() const
|
||||||
{
|
{
|
||||||
|
|
@ -273,38 +279,36 @@ namespace rotgen
|
||||||
void resize(int s)
|
void resize(int s)
|
||||||
requires(IsVectorAtCompileTime)
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
if constexpr (Rows == 1)
|
if constexpr (Rows == 1) parent::resize(1, s);
|
||||||
assert(s == Cols && "Mismatched between dynamic and static col size");
|
else parent::resize(s, 1);
|
||||||
if constexpr (Cols == 1)
|
|
||||||
assert(s == Rows && "Mismatched between dynamic and static row size");
|
|
||||||
parent::resize(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void resize(int r, int c)
|
void resize(int r, int c)
|
||||||
{
|
{
|
||||||
if constexpr (Rows == 1)
|
if constexpr (Cols != -1)
|
||||||
assert(c == Cols && "Mismatched between dynamic and static col size");
|
ROTGEN_ASSERT(c == Cols,
|
||||||
if constexpr (Cols == 1)
|
"Mismatched between dynamic and static col size");
|
||||||
assert(r == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
|
ROTGEN_ASSERT(r == Rows,
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
parent::resize(r, c);
|
parent::resize(r, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void conservativeResize(int s)
|
void conservativeResize(int s)
|
||||||
requires(IsVectorAtCompileTime)
|
requires(IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
if constexpr (Rows == 1)
|
if constexpr (Rows == 1) parent::conservativeResize(1, s);
|
||||||
assert(s == Cols && "Mismatched between dynamic and static col size");
|
else parent::conservativeResize(s, 1);
|
||||||
if constexpr (Cols == 1)
|
|
||||||
assert(s == Rows && "Mismatched between dynamic and static row size");
|
|
||||||
parent::conservativeResize(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void conservativeResize(int r, int c)
|
void conservativeResize(int r, int c)
|
||||||
{
|
{
|
||||||
if constexpr (Rows == 1)
|
if constexpr (Cols != -1)
|
||||||
assert(c == Cols && "Mismatched between dynamic and static col size");
|
ROTGEN_ASSERT(c == Cols,
|
||||||
if constexpr (Cols == 1)
|
"Mismatched between dynamic and static col size");
|
||||||
assert(r == Rows && "Mismatched between dynamic and static row size");
|
if constexpr (Rows != -1)
|
||||||
|
ROTGEN_ASSERT(r == Rows,
|
||||||
|
"Mismatched between dynamic and static row size");
|
||||||
parent::conservativeResize(r, c);
|
parent::conservativeResize(r, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -317,11 +321,11 @@ namespace rotgen
|
||||||
static matrix Constant(int rows, int cols, Scalar value)
|
static matrix Constant(int rows, int cols, Scalar value)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(rows == Rows &&
|
ROTGEN_ASSERT(rows == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
assert(cols == Cols &&
|
ROTGEN_ASSERT(cols == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Constant(rows, cols, static_cast<Scalar>(value));
|
return parent::Constant(rows, cols, static_cast<Scalar>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -334,11 +338,11 @@ namespace rotgen
|
||||||
static matrix Identity(int rows, int cols)
|
static matrix Identity(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(rows == Rows &&
|
ROTGEN_ASSERT(rows == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
assert(cols == Cols &&
|
ROTGEN_ASSERT(cols == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Identity(rows, cols);
|
return parent::Identity(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -351,11 +355,11 @@ namespace rotgen
|
||||||
static matrix Ones(int rows, int cols)
|
static matrix Ones(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(rows == Rows &&
|
ROTGEN_ASSERT(rows == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
assert(cols == Cols &&
|
ROTGEN_ASSERT(cols == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Ones(rows, cols);
|
return parent::Ones(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -368,11 +372,11 @@ namespace rotgen
|
||||||
static matrix Zero(int rows, int cols)
|
static matrix Zero(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(rows == Rows &&
|
ROTGEN_ASSERT(rows == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
assert(cols == Cols &&
|
ROTGEN_ASSERT(cols == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Zero(rows, cols);
|
return parent::Zero(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -385,11 +389,11 @@ namespace rotgen
|
||||||
static matrix Random(int rows, int cols)
|
static matrix Random(int rows, int cols)
|
||||||
{
|
{
|
||||||
if constexpr (Rows != -1)
|
if constexpr (Rows != -1)
|
||||||
assert(rows == Rows &&
|
ROTGEN_ASSERT(rows == Rows,
|
||||||
"Mismatched between dynamic and static row size");
|
"Mismatched between dynamic and static row size");
|
||||||
if constexpr (Cols != -1)
|
if constexpr (Cols != -1)
|
||||||
assert(cols == Cols &&
|
ROTGEN_ASSERT(cols == Cols,
|
||||||
"Mismatched between dynamic and static column size");
|
"Mismatched between dynamic and static column size");
|
||||||
return parent::Random(rows, cols);
|
return parent::Random(rows, cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -519,7 +523,7 @@ namespace rotgen
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
matrix operator-() const { return matrix(base()(*this).operator-()); }
|
matrix operator-() const { return -base(); }
|
||||||
|
|
||||||
matrix& operator*=(matrix const& rhs)
|
matrix& operator*=(matrix const& rhs)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,13 @@
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <rotgen/detail/assert.hpp>
|
||||||
|
|
||||||
#include <rotgen/config.hpp>
|
#include <rotgen/config.hpp>
|
||||||
#include <rotgen/container/block.hpp>
|
#include <rotgen/container/block.hpp>
|
||||||
#include <rotgen/container/map.hpp>
|
#include <rotgen/container/map.hpp>
|
||||||
#include <rotgen/format.hpp>
|
#include <rotgen/format.hpp>
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cassert>
|
#include <rotgen/detail/assert.hpp>
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#if !defined(ROTGEN_FORCE_DYNAMIC)
|
#if !defined(ROTGEN_FORCE_DYNAMIC)
|
||||||
|
|
@ -15,6 +16,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <rotgen/detail/accept_as_ref.hpp>
|
#include <rotgen/detail/accept_as_ref.hpp>
|
||||||
|
#include <rotgen/detail/product.hpp>
|
||||||
|
|
||||||
namespace rotgen
|
namespace rotgen
|
||||||
{
|
{
|
||||||
|
|
@ -149,6 +151,7 @@ namespace rotgen
|
||||||
using parent::Zero;
|
using parent::Zero;
|
||||||
|
|
||||||
using parent::operator=;
|
using parent::operator=;
|
||||||
|
using parent::operator-;
|
||||||
|
|
||||||
template<typename RO, int OO, typename SO>
|
template<typename RO, int OO, typename SO>
|
||||||
auto qr_solve(ref<RO, OO, SO> rhs) const
|
auto qr_solve(ref<RO, OO, SO> rhs) const
|
||||||
|
|
@ -166,12 +169,18 @@ namespace rotgen
|
||||||
|
|
||||||
parent& as_map() { return base(); }
|
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>
|
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>>)
|
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{})
|
ref(matrix<S, R, C, O, MR, MC>& m) : parent(detail::postpone{})
|
||||||
{
|
{
|
||||||
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, m);
|
[[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>
|
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{})
|
ref(block<Ref, R, C, I>&& b) : parent(detail::postpone{})
|
||||||
{
|
{
|
||||||
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
|
[[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>
|
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{})
|
ref(block<Ref, R, C, I>& b) : parent(detail::postpone{})
|
||||||
{
|
{
|
||||||
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
|
[[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>
|
template<typename Ref, int R, int C, bool I>
|
||||||
|
|
@ -229,7 +238,7 @@ namespace rotgen
|
||||||
ref(map<Ref, O, S>& b) : parent(detail::postpone{})
|
ref(map<Ref, O, S>& b) : parent(detail::postpone{})
|
||||||
{
|
{
|
||||||
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
|
[[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>
|
template<typename Ref, int O, typename S>
|
||||||
|
|
@ -259,15 +268,15 @@ namespace rotgen
|
||||||
ref(ref<TT, OO, SS>& b) : parent(detail::postpone{})
|
ref(ref<TT, OO, SS>& b) : parent(detail::postpone{})
|
||||||
{
|
{
|
||||||
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
|
[[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>
|
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{})
|
ref(ref<TT, OO, SS> const& b) : parent(detail::postpone{})
|
||||||
{
|
{
|
||||||
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
|
[[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()) {}
|
ref(parent& m) : parent(m.data(), m.rows(), m.cols()) {}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <rotgen/detail/helpers.hpp>
|
#include <rotgen/detail/helpers.hpp>
|
||||||
|
#include <rotgen/detail/product.hpp>
|
||||||
|
|
||||||
#include <Eigen/Dense>
|
#include <Eigen/Dense>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
@ -52,6 +53,9 @@ namespace rotgen
|
||||||
|
|
||||||
template<typename T, int Options, typename Stride>
|
template<typename T, int Options, typename Stride>
|
||||||
using compile_ref_t = typename compile_ref<T, Options, Stride>::type;
|
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>
|
template<typename T, int Options, typename Stride>
|
||||||
|
|
@ -59,6 +63,7 @@ namespace rotgen
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using parent = detail::compile_ref_t<T, Options, Stride>;
|
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 referee = std::remove_const_t<T>;
|
||||||
using value_type = typename referee::value_type;
|
using value_type = typename referee::value_type;
|
||||||
using rotgen_tag = void;
|
using rotgen_tag = void;
|
||||||
|
|
@ -91,17 +96,7 @@ namespace rotgen
|
||||||
using parent::size;
|
using parent::size;
|
||||||
|
|
||||||
// Aliasing handling
|
// Aliasing handling
|
||||||
auto evaluate() const
|
auto evaluate() const { return T(base().eval()); }
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
decltype(auto) noalias() const
|
decltype(auto) noalias() const
|
||||||
{
|
{
|
||||||
|
|
@ -116,10 +111,27 @@ namespace rotgen
|
||||||
}
|
}
|
||||||
|
|
||||||
// Numeric functions
|
// Numeric functions
|
||||||
using parent::cwiseAbs;
|
auto operator-() const { return detail::concretize<matrix>(-base()); }
|
||||||
using parent::cwiseAbs2;
|
|
||||||
using parent::cwiseInverse;
|
auto cwiseAbs() const
|
||||||
using parent::cwiseSqrt;
|
{
|
||||||
|
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
|
// Reductions
|
||||||
using parent::lpNorm;
|
using parent::lpNorm;
|
||||||
|
|
@ -172,10 +184,26 @@ namespace rotgen
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shape modifications
|
// Shape modifications
|
||||||
using parent::adjoint;
|
auto normalized() const
|
||||||
using parent::conjugate;
|
requires(IsVectorAtCompileTime)
|
||||||
using parent::normalized;
|
{
|
||||||
using parent::transpose;
|
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
|
// In-place Shape modifications
|
||||||
using parent::adjointInPlace;
|
using parent::adjointInPlace;
|
||||||
|
|
@ -183,16 +211,79 @@ namespace rotgen
|
||||||
using parent::transposeInPlace;
|
using parent::transposeInPlace;
|
||||||
|
|
||||||
// Generators
|
// Generators
|
||||||
using parent::Constant;
|
static auto Zero() { return detail::concretize<matrix>(parent::Zero()); }
|
||||||
using parent::Identity;
|
|
||||||
using parent::Ones;
|
static auto Zero(int rows, int cols)
|
||||||
using parent::Random;
|
{
|
||||||
using parent::setConstant;
|
return detail::concretize<matrix>(parent::Zero(rows, cols));
|
||||||
using parent::setIdentity;
|
}
|
||||||
using parent::setOnes;
|
|
||||||
using parent::setRandom;
|
static auto Ones() { return detail::concretize<matrix>(parent::Ones()); }
|
||||||
using parent::setZero;
|
|
||||||
using parent::Zero;
|
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
|
auto qr_solve(auto const& rhs) const
|
||||||
{
|
{
|
||||||
|
|
@ -212,6 +303,12 @@ namespace rotgen
|
||||||
|
|
||||||
parent& base() { return static_cast<parent&>(*this); }
|
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>
|
template<typename S, int R, int C, int O, int MR, int MC>
|
||||||
ref(matrix<S, R, C, O, MR, MC>& m)
|
ref(matrix<S, R, C, O, MR, MC>& m)
|
||||||
requires(requires { parent(m.base()); })
|
requires(requires { parent(m.base()); })
|
||||||
|
|
@ -307,13 +404,14 @@ namespace rotgen
|
||||||
// Deduction Guides
|
// Deduction Guides
|
||||||
//============================================================================
|
//============================================================================
|
||||||
template<typename S, int R, int C, int O, int MR, int MC>
|
template<typename S, int R, int C, int O, int MR, int MC>
|
||||||
ref(matrix<S, R, C, O, MR, MC>&) -> ref<matrix<S>>;
|
ref(matrix<S, R, C, O, MR, MC>&) -> ref<matrix<S, R, C, O, MR, MC>>;
|
||||||
|
|
||||||
template<typename Ref, int R, int C, bool I>
|
template<typename Ref, int R, int C, bool I>
|
||||||
ref(block<Ref, R, C, I>& b) -> ref<Ref>;
|
ref(block<Ref, R, C, I>& b) -> ref<Ref>;
|
||||||
|
|
||||||
template<typename S, int R, int C, int O, int MR, int MC>
|
template<typename S, int R, int C, int O, int MR, int MC>
|
||||||
ref(matrix<S, R, C, O, MR, MC> const&) -> ref<matrix<S> const>;
|
ref(matrix<S, R, C, O, MR, MC> const&)
|
||||||
|
-> ref<matrix<S, R, C, O, MR, MC> const>;
|
||||||
|
|
||||||
template<typename Ref, int R, int C, bool I>
|
template<typename Ref, int R, int C, bool I>
|
||||||
ref(block<Ref, R, C, I> const& b) -> ref<Ref const>;
|
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>
|
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)
|
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>
|
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>
|
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)
|
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()));
|
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>>;
|
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;
|
return ROTGEN_FWD(a);
|
||||||
}
|
|
||||||
|
|
||||||
template<concepts::eigen_compatible T> auto& base_of(T& a)
|
|
||||||
{
|
|
||||||
return a;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,46 +12,49 @@
|
||||||
namespace rotgen
|
namespace rotgen
|
||||||
{
|
{
|
||||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||||
bool operator==(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
bool operator==(ref<A, O, S> const& lhs, ref<B, P, T> const& rhs)
|
||||||
{
|
{
|
||||||
return lhs.base() == rhs.base();
|
return lhs.base() == rhs.base();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||||
bool operator!=(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
bool operator!=(ref<A, O, S> const& lhs, ref<B, P, T> const& rhs)
|
||||||
{
|
{
|
||||||
return lhs.base() != rhs.base();
|
return lhs.base() != rhs.base();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S>
|
template<typename A, int O, typename S>
|
||||||
auto operator*(std::convertible_to<typename A::value_type> auto 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;
|
return rhs * s;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||||
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());
|
return lhs.base().dot(rhs.base());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S>
|
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)
|
-> decltype(lhs * s)
|
||||||
{
|
{
|
||||||
return lhs * s;
|
return lhs * s;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S>
|
template<typename A, int O, typename S>
|
||||||
auto mul(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs)
|
auto mul(std::convertible_to<typename A::value_type> auto s,
|
||||||
-> decltype(s * rhs)
|
ref<A, O, S> const& rhs) -> decltype(s * rhs)
|
||||||
{
|
{
|
||||||
return s * rhs;
|
return s * rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, int O, typename S>
|
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)
|
-> decltype(lhs / s)
|
||||||
{
|
{
|
||||||
return lhs / s;
|
return lhs / s;
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,12 @@ namespace rotgen
|
||||||
|
|
||||||
template<concepts::entity T> struct generalize<T>
|
template<concepts::entity T> struct generalize<T>
|
||||||
{
|
{
|
||||||
static constexpr bool is_const = std::is_const_v<T>;
|
static constexpr bool is_const =
|
||||||
using base = matrix<typename T::value_type,
|
std::is_const_v<std::remove_reference_t<T>>;
|
||||||
T::RowsAtCompileTime,
|
using base = matrix<typename std::remove_cvref_t<T>::value_type,
|
||||||
T::ColsAtCompileTime,
|
std::remove_cvref_t<T>::RowsAtCompileTime,
|
||||||
T::storage_order>;
|
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>>;
|
using type = std::conditional_t<is_const, ref<base const>, ref<base>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cassert>
|
#include <rotgen/detail/assert.hpp>
|
||||||
|
|
||||||
#include <concepts>
|
#include <concepts>
|
||||||
|
|
||||||
namespace rotgen::detail
|
namespace rotgen::detail
|
||||||
|
|
@ -77,22 +78,26 @@ namespace rotgen::detail
|
||||||
|
|
||||||
if (Ref::RowsAtCompileTime == 1)
|
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;
|
rows = 1;
|
||||||
cols = in.size();
|
cols = in.size();
|
||||||
}
|
}
|
||||||
else if (Ref::ColsAtCompileTime == 1)
|
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();
|
rows = in.size();
|
||||||
cols = 1;
|
cols = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that the sizes are valid.
|
// Verify that the sizes are valid.
|
||||||
assert((Ref::RowsAtCompileTime == Dynamic) ||
|
ROTGEN_ASSERT((Ref::RowsAtCompileTime == Dynamic) ||
|
||||||
(Ref::RowsAtCompileTime == rows));
|
(Ref::RowsAtCompileTime == rows),
|
||||||
assert((Ref::ColsAtCompileTime == Dynamic) ||
|
"Incompatible static rows/cols in ref binding");
|
||||||
(Ref::ColsAtCompileTime == cols));
|
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
|
// Swap stride if we are a vector and we changed rows as such
|
||||||
bool transpose = Ref::IsVectorAtCompileTime && (rows != in.rows());
|
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,
|
using type = Wrapper<typename EigenType::value_type,
|
||||||
EigenType::RowsAtCompileTime,
|
EigenType::RowsAtCompileTime,
|
||||||
EigenType::ColsAtCompileTime,
|
EigenType::ColsAtCompileTime,
|
||||||
EigenType::Flags & 1,
|
EigenType::IsRowMajor ? RowMajor : ColMajor,
|
||||||
EigenType::MaxRowsAtCompileTime,
|
EigenType::MaxRowsAtCompileTime,
|
||||||
EigenType::MaxColsAtCompileTime>;
|
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 ni,
|
||||||
[[maybe_unused]] Index nj)
|
[[maybe_unused]] Index nj)
|
||||||
{
|
{
|
||||||
assert(i0 >= 0 && "block extraction uses negative row index.");
|
ROTGEN_ASSERT(i0 >= 0, "block extraction uses negative row index.");
|
||||||
assert(j0 >= 0 && "block extraction uses negative col index.");
|
ROTGEN_ASSERT(j0 >= 0, "block extraction uses negative col index.");
|
||||||
assert(i0 + ni <= e.rows() && "block extraction rows is out of range.");
|
ROTGEN_ASSERT(i0 + ni <= e.rows(),
|
||||||
assert(j0 + nj <= e.cols() && "block extraction cols is out of range.");
|
"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
|
#pragma once
|
||||||
|
|
||||||
|
#include <rotgen/detail/assert.hpp>
|
||||||
#include <rotgen/detail/helpers.hpp>
|
#include <rotgen/detail/helpers.hpp>
|
||||||
|
|
||||||
namespace rotgen
|
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
|
// Generators
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,10 @@
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <rotgen/detail/product.hpp>
|
||||||
|
|
||||||
#include <rotgen/concepts.hpp>
|
#include <rotgen/concepts.hpp>
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
|
||||||
namespace rotgen
|
namespace rotgen
|
||||||
|
|
@ -80,30 +81,27 @@ namespace rotgen
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------
|
||||||
// Compounds operators across types
|
// Compounds operators across types
|
||||||
template<typename A, typename B>
|
template<concepts::entity A, concepts::entity B>
|
||||||
auto operator+=(A& a, B const& b)
|
decltype(auto) operator+=(A&& a, B const& b)
|
||||||
requires(concepts::entity<A> && concepts::entity<B>)
|
requires(!concepts::block<A>)
|
||||||
{
|
{
|
||||||
if constexpr (!use_expression_templates)
|
generalize_t<A>(ROTGEN_FWD(a)) += generalize_t<B const>(b);
|
||||||
return generalize_t<A>(a) += generalize_t<B const>(b);
|
return ROTGEN_FWD(a);
|
||||||
else return base_of(a) += base_of(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, typename B>
|
template<concepts::entity A, concepts::entity B>
|
||||||
auto operator-=(A& a, B const& b)
|
decltype(auto) operator-=(A&& a, B const& b)
|
||||||
requires(concepts::entity<A> && concepts::entity<B>)
|
requires(!concepts::block<A>)
|
||||||
{
|
{
|
||||||
if constexpr (!use_expression_templates)
|
generalize_t<A>(ROTGEN_FWD(a)) -= generalize_t<B const>(b);
|
||||||
return generalize_t<A>(a) -= generalize_t<B const>(b);
|
return ROTGEN_FWD(a);
|
||||||
else return base_of(a) -= base_of(b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename A, typename B>
|
template<concepts::entity A, concepts::entity B>
|
||||||
auto operator*=(A& a, B const& b)
|
decltype(auto) operator*=(A&& a, B const& b)
|
||||||
requires(concepts::entity<A> && concepts::entity<B>)
|
requires(!concepts::block<A>)
|
||||||
{
|
{
|
||||||
if constexpr (!use_expression_templates)
|
generalize_t<A>(ROTGEN_FWD(a)) *= generalize_t<B const>(b);
|
||||||
return generalize_t<A>(a) *= generalize_t<B const>(b);
|
return ROTGEN_FWD(a);
|
||||||
else return base_of(a) *= base_of(b);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,30 +10,38 @@
|
||||||
#define STORAGE_ORDER Eigen::ColMajor
|
#define STORAGE_ORDER Eigen::ColMajor
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
#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 TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
||||||
|
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
||||||
#include "model.cpp"
|
#include "model.cpp"
|
||||||
#undef CLASSNAME
|
#undef CLASSNAME
|
||||||
|
#undef CLASSCONSTNAME
|
||||||
#undef TRANSNAME
|
#undef TRANSNAME
|
||||||
#undef TRANSCLASSNAME
|
#undef TRANSCLASSNAME
|
||||||
#undef SOURCENAME
|
#undef SOURCENAME
|
||||||
#undef MAPNAME
|
#undef MAPNAME
|
||||||
|
#undef TRANSMAPNAME
|
||||||
#undef STORAGE_ORDER
|
#undef STORAGE_ORDER
|
||||||
|
|
||||||
#define STORAGE_ORDER Eigen::RowMajor
|
#define STORAGE_ORDER Eigen::RowMajor
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
#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 TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
||||||
|
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
||||||
#include "model.cpp"
|
#include "model.cpp"
|
||||||
#undef CLASSNAME
|
#undef CLASSNAME
|
||||||
|
#undef CLASSCONSTNAME
|
||||||
#undef TRANSNAME
|
#undef TRANSNAME
|
||||||
#undef TRANSCLASSNAME
|
#undef TRANSCLASSNAME
|
||||||
#undef SOURCENAME
|
#undef SOURCENAME
|
||||||
#undef MAPNAME
|
#undef MAPNAME
|
||||||
|
#undef TRANSMAPNAME
|
||||||
#undef STORAGE_ORDER
|
#undef STORAGE_ORDER
|
||||||
|
|
||||||
#undef SIZE
|
#undef SIZE
|
||||||
|
|
@ -44,30 +52,38 @@
|
||||||
#define STORAGE_ORDER Eigen::ColMajor
|
#define STORAGE_ORDER Eigen::ColMajor
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
#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 TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
||||||
|
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
||||||
#include "model.cpp"
|
#include "model.cpp"
|
||||||
#undef CLASSNAME
|
#undef CLASSNAME
|
||||||
|
#undef CLASSCONSTNAME
|
||||||
#undef TRANSNAME
|
#undef TRANSNAME
|
||||||
#undef TRANSCLASSNAME
|
#undef TRANSCLASSNAME
|
||||||
#undef SOURCENAME
|
#undef SOURCENAME
|
||||||
#undef MAPNAME
|
#undef MAPNAME
|
||||||
|
#undef TRANSMAPNAME
|
||||||
#undef STORAGE_ORDER
|
#undef STORAGE_ORDER
|
||||||
|
|
||||||
#define STORAGE_ORDER Eigen::RowMajor
|
#define STORAGE_ORDER Eigen::RowMajor
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
#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 TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
||||||
|
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
||||||
#include "model.cpp"
|
#include "model.cpp"
|
||||||
#undef CLASSNAME
|
#undef CLASSNAME
|
||||||
|
#undef CLASSCONSTNAME
|
||||||
#undef TRANSNAME
|
#undef TRANSNAME
|
||||||
#undef TRANSCLASSNAME
|
#undef TRANSCLASSNAME
|
||||||
#undef SOURCENAME
|
#undef SOURCENAME
|
||||||
#undef MAPNAME
|
#undef MAPNAME
|
||||||
|
#undef TRANSMAPNAME
|
||||||
#undef STORAGE_ORDER
|
#undef STORAGE_ORDER
|
||||||
|
|
||||||
#undef SIZE
|
#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
|
// We're building a block from a block - So we have to dig around the internals
|
||||||
CLASSNAME::CLASSNAME(
|
CLASSNAME::CLASSNAME(
|
||||||
TRANSCLASSNAME CONST& p, Index i0, Index j0, Index ni, Index nj)
|
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)
|
#if !defined(USE_CONST)
|
||||||
TYPE& CLASSNAME::operator()(Index index)
|
TYPE& CLASSNAME::operator()(Index index)
|
||||||
{
|
{
|
||||||
TYPE* ptr = nullptr;
|
auto r = rows() == 1 ? 0 : index;
|
||||||
storage_->apply([&](auto& blk) { ptr = blk.data() + index; });
|
auto c = cols() == 1 ? 0 : index;
|
||||||
return *ptr;
|
return (*this)(r, c);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TYPE CLASSNAME::operator()(Index index) const
|
TYPE CLASSNAME::operator()(Index index) const
|
||||||
{
|
{
|
||||||
TYPE ptr;
|
auto r = rows() == 1 ? 0 : index;
|
||||||
storage_->apply([&](auto const& blk) { ptr = *(blk.data() + index); });
|
auto c = cols() == 1 ? 0 : index;
|
||||||
return ptr;
|
return (*this)(r, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Raw pointer access
|
// Raw pointer access
|
||||||
|
|
@ -448,6 +454,28 @@ CLASSNAME& CLASSNAME::operator+=(CLASSNAME const& rhs)
|
||||||
return *this;
|
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)
|
CLASSNAME& CLASSNAME::operator-=(CLASSNAME const& rhs)
|
||||||
{
|
{
|
||||||
std::visit(
|
std::visit(
|
||||||
|
|
@ -456,6 +484,28 @@ CLASSNAME& CLASSNAME::operator-=(CLASSNAME const& rhs)
|
||||||
return *this;
|
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)
|
CLASSNAME& CLASSNAME::operator*=(CLASSNAME const& rhs)
|
||||||
{
|
{
|
||||||
std::visit(
|
std::visit(
|
||||||
|
|
@ -464,6 +514,28 @@ CLASSNAME& CLASSNAME::operator*=(CLASSNAME const& rhs)
|
||||||
return *this;
|
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)
|
CLASSNAME& CLASSNAME::operator*=(TYPE s)
|
||||||
{
|
{
|
||||||
storage_->apply([&](auto& blk) { blk *= s; });
|
storage_->apply([&](auto& blk) { blk *= s; });
|
||||||
|
|
|
||||||
|
|
@ -11,29 +11,41 @@
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
#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 TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||||
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
|
#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)
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||||
#include "model.cpp"
|
#include "model.cpp"
|
||||||
#undef CLASSNAME
|
#undef CLASSNAME
|
||||||
#undef TRANSCLASSNAME
|
#undef TRANSCLASSNAME
|
||||||
|
#undef TRANSCLASSCONSTNAME
|
||||||
|
#undef TRANSCLASSNONCONSTNAME
|
||||||
#undef TRANSSOURCENAME
|
#undef TRANSSOURCENAME
|
||||||
#undef CLASSCONSTNAME
|
#undef CLASSCONSTNAME
|
||||||
|
#undef CLASSNONCONSTNAME
|
||||||
#undef SOURCENAME
|
#undef SOURCENAME
|
||||||
#undef STORAGE_ORDER
|
#undef STORAGE_ORDER
|
||||||
|
|
||||||
#define STORAGE_ORDER Eigen::RowMajor
|
#define STORAGE_ORDER Eigen::RowMajor
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
#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 TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||||
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
|
#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)
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||||
#include "model.cpp"
|
#include "model.cpp"
|
||||||
#undef CLASSNAME
|
#undef CLASSNAME
|
||||||
#undef TRANSCLASSNAME
|
#undef TRANSCLASSNAME
|
||||||
|
#undef TRANSCLASSCONSTNAME
|
||||||
|
#undef TRANSCLASSNONCONSTNAME
|
||||||
#undef TRANSSOURCENAME
|
#undef TRANSSOURCENAME
|
||||||
#undef SOURCENAME
|
#undef SOURCENAME
|
||||||
#undef CLASSCONSTNAME
|
#undef CLASSCONSTNAME
|
||||||
|
#undef CLASSNONCONSTNAME
|
||||||
#undef STORAGE_ORDER
|
#undef STORAGE_ORDER
|
||||||
|
|
||||||
#undef SIZE
|
#undef SIZE
|
||||||
|
|
@ -45,28 +57,40 @@
|
||||||
|
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
#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 TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||||
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
|
#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)
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||||
#include "model.cpp"
|
#include "model.cpp"
|
||||||
#undef CLASSNAME
|
#undef CLASSNAME
|
||||||
#undef TRANSCLASSNAME
|
#undef TRANSCLASSNAME
|
||||||
|
#undef TRANSCLASSCONSTNAME
|
||||||
|
#undef TRANSCLASSNONCONSTNAME
|
||||||
#undef TRANSSOURCENAME
|
#undef TRANSSOURCENAME
|
||||||
#undef CLASSCONSTNAME
|
#undef CLASSCONSTNAME
|
||||||
|
#undef CLASSNONCONSTNAME
|
||||||
#undef SOURCENAME
|
#undef SOURCENAME
|
||||||
#undef STORAGE_ORDER
|
#undef STORAGE_ORDER
|
||||||
|
|
||||||
#define STORAGE_ORDER Eigen::RowMajor
|
#define STORAGE_ORDER Eigen::RowMajor
|
||||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
#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 TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||||
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
|
#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)
|
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||||
#include "model.cpp"
|
#include "model.cpp"
|
||||||
#undef CLASSNAME
|
#undef CLASSNAME
|
||||||
#undef TRANSCLASSNAME
|
#undef TRANSCLASSNAME
|
||||||
|
#undef TRANSCLASSCONSTNAME
|
||||||
|
#undef TRANSCLASSNONCONSTNAME
|
||||||
#undef TRANSSOURCENAME
|
#undef TRANSSOURCENAME
|
||||||
#undef CLASSCONSTNAME
|
#undef CLASSCONSTNAME
|
||||||
|
#undef CLASSNONCONSTNAME
|
||||||
#undef SOURCENAME
|
#undef SOURCENAME
|
||||||
#undef STORAGE_ORDER
|
#undef STORAGE_ORDER
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -239,12 +239,22 @@ void CLASSNAME::adjointInPlace()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TYPE CLASSNAME::dot(CLASSNAME const& rhs) const
|
TYPE CLASSNAME::dot(CLASSNONCONSTNAME const& rhs) const
|
||||||
{
|
{
|
||||||
return storage_->data.reshaped().dot(rhs.storage()->data.reshaped());
|
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());
|
return storage_->data.reshaped().dot(rhs.storage()->data.reshaped());
|
||||||
}
|
}
|
||||||
|
|
@ -378,7 +388,7 @@ SOURCENAME CLASSNAME::operator-() const
|
||||||
#if !defined(USE_CONST)
|
#if !defined(USE_CONST)
|
||||||
CLASSNAME& CLASSNAME::operator+=(CLASSNAME const& rhs)
|
CLASSNAME& CLASSNAME::operator+=(CLASSNAME const& rhs)
|
||||||
{
|
{
|
||||||
storage_->data += rhs.storage_->data;
|
storage_->data += rhs.storage()->data;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -388,9 +398,21 @@ CLASSNAME& CLASSNAME::operator+=(CLASSCONSTNAME const& rhs)
|
||||||
return *this;
|
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)
|
CLASSNAME& CLASSNAME::operator-=(CLASSNAME const& rhs)
|
||||||
{
|
{
|
||||||
storage_->data -= rhs.storage_->data;
|
storage_->data -= rhs.storage()->data;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -400,9 +422,21 @@ CLASSNAME& CLASSNAME::operator-=(CLASSCONSTNAME const& rhs)
|
||||||
return *this;
|
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)
|
CLASSNAME& CLASSNAME::operator*=(CLASSNAME const& rhs)
|
||||||
{
|
{
|
||||||
storage_->data *= rhs.storage_->data;
|
storage_->data *= rhs.storage()->data;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -412,6 +446,18 @@ CLASSNAME& CLASSNAME::operator*=(CLASSCONSTNAME const& rhs)
|
||||||
return *this;
|
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)
|
CLASSNAME& CLASSNAME::operator*=(TYPE s)
|
||||||
{
|
{
|
||||||
storage_->data *= 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 r = 0; r < 4; r++)
|
||||||
for (rotgen::Index c = 0; c < 3; c++) TTS_EQUAL(sliced(r, c), 5.f);
|
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"
|
#include "unit/tests.hpp"
|
||||||
|
|
||||||
TTS_CASE_TPL("SVD decomposition - Dynamic case",
|
TTS_CASE_TPL("SVD decomposition - Dynamic case", rotgen::tests::types)
|
||||||
rotgen::tests::types)<typename T, typename O>(
|
|
||||||
tts::type<tts::types<T, O>>)
|
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
int rank, i = 5;
|
int rank, i = 5;
|
||||||
auto eps = std::numeric_limits<T>::epsilon();
|
auto eps = std::numeric_limits<T>::epsilon();
|
||||||
|
|
@ -24,10 +24,10 @@ TTS_CASE_TPL("SVD decomposition - Dynamic case",
|
||||||
{
|
{
|
||||||
rank = decomp.rank();
|
rank = decomp.rank();
|
||||||
|
|
||||||
auto u = decomp.U(rank);
|
auto u = decomp.matrixU(rank);
|
||||||
auto d = decomp.singular_values(rank);
|
auto d = decomp.singularValues(rank);
|
||||||
auto dd = decomp.D(rank);
|
auto dd = decomp.matrixD(rank);
|
||||||
auto v = decomp.V(rank);
|
auto v = decomp.matrixV(rank);
|
||||||
|
|
||||||
TTS_EQUAL(rank, i);
|
TTS_EQUAL(rank, i);
|
||||||
|
|
||||||
|
|
@ -48,9 +48,9 @@ TTS_CASE_TPL("SVD decomposition - Dynamic case",
|
||||||
} while (rank != 1);
|
} while (rank != 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
TTS_CASE_TPL("SVD decomposition - Static case",
|
TTS_CASE_TPL("SVD decomposition - Static case", rotgen::tests::types)
|
||||||
rotgen::tests::types)<typename T, typename O>(
|
|
||||||
tts::type<tts::types<T, O>>)
|
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||||
{
|
{
|
||||||
int rank, i = 5;
|
int rank, i = 5;
|
||||||
auto eps = std::numeric_limits<T>::epsilon();
|
auto eps = std::numeric_limits<T>::epsilon();
|
||||||
|
|
@ -62,10 +62,10 @@ TTS_CASE_TPL("SVD decomposition - Static case",
|
||||||
{
|
{
|
||||||
rank = decomp.rank();
|
rank = decomp.rank();
|
||||||
|
|
||||||
auto u = decomp.U(rank);
|
auto u = decomp.matrixU(rank);
|
||||||
auto d = decomp.singular_values(rank);
|
auto d = decomp.singularValues(rank);
|
||||||
auto dd = decomp.D(rank);
|
auto dd = decomp.matrixD(rank);
|
||||||
auto v = decomp.V(rank);
|
auto v = decomp.matrixV(rank);
|
||||||
|
|
||||||
TTS_EQUAL(rank, i);
|
TTS_EQUAL(rank, i);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue