More specific fixes

See merge request oss/rotgen!47
This commit is contained in:
Joel Falcou 2025-12-02 14:40:01 +01:00
parent 083ada097e
commit 8e80d1d083
34 changed files with 1171 additions and 416 deletions

View file

@ -25,20 +25,20 @@ namespace rotgen
int rank() const { return parent::rank(); }
m_type U() const { return parent::U(); }
m_type matrixU() const { return parent::U(); }
m_type D() const { return parent::D(); }
m_type matrixD() const { return parent::D(); }
m_type V() const { return parent::V(); }
m_type matrixV() const { return parent::V(); }
d_type singular_values() const { return parent::singular_values(); }
d_type singularValues() const { return parent::singular_values(); }
m_type U(int r) const { return parent::U(r); }
m_type matrixU(int r) const { return parent::U(r); }
m_type D(int r) const { return parent::D(r); }
m_type matrixD(int r) const { return parent::D(r); }
m_type V(int r) const { return parent::V(r); }
m_type matrixV(int r) const { return parent::V(r); }
m_type singular_values(int r) const { return parent::singular_values(r); }
m_type singularValues(int r) const { return parent::singular_values(r); }
};
}

View file

@ -31,28 +31,28 @@ namespace rotgen
int rank() const { return svd_.rank(); }
auto singular_values() const
auto singularValues() const
{
if constexpr (!use_expression_templates)
return detail::as_concrete_t<d_type, matrix>{svd_.singularValues()};
else return svd_.singularValues();
}
auto U() const
auto matrixU() const
{
if constexpr (!use_expression_templates)
return detail::as_concrete_t<u_type, matrix>{svd_.matrixU()};
else return svd_.matrixU();
}
auto V() const
auto matrixV() const
{
if constexpr (!use_expression_templates)
return detail::as_concrete_t<v_type, matrix>{svd_.matrixV()};
else return svd_.matrixV();
}
auto D() const
auto matrixD() const
{
auto d = svd_.singularValues().asDiagonal();
if constexpr (!use_expression_templates)
@ -61,7 +61,7 @@ namespace rotgen
else return d;
}
auto singular_values(int r) const
auto singularValues(int r) const
{
auto that = svd_.singularValues().head(r);
if constexpr (!use_expression_templates)
@ -69,7 +69,7 @@ namespace rotgen
else return svd_.singularValues();
}
auto U(int r) const
auto matrixU(int r) const
{
auto that = svd_.matrixU().leftCols(r);
if constexpr (!use_expression_templates)
@ -77,7 +77,7 @@ namespace rotgen
else return that;
}
auto V(int r) const
auto matrixV(int r) const
{
auto that = svd_.matrixV().leftCols(r);
if constexpr (!use_expression_templates)
@ -85,7 +85,7 @@ namespace rotgen
else return that;
}
auto D(int r) const
auto matrixD(int r) const
{
auto d = svd_.singularValues().head(r).asDiagonal();
if constexpr (!use_expression_templates)

View file

@ -12,6 +12,26 @@
namespace rotgen::concepts
{
//================================================================================================
//! @brief Check if a type is a Rotgen block.
//================================================================================================
template<typename T>
concept block =
requires { typename std::remove_cvref_t<T>::rotgen_block_tag; };
//================================================================================================
//! @brief Check if a type is a Rotgen matrix.
//================================================================================================
template<typename T>
concept matrix =
requires { typename std::remove_cvref_t<T>::rotgen_matrix_tag; };
//================================================================================================
//! @brief Check if a type is a Rotgen map.
//================================================================================================
template<typename T>
concept map = requires { typename std::remove_cvref_t<T>::rotgen_map_tag; };
//================================================================================================
//! @brief Check if a type is a Rotgen reference.
//================================================================================================
@ -36,10 +56,8 @@ namespace rotgen::concepts
//! @brief Check if a type is a ROTGEN type.
//================================================================================================
template<typename T>
concept entity = requires(T const&) {
typename std::remove_cvref_t<T>::rotgen_tag;
typename std::remove_cvref_t<T>::parent;
};
concept entity =
requires(T const&) { typename std::remove_cvref_t<T>::rotgen_tag; };
//================================================================================================
//! @brief Check if a type is an EIGEN type.

View file

@ -7,11 +7,12 @@
//==================================================================================================
#pragma once
#include <rotgen/detail/assert.hpp>
#include <rotgen/concepts.hpp>
#include <rotgen/container/block/dynamic/impl.hpp>
#include <rotgen/container/matrix/dynamic.hpp>
#include <cassert>
#include <initializer_list>
namespace rotgen
@ -76,14 +77,37 @@ namespace rotgen
using parent::operator=;
block& operator=(concepts::entity auto const& other)
template<concepts::entity Src>
block& operator=(Src const& other)
requires(!is_immutable)
{
assert(parent::rows() == other.rows() && parent::cols() == other.cols());
for (rotgen::Index r = 0; r < parent::rows(); ++r)
for (rotgen::Index c = 0; c < parent::cols(); ++c)
(*this)(r, c) = other(r, c);
if constexpr (IsVectorAtCompileTime && Src::IsVectorAtCompileTime)
{
ROTGEN_ASSERT(parent::size() == other.size(),
"Block assignment from 1D source doesn't match size");
for (rotgen::Index i = 0; i < parent::size(); ++i)
(*this)[i] = other[i];
}
else if constexpr (IsVectorAtCompileTime && !Src::IsVectorAtCompileTime)
{
auto r = other.rows();
auto c = other.cols();
ROTGEN_ASSERT((r == 1 || c == 1), "Block assignment from dynamic sized "
"source doesn't match static size");
for (rotgen::Index i = 0; i < parent::size(); ++i)
(*this)[i] = other(r == 1 ? 0 : i, c == 1 ? 0 : i);
}
else
{
ROTGEN_ASSERT(parent::rows() == other.rows() &&
parent::cols() == other.cols(),
"Block assignment size mismatch");
for (rotgen::Index r = 0; r < parent::rows(); ++r)
for (rotgen::Index c = 0; c < parent::cols(); ++c)
(*this)(r, c) = other(r, c);
}
return *this;
}
@ -167,13 +191,6 @@ namespace rotgen
block(parent const& base) : parent(base) {}
bool is_contiguous_linear() const
{
if (parent::innerStride() != 1) return false;
if constexpr (IsRowMajor) return parent::outerStride() == parent::cols();
else return parent::outerStride() == parent::rows();
}
value_type& operator()(Index i, Index j)
requires(!is_immutable)
{
@ -183,7 +200,6 @@ namespace rotgen
value_type& operator()(Index i)
requires(!is_immutable && IsVectorAtCompileTime)
{
assert(is_contiguous_linear());
return parent::operator()(i);
}
@ -201,7 +217,6 @@ namespace rotgen
value_type operator()(Index i) const
requires(IsVectorAtCompileTime)
{
assert(is_contiguous_linear());
return parent::operator()(i);
}
@ -211,7 +226,7 @@ namespace rotgen
return (*this)(i);
}
auto evaluate() const { return *this; }
concrete_type evaluate() const { return concrete_type{*this}; }
decltype(auto) noalias() const { return *this; }
@ -278,17 +293,19 @@ namespace rotgen
return static_cast<parent const&>(lhs) == static_cast<parent const&>(rhs);
}
block& operator+=(block const& rhs)
template<concepts::entity E>
block& operator+=(E const& rhs)
requires(!is_immutable)
{
base() += static_cast<parent const&>(rhs);
base() += rhs.base();
return *this;
}
block& operator-=(block const& rhs)
template<concepts::entity E>
block& operator-=(E const& rhs)
requires(!is_immutable)
{
base() -= static_cast<parent const&>(rhs);
base() -= rhs.base();
return *this;
}
@ -297,10 +314,11 @@ namespace rotgen
return concrete_type(static_cast<parent const&>(*this).operator-());
}
block& operator*=(block const& rhs)
template<concepts::entity E>
block& operator*=(E const& rhs)
requires(!is_immutable)
{
base() *= static_cast<parent const&>(rhs);
base() *= rhs.base();
return *this;
}
@ -351,11 +369,11 @@ namespace rotgen
static concrete_type Zero(int rows, int cols)
{
if constexpr (Rows != -1)
assert(rows == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(cols == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Zero(rows, cols);
}
@ -368,11 +386,11 @@ namespace rotgen
static concrete_type Ones(int rows, int cols)
{
if constexpr (Rows != -1)
assert(rows == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(cols == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Ones(rows, cols);
}
@ -385,11 +403,11 @@ namespace rotgen
static concrete_type Constant(int rows, int cols, value_type value)
{
if constexpr (Rows != -1)
assert(rows == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(cols == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Constant(rows, cols, static_cast<double>(value));
}
@ -402,11 +420,11 @@ namespace rotgen
static concrete_type Random(int rows, int cols)
{
if constexpr (Rows != -1)
assert(rows == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(cols == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Random(rows, cols);
}
@ -419,11 +437,11 @@ namespace rotgen
static concrete_type Identity(int rows, int cols)
{
if constexpr (Rows != -1)
assert(rows == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(cols == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Identity(rows, cols);
}
@ -464,7 +482,7 @@ namespace rotgen
template<int P> value_type lpNorm() const
{
assert(P == 1 || P == 2 || P == Infinity);
static_assert(P == 1 || P == 2 || P == Infinity);
return parent::lpNorm(P);
}

View file

@ -2,28 +2,36 @@
#define TYPE double
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _col)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
#include <rotgen/container/block/dynamic/model.hpp>
#undef CLASSNAME
#undef CLASSCONSTNAME
#undef TRANSCLASSNAME
#undef TRANSNAME
#undef SOURCENAME
#undef MAPNAME
#undef TRANSMAPNAME
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _row)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
#include <rotgen/container/block/dynamic/model.hpp>
#undef CLASSNAME
#undef CLASSCONSTNAME
#undef TRANSCLASSNAME
#undef TRANSNAME
#undef SOURCENAME
#undef MAPNAME
#undef TRANSMAPNAME
#undef SIZE
#undef TYPE
@ -32,28 +40,36 @@
#define TYPE float
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _col)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
#include <rotgen/container/block/dynamic/model.hpp>
#undef CLASSNAME
#undef CLASSCONSTNAME
#undef TRANSCLASSNAME
#undef TRANSNAME
#undef SOURCENAME
#undef MAPNAME
#undef TRANSMAPNAME
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _row)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
#include <rotgen/container/block/dynamic/model.hpp>
#undef CLASSNAME
#undef CLASSCONSTNAME
#undef TRANSCLASSNAME
#undef TRANSNAME
#undef SOURCENAME
#undef MAPNAME
#undef TRANSMAPNAME
#undef SIZE
#undef TYPE

View file

@ -23,6 +23,7 @@ public:
CLASSNAME(MAPNAME CONST& r, Index i0, Index j0, Index ni, Index nj);
CLASSNAME(CLASSNAME CONST& r, Index i0, Index j0, Index ni, Index nj);
CLASSNAME(TRANSCLASSNAME CONST& r, Index i0, Index j0, Index ni, Index nj);
CLASSNAME(TRANSMAPNAME CONST& r, Index i0, Index j0, Index ni, Index nj);
CLASSNAME(CLASSNAME const& other);
CLASSNAME(CLASSNAME&&) noexcept;
@ -81,8 +82,17 @@ public:
TYPE& operator()(Index i, Index j);
TYPE& operator()(Index index);
CLASSNAME& operator+=(CLASSNAME const& rhs);
CLASSNAME& operator+=(CLASSCONSTNAME const& rhs);
CLASSNAME& operator+=(SOURCENAME const& rhs);
CLASSNAME& operator+=(TRANSNAME const& rhs);
CLASSNAME& operator-=(CLASSNAME const& rhs);
CLASSNAME& operator-=(CLASSCONSTNAME const& rhs);
CLASSNAME& operator-=(SOURCENAME const& rhs);
CLASSNAME& operator-=(TRANSNAME const& rhs);
CLASSNAME& operator*=(CLASSNAME const& rhs);
CLASSNAME& operator*=(CLASSCONSTNAME const& rhs);
CLASSNAME& operator*=(SOURCENAME const& rhs);
CLASSNAME& operator*=(TRANSNAME const& rhs);
CLASSNAME& operator*=(TYPE d);
CLASSNAME& operator/=(TYPE d);
#endif

View file

@ -193,11 +193,7 @@ namespace rotgen
parent const& base() const { return static_cast<parent const&>(*this); }
auto evaluate() const
{
auto res = base().eval();
return as_concrete_type<decltype(res)>(res);
}
auto evaluate() const { return concrete_type(base().eval()); }
decltype(auto) noalias() const
{
@ -298,11 +294,11 @@ namespace rotgen
static concrete_type Constant(int rows, int cols, value_type value)
{
if constexpr (Rows != -1)
assert(rows == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(cols == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Constant(rows, cols, static_cast<value_type>(value));
}
@ -315,11 +311,11 @@ namespace rotgen
static concrete_type Identity(int rows, int cols)
{
if constexpr (Rows != -1)
assert(rows == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(cols == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Identity(rows, cols);
}
@ -332,11 +328,11 @@ namespace rotgen
static concrete_type Zero(int rows, int cols)
{
if constexpr (Rows != -1)
assert(rows == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(cols == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Zero(rows, cols);
}
@ -349,11 +345,11 @@ namespace rotgen
static concrete_type Ones(int rows, int cols)
{
if constexpr (Rows != -1)
assert(rows == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(cols == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Ones(rows, cols);
}
@ -366,11 +362,11 @@ namespace rotgen
static concrete_type Random(int rows, int cols)
{
if constexpr (Rows != -1)
assert(rows == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(cols == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Random(rows, cols);
}
@ -523,17 +519,19 @@ namespace rotgen
Index startCol() const { return base().startCol(); }
block& operator+=(block const& rhs)
template<concepts::entity E>
block& operator+=(E const& rhs)
requires(!is_immutable)
{
static_cast<parent&>(*this) += static_cast<parent const&>(rhs);
base() += rhs.base();
return *this;
}
block& operator-=(block const& rhs)
template<concepts::entity E>
block& operator-=(E const& rhs)
requires(!is_immutable)
{
static_cast<parent&>(*this) -= static_cast<parent const&>(rhs);
base() -= rhs.base();
return *this;
}
@ -542,10 +540,11 @@ namespace rotgen
return concrete_type(static_cast<parent const&>(*this).operator-());
}
block& operator*=(block const& rhs)
template<concepts::entity E>
block& operator*=(E const& rhs)
requires(!is_immutable)
{
static_cast<parent&>(*this) *= static_cast<parent const&>(rhs);
base() *= rhs.base();
return *this;
}

View file

@ -7,14 +7,14 @@
//==================================================================================================
#pragma once
#include <rotgen/detail/assert.hpp>
#include <rotgen/detail/helpers.hpp>
#include <rotgen/detail/product.hpp>
#include <rotgen/concepts.hpp>
#include <rotgen/container/map/dynamic/impl.hpp>
#include <rotgen/container/matrix.hpp>
#include <cassert>
namespace rotgen
{
namespace detail
@ -35,6 +35,7 @@ namespace rotgen
using parent = find_map<Ref>;
using rotgen_tag = void;
using rotgen_map_tag = void;
using value_type = typename std::remove_const_t<Ref>::value_type;
using concrete_type = typename std::remove_const_t<Ref>::concrete_type;
@ -52,6 +53,7 @@ namespace rotgen
static constexpr int ColsAtCompileTime = Ref::ColsAtCompileTime;
static constexpr int MaxRowsAtCompileTime = Ref::MaxRowsAtCompileTime;
static constexpr int MaxColsAtCompileTime = Ref::MaxColsAtCompileTime;
static constexpr int SizeAtCompileTime = Ref::SizeAtCompileTime;
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
static constexpr bool is_defined_static =
RowsAtCompileTime != -1 && ColsAtCompileTime != -1;
@ -75,12 +77,12 @@ namespace rotgen
: parent(ptr, r, c, strides<storage_order>(s, r, c))
{
if constexpr (RowsAtCompileTime != -1)
assert(r == RowsAtCompileTime &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(r == RowsAtCompileTime,
"Mismatched between dynamic and static row size");
if constexpr (ColsAtCompileTime != -1)
assert(c == ColsAtCompileTime &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(c == ColsAtCompileTime,
"Mismatched between dynamic and static column size");
}
// Used to properly delay ref dynamic construction
@ -135,24 +137,50 @@ namespace rotgen
map(map const& other) : parent(other) {}
map(map&& other) : parent(std::move(other)) {}
map& operator=(map const& other)
requires(!is_immutable)
{
base() = static_cast<parent const&>(other);
base() = other.base();
return *this;
}
map& operator=(concepts::entity auto const& other)
map& operator=(map&& other)
requires(!is_immutable)
{
assert(parent::rows() == other.rows() && parent::cols() == other.cols());
if constexpr (IsVectorAtCompileTime)
base() = std::move(other.base());
return *this;
}
template<concepts::entity Src>
map& operator=(Src const& other)
requires(!is_immutable)
{
if constexpr (IsVectorAtCompileTime && Src::IsVectorAtCompileTime)
{
ROTGEN_ASSERT(parent::size() == other.size(),
"Map assignment from 1D source doesn't match size");
for (rotgen::Index i = 0; i < parent::size(); ++i)
(*this)(i) = other(i);
(*this)[i] = other[i];
}
else if constexpr (IsVectorAtCompileTime && !Src::IsVectorAtCompileTime)
{
auto r = other.rows();
auto c = other.cols();
ROTGEN_ASSERT(
(r == 1 || c == 1),
"Map assignment from dynamic sized source doesn't match static size");
for (rotgen::Index i = 0; i < parent::size(); ++i)
(*this)[i] = other(r == 1 ? 0 : i, c == 1 ? 0 : i);
}
else
{
ROTGEN_ASSERT(parent::rows() == other.rows() &&
parent::cols() == other.cols(),
"Map assignment size mismatch");
for (rotgen::Index r = 0; r < parent::rows(); ++r)
for (rotgen::Index c = 0; c < parent::cols(); ++c)
(*this)(r, c) = other(r, c);
@ -196,7 +224,7 @@ namespace rotgen
return (*this)(i);
}
auto evaluate() const { return *this; }
concrete_type evaluate() const { return concrete_type{*this}; }
decltype(auto) noalias() const { return *this; }
@ -275,7 +303,7 @@ namespace rotgen
concrete_type cross(map const& other) const
{
concrete_type that;
if constexpr (RowsAtCompileTime == -1)
if constexpr (ColsAtCompileTime == 1)
{
that(0, 0) = (*this)(1, 0) * other(2, 0) - (*this)(2, 0) * other(1, 0);
that(1, 0) = (*this)(2, 0) * other(0, 0) - (*this)(0, 0) * other(2, 0);
@ -312,6 +340,7 @@ namespace rotgen
map& operator+=(map<R2, O2, S2> const& rhs)
requires(!is_immutable)
{
validate_compound_operator(rhs);
base() += rhs.base();
return *this;
}
@ -320,6 +349,7 @@ namespace rotgen
map& operator-=(map<R2, O2, S2> const& rhs)
requires(!is_immutable)
{
validate_compound_operator(rhs);
base() -= rhs.base();
return *this;
}
@ -333,6 +363,9 @@ namespace rotgen
map& operator*=(map<R2, O2, S2> const& rhs)
requires(!is_immutable)
{
ROTGEN_ASSERT(parent::cols() == rhs.rows() &&
parent::cols() == rhs.cols(),
"Incompatible dimensions for compound matrix-product");
base() *= rhs.base();
return *this;
}
@ -464,7 +497,7 @@ namespace rotgen
template<int P> value_type lpNorm() const
{
assert(P == 1 || P == 2 || P == Infinity);
static_assert(P == 1 || P == 2 || P == Infinity);
return parent::lpNorm(P);
}
@ -476,6 +509,32 @@ namespace rotgen
{
return concrete_type(base().qr_solve(rhs.base()));
};
template<typename R2, int O2, typename S2>
void validate_compound_operator(map<R2, O2, S2> const& rhs)
{
if constexpr (IsVectorAtCompileTime && R2::IsVectorAtCompileTime)
{
if constexpr (is_defined_static && R2::is_defined_static)
{
static_assert(
SizeAtCompileTime == R2::SizeAtCompileTime,
"Compile-time size mismatch in compound assignment operator");
}
else
{
ROTGEN_ASSERT(parent::size() == rhs.size(),
"Size mismatch in compound assignment operator");
}
}
else
{
ROTGEN_ASSERT(parent::rows() == rhs.rows(),
"Mismatched rows count in compound assignment operator");
ROTGEN_ASSERT(parent::cols() == rhs.cols(),
"Mismatched cols count in compound assignment operator");
}
}
};
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
@ -499,18 +558,20 @@ namespace rotgen
}
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
matrix<typename R1::value_type,
R1::RowsAtCompileTime,
R2::ColsAtCompileTime,
R1::storage_order>
operator*(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
auto operator*(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
{
using map1_type = map<R1 const, O1, S1>;
using map2_type = map<R2 const, O2, S2>;
using concrete_type = matrix<typename R1::value_type, R1::RowsAtCompileTime,
R2::ColsAtCompileTime, R1::storage_order>;
return concrete_type(map1_type(lhs).base().mul(map2_type(rhs).base()));
if constexpr (concrete_type::SizeAtCompileTime == 0) return concrete_type{};
else
{
auto p = concrete_type(map1_type(lhs).base().mul(map2_type(rhs).base()));
if constexpr (concrete_type::SizeAtCompileTime == 1) return product{p};
else return p;
}
}
template<typename R, int O, typename S>

View file

@ -3,27 +3,39 @@
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#include <rotgen/container/map/dynamic/model.hpp>
#undef CLASSNAME
#undef TRANSCLASSNAME
#undef TRANSCLASSCONSTNAME
#undef TRANSCLASSNONCONSTNAME
#undef TRANSSOURCENAME
#undef SOURCENAME
#undef CLASSCONSTNAME
#undef CLASSNONCONSTNAME
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#include <rotgen/container/map/dynamic/model.hpp>
#undef CLASSNAME
#undef TRANSCLASSNAME
#undef TRANSCLASSCONSTNAME
#undef TRANSCLASSNONCONSTNAME
#undef TRANSSOURCENAME
#undef SOURCENAME
#undef CLASSCONSTNAME
#undef CLASSNONCONSTNAME
#undef SIZE
#undef TYPE
@ -33,27 +45,39 @@
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#include <rotgen/container/map/dynamic/model.hpp>
#undef CLASSNAME
#undef TRANSCLASSNAME
#undef TRANSCLASSCONSTNAME
#undef TRANSCLASSNONCONSTNAME
#undef TRANSSOURCENAME
#undef SOURCENAME
#undef CLASSCONSTNAME
#undef CLASSNONCONSTNAME
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#include <rotgen/container/map/dynamic/model.hpp>
#undef CLASSNAME
#undef TRANSCLASSNAME
#undef TRANSCLASSCONSTNAME
#undef TRANSCLASSNONCONSTNAME
#undef TRANSSOURCENAME
#undef SOURCENAME
#undef CLASSCONSTNAME
#undef CLASSNONCONSTNAME
#undef SIZE
#undef TYPE

View file

@ -66,8 +66,10 @@ public:
TYPE minCoeff() const;
TYPE maxCoeff(Index*, Index*) const;
TYPE minCoeff(Index*, Index*) const;
TYPE dot(CLASSNAME const&) const;
TYPE dot(TRANSCLASSNAME const&) const;
TYPE dot(CLASSNONCONSTNAME const&) const;
TYPE dot(CLASSCONSTNAME const&) const;
TYPE dot(TRANSCLASSCONSTNAME const&) const;
TYPE dot(TRANSCLASSNONCONSTNAME const&) const;
TYPE squaredNorm() const;
TYPE norm() const;
@ -86,10 +88,16 @@ public:
#if !defined(USE_CONST)
CLASSNAME& operator+=(CLASSNAME const& rhs);
CLASSNAME& operator+=(CLASSCONSTNAME const& rhs);
CLASSNAME& operator+=(TRANSCLASSCONSTNAME const& rhs);
CLASSNAME& operator+=(TRANSCLASSNONCONSTNAME const& rhs);
CLASSNAME& operator-=(CLASSNAME const& rhs);
CLASSNAME& operator-=(CLASSCONSTNAME const& rhs);
CLASSNAME& operator-=(TRANSCLASSCONSTNAME const& rhs);
CLASSNAME& operator-=(TRANSCLASSNONCONSTNAME const& rhs);
CLASSNAME& operator*=(CLASSNAME const& rhs);
CLASSNAME& operator*=(CLASSCONSTNAME const& rhs);
CLASSNAME& operator*=(TRANSCLASSCONSTNAME const& rhs);
CLASSNAME& operator*=(TRANSCLASSNONCONSTNAME const& rhs);
CLASSNAME& operator*=(TYPE d);
CLASSNAME& operator/=(TYPE d);
#endif

View file

@ -7,6 +7,8 @@
//==================================================================================================
#pragma once
#include <rotgen/detail/product.hpp>
#include <Eigen/Dense>
#include <iostream>
@ -41,6 +43,7 @@ namespace rotgen
{
public:
using rotgen_tag = void;
using rotgen_map_tag = void;
using parent = detail::
map_type<std::remove_const_t<Ref>, Options, std::is_const_v<Ref>, Stride>;
using value_type = typename std::remove_const_t<Ref>::value_type;
@ -50,6 +53,7 @@ namespace rotgen
static constexpr int ColsAtCompileTime = Ref::ColsAtCompileTime;
static constexpr int MaxRowsAtCompileTime = Ref::MaxRowsAtCompileTime;
static constexpr int MaxColsAtCompileTime = Ref::MaxColsAtCompileTime;
static constexpr int SizeAtCompileTime = Ref::SizeAtCompileTime;
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
static constexpr bool has_static_storage = Ref::has_static_storage;
static constexpr bool IsRowMajor = Ref::IsRowMajor;
@ -112,21 +116,25 @@ namespace rotgen
return *this;
}
template<typename OtherDerived>
map& operator=(Eigen::MatrixBase<OtherDerived> const& other)
{
parent::operator=(other);
return *this;
}
template<typename OtherDerived>
map& operator=(Eigen::EigenBase<OtherDerived> const& other)
{
parent::operator=(other);
return *this;
}
parent& base() { return static_cast<parent&>(*this); }
parent const& base() const { return static_cast<parent const&>(*this); }
auto evaluate() const
{
auto res = static_cast<parent const&>(*this).eval();
return as_concrete_type<decltype(res)>(res);
}
auto evaluate()
{
auto res = static_cast<parent&>(*this).eval();
return as_concrete_type<decltype(res)>(res);
}
auto evaluate() const { return concrete_type(base().eval()); }
decltype(auto) noalias() const
{
@ -176,6 +184,7 @@ namespace rotgen
map& operator+=(map<R2, O2, S2> const& rhs)
requires(!is_immutable)
{
validate_compound_operator(rhs);
base() += rhs.base();
return *this;
}
@ -184,6 +193,7 @@ namespace rotgen
map& operator-=(map<R2, O2, S2> const& rhs)
requires(!is_immutable)
{
validate_compound_operator(rhs);
base() -= rhs.base();
return *this;
}
@ -192,6 +202,9 @@ namespace rotgen
map& operator*=(map<R2, O2, S2> const& rhs)
requires(!is_immutable)
{
ROTGEN_ASSERT(parent::cols() == rhs.rows() &&
parent::cols() == rhs.cols(),
"Incompatible dimensions for compound matrix-product");
base() *= rhs.base();
return *this;
}
@ -463,6 +476,32 @@ namespace rotgen
static_assert(P == 1 || P == 2 || P == Infinity);
return parent::template lpNorm<P>();
}
template<typename R2, int O2, typename S2>
void validate_compound_operator(map<R2, O2, S2> const& rhs)
{
if constexpr (IsVectorAtCompileTime && R2::IsVectorAtCompileTime)
{
if constexpr (is_defined_static && R2::is_defined_static)
{
static_assert(
SizeAtCompileTime == R2::SizeAtCompileTime,
"Compile-time size mismatch in compound assignment operator");
}
else
{
ROTGEN_ASSERT(parent::size() == rhs.size(),
"Size mismatch in compound assignment operator");
}
}
else
{
ROTGEN_ASSERT(parent::rows() == rhs.rows(),
"Mismatched rows count in compound assignment operator");
ROTGEN_ASSERT(parent::cols() == rhs.cols(),
"Mismatched cols count in compound assignment operator");
}
}
};
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
@ -534,13 +573,14 @@ namespace rotgen
}
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
matrix<typename R1::value_type, R1::RowsAtCompileTime, R2::ColsAtCompileTime>
operator*(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
auto operator*(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
{
using concrete_type = matrix<typename R1::value_type, R1::RowsAtCompileTime,
R2::ColsAtCompileTime>;
auto p = lhs.base() * rhs.base();
using concrete_type = detail::as_concrete_t<decltype(p), matrix>;
return concrete_type(lhs.base() * rhs.base());
if constexpr (concrete_type::SizeAtCompileTime == 1)
return product{concrete_type{p}};
else return concrete_type{p};
}
template<typename R, int O, typename S>

View file

@ -7,11 +7,12 @@
//==================================================================================================
#pragma once
#include <rotgen/detail/assert.hpp>
#include <rotgen/detail/helpers.hpp>
#include <rotgen/concepts.hpp>
#include <rotgen/container/matrix/dynamic/impl.hpp>
#include <cassert>
#include <initializer_list>
namespace rotgen
@ -27,6 +28,7 @@ namespace rotgen
public:
using parent = find_matrix<Scalar, Opts>;
using rotgen_tag = void;
using rotgen_matrix_tag = void;
using concrete_type = matrix;
using value_type = Scalar;
@ -48,29 +50,40 @@ namespace rotgen
static constexpr bool has_static_storage = false;
static constexpr bool is_immutable = false;
static constexpr int InnerStrideAtCompileTime = 1;
static constexpr int OuterStrideAtCompileTime =
IsRowMajor ? ColsAtCompileTime : RowsAtCompileTime;
static constexpr int OuterStrideAtCompileTime = IsRowMajor ? Cols : Rows;
using transposed_type = matrix<value_type, Cols, Rows, storage_order>;
matrix() : parent(Rows == -1 ? 0 : Rows, Cols == -1 ? 0 : Cols) {}
static constexpr int AllocatedRows =
Rows == -1 ? (MaxRows == -1 ? 0 : MaxRows) : Rows;
static constexpr int AllocatedCols =
Cols == -1 ? (MaxCols == -1 ? 0 : MaxCols) : Cols;
matrix() : parent(AllocatedRows, AllocatedCols) {}
matrix(Index r, Index c) : parent(r, c)
{
if constexpr (Rows != -1)
assert(r == Rows && "Mismatched between dynamic and static row size");
ROTGEN_ASSERT(r == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(c == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(c == Cols,
"Mismatched between dynamic and static column size");
}
matrix(Index n)
requires(IsVectorAtCompileTime && (Rows != 1 || Cols != 1))
: parent(Rows != -1 ? 1 : n, Cols != -1 ? 1 : n)
: parent(Rows != 1 ? n : 1, Cols != 1 ? n : 1)
{
if constexpr (Rows == 1 && Cols != -1)
ROTGEN_ASSERT(Cols == n,
"Mismatched between dynamic and static col size");
if constexpr (Cols == 1 && Rows != -1)
ROTGEN_ASSERT(Rows == n,
"Mismatched between dynamic and static row size");
}
matrix(Scalar v)
explicit matrix(Scalar v)
requires(Rows == 1 && Cols == 1)
: parent(1, 1, {v})
{
@ -89,14 +102,14 @@ namespace rotgen
: parent(init)
{
if constexpr (Rows != -1)
assert(init.size() == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(init.size() == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
{
[[maybe_unused]] Index c = 0;
if (init.size()) c = init.begin()->size();
assert(c == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(c == Cols,
"Mismatched between dynamic and static column size");
}
}
@ -106,31 +119,28 @@ namespace rotgen
{
}
matrix(concepts::entity auto const& e) : parent(e.rows(), e.cols())
template<concepts::entity Src> matrix(Src const& other) : parent()
{
if constexpr (Rows != -1)
assert(e.rows() == Rows &&
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(e.cols() == Cols &&
"Mismatched between dynamic and static col size");
for (rotgen::Index r = 0; r < e.rows(); ++r)
for (rotgen::Index c = 0; c < e.cols(); ++c) (*this)(r, c) = e(r, c);
if constexpr (IsVectorAtCompileTime && Src::IsVectorAtCompileTime)
{
resize(other.size());
for (rotgen::Index i = 0; i < parent::size(); ++i)
(*this)[i] = other[i];
}
else
{
resize(other.rows(), other.cols());
for (rotgen::Index r = 0; r < parent::rows(); ++r)
for (rotgen::Index c = 0; c < parent::cols(); ++c)
(*this)(r, c) = other(r, c);
}
}
matrix& operator=(concepts::entity auto const& e)
matrix& operator=(concepts::entity auto const& other)
{
if constexpr (Rows != -1)
assert(e.rows() == Rows &&
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(e.cols() == Cols &&
"Mismatched between dynamic and static col size");
resize(e.rows(), e.cols());
for (rotgen::Index r = 0; r < e.rows(); ++r)
for (rotgen::Index c = 0; c < e.cols(); ++c) (*this)(r, c) = e(r, c);
matrix local(other);
swap(local);
return *this;
}
@ -146,6 +156,13 @@ namespace rotgen
return (*this)(i);
}
void swap(matrix& other)
{
// TODO: Swap elements per elements if statically defined to preserve
// data location in memory as with actual statically defines matrix
base().swap(other.base());
}
auto evaluate() const { return *this; }
decltype(auto) noalias() const { return *this; }
@ -156,17 +173,22 @@ namespace rotgen
Index outerStride() const noexcept
{
return IsVectorAtCompileTime ? this->size()
: IsRowMajor ? this->cols()
: this->rows();
if constexpr (IsVectorAtCompileTime) return this->size();
else
{
if constexpr (IsRowMajor) return this->cols();
else return this->rows();
}
}
void resize(int r, int c)
{
if constexpr (Rows == 1)
assert(c == Cols && "Mismatched between dynamic and static col size");
if constexpr (Cols == 1)
assert(r == Rows && "Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
ROTGEN_ASSERT(c == Cols,
"Mismatched between dynamic and static col size");
if constexpr (Rows != -1)
ROTGEN_ASSERT(r == Rows,
"Mismatched between dynamic and static row size");
parent::resize(r, c);
}
@ -179,10 +201,12 @@ namespace rotgen
void conservativeResize(int r, int c)
{
if constexpr (Rows == 1)
assert(c == Cols && "Mismatched between dynamic and static col size");
if constexpr (Cols == 1)
assert(r == Rows && "Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
ROTGEN_ASSERT(c == Cols,
"Mismatched between dynamic and static col size");
if constexpr (Rows != -1)
ROTGEN_ASSERT(r == Rows,
"Mismatched between dynamic and static row size");
parent::conservativeResize(r, c);
}
@ -231,26 +255,26 @@ namespace rotgen
friend bool operator==(matrix const& lhs, matrix const& rhs)
{
return static_cast<parent const&>(lhs) == static_cast<parent const&>(rhs);
return lhs.base() == rhs.base();
}
matrix& operator+=(matrix const& rhs)
{
base() += static_cast<parent const&>(rhs);
base() += rhs.base();
return *this;
}
matrix& operator-=(matrix const& rhs)
{
base() -= static_cast<parent const&>(rhs);
base() -= rhs.base();
return *this;
}
matrix operator-() const { return matrix(base().operator-()); }
matrix operator-() const { return -base(); }
matrix& operator*=(matrix const& rhs)
{
base() *= static_cast<parent const&>(rhs);
base() *= rhs.base();
return *this;
}
@ -299,11 +323,11 @@ namespace rotgen
static matrix Ones(int rows, int cols)
{
if constexpr (Rows != -1)
assert(rows == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(cols == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Ones(rows, cols);
}
@ -316,11 +340,11 @@ namespace rotgen
static matrix Zero(int rows, int cols)
{
if constexpr (Rows != -1)
assert(rows == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(cols == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Zero(rows, cols);
}
@ -333,11 +357,11 @@ namespace rotgen
static matrix Constant(int rows, int cols, Scalar value)
{
if constexpr (Rows != -1)
assert(rows == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(cols == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Constant(rows, cols, static_cast<Scalar>(value));
}
@ -350,11 +374,11 @@ namespace rotgen
static matrix Random(int rows, int cols)
{
if constexpr (Rows != -1)
assert(rows == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(cols == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Random(rows, cols);
}
@ -367,11 +391,11 @@ namespace rotgen
static matrix Identity(int rows, int cols)
{
if constexpr (Rows != -1)
assert(rows == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(cols == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Identity(rows, cols);
}
@ -446,51 +470,4 @@ namespace rotgen
parent const& base() const { return static_cast<parent const&>(*this); }
};
template<typename S, int R, int C, int O, int MR, int MC>
matrix<S, R, C, O, MR, MC> operator+(matrix<S, R, C, O, MR, MC> const& lhs,
matrix<S, R, C, O, MR, MC> const& rhs)
{
matrix<S, R, C, O, MR, MC> that(lhs);
return that += rhs;
}
template<typename S, int R, int C, int O, int MR, int MC>
matrix<S, R, C, O, MR, MC> operator-(matrix<S, R, C, O, MR, MC> const& lhs,
matrix<S, R, C, O, MR, MC> const& rhs)
{
matrix<S, R, C, O, MR, MC> that(lhs);
return that -= rhs;
}
template<typename S, int R, int C, int O, int MR, int MC>
matrix<S, R, C, O, MR, MC> operator*(matrix<S, R, C, O, MR, MC> const& lhs,
matrix<S, R, C, O, MR, MC> const& rhs)
{
matrix<S, R, C, O, MR, MC> that(lhs);
return that *= rhs;
}
template<typename S, int R, int C, int O, int MR, int MC>
matrix<S, R, C, O, MR, MC> operator*(matrix<S, R, C, O, MR, MC> const& lhs,
double rhs)
{
matrix<S, R, C, O, MR, MC> that(lhs);
return that *= rhs;
}
template<typename S, int R, int C, int O, int MR, int MC>
matrix<S, R, C, O, MR, MC> operator*(double lhs,
matrix<S, R, C, O, MR, MC> const& rhs)
{
return rhs * lhs;
}
template<typename S, int R, int C, int O, int MR, int MC>
matrix<S, R, C, O, MR, MC> operator/(matrix<S, R, C, O, MR, MC> const& lhs,
double rhs)
{
matrix<S, R, C, O, MR, MC> that(lhs);
return that /= rhs;
}
}

View file

@ -99,6 +99,8 @@ public:
void setRandom(Index rows, Index cols);
void setIdentity(Index rows, Index cols);
void swap(CLASSNAME& other) { storage_.swap(other.storage_); }
private:
struct payload;
std::unique_ptr<payload> storage_;

View file

@ -7,6 +7,7 @@
//==================================================================================================
#pragma once
#include <rotgen/detail/assert.hpp>
#include <rotgen/detail/helpers.hpp>
#include <rotgen/concepts.hpp>
@ -40,6 +41,7 @@ namespace rotgen
{
public:
using rotgen_tag = void;
using rotgen_matrix_tag = void;
using parent =
detail::storage_type<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>;
using value_type = Scalar;
@ -49,6 +51,9 @@ namespace rotgen
using concrete_type = matrix;
using concrete_dynamic_type = matrix<value_type>;
using exact_base =
Eigen::Matrix<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>;
static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols;
static constexpr int SizeAtCompileTime = detail::static_size<matrix>();
@ -75,6 +80,11 @@ namespace rotgen
static constexpr bool has_static_storage =
storage_status<Rows, Cols, MaxRows, MaxCols>;
static constexpr int AllocatedRows =
Rows == -1 ? (MaxRows == -1 ? 0 : MaxRows) : Rows;
static constexpr int AllocatedCols =
Cols == -1 ? (MaxCols == -1 ? 0 : MaxCols) : Cols;
public:
matrix()
requires(has_static_storage)
@ -83,19 +93,19 @@ namespace rotgen
matrix()
requires(!has_static_storage)
: parent(Rows > 0 ? Rows : 0, Cols > 0 ? Cols : 0)
: parent(AllocatedRows, AllocatedCols)
{
}
matrix(Index r, Index c) : parent(r, c)
{
if constexpr (RowsAtCompileTime != -1)
assert(r == RowsAtCompileTime &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(r == RowsAtCompileTime,
"Mismatched between dynamic and static row size");
if constexpr (ColsAtCompileTime != -1)
assert(c == ColsAtCompileTime &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(c == ColsAtCompileTime,
"Mismatched between dynamic and static column size");
}
matrix(matrix const& other) = default;
@ -181,11 +191,7 @@ namespace rotgen
parent const& base() const { return static_cast<parent const&>(*this); }
auto evaluate() const
{
auto res = base().eval();
return as_concrete_type<decltype(res)>(res);
}
auto evaluate() const { return *this; }
decltype(auto) noalias() const
{
@ -273,38 +279,36 @@ namespace rotgen
void resize(int s)
requires(IsVectorAtCompileTime)
{
if constexpr (Rows == 1)
assert(s == Cols && "Mismatched between dynamic and static col size");
if constexpr (Cols == 1)
assert(s == Rows && "Mismatched between dynamic and static row size");
parent::resize(s);
if constexpr (Rows == 1) parent::resize(1, s);
else parent::resize(s, 1);
}
void resize(int r, int c)
{
if constexpr (Rows == 1)
assert(c == Cols && "Mismatched between dynamic and static col size");
if constexpr (Cols == 1)
assert(r == Rows && "Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
ROTGEN_ASSERT(c == Cols,
"Mismatched between dynamic and static col size");
if constexpr (Rows != -1)
ROTGEN_ASSERT(r == Rows,
"Mismatched between dynamic and static row size");
parent::resize(r, c);
}
void conservativeResize(int s)
requires(IsVectorAtCompileTime)
{
if constexpr (Rows == 1)
assert(s == Cols && "Mismatched between dynamic and static col size");
if constexpr (Cols == 1)
assert(s == Rows && "Mismatched between dynamic and static row size");
parent::conservativeResize(s);
if constexpr (Rows == 1) parent::conservativeResize(1, s);
else parent::conservativeResize(s, 1);
}
void conservativeResize(int r, int c)
{
if constexpr (Rows == 1)
assert(c == Cols && "Mismatched between dynamic and static col size");
if constexpr (Cols == 1)
assert(r == Rows && "Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
ROTGEN_ASSERT(c == Cols,
"Mismatched between dynamic and static col size");
if constexpr (Rows != -1)
ROTGEN_ASSERT(r == Rows,
"Mismatched between dynamic and static row size");
parent::conservativeResize(r, c);
}
@ -317,11 +321,11 @@ namespace rotgen
static matrix Constant(int rows, int cols, Scalar value)
{
if constexpr (Rows != -1)
assert(rows == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(cols == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Constant(rows, cols, static_cast<Scalar>(value));
}
@ -334,11 +338,11 @@ namespace rotgen
static matrix Identity(int rows, int cols)
{
if constexpr (Rows != -1)
assert(rows == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(cols == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Identity(rows, cols);
}
@ -351,11 +355,11 @@ namespace rotgen
static matrix Ones(int rows, int cols)
{
if constexpr (Rows != -1)
assert(rows == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(cols == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Ones(rows, cols);
}
@ -368,11 +372,11 @@ namespace rotgen
static matrix Zero(int rows, int cols)
{
if constexpr (Rows != -1)
assert(rows == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(cols == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Zero(rows, cols);
}
@ -385,11 +389,11 @@ namespace rotgen
static matrix Random(int rows, int cols)
{
if constexpr (Rows != -1)
assert(rows == Rows &&
"Mismatched between dynamic and static row size");
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(cols == Cols &&
"Mismatched between dynamic and static column size");
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Random(rows, cols);
}
@ -519,7 +523,7 @@ namespace rotgen
return *this;
}
matrix operator-() const { return matrix(base()(*this).operator-()); }
matrix operator-() const { return -base(); }
matrix& operator*=(matrix const& rhs)
{

View file

@ -7,12 +7,13 @@
//==================================================================================================
#pragma once
#include <rotgen/detail/assert.hpp>
#include <rotgen/config.hpp>
#include <rotgen/container/block.hpp>
#include <rotgen/container/map.hpp>
#include <rotgen/format.hpp>
#include <cassert>
#include <iostream>
#include <type_traits>

View file

@ -7,7 +7,8 @@
//==================================================================================================
#pragma once
#include <cassert>
#include <rotgen/detail/assert.hpp>
#include <type_traits>
#if !defined(ROTGEN_FORCE_DYNAMIC)
@ -15,6 +16,7 @@
#endif
#include <rotgen/detail/accept_as_ref.hpp>
#include <rotgen/detail/product.hpp>
namespace rotgen
{
@ -149,6 +151,7 @@ namespace rotgen
using parent::Zero;
using parent::operator=;
using parent::operator-;
template<typename RO, int OO, typename SO>
auto qr_solve(ref<RO, OO, SO> rhs) const
@ -166,12 +169,18 @@ namespace rotgen
parent& as_map() { return base(); }
template<typename M>
requires(is_immutable)
ref(product<M> const& m) : ref(m.storage_)
{
}
template<typename S, int R, int C, int O, int MR, int MC>
requires(detail::accept_as_ref<ref, matrix<S, R, C, O, MR, MC>>)
ref(matrix<S, R, C, O, MR, MC>& m) : parent(detail::postpone{})
{
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, m);
assert(correct_ref_setup);
ROTGEN_ASSERT(correct_ref_setup, "Invalid reference binding");
}
template<typename S, int R, int C, int O, int MR, int MC>
@ -202,7 +211,7 @@ namespace rotgen
ref(block<Ref, R, C, I>&& b) : parent(detail::postpone{})
{
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
assert(correct_ref_setup);
ROTGEN_ASSERT(correct_ref_setup, "Invalid reference binding");
}
template<typename Ref, int R, int C, bool I>
@ -210,7 +219,7 @@ namespace rotgen
ref(block<Ref, R, C, I>& b) : parent(detail::postpone{})
{
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
assert(correct_ref_setup);
ROTGEN_ASSERT(correct_ref_setup, "Invalid reference binding");
}
template<typename Ref, int R, int C, bool I>
@ -229,7 +238,7 @@ namespace rotgen
ref(map<Ref, O, S>& b) : parent(detail::postpone{})
{
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
assert(correct_ref_setup);
ROTGEN_ASSERT(correct_ref_setup, "Invalid reference binding");
}
template<typename Ref, int O, typename S>
@ -259,15 +268,15 @@ namespace rotgen
ref(ref<TT, OO, SS>& b) : parent(detail::postpone{})
{
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
assert(correct_ref_setup);
ROTGEN_ASSERT(correct_ref_setup, "Invalid reference binding");
}
template<typename TT, int OO, typename SS>
requires(detail::same_scalar<ref, ref<TT, OO, SS>>)
requires(detail::accept_as_ref<ref, ref<TT, OO, SS>>)
ref(ref<TT, OO, SS> const& b) : parent(detail::postpone{})
{
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
assert(correct_ref_setup);
ROTGEN_ASSERT(correct_ref_setup, "Invalid reference binding");
}
ref(parent& m) : parent(m.data(), m.rows(), m.cols()) {}

View file

@ -8,6 +8,7 @@
#pragma once
#include <rotgen/detail/helpers.hpp>
#include <rotgen/detail/product.hpp>
#include <Eigen/Dense>
#include <type_traits>
@ -52,6 +53,9 @@ namespace rotgen
template<typename T, int Options, typename Stride>
using compile_ref_t = typename compile_ref<T, Options, Stride>::type;
template<typename T, int Options, typename Stride>
using compile_base_t = typename compile_ref<T, Options, Stride>::base;
}
template<typename T, int Options, typename Stride>
@ -59,6 +63,7 @@ namespace rotgen
{
public:
using parent = detail::compile_ref_t<T, Options, Stride>;
using exact_base = detail::compile_base_t<T, Options, Stride>;
using referee = std::remove_const_t<T>;
using value_type = typename referee::value_type;
using rotgen_tag = void;
@ -91,17 +96,7 @@ namespace rotgen
using parent::size;
// Aliasing handling
auto evaluate() const
{
auto res = static_cast<parent const&>(*this).eval();
return as_concrete_type<decltype(res)>(res);
}
auto evaluate()
{
auto res = static_cast<parent&>(*this).eval();
return as_concrete_type<decltype(res)>(res);
}
auto evaluate() const { return T(base().eval()); }
decltype(auto) noalias() const
{
@ -116,10 +111,27 @@ namespace rotgen
}
// Numeric functions
using parent::cwiseAbs;
using parent::cwiseAbs2;
using parent::cwiseInverse;
using parent::cwiseSqrt;
auto operator-() const { return detail::concretize<matrix>(-base()); }
auto cwiseAbs() const
{
return detail::concretize<matrix>(base().cwiseAbs());
}
auto cwiseAbs2() const
{
return detail::concretize<matrix>(base().cwiseAbs2());
}
auto cwiseInverse() const
{
return detail::concretize<matrix>(base().cwiseInverse());
}
auto cwiseSqrt() const
{
return detail::concretize<matrix>(base().cwiseSqrt());
}
// Reductions
using parent::lpNorm;
@ -172,10 +184,26 @@ namespace rotgen
}
// Shape modifications
using parent::adjoint;
using parent::conjugate;
using parent::normalized;
using parent::transpose;
auto normalized() const
requires(IsVectorAtCompileTime)
{
return detail::concretize<matrix>(base().normalized());
}
auto transpose() const
{
return detail::concretize<matrix>(base().transpose());
}
auto adjoint() const
{
return detail::concretize<matrix>(base().adjoint());
}
auto conjugate() const
{
return detail::concretize<matrix>(base().conjugate());
}
// In-place Shape modifications
using parent::adjointInPlace;
@ -183,16 +211,79 @@ namespace rotgen
using parent::transposeInPlace;
// Generators
using parent::Constant;
using parent::Identity;
using parent::Ones;
using parent::Random;
using parent::setConstant;
using parent::setIdentity;
using parent::setOnes;
using parent::setRandom;
using parent::setZero;
using parent::Zero;
static auto Zero() { return detail::concretize<matrix>(parent::Zero()); }
static auto Zero(int rows, int cols)
{
return detail::concretize<matrix>(parent::Zero(rows, cols));
}
static auto Ones() { return detail::concretize<matrix>(parent::Ones()); }
static auto Ones(int rows, int cols)
{
return detail::concretize<matrix>(parent::Ones(rows, cols));
}
static auto Constant(value_type value)
{
return detail::concretize<matrix>(parent::Constant(value));
}
static auto Constant(int rows, int cols, value_type value)
{
return detail::concretize<matrix>(parent::Constant(rows, cols, value));
}
static auto Random()
{
return detail::concretize<matrix>(parent::Random());
}
static auto Random(int rows, int cols)
{
return detail::concretize<matrix>(parent::Random(rows, cols));
}
static auto Identity()
{
return detail::concretize<matrix>(parent::Identity());
}
static auto Identity(int rows, int cols)
{
return detail::concretize<matrix>(parent::Identity(rows, cols));
}
ref& setOnes()
{
base() = parent::Ones(base().rows(), base().cols());
return *this;
}
ref& setZero()
{
base() = parent::Zero(base().rows(), base().cols());
return *this;
}
ref& setConstant(value_type value)
{
base() = parent::Constant(base().rows(), base().cols(), value);
return *this;
}
ref& setRandom()
{
base() = parent::Random(base().rows(), base().cols());
return *this;
}
ref& setIdentity()
{
base() = parent::Identity(base().rows(), base().cols());
return *this;
}
auto qr_solve(auto const& rhs) const
{
@ -212,6 +303,12 @@ namespace rotgen
parent& base() { return static_cast<parent&>(*this); }
template<typename M>
requires(is_immutable)
ref(product<M> const& m) : ref(m.storage_)
{
}
template<typename S, int R, int C, int O, int MR, int MC>
ref(matrix<S, R, C, O, MR, MC>& m)
requires(requires { parent(m.base()); })
@ -307,13 +404,14 @@ namespace rotgen
// Deduction Guides
//============================================================================
template<typename S, int R, int C, int O, int MR, int MC>
ref(matrix<S, R, C, O, MR, MC>&) -> ref<matrix<S>>;
ref(matrix<S, R, C, O, MR, MC>&) -> ref<matrix<S, R, C, O, MR, MC>>;
template<typename Ref, int R, int C, bool I>
ref(block<Ref, R, C, I>& b) -> ref<Ref>;
template<typename S, int R, int C, int O, int MR, int MC>
ref(matrix<S, R, C, O, MR, MC> const&) -> ref<matrix<S> const>;
ref(matrix<S, R, C, O, MR, MC> const&)
-> ref<matrix<S, R, C, O, MR, MC> const>;
template<typename Ref, int R, int C, bool I>
ref(block<Ref, R, C, I> const& b) -> ref<Ref const>;
@ -336,7 +434,14 @@ namespace rotgen
template<typename A, int O, typename S, typename B, int P, typename T>
auto operator*(ref<A, O, S> lhs, ref<B, P, T> rhs)
{
return detail::concretize<matrix>(lhs.base() * rhs.base());
auto p = lhs.base() * rhs.base();
using concrete_type = detail::as_concrete_t<decltype(p), matrix>;
if constexpr (concrete_type::SizeAtCompileTime == 1)
return product{concrete_type{p}};
else if constexpr (concrete_type::SizeAtCompileTime == 0)
return concrete_type{};
else return concrete_type{p};
}
template<typename A, int O, typename S>
@ -411,7 +516,6 @@ namespace rotgen
template<typename A, int O, typename S, typename B, int P, typename T>
auto cross(ref<A, O, S> lhs, ref<B, P, T> rhs)
-> decltype(lhs.base().cross(rhs.base()))
{
return detail::concretize<matrix>(lhs.base().cross(rhs.base()));
}
@ -432,13 +536,8 @@ namespace rotgen
using type = std::conditional_t<is_const, ref<base const>, ref<base>>;
};
template<concepts::eigen_compatible T> auto const& base_of(T const& a)
template<concepts::eigen_compatible T> decltype(auto) base_of(T&& a)
{
return a;
}
template<concepts::eigen_compatible T> auto& base_of(T& a)
{
return a;
return ROTGEN_FWD(a);
}
}

View file

@ -12,46 +12,49 @@
namespace rotgen
{
template<typename A, int O, typename S, typename B, int P, typename T>
bool operator==(ref<A, O, S> lhs, ref<B, P, T> rhs)
bool operator==(ref<A, O, S> const& lhs, ref<B, P, T> const& rhs)
{
return lhs.base() == rhs.base();
}
template<typename A, int O, typename S, typename B, int P, typename T>
bool operator!=(ref<A, O, S> lhs, ref<B, P, T> rhs)
bool operator!=(ref<A, O, S> const& lhs, ref<B, P, T> const& rhs)
{
return lhs.base() != rhs.base();
}
template<typename A, int O, typename S>
auto operator*(std::convertible_to<typename A::value_type> auto s,
ref<A, O, S> rhs)
ref<A, O, S> const& rhs)
{
// void* _ = rhs;
return rhs * s;
}
template<typename A, int O, typename S, typename B, int P, typename T>
auto dot(ref<A, O, S> lhs, ref<B, P, T> rhs)
auto dot(ref<A, O, S> const& lhs, ref<B, P, T> const& rhs)
{
return lhs.base().dot(rhs.base());
}
template<typename A, int O, typename S>
auto mul(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
auto mul(ref<A, O, S> const& lhs,
std::convertible_to<typename A::value_type> auto s)
-> decltype(lhs * s)
{
return lhs * s;
}
template<typename A, int O, typename S>
auto mul(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs)
-> decltype(s * rhs)
auto mul(std::convertible_to<typename A::value_type> auto s,
ref<A, O, S> const& rhs) -> decltype(s * rhs)
{
return s * rhs;
}
template<typename A, int O, typename S>
auto div(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
auto div(ref<A, O, S> const& lhs,
std::convertible_to<typename A::value_type> auto s)
-> decltype(lhs / s)
{
return lhs / s;

View file

@ -32,11 +32,12 @@ namespace rotgen
template<concepts::entity T> struct generalize<T>
{
static constexpr bool is_const = std::is_const_v<T>;
using base = matrix<typename T::value_type,
T::RowsAtCompileTime,
T::ColsAtCompileTime,
T::storage_order>;
static constexpr bool is_const =
std::is_const_v<std::remove_reference_t<T>>;
using base = matrix<typename std::remove_cvref_t<T>::value_type,
std::remove_cvref_t<T>::RowsAtCompileTime,
std::remove_cvref_t<T>::ColsAtCompileTime,
std::remove_cvref_t<T>::storage_order>;
using type = std::conditional_t<is_const, ref<base const>, ref<base>>;
};

View file

@ -7,7 +7,8 @@
//==================================================================================================
#pragma once
#include <cassert>
#include <rotgen/detail/assert.hpp>
#include <concepts>
namespace rotgen::detail
@ -77,22 +78,26 @@ namespace rotgen::detail
if (Ref::RowsAtCompileTime == 1)
{
assert(in.rows() == 1 || in.cols() == 1);
ROTGEN_ASSERT(in.rows() == 1 || in.cols() == 1,
"Incompatible rows/cols in ref binding");
rows = 1;
cols = in.size();
}
else if (Ref::ColsAtCompileTime == 1)
{
assert(in.rows() == 1 || in.cols() == 1);
ROTGEN_ASSERT(in.rows() == 1 || in.cols() == 1,
"Incompatible rows/cols in ref binding");
rows = in.size();
cols = 1;
}
// Verify that the sizes are valid.
assert((Ref::RowsAtCompileTime == Dynamic) ||
(Ref::RowsAtCompileTime == rows));
assert((Ref::ColsAtCompileTime == Dynamic) ||
(Ref::ColsAtCompileTime == cols));
ROTGEN_ASSERT((Ref::RowsAtCompileTime == Dynamic) ||
(Ref::RowsAtCompileTime == rows),
"Incompatible static rows/cols in ref binding");
ROTGEN_ASSERT((Ref::ColsAtCompileTime == Dynamic) ||
(Ref::ColsAtCompileTime == cols),
"Incompatible static rows/cols in ref binding");
// Swap stride if we are a vector and we changed rows as such
bool transpose = Ref::IsVectorAtCompileTime && (rows != in.rows());

View 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

View file

@ -31,7 +31,7 @@ namespace rotgen::detail
using type = Wrapper<typename EigenType::value_type,
EigenType::RowsAtCompileTime,
EigenType::ColsAtCompileTime,
EigenType::Flags & 1,
EigenType::IsRowMajor ? RowMajor : ColMajor,
EigenType::MaxRowsAtCompileTime,
EigenType::MaxColsAtCompileTime>;
};

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

View file

@ -21,10 +21,12 @@ namespace rotgen
[[maybe_unused]] Index ni,
[[maybe_unused]] Index nj)
{
assert(i0 >= 0 && "block extraction uses negative row index.");
assert(j0 >= 0 && "block extraction uses negative col index.");
assert(i0 + ni <= e.rows() && "block extraction rows is out of range.");
assert(j0 + nj <= e.cols() && "block extraction cols is out of range.");
ROTGEN_ASSERT(i0 >= 0, "block extraction uses negative row index.");
ROTGEN_ASSERT(j0 >= 0, "block extraction uses negative col index.");
ROTGEN_ASSERT(i0 + ni <= e.rows(),
"block extraction rows is out of range.");
ROTGEN_ASSERT(j0 + nj <= e.cols(),
"block extraction cols is out of range.");
}
}

View file

@ -7,10 +7,24 @@
//==================================================================================================
#pragma once
#include <rotgen/detail/assert.hpp>
#include <rotgen/detail/helpers.hpp>
namespace rotgen
{
//-----------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------
template<typename T, typename... Args> void initialize_with(T&& m, Args... v)
{
using type = typename std::remove_cvref_t<T>::value_type;
using map_t = rotgen::map<rotgen::matrix<type, -1, -1, rotgen::RowMajor>>;
ROTGEN_ASSERT(sizeof...(v) == m.size(),
"Incorrect quantity of coefficients for initialization");
type data[] = {static_cast<type>(v)...};
m = map_t(data, m.rows(), m.cols());
}
//-----------------------------------------------------------------------------------------------
// Generators
//-----------------------------------------------------------------------------------------------

View file

@ -7,9 +7,10 @@
//==================================================================================================
#pragma once
#include <rotgen/detail/product.hpp>
#include <rotgen/concepts.hpp>
#include <cassert>
#include <iosfwd>
namespace rotgen
@ -80,30 +81,27 @@ namespace rotgen
//------------------------------------------------------------------------------------------------
// Compounds operators across types
template<typename A, typename B>
auto operator+=(A& a, B const& b)
requires(concepts::entity<A> && concepts::entity<B>)
template<concepts::entity A, concepts::entity B>
decltype(auto) operator+=(A&& a, B const& b)
requires(!concepts::block<A>)
{
if constexpr (!use_expression_templates)
return generalize_t<A>(a) += generalize_t<B const>(b);
else return base_of(a) += base_of(b);
generalize_t<A>(ROTGEN_FWD(a)) += generalize_t<B const>(b);
return ROTGEN_FWD(a);
}
template<typename A, typename B>
auto operator-=(A& a, B const& b)
requires(concepts::entity<A> && concepts::entity<B>)
template<concepts::entity A, concepts::entity B>
decltype(auto) operator-=(A&& a, B const& b)
requires(!concepts::block<A>)
{
if constexpr (!use_expression_templates)
return generalize_t<A>(a) -= generalize_t<B const>(b);
else return base_of(a) -= base_of(b);
generalize_t<A>(ROTGEN_FWD(a)) -= generalize_t<B const>(b);
return ROTGEN_FWD(a);
}
template<typename A, typename B>
auto operator*=(A& a, B const& b)
requires(concepts::entity<A> && concepts::entity<B>)
template<concepts::entity A, concepts::entity B>
decltype(auto) operator*=(A&& a, B const& b)
requires(!concepts::block<A>)
{
if constexpr (!use_expression_templates)
return generalize_t<A>(a) *= generalize_t<B const>(b);
else return base_of(a) *= base_of(b);
generalize_t<A>(ROTGEN_FWD(a)) *= generalize_t<B const>(b);
return ROTGEN_FWD(a);
}
}

View file

@ -10,30 +10,38 @@
#define STORAGE_ORDER Eigen::ColMajor
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _col)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
#include "model.cpp"
#undef CLASSNAME
#undef CLASSCONSTNAME
#undef TRANSNAME
#undef TRANSCLASSNAME
#undef SOURCENAME
#undef MAPNAME
#undef TRANSMAPNAME
#undef STORAGE_ORDER
#define STORAGE_ORDER Eigen::RowMajor
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _row)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
#include "model.cpp"
#undef CLASSNAME
#undef CLASSCONSTNAME
#undef TRANSNAME
#undef TRANSCLASSNAME
#undef SOURCENAME
#undef MAPNAME
#undef TRANSMAPNAME
#undef STORAGE_ORDER
#undef SIZE
@ -44,30 +52,38 @@
#define STORAGE_ORDER Eigen::ColMajor
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _col)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
#include "model.cpp"
#undef CLASSNAME
#undef CLASSCONSTNAME
#undef TRANSNAME
#undef TRANSCLASSNAME
#undef SOURCENAME
#undef MAPNAME
#undef TRANSMAPNAME
#undef STORAGE_ORDER
#define STORAGE_ORDER Eigen::RowMajor
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _row)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
#include "model.cpp"
#undef CLASSNAME
#undef CLASSCONSTNAME
#undef TRANSNAME
#undef TRANSCLASSNAME
#undef SOURCENAME
#undef MAPNAME
#undef TRANSMAPNAME
#undef STORAGE_ORDER
#undef SIZE

View file

@ -33,6 +33,12 @@ CLASSNAME::CLASSNAME(MAPNAME CONST& r, Index i0, Index j0, Index ni, Index nj)
{
}
CLASSNAME::CLASSNAME(
TRANSMAPNAME CONST& r, Index i0, Index j0, Index ni, Index nj)
: storage_(std::make_unique<payload>(r, i0, j0, ni, nj, map_t{}, trans_t{}))
{
}
// We're building a block from a block - So we have to dig around the internals
CLASSNAME::CLASSNAME(
TRANSCLASSNAME CONST& p, Index i0, Index j0, Index ni, Index nj)
@ -197,17 +203,17 @@ TYPE CLASSNAME::operator()(Index i, Index j) const
#if !defined(USE_CONST)
TYPE& CLASSNAME::operator()(Index index)
{
TYPE* ptr = nullptr;
storage_->apply([&](auto& blk) { ptr = blk.data() + index; });
return *ptr;
auto r = rows() == 1 ? 0 : index;
auto c = cols() == 1 ? 0 : index;
return (*this)(r, c);
}
#endif
TYPE CLASSNAME::operator()(Index index) const
{
TYPE ptr;
storage_->apply([&](auto const& blk) { ptr = *(blk.data() + index); });
return ptr;
auto r = rows() == 1 ? 0 : index;
auto c = cols() == 1 ? 0 : index;
return (*this)(r, c);
}
// Raw pointer access
@ -448,6 +454,28 @@ CLASSNAME& CLASSNAME::operator+=(CLASSNAME const& rhs)
return *this;
}
CLASSNAME& CLASSNAME::operator+=(CLASSCONSTNAME const& rhs)
{
std::visit(
[](auto& lhs_blk, auto const& rhs_blk) { lhs_blk.first += rhs_blk.first; },
storage_->data, rhs.storage()->data);
return *this;
}
CLASSNAME& CLASSNAME::operator+=(SOURCENAME const& rhs)
{
std::visit([&](auto& lhs_blk) { lhs_blk.first += rhs.storage()->data; },
storage_->data);
return *this;
}
CLASSNAME& CLASSNAME::operator+=(TRANSNAME const& rhs)
{
std::visit([&](auto& lhs_blk) { lhs_blk.first += rhs.storage()->data; },
storage_->data);
return *this;
}
CLASSNAME& CLASSNAME::operator-=(CLASSNAME const& rhs)
{
std::visit(
@ -456,6 +484,28 @@ CLASSNAME& CLASSNAME::operator-=(CLASSNAME const& rhs)
return *this;
}
CLASSNAME& CLASSNAME::operator-=(CLASSCONSTNAME const& rhs)
{
std::visit(
[](auto& lhs_blk, auto const& rhs_blk) { lhs_blk.first -= rhs_blk.first; },
storage_->data, rhs.storage()->data);
return *this;
}
CLASSNAME& CLASSNAME::operator-=(SOURCENAME const& rhs)
{
std::visit([&](auto& lhs_blk) { lhs_blk.first -= rhs.storage()->data; },
storage_->data);
return *this;
}
CLASSNAME& CLASSNAME::operator-=(TRANSNAME const& rhs)
{
std::visit([&](auto& lhs_blk) { lhs_blk.first -= rhs.storage()->data; },
storage_->data);
return *this;
}
CLASSNAME& CLASSNAME::operator*=(CLASSNAME const& rhs)
{
std::visit(
@ -464,6 +514,28 @@ CLASSNAME& CLASSNAME::operator*=(CLASSNAME const& rhs)
return *this;
}
CLASSNAME& CLASSNAME::operator*=(CLASSCONSTNAME const& rhs)
{
std::visit(
[](auto& lhs_blk, auto const& rhs_blk) { lhs_blk.first *= rhs_blk.first; },
storage_->data, rhs.storage()->data);
return *this;
}
CLASSNAME& CLASSNAME::operator*=(SOURCENAME const& rhs)
{
std::visit([&](auto& lhs_blk) { lhs_blk.first *= rhs.storage()->data; },
storage_->data);
return *this;
}
CLASSNAME& CLASSNAME::operator*=(TRANSNAME const& rhs)
{
std::visit([&](auto& lhs_blk) { lhs_blk.first *= rhs.storage()->data; },
storage_->data);
return *this;
}
CLASSNAME& CLASSNAME::operator*=(TYPE s)
{
storage_->apply([&](auto& blk) { blk *= s; });

View file

@ -11,29 +11,41 @@
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#include "model.cpp"
#undef CLASSNAME
#undef TRANSCLASSNAME
#undef TRANSCLASSCONSTNAME
#undef TRANSCLASSNONCONSTNAME
#undef TRANSSOURCENAME
#undef CLASSCONSTNAME
#undef CLASSNONCONSTNAME
#undef SOURCENAME
#undef STORAGE_ORDER
#define STORAGE_ORDER Eigen::RowMajor
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#include "model.cpp"
#undef CLASSNAME
#undef TRANSCLASSNAME
#undef TRANSCLASSCONSTNAME
#undef TRANSCLASSNONCONSTNAME
#undef TRANSSOURCENAME
#undef SOURCENAME
#undef CLASSCONSTNAME
#undef CLASSNONCONSTNAME
#undef STORAGE_ORDER
#undef SIZE
@ -45,28 +57,40 @@
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#include "model.cpp"
#undef CLASSNAME
#undef TRANSCLASSNAME
#undef TRANSCLASSCONSTNAME
#undef TRANSCLASSNONCONSTNAME
#undef TRANSSOURCENAME
#undef CLASSCONSTNAME
#undef CLASSNONCONSTNAME
#undef SOURCENAME
#undef STORAGE_ORDER
#define STORAGE_ORDER Eigen::RowMajor
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#include "model.cpp"
#undef CLASSNAME
#undef TRANSCLASSNAME
#undef TRANSCLASSCONSTNAME
#undef TRANSCLASSNONCONSTNAME
#undef TRANSSOURCENAME
#undef CLASSCONSTNAME
#undef CLASSNONCONSTNAME
#undef SOURCENAME
#undef STORAGE_ORDER

View file

@ -239,12 +239,22 @@ void CLASSNAME::adjointInPlace()
}
#endif
TYPE CLASSNAME::dot(CLASSNAME const& rhs) const
TYPE CLASSNAME::dot(CLASSNONCONSTNAME const& rhs) const
{
return storage_->data.reshaped().dot(rhs.storage()->data.reshaped());
}
TYPE CLASSNAME::dot(TRANSCLASSNAME const& rhs) const
TYPE CLASSNAME::dot(CLASSCONSTNAME const& rhs) const
{
return storage_->data.reshaped().dot(rhs.storage()->data.reshaped());
}
TYPE CLASSNAME::dot(TRANSCLASSNONCONSTNAME const& rhs) const
{
return storage_->data.reshaped().dot(rhs.storage()->data.reshaped());
}
TYPE CLASSNAME::dot(TRANSCLASSCONSTNAME const& rhs) const
{
return storage_->data.reshaped().dot(rhs.storage()->data.reshaped());
}
@ -378,7 +388,7 @@ SOURCENAME CLASSNAME::operator-() const
#if !defined(USE_CONST)
CLASSNAME& CLASSNAME::operator+=(CLASSNAME const& rhs)
{
storage_->data += rhs.storage_->data;
storage_->data += rhs.storage()->data;
return *this;
}
@ -388,9 +398,21 @@ CLASSNAME& CLASSNAME::operator+=(CLASSCONSTNAME const& rhs)
return *this;
}
CLASSNAME& CLASSNAME::operator+=(TRANSCLASSNONCONSTNAME const& rhs)
{
storage_->data.reshaped() += rhs.storage()->data.reshaped();
return *this;
}
CLASSNAME& CLASSNAME::operator+=(TRANSCLASSCONSTNAME const& rhs)
{
storage_->data.reshaped() += rhs.storage()->data.reshaped();
return *this;
}
CLASSNAME& CLASSNAME::operator-=(CLASSNAME const& rhs)
{
storage_->data -= rhs.storage_->data;
storage_->data -= rhs.storage()->data;
return *this;
}
@ -400,9 +422,21 @@ CLASSNAME& CLASSNAME::operator-=(CLASSCONSTNAME const& rhs)
return *this;
}
CLASSNAME& CLASSNAME::operator-=(TRANSCLASSNONCONSTNAME const& rhs)
{
storage_->data.reshaped() -= rhs.storage()->data.reshaped();
return *this;
}
CLASSNAME& CLASSNAME::operator-=(TRANSCLASSCONSTNAME const& rhs)
{
storage_->data.reshaped() -= rhs.storage()->data.reshaped();
return *this;
}
CLASSNAME& CLASSNAME::operator*=(CLASSNAME const& rhs)
{
storage_->data *= rhs.storage_->data;
storage_->data *= rhs.storage()->data;
return *this;
}
@ -412,6 +446,18 @@ CLASSNAME& CLASSNAME::operator*=(CLASSCONSTNAME const& rhs)
return *this;
}
CLASSNAME& CLASSNAME::operator*=(TRANSCLASSNONCONSTNAME const& rhs)
{
storage_->data *= rhs.storage()->data;
return *this;
}
CLASSNAME& CLASSNAME::operator*=(TRANSCLASSCONSTNAME const& rhs)
{
storage_->data *= rhs.storage()->data;
return *this;
}
CLASSNAME& CLASSNAME::operator*=(TYPE s)
{
storage_->data *= s;

View file

@ -77,3 +77,39 @@ TTS_CASE("Extraction of ref/ref const")
for (rotgen::Index r = 0; r < 4; r++)
for (rotgen::Index c = 0; c < 3; c++) TTS_EQUAL(sliced(r, c), 5.f);
};
void process_col(rotgen::matrix<float, 3, 4>& m,
rotgen::matrix<float, 3, 1> const& n,
int c)
{
col(m, c) += n;
}
TTS_CASE("Compound operators on extractions")
{
rotgen::matrix<float, 3, 4> m;
rotgen::matrix<float, 3, 4> reference;
rotgen::matrix<float, 3, 1> n;
setZero(m);
setConstant(n, 10);
setConstant(reference, 10);
for (int i = 0; i < m.cols(); i++) process_col(m, n, i);
TTS_EQUAL(m, reference);
};
TTS_CASE("Compatibility of 1D blocks")
{
rotgen::matrix<float, 4, 2> V;
setConstant(V, 99);
rotgen::matrix<float, 3, 1> C{12, 34, 56};
extract<1, 2>(V, 0, 0) = segment<2>(C, 0);
extract<2, 1>(V, 1, 0) = segment<2>(C, 1);
TTS_EQUAL(V(0, 0), C(0));
TTS_EQUAL(V(0, 1), C(1));
TTS_EQUAL(V(1, 0), C(1));
TTS_EQUAL(V(2, 0), C(2));
};

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

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

View file

@ -9,9 +9,9 @@
#include "unit/tests.hpp"
TTS_CASE_TPL("SVD decomposition - Dynamic case",
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>)
TTS_CASE_TPL("SVD decomposition - Dynamic case", rotgen::tests::types)
<typename T, typename O>(tts::type<tts::types<T, O>>)
{
int rank, i = 5;
auto eps = std::numeric_limits<T>::epsilon();
@ -24,10 +24,10 @@ TTS_CASE_TPL("SVD decomposition - Dynamic case",
{
rank = decomp.rank();
auto u = decomp.U(rank);
auto d = decomp.singular_values(rank);
auto dd = decomp.D(rank);
auto v = decomp.V(rank);
auto u = decomp.matrixU(rank);
auto d = decomp.singularValues(rank);
auto dd = decomp.matrixD(rank);
auto v = decomp.matrixV(rank);
TTS_EQUAL(rank, i);
@ -48,9 +48,9 @@ TTS_CASE_TPL("SVD decomposition - Dynamic case",
} while (rank != 1);
};
TTS_CASE_TPL("SVD decomposition - Static case",
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>)
TTS_CASE_TPL("SVD decomposition - Static case", rotgen::tests::types)
<typename T, typename O>(tts::type<tts::types<T, O>>)
{
int rank, i = 5;
auto eps = std::numeric_limits<T>::epsilon();
@ -62,10 +62,10 @@ TTS_CASE_TPL("SVD decomposition - Static case",
{
rank = decomp.rank();
auto u = decomp.U(rank);
auto d = decomp.singular_values(rank);
auto dd = decomp.D(rank);
auto v = decomp.V(rank);
auto u = decomp.matrixU(rank);
auto d = decomp.singularValues(rank);
auto dd = decomp.matrixD(rank);
auto v = decomp.matrixV(rank);
TTS_EQUAL(rank, i);