Resolve "[API-#2] Pseudo-privatization of rotgen entity member functions"

Closes #18

Co-authored-by: Jules Pénuchot <jules@penuchot.com>

See merge request oss/rotgen!50
This commit is contained in:
Jules Pénuchot 2025-12-17 20:48:00 +01:00 committed by Joel Falcou
parent 6489697c05
commit e151e136d6
52 changed files with 2212 additions and 1556 deletions

View file

@ -90,22 +90,22 @@ namespace rotgen
}
else if constexpr (IsVectorAtCompileTime && !Src::IsVectorAtCompileTime)
{
auto r = other.rows();
auto c = other.cols();
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");
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(),
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)
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;
@ -226,66 +226,69 @@ namespace rotgen
return (*this)(i);
}
concrete_type evaluate() const { return concrete_type{*this}; }
concrete_type _evaluate() const { return concrete_type{*this}; }
decltype(auto) noalias() const { return *this; }
decltype(auto) _noalias() const { return *this; }
decltype(auto) noalias() { return *this; }
decltype(auto) _noalias() { return *this; }
concrete_type normalized() const
concrete_type _normalized() const
requires(IsVectorAtCompileTime)
{
return concrete_type(base().normalized());
return concrete_type(base()._normalized());
}
transposed_type transpose() const
transposed_type _transpose() const
{
return transposed_type(base().transpose());
return transposed_type(base()._transpose());
}
concrete_type conjugate() const
concrete_type _conjugate() const
{
return concrete_type(base().conjugate());
return concrete_type(base()._conjugate());
}
transposed_type adjoint() const
transposed_type _adjoint() const
{
return transposed_type(base().adjoint());
return transposed_type(base()._adjoint());
}
concrete_type cwiseAbs() const { return concrete_type(base().cwiseAbs()); }
concrete_type cwiseAbs2() const
concrete_type _cwiseAbs() const
{
return concrete_type(base().cwiseAbs2());
return concrete_type(base()._cwiseAbs());
}
concrete_type cwiseInverse() const
concrete_type _cwiseAbs2() const
{
return concrete_type(base().cwiseInverse());
return concrete_type(base()._cwiseAbs2());
}
concrete_type cwiseSqrt() const
concrete_type _cwiseInverse() const
{
return concrete_type(base().cwiseSqrt());
return concrete_type(base()._cwiseInverse());
}
void normalize()
concrete_type _cwiseSqrt() const
{
return concrete_type(base()._cwiseSqrt());
}
void _normalize()
requires(!is_immutable && IsVectorAtCompileTime)
{
parent::normalize();
parent::_normalize();
}
void transposeInPlace()
void _transposeInPlace()
requires(!is_immutable)
{
parent::transposeInPlace();
parent::_transposeInPlace();
}
void adjointInPlace()
void _adjointInPlace()
requires(!is_immutable)
{
parent::adjointInPlace();
parent::_adjointInPlace();
}
friend bool operator==(block const& lhs, block const& rhs)
@ -336,37 +339,37 @@ namespace rotgen
return *this;
}
auto minCoeff() const { return parent::minCoeff(); }
auto _minCoeff() const { return parent::_minCoeff(); }
auto maxCoeff() const { return parent::maxCoeff(); }
auto _maxCoeff() const { return parent::_maxCoeff(); }
template<std::integral IndexType>
auto minCoeff(IndexType* row, IndexType* col) const
auto _minCoeff(IndexType* row, IndexType* col) const
{
Index r, c;
auto result = parent::minCoeff(&r, &c);
auto result = parent::_minCoeff(&r, &c);
*row = r;
*col = c;
return result;
}
template<std::integral IndexType>
auto maxCoeff(IndexType* row, IndexType* col) const
auto _maxCoeff(IndexType* row, IndexType* col) const
{
Index r, c;
auto result = parent::maxCoeff(&r, &c);
auto result = parent::_maxCoeff(&r, &c);
*row = r;
*col = c;
return result;
}
static concrete_type Zero()
static concrete_type _Zero()
requires(Rows != -1 && Cols != -1)
{
return parent::Zero(Rows, Cols);
return parent::_Zero(Rows, Cols);
}
static concrete_type Zero(int rows, int cols)
static concrete_type _Zero(int rows, int cols)
{
if constexpr (Rows != -1)
ROTGEN_ASSERT(rows == Rows,
@ -374,16 +377,16 @@ namespace rotgen
if constexpr (Cols != -1)
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Zero(rows, cols);
return parent::_Zero(rows, cols);
}
static concrete_type Ones()
static concrete_type _Ones()
requires(Rows != -1 && Cols != -1)
{
return parent::Ones(Rows, Cols);
return parent::_Ones(Rows, Cols);
}
static concrete_type Ones(int rows, int cols)
static concrete_type _Ones(int rows, int cols)
{
if constexpr (Rows != -1)
ROTGEN_ASSERT(rows == Rows,
@ -391,16 +394,16 @@ namespace rotgen
if constexpr (Cols != -1)
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Ones(rows, cols);
return parent::_Ones(rows, cols);
}
static concrete_type Constant(value_type value)
static concrete_type _Constant(value_type value)
requires(Rows != -1 && Cols != -1)
{
return parent::Constant(Rows, Cols, static_cast<double>(value));
return parent::_Constant(Rows, Cols, static_cast<double>(value));
}
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)
ROTGEN_ASSERT(rows == Rows,
@ -408,16 +411,16 @@ namespace rotgen
if constexpr (Cols != -1)
ROTGEN_ASSERT(cols == Cols,
"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));
}
static concrete_type Random()
static concrete_type _Random()
requires(Rows != -1 && Cols != -1)
{
return parent::Random(Rows, Cols);
return parent::_Random(Rows, Cols);
}
static concrete_type Random(int rows, int cols)
static concrete_type _Random(int rows, int cols)
{
if constexpr (Rows != -1)
ROTGEN_ASSERT(rows == Rows,
@ -425,16 +428,16 @@ namespace rotgen
if constexpr (Cols != -1)
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Random(rows, cols);
return parent::_Random(rows, cols);
}
static concrete_type Identity()
static concrete_type _Identity()
requires(Rows != -1 && Cols != -1)
{
return parent::Identity(Rows, Cols);
return parent::_Identity(Rows, Cols);
}
static concrete_type Identity(int rows, int cols)
static concrete_type _Identity(int rows, int cols)
{
if constexpr (Rows != -1)
ROTGEN_ASSERT(rows == Rows,
@ -442,48 +445,49 @@ namespace rotgen
if constexpr (Cols != -1)
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Identity(rows, cols);
return parent::_Identity(rows, cols);
}
block& setOnes()
block& _setOnes()
requires(!is_immutable)
{
parent::assign(parent::Ones(parent::rows(), parent::cols()));
parent::assign(parent::_Ones(parent::_rows(), parent::_cols()));
return *this;
}
block& setZero()
block& _setZero()
requires(!is_immutable)
{
parent::assign(parent::Zero(parent::rows(), parent::cols()));
parent::assign(parent::_Zero(parent::_rows(), parent::_cols()));
return *this;
}
block& setConstant(value_type value)
block& _setConstant(value_type value)
requires(!is_immutable)
{
parent::assign(parent::Constant(parent::rows(), parent::cols(), value));
parent::assign(
parent::_Constant(parent::_rows(), parent::_cols(), value));
return *this;
}
block& setRandom()
block& _setRandom()
requires(!is_immutable)
{
parent::assign(parent::Random(parent::rows(), parent::cols()));
parent::assign(parent::_Random(parent::_rows(), parent::_cols()));
return *this;
}
block& setIdentity()
block& _setIdentity()
requires(!is_immutable)
{
parent::assign(parent::Identity(parent::rows(), parent::cols()));
parent::assign(parent::_Identity(parent::_rows(), parent::_cols()));
return *this;
}
template<int P> value_type lpNorm() const
template<int P> value_type _lpNorm() const
{
static_assert(P == 1 || P == 2 || P == Infinity);
return parent::lpNorm(P);
return parent::_lpNorm(P);
}
parent& base() { return static_cast<parent&>(*this); }
@ -495,41 +499,41 @@ namespace rotgen
auto operator+(block<Ref, R, C, I> const& lhs, block<Ref, R, C, I> const& rhs)
{
using concrete_type = typename block<Ref, R, C, I>::concrete_type;
return concrete_type(lhs.base().add(rhs));
return concrete_type(lhs.base()._add(rhs));
}
template<typename Ref, int R, int C, bool I>
auto operator-(block<Ref, R, C, I> const& lhs, block<Ref, R, C, I> const& rhs)
{
using concrete_type = typename block<Ref, R, C, I>::concrete_type;
return concrete_type(lhs.base().sub(rhs));
return concrete_type(lhs.base()._sub(rhs));
}
template<typename Ref, int R, int C, bool I>
auto operator*(block<Ref, R, C, I> const& lhs, block<Ref, R, C, I> const& rhs)
{
using concrete_type = typename block<Ref, R, C, I>::concrete_type;
return concrete_type(lhs.base().mul(rhs));
return concrete_type(lhs.base()._mul(rhs));
}
template<typename Ref, int R, int C, bool I>
auto operator*(block<Ref, R, C, I> const& lhs, double rhs)
{
using concrete_type = typename block<Ref, R, C, I>::concrete_type;
return concrete_type(lhs.base().mul(rhs));
return concrete_type(lhs.base()._mul(rhs));
}
template<typename Ref, int R, int C, bool I>
auto operator*(double lhs, block<Ref, R, C, I> const& rhs)
{
using concrete_type = typename block<Ref, R, C, I>::concrete_type;
return concrete_type(rhs.base().mul(lhs));
return concrete_type(rhs.base()._mul(lhs));
}
template<typename Ref, int R, int C, bool I>
auto operator/(block<Ref, R, C, I> const& lhs, double rhs)
{
using concrete_type = typename block<Ref, R, C, I>::concrete_type;
return concrete_type(lhs.base().div(rhs));
return concrete_type(lhs.base()._div(rhs));
}
}

View file

@ -39,44 +39,45 @@ public:
void assign(SOURCENAME const&);
#endif
Index rows() const;
Index cols() const;
Index size() const;
Index innerStride() const;
Index outerStride() const;
Index _rows() const;
Index _cols() const;
Index startRow() const;
Index startCol() const;
Index _innerStride() const;
Index _outerStride() const;
SOURCENAME normalized() const;
SOURCENAME transpose() const;
SOURCENAME conjugate() const;
SOURCENAME adjoint() const;
Index _startRow() const;
Index _startCol() const;
SOURCENAME cwiseAbs() const;
SOURCENAME cwiseAbs2() const;
SOURCENAME cwiseInverse() const;
SOURCENAME cwiseSqrt() const;
SOURCENAME _normalized() const;
SOURCENAME _transpose() const;
SOURCENAME _conjugate() const;
SOURCENAME _adjoint() const;
SOURCENAME _cwiseAbs() const;
SOURCENAME _cwiseAbs2() const;
SOURCENAME _cwiseInverse() const;
SOURCENAME _cwiseSqrt() const;
#if !defined(USE_CONST)
void normalize();
void transposeInPlace();
void adjointInPlace();
void _normalize();
void _transposeInPlace();
void _adjointInPlace();
#endif
TYPE sum() const;
TYPE prod() const;
TYPE mean() const;
TYPE trace() const;
TYPE maxCoeff() const;
TYPE minCoeff() const;
TYPE maxCoeff(Index* row, Index* col) const;
TYPE minCoeff(Index* row, Index* col) const;
TYPE _sum() const;
TYPE _prod() const;
TYPE _mean() const;
TYPE _trace() const;
TYPE _maxCoeff() const;
TYPE _minCoeff() const;
TYPE _maxCoeff(Index* row, Index* col) const;
TYPE _minCoeff(Index* row, Index* col) const;
TYPE squaredNorm() const;
TYPE norm() const;
TYPE lpNorm(int p) const;
TYPE _squaredNorm() const;
TYPE _norm() const;
TYPE _lpNorm(int p) const;
#if !defined(USE_CONST)
TYPE& operator()(Index i, Index j);
@ -101,11 +102,11 @@ public:
TYPE operator()(Index index) const;
SOURCENAME operator-() const;
SOURCENAME add(CLASSNAME const& rhs) const;
SOURCENAME sub(CLASSNAME const& rhs) const;
SOURCENAME mul(CLASSNAME const& rhs) const;
SOURCENAME mul(TYPE s) const;
SOURCENAME div(TYPE s) const;
SOURCENAME _add(CLASSNAME const& rhs) const;
SOURCENAME _sub(CLASSNAME const& rhs) const;
SOURCENAME _mul(CLASSNAME const& rhs) const;
SOURCENAME _mul(TYPE s) const;
SOURCENAME _div(TYPE s) const;
friend ROTGEN_EXPORT std::ostream& operator<<(std::ostream&,
CLASSNAME const&);
@ -121,23 +122,23 @@ public:
#endif
const TYPE* data() const;
static SOURCENAME Zero(Index r, Index c) { return SOURCENAME::Zero(r, c); }
static SOURCENAME _Zero(Index r, Index c) { return SOURCENAME::_Zero(r, c); }
static SOURCENAME Ones(Index r, Index c) { return SOURCENAME::Ones(r, c); }
static SOURCENAME _Ones(Index r, Index c) { return SOURCENAME::_Ones(r, c); }
static SOURCENAME Constant(Index r, Index c, TYPE v)
static SOURCENAME _Constant(Index r, Index c, TYPE v)
{
return SOURCENAME::Constant(r, c, v);
return SOURCENAME::_Constant(r, c, v);
}
static SOURCENAME Random(Index r, Index c)
static SOURCENAME _Random(Index r, Index c)
{
return SOURCENAME::Random(r, c);
return SOURCENAME::_Random(r, c);
}
static SOURCENAME Identity(Index r, Index c)
static SOURCENAME _Identity(Index r, Index c)
{
return SOURCENAME::Identity(r, c);
return SOURCENAME::_Identity(r, c);
}
public:

View file

@ -193,21 +193,21 @@ namespace rotgen
parent const& base() const { return static_cast<parent const&>(*this); }
auto evaluate() const { return concrete_type(base().eval()); }
auto _evaluate() const { return concrete_type(base().eval()); }
decltype(auto) noalias() const
decltype(auto) _noalias() const
{
if constexpr (use_expression_templates) return base().noalias();
else return *this;
}
decltype(auto) noalias()
decltype(auto) _noalias()
{
if constexpr (use_expression_templates) return base().noalias();
else return *this;
}
auto normalized() const
auto _normalized() const
requires(IsVectorAtCompileTime)
{
if constexpr (use_expression_templates) return base().normalized();
@ -216,7 +216,7 @@ namespace rotgen
base().normalized());
}
auto transpose() const
auto _transpose() const
{
if constexpr (use_expression_templates) return base().transpose();
else
@ -224,14 +224,14 @@ namespace rotgen
base().transpose());
}
auto adjoint() const
auto _adjoint() const
{
if constexpr (use_expression_templates) return base().adjoint();
else
return as_concrete_type<decltype(base().adjoint())>(base().adjoint());
}
auto conjugate() const
auto _conjugate() const
{
if constexpr (use_expression_templates) return base().conjugate();
else
@ -239,59 +239,59 @@ namespace rotgen
base().conjugate());
}
void normalize()
void _normalize()
requires(!is_immutable && IsVectorAtCompileTime)
{
parent::normalize();
}
void transposeInPlace()
void _transposeInPlace()
requires(!is_immutable)
{
parent::transposeInPlace();
}
void adjointInPlace()
void _adjointInPlace()
requires(!is_immutable)
{
parent::adjointInPlace();
}
auto cwiseAbs() const
auto _cwiseAbs() const
{
if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseAbs()};
else return base().cwiseAbs();
}
auto cwiseAbs2() const
auto _cwiseAbs2() const
{
if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseAbs2()};
else return base().cwiseAbs2();
}
auto cwiseInverse() const
auto _cwiseInverse() const
{
if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseInverse()};
else return base().cwiseInverse();
}
auto cwiseSqrt() const
auto _cwiseSqrt() const
{
if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseSqrt()};
else return base().cwiseSqrt();
}
static concrete_type Constant(value_type value)
static concrete_type _Constant(value_type value)
requires(Rows != -1 && Cols != -1)
{
return parent::Constant(Rows, Cols, static_cast<value_type>(value));
}
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)
ROTGEN_ASSERT(rows == Rows,
@ -302,13 +302,13 @@ namespace rotgen
return parent::Constant(rows, cols, static_cast<value_type>(value));
}
static concrete_type Identity()
static concrete_type _Identity()
requires(Rows != -1 && Cols != -1)
{
return parent::Identity(Rows, Cols);
}
static concrete_type Identity(int rows, int cols)
static concrete_type _Identity(int rows, int cols)
{
if constexpr (Rows != -1)
ROTGEN_ASSERT(rows == Rows,
@ -319,13 +319,13 @@ namespace rotgen
return parent::Identity(rows, cols);
}
static concrete_type Zero()
static concrete_type _Zero()
requires(Rows != -1 && Cols != -1)
{
return parent::Zero(Rows, Cols);
}
static concrete_type Zero(int rows, int cols)
static concrete_type _Zero(int rows, int cols)
{
if constexpr (Rows != -1)
ROTGEN_ASSERT(rows == Rows,
@ -336,13 +336,13 @@ namespace rotgen
return parent::Zero(rows, cols);
}
static concrete_type Ones()
static concrete_type _Ones()
requires(Rows != -1 && Cols != -1)
{
return parent::Ones(Rows, Cols);
}
static concrete_type Ones(int rows, int cols)
static concrete_type _Ones(int rows, int cols)
{
if constexpr (Rows != -1)
ROTGEN_ASSERT(rows == Rows,
@ -353,13 +353,13 @@ namespace rotgen
return parent::Ones(rows, cols);
}
static concrete_type Random()
static concrete_type _Random()
requires(Rows != -1 && Cols != -1)
{
return parent::Random(Rows, Cols);
}
static concrete_type Random(int rows, int cols)
static concrete_type _Random(int rows, int cols)
{
if constexpr (Rows != -1)
ROTGEN_ASSERT(rows == Rows,
@ -370,77 +370,77 @@ namespace rotgen
return parent::Random(rows, cols);
}
block& setOnes()
block& _setOnes()
requires(!is_immutable)
{
*this = parent::Ones(rows(), cols());
*this = parent::Ones(_rows(), _cols());
return *this;
}
block& setOnes(int r, int c)
block& _setOnes(int r, int c)
requires(!is_immutable)
{
*this = parent::Ones(r, c);
return *this;
}
block& setZero()
block& _setZero()
requires(!is_immutable)
{
*this = parent::Zero(rows(), cols());
*this = parent::Zero(_rows(), _cols());
return *this;
}
block& setZero(int r, int c)
block& _setZero(int r, int c)
requires(!is_immutable)
{
*this = parent::Zero(r, c);
return *this;
}
block& setConstant(value_type value)
block& _setConstant(value_type value)
requires(!is_immutable)
{
*this = parent::Constant(rows(), cols(), value);
*this = parent::Constant(_rows(), _cols(), value);
return *this;
}
block& setConstant(int r, int c, value_type value)
block& _setConstant(int r, int c, value_type value)
requires(!is_immutable)
{
*this = parent::Constant(r, c, value);
return *this;
}
block& setRandom()
block& _setRandom()
requires(!is_immutable)
{
*this = parent::Random(rows(), cols());
*this = parent::Random(_rows(), _cols());
return *this;
}
block& setRandom(int r, int c)
block& _setRandom(int r, int c)
requires(!is_immutable)
{
*this = parent::Random(r, c);
return *this;
}
block& setIdentity()
block& _setIdentity()
requires(!is_immutable)
{
*this = parent::Identity(rows(), cols());
*this = parent::Identity(_rows(), _cols());
return *this;
}
block& setIdentity(int r, int c)
block& _setIdentity(int r, int c)
requires(!is_immutable)
{
*this = parent::Identity(r, c);
return *this;
}
template<int P> value_type lpNorm() const
template<int P> value_type _lpNorm() const
{
static_assert(P == 1 || P == 2 || P == Infinity);
return parent::template lpNorm<P>();
@ -478,25 +478,35 @@ namespace rotgen
return (*this)(i);
}
using parent::cols;
using parent::data;
using parent::innerStride;
using parent::mean;
using parent::norm;
using parent::outerStride;
using parent::prod;
using parent::rows;
using parent::size;
using parent::squaredNorm;
using parent::sum;
using parent::trace;
auto minCoeff() const { return parent::minCoeff(); }
Index _cols() const { return parent::cols(); }
auto maxCoeff() const { return parent::maxCoeff(); }
Index _rows() const { return parent::rows(); }
value_type _mean() const { return parent::mean(); }
value_type _norm() const { return parent::norm(); }
value_type _squaredNorm() const { return parent::squaredNorm(); }
value_type _sum() const { return parent::sum(); }
value_type _prod() const { return parent::prod(); }
value_type _trace() const { return parent::trace(); }
Index _innerStride() const noexcept { return parent::innerStride(); };
Index _outerStride() const noexcept { return parent::outerStride(); };
auto _minCoeff() const { return parent::minCoeff(); }
auto _maxCoeff() const { return parent::maxCoeff(); }
template<std::integral IndexType>
auto minCoeff(IndexType* row, IndexType* col) const
auto _minCoeff(IndexType* row, IndexType* col) const
{
Index r, c;
auto result = parent::minCoeff(&r, &c);
@ -506,7 +516,7 @@ namespace rotgen
}
template<std::integral IndexType>
auto maxCoeff(IndexType* row, IndexType* col) const
auto _maxCoeff(IndexType* row, IndexType* col) const
{
Index r, c;
auto result = parent::maxCoeff(&r, &c);
@ -515,9 +525,9 @@ namespace rotgen
return result;
}
Index startRow() const { return base().startRow(); }
Index _startRow() const { return base().startRow(); }
Index startCol() const { return base().startCol(); }
Index _startCol() const { return base().startCol(); }
template<concepts::entity E>
block& operator+=(E const& rhs)

View file

@ -97,8 +97,13 @@ namespace rotgen
map(ptr_type ptr, Index r, Index c)
: parent(ptr, r, c, [&]() {
if constexpr (!std::same_as<Stride, stride<0, 0>>)
{
return strides<storage_order>(Stride{}, r, c);
else return strides<storage_order>(r, c);
}
else
{
return strides<storage_order>(r, c);
}
}())
{
}
@ -127,9 +132,9 @@ namespace rotgen
template<typename R2, int O2, typename S2>
map(map<R2, O2, S2> const& other)
: map(other.data(),
other.rows(),
other.cols(),
dynamic_stride{other.outerStride(), other.innerStride()})
other._rows(),
other._cols(),
dynamic_stride{other._outerStride(), other._innerStride()})
{
}
@ -166,11 +171,11 @@ namespace rotgen
}
else if constexpr (IsVectorAtCompileTime && !Src::IsVectorAtCompileTime)
{
auto r = other.rows();
auto c = other.cols();
auto r = other._rows();
auto c = other._cols();
ROTGEN_ASSERT(
(r == 1 || c == 1),
r == 1 || c == 1,
"Map assignment from dynamic sized source doesn't match static size");
for (rotgen::Index i = 0; i < parent::size(); ++i)
@ -178,11 +183,11 @@ namespace rotgen
}
else
{
ROTGEN_ASSERT(parent::rows() == other.rows() &&
parent::cols() == other.cols(),
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)
for (rotgen::Index r = 0; r < parent::_rows(); ++r)
for (rotgen::Index c = 0; c < parent::_cols(); ++c)
(*this)(r, c) = other(r, c);
}
@ -224,83 +229,86 @@ namespace rotgen
return (*this)(i);
}
concrete_type evaluate() const { return concrete_type{*this}; }
concrete_type _evaluate() const { return concrete_type{*this}; }
decltype(auto) noalias() const { return *this; }
decltype(auto) _noalias() const { return *this; }
decltype(auto) noalias() { return *this; }
decltype(auto) _noalias() { return *this; }
concrete_type normalized() const
concrete_type _normalized() const
requires(IsVectorAtCompileTime)
{
return concrete_type(base().normalized());
return concrete_type(base()._normalized());
}
transposed_type transpose() const
transposed_type _transpose() const
{
return transposed_type(base().transpose());
return transposed_type(base()._transpose());
}
concrete_type conjugate() const
concrete_type _conjugate() const
{
return concrete_type(base().conjugate());
return concrete_type(base()._conjugate());
}
transposed_type adjoint() const
transposed_type _adjoint() const
{
return transposed_type(base().adjoint());
return transposed_type(base()._adjoint());
}
concrete_type cwiseAbs() const { return concrete_type(base().cwiseAbs()); }
concrete_type cwiseAbs2() const
concrete_type _cwiseAbs() const
{
return concrete_type(base().cwiseAbs2());
return concrete_type(base()._cwiseAbs());
}
concrete_type cwiseInverse() const
concrete_type _cwiseAbs2() const
{
return concrete_type(base().cwiseInverse());
return concrete_type(base()._cwiseAbs2());
}
concrete_type cwiseSqrt() const
concrete_type _cwiseInverse() const
{
return concrete_type(base().cwiseSqrt());
return concrete_type(base()._cwiseInverse());
}
concrete_type cwiseMin(map const& rhs) const
concrete_type _cwiseSqrt() const
{
return concrete_type(base().cwiseMin(rhs.base()));
return concrete_type(base()._cwiseSqrt());
}
concrete_type cwiseMax(map const& rhs) const
concrete_type _cwiseMin(map const& rhs) const
{
return concrete_type(base().cwiseMax(rhs.base()));
return concrete_type(base()._cwiseMin(rhs.base()));
}
concrete_type cwiseQuotient(map const& rhs) const
concrete_type _cwiseMax(map const& rhs) const
{
return concrete_type(base().cwiseQuotient(rhs.base()));
return concrete_type(base()._cwiseMax(rhs.base()));
}
concrete_type cwiseProduct(map const& rhs) const
concrete_type _cwiseQuotient(map const& rhs) const
{
return concrete_type(base().cwiseProduct(rhs.base()));
return concrete_type(base()._cwiseQuotient(rhs.base()));
}
concrete_type cwiseMin(value_type s) const
concrete_type _cwiseProduct(map const& rhs) const
{
return concrete_type(base().cwiseMin(s));
return concrete_type(base()._cwiseProduct(rhs.base()));
}
concrete_type cwiseMax(value_type s) const
concrete_type _cwiseMin(value_type s) const
{
return concrete_type(base().cwiseMax(s));
return concrete_type(base()._cwiseMin(s));
}
concrete_type inverse() const { return concrete_type(base().inverse()); }
concrete_type _cwiseMax(value_type s) const
{
return concrete_type(base()._cwiseMax(s));
}
concrete_type cross(map const& other) const
concrete_type _inverse() const { return concrete_type(base()._inverse()); }
concrete_type _cross(map const& other) const
{
concrete_type that;
if constexpr (ColsAtCompileTime == 1)
@ -318,22 +326,22 @@ namespace rotgen
return that;
}
void normalize()
void _normalize()
requires(!is_immutable && IsVectorAtCompileTime)
{
parent::normalize();
parent::_normalize();
}
void transposeInPlace()
void _transposeInPlace()
requires(!is_immutable)
{
parent::transposeInPlace();
parent::_transposeInPlace();
}
void adjointInPlace()
void _adjointInPlace()
requires(!is_immutable)
{
parent::adjointInPlace();
parent::_adjointInPlace();
}
template<typename R2, int O2, typename S2>
@ -363,8 +371,8 @@ namespace rotgen
map& operator*=(map<R2, O2, S2> const& rhs)
requires(!is_immutable)
{
ROTGEN_ASSERT(parent::cols() == rhs.rows() &&
parent::cols() == rhs.cols(),
ROTGEN_ASSERT(parent::_cols() == rhs._rows() &&
parent::_cols() == rhs._cols(),
"Incompatible dimensions for compound matrix-product");
base() *= rhs.base();
return *this;
@ -384,121 +392,121 @@ namespace rotgen
return *this;
}
auto minCoeff() const { return parent::minCoeff(); }
auto _minCoeff() const { return parent::_minCoeff(); }
auto maxCoeff() const { return parent::maxCoeff(); }
auto _maxCoeff() const { return parent::_maxCoeff(); }
template<std::integral IndexType>
auto minCoeff(IndexType* row, IndexType* col) const
auto _minCoeff(IndexType* row, IndexType* col) const
{
Index r, c;
auto result = parent::minCoeff(&r, &c);
auto result = parent::_minCoeff(&r, &c);
*row = r;
*col = c;
return result;
}
template<std::integral IndexType>
auto maxCoeff(IndexType* row, IndexType* col) const
auto _maxCoeff(IndexType* row, IndexType* col) const
{
Index r, c;
auto result = parent::maxCoeff(&r, &c);
auto result = parent::_maxCoeff(&r, &c);
*row = r;
*col = c;
return result;
}
static auto Zero()
requires(requires { Ref::Zero(); })
static auto _Zero()
requires(requires { Ref::_Zero(); })
{
return Ref::Zero();
return Ref::_Zero();
}
static auto Ones()
requires(requires { Ref::Ones(); })
static auto _Ones()
requires(requires { Ref::_Ones(); })
{
return Ref::Ones();
return Ref::_Ones();
}
static auto Zero(int rows, int cols) { return Ref::Zero(rows, cols); }
static auto _Zero(int rows, int cols) { return Ref::_Zero(rows, cols); }
static auto Ones(int rows, int cols) { return Ref::Ones(rows, cols); }
static auto _Ones(int rows, int cols) { return Ref::_Ones(rows, cols); }
static auto Constant(value_type value)
requires(requires { Ref::Constant(value); })
static auto _Constant(value_type value)
requires(requires { Ref::_Constant(value); })
{
return Ref::Constant(value);
return Ref::_Constant(value);
}
static auto Constant(int rows, int cols, value_type value)
static auto _Constant(int rows, int cols, value_type value)
{
return Ref::Constant(rows, cols, value);
return Ref::_Constant(rows, cols, value);
}
static auto Random()
requires(requires { Ref::Random(); })
static auto _Random()
requires(requires { Ref::_Random(); })
{
return Ref::Random();
return Ref::_Random();
}
static auto Random(int rows, int cols) { return Ref::Random(rows, cols); }
static auto _Random(int rows, int cols) { return Ref::_Random(rows, cols); }
static auto Identity()
requires(requires { Ref::Identity(); })
static auto _Identity()
requires(requires { Ref::_Identity(); })
{
return Ref::Identity();
return Ref::_Identity();
}
static auto Identity(int rows, int cols)
static auto _Identity(int rows, int cols)
{
return Ref::Identity(rows, cols);
return Ref::_Identity(rows, cols);
}
map& setZero()
map& _setZero()
requires(!is_immutable)
{
parent::setZero();
parent::_setZero();
return *this;
}
map& setOnes()
map& _setOnes()
requires(!is_immutable)
{
parent::setOnes();
parent::_setOnes();
return *this;
}
map& setIdentity()
map& _setIdentity()
requires(!is_immutable)
{
parent::setIdentity();
parent::_setIdentity();
return *this;
}
map& setRandom()
map& _setRandom()
requires(!is_immutable)
{
parent::setRandom();
parent::_setRandom();
return *this;
}
map& setConstant(value_type s)
map& _setConstant(value_type scalar)
requires(!is_immutable)
{
parent::setConstant(s);
parent::_setConstant(scalar);
return *this;
}
template<typename R2, int O2, typename S2>
value_type dot(map<R2, O2, S2> const& rhs) const
value_type _dot(map<R2, O2, S2> const& rhs) const
{
return base().dot(rhs.base());
return base()._dot(rhs.base());
}
template<int P> value_type lpNorm() const
template<int P> value_type _lpNorm() const
{
static_assert(P == 1 || P == 2 || P == Infinity);
return parent::lpNorm(P);
return parent::_lpNorm(P);
}
parent& base() { return static_cast<parent&>(*this); }
@ -529,9 +537,9 @@ namespace rotgen
}
else
{
ROTGEN_ASSERT(parent::rows() == rhs.rows(),
ROTGEN_ASSERT(parent::_rows() == rhs._rows(),
"Mismatched rows count in compound assignment operator");
ROTGEN_ASSERT(parent::cols() == rhs.cols(),
ROTGEN_ASSERT(parent::_cols() == rhs._cols(),
"Mismatched cols count in compound assignment operator");
}
}
@ -544,7 +552,7 @@ namespace rotgen
using map1_type = map<R1 const, O1, S1>;
using map2_type = map<R2 const, O2, S2>;
using concrete_type = detail::composite_type<R1, R2, matrix>;
return concrete_type(map1_type(lhs).base().add(map2_type(rhs)));
return concrete_type(map1_type(lhs).base()._add(map2_type(rhs)));
}
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
@ -554,7 +562,7 @@ namespace rotgen
using map1_type = map<R1 const, O1, S1>;
using map2_type = map<R2 const, O2, S2>;
using concrete_type = detail::composite_type<R1, R2, matrix>;
return concrete_type(map1_type(lhs).base().sub(map2_type(rhs)));
return concrete_type(map1_type(lhs).base()._sub(map2_type(rhs)));
}
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
@ -565,12 +573,22 @@ namespace rotgen
using concrete_type = matrix<typename R1::value_type, R1::RowsAtCompileTime,
R2::ColsAtCompileTime, R1::storage_order>;
if constexpr (concrete_type::SizeAtCompileTime == 0) return concrete_type{};
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;
auto product_result =
concrete_type(map1_type(lhs).base()._mul(map2_type(rhs).base()));
if constexpr (concrete_type::SizeAtCompileTime == 1)
{
return product{product_result};
}
else
{
return product_result;
}
}
}
@ -579,7 +597,7 @@ namespace rotgen
map<R, O, S> const& lhs, std::convertible_to<typename R::value_type> auto s)
{
using concrete_type = typename map<R, O, S>::concrete_type;
return concrete_type(lhs.base().mul(s));
return concrete_type(lhs.base()._mul(s));
}
template<typename R, int O, typename S>
@ -587,7 +605,7 @@ namespace rotgen
std::convertible_to<typename R::value_type> auto s, map<R, O, S> const& rhs)
{
using concrete_type = typename map<R, O, S>::concrete_type;
return concrete_type(rhs.base().mul(s));
return concrete_type(rhs.base()._mul(s));
}
template<typename R, int O, typename S>
@ -595,7 +613,7 @@ namespace rotgen
map<R, O, S> const& lhs, std::convertible_to<typename R::value_type> auto s)
{
using concrete_type = typename map<R, O, S>::concrete_type;
return concrete_type(lhs.base().div(s));
return concrete_type(lhs.base()._div(s));
}
template<typename R1, int O1, typename S1, typename R2, int O2, typename S2>

View file

@ -28,52 +28,53 @@ public:
~CLASSNAME();
Index rows() const;
Index cols() const;
Index size() const;
Index innerStride() const;
Index outerStride() const;
Index _rows() const;
Index _cols() const;
SOURCENAME normalized() const;
SOURCENAME transpose() const;
SOURCENAME conjugate() const;
SOURCENAME adjoint() const;
Index _innerStride() const;
Index _outerStride() const;
SOURCENAME cwiseAbs() const;
SOURCENAME cwiseAbs2() const;
SOURCENAME cwiseInverse() const;
SOURCENAME cwiseSqrt() const;
SOURCENAME _normalized() const;
SOURCENAME _transpose() const;
SOURCENAME _conjugate() const;
SOURCENAME _adjoint() const;
SOURCENAME cwiseMax(CLASSNAME const&) const;
SOURCENAME cwiseMin(CLASSNAME const&) const;
SOURCENAME cwiseProduct(CLASSNAME const&) const;
SOURCENAME cwiseQuotient(CLASSNAME const&) const;
SOURCENAME cwiseMax(TYPE) const;
SOURCENAME cwiseMin(TYPE) const;
SOURCENAME _cwiseAbs() const;
SOURCENAME _cwiseAbs2() const;
SOURCENAME _cwiseInverse() const;
SOURCENAME _cwiseSqrt() const;
SOURCENAME _cwiseMax(CLASSNAME const&) const;
SOURCENAME _cwiseMin(CLASSNAME const&) const;
SOURCENAME _cwiseProduct(CLASSNAME const&) const;
SOURCENAME _cwiseQuotient(CLASSNAME const&) const;
SOURCENAME _cwiseMax(TYPE) const;
SOURCENAME _cwiseMin(TYPE) const;
#if !defined(USE_CONST)
void normalize();
void transposeInPlace();
void adjointInPlace();
void _normalize();
void _transposeInPlace();
void _adjointInPlace();
#endif
TYPE sum() const;
TYPE prod() const;
TYPE mean() const;
TYPE trace() const;
TYPE maxCoeff() const;
TYPE minCoeff() const;
TYPE maxCoeff(Index*, Index*) const;
TYPE minCoeff(Index*, Index*) const;
TYPE dot(CLASSNONCONSTNAME const&) const;
TYPE dot(CLASSCONSTNAME const&) const;
TYPE dot(TRANSCLASSCONSTNAME const&) const;
TYPE dot(TRANSCLASSNONCONSTNAME const&) const;
TYPE _sum() const;
TYPE _prod() const;
TYPE _mean() const;
TYPE _trace() const;
TYPE _maxCoeff() const;
TYPE _minCoeff() const;
TYPE _maxCoeff(Index*, Index*) const;
TYPE _minCoeff(Index*, Index*) 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;
TYPE lpNorm(int p) const;
TYPE _squaredNorm() const;
TYPE _norm() const;
TYPE _lpNorm(int p) const;
SOURCENAME qr_solve(CLASSNAME const& rhs) const;
@ -103,16 +104,16 @@ public:
#endif
SOURCENAME operator-() const;
SOURCENAME add(CLASSNAME const& rhs) const;
SOURCENAME add(TRANSCLASSNAME const& rhs) const;
SOURCENAME sub(CLASSNAME const& rhs) const;
SOURCENAME sub(TRANSCLASSNAME const& rhs) const;
SOURCENAME mul(CLASSNAME const& rhs) const;
SOURCENAME mul(TRANSCLASSNAME const& rhs) const;
SOURCENAME mul(TYPE s) const;
SOURCENAME div(TYPE s) const;
SOURCENAME _add(CLASSNAME const& rhs) const;
SOURCENAME _add(TRANSCLASSNAME const& rhs) const;
SOURCENAME _sub(CLASSNAME const& rhs) const;
SOURCENAME _sub(TRANSCLASSNAME const& rhs) const;
SOURCENAME _mul(CLASSNAME const& rhs) const;
SOURCENAME _mul(TRANSCLASSNAME const& rhs) const;
SOURCENAME _mul(TYPE s) const;
SOURCENAME _div(TYPE s) const;
SOURCENAME inverse() const;
SOURCENAME _inverse() const;
friend ROTGEN_EXPORT std::ostream& operator<<(std::ostream&,
CLASSNAME const&);
@ -122,11 +123,11 @@ public:
#if !defined(USE_CONST)
TYPE* data();
void setZero();
void setOnes();
void setRandom();
void setIdentity();
void setConstant(TYPE);
void _setZero();
void _setOnes();
void _setRandom();
void _setIdentity();
void _setConstant(TYPE);
#endif
friend ROTGEN_EXPORT bool operator==(CLASSNAME const& lhs,

View file

@ -134,15 +134,15 @@ namespace rotgen
parent const& base() const { return static_cast<parent const&>(*this); }
auto evaluate() const { return concrete_type(base().eval()); }
auto _evaluate() const { return concrete_type(base().eval()); }
decltype(auto) noalias() const
decltype(auto) _noalias() const
{
if constexpr (use_expression_templates) return base().noalias();
else return *this;
}
decltype(auto) noalias()
decltype(auto) _noalias()
{
if constexpr (use_expression_templates) return base().noalias();
else return *this;
@ -221,91 +221,91 @@ namespace rotgen
return *this;
}
auto cwiseMin(map const& rhs) const
auto _cwiseMin(map const& rhs) const
{
if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseMin(rhs.base())};
else return base().cwiseMin(rhs.base());
}
auto cwiseMin(value_type rhs) const
auto _cwiseMin(value_type rhs) const
{
if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseMin(rhs)};
else return base().cwiseMin(rhs);
}
auto cwiseMax(map const& rhs) const
auto _cwiseMax(map const& rhs) const
{
if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseMax(rhs.base())};
else return base().cwiseMax(rhs.base());
}
auto cwiseMax(value_type rhs) const
auto _cwiseMax(value_type rhs) const
{
if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseMax(rhs)};
else return base().cwiseMax(rhs);
}
auto cwiseProduct(map const& rhs) const
auto _cwiseProduct(map const& rhs) const
{
if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseProduct(rhs.base())};
else return base().cwiseProduct(rhs.base());
}
auto cwiseQuotient(map const& rhs) const
auto _cwiseQuotient(map const& rhs) const
{
if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseQuotient(rhs.base())};
else return base().cwiseQuotient(rhs.base());
}
auto cwiseAbs() const
auto _cwiseAbs() const
{
if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseAbs()};
else return base().cwiseAbs();
}
auto cwiseAbs2() const
auto _cwiseAbs2() const
{
if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseAbs2()};
else return base().cwiseAbs2();
}
auto cwiseInverse() const
auto _cwiseInverse() const
{
if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseInverse()};
else return base().cwiseInverse();
}
auto cwiseSqrt() const
auto _cwiseSqrt() const
{
if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseSqrt()};
else return base().cwiseSqrt();
}
auto cross(map const& rhs) const
auto _cross(map const& rhs) const
{
if constexpr (!use_expression_templates)
return concrete_type{parent::cross(rhs.base())};
else return base().cross(rhs.base());
}
auto inverse() const
auto _inverse() const
{
if constexpr (use_expression_templates) return base().inverse();
else
return as_concrete_type<decltype(base().inverse())>(base().inverse());
}
auto normalized() const
auto _normalized() const
requires(IsVectorAtCompileTime)
{
if constexpr (use_expression_templates) return base().normalized();
@ -314,7 +314,7 @@ namespace rotgen
base().normalized());
}
auto transpose() const
auto _transpose() const
{
if constexpr (use_expression_templates) return base().transpose();
else
@ -322,14 +322,14 @@ namespace rotgen
base().transpose());
}
auto adjoint() const
auto _adjoint() const
{
if constexpr (use_expression_templates) return base().adjoint();
else
return as_concrete_type<decltype(base().adjoint())>(base().adjoint());
}
auto conjugate() const
auto _conjugate() const
{
if constexpr (use_expression_templates) return base().conjugate();
else
@ -337,116 +337,126 @@ namespace rotgen
base().conjugate());
}
void normalize()
void _normalize()
requires(IsVectorAtCompileTime)
{
base().normalize();
}
void transposeInPlace() { base().transposeInPlace(); }
void _transposeInPlace() { base().transposeInPlace(); }
void adjointInPlace() { base().adjointInPlace(); }
void _adjointInPlace() { base().adjointInPlace(); }
auto qr_solve(auto const& rhs) const
{
return concrete_type(base().colPivHouseholderQr().solve(rhs.base()));
};
static auto Zero()
static auto _Zero()
requires(requires { Ref::Zero(); })
{
return Ref::Zero();
}
static auto Zero(int rows, int cols) { return Ref::Zero(rows, cols); }
static auto _Zero(int rows, int cols) { return Ref::Zero(rows, cols); }
static auto Ones()
static auto _Ones()
requires(requires { Ref::Ones(); })
{
return Ref::Ones();
}
static auto Ones(int rows, int cols) { return Ref::Ones(rows, cols); }
static auto _Ones(int rows, int cols) { return Ref::Ones(rows, cols); }
static auto Constant(value_type value)
static auto _Constant(value_type value)
requires(requires { Ref::Constant(value); })
{
return Ref::Constant(value);
}
static auto Constant(int rows, int cols, value_type value)
static auto _Constant(int rows, int cols, value_type value)
{
return Ref::Constant(rows, cols, value);
}
static auto Random()
static auto _Random()
requires(requires { Ref::Random(); })
{
return Ref::Random();
}
static auto Random(int rows, int cols) { return Ref::Random(rows, cols); }
static auto _Random(int rows, int cols) { return Ref::Random(rows, cols); }
static auto Identity()
static auto _Identity()
requires(requires { Ref::Identity(); })
{
return Ref::Identity();
}
static auto Identity(int rows, int cols)
static auto _Identity(int rows, int cols)
{
return Ref::Identity(rows, cols);
}
map& setOnes()
map& _setOnes()
{
base() = parent::Ones(base().rows(), base().cols());
return *this;
}
map& setZero()
map& _setZero()
{
base() = parent::Zero(base().rows(), base().cols());
return *this;
}
map& setConstant(value_type value)
map& _setConstant(value_type value)
{
base() = parent::Constant(base().rows(), base().cols(), value);
return *this;
}
map& setRandom()
map& _setRandom()
{
base() = parent::Random(base().rows(), base().cols());
return *this;
}
map& setIdentity()
map& _setIdentity()
{
base() = parent::Identity(base().rows(), base().cols());
return *this;
}
using parent::cols;
using parent::data;
using parent::innerStride;
using parent::mean;
using parent::norm;
using parent::outerStride;
using parent::prod;
using parent::rows;
using parent::size;
using parent::squaredNorm;
using parent::sum;
using parent::trace;
auto minCoeff() const { return parent::minCoeff(); }
Index _cols() const { return parent::cols(); }
auto maxCoeff() const { return parent::maxCoeff(); }
Index _rows() const { return parent::rows(); }
value_type _mean() const { return parent::mean(); }
value_type _norm() const { return parent::norm(); }
value_type _squaredNorm() const { return parent::squaredNorm(); }
value_type _sum() const { return parent::sum(); }
value_type _prod() const { return parent::prod(); }
value_type _trace() const { return parent::trace(); }
Index _innerStride() const noexcept { return parent::innerStride(); };
Index _outerStride() const noexcept { return parent::outerStride(); };
auto _minCoeff() const { return parent::minCoeff(); }
auto _maxCoeff() const { return parent::maxCoeff(); }
template<std::integral IndexType>
auto minCoeff(IndexType* row, IndexType* col) const
auto _minCoeff(IndexType* row, IndexType* col) const
{
Index r, c;
auto result = parent::minCoeff(&r, &c);
@ -456,7 +466,7 @@ namespace rotgen
}
template<std::integral IndexType>
auto maxCoeff(IndexType* row, IndexType* col) const
auto _maxCoeff(IndexType* row, IndexType* col) const
{
Index r, c;
auto result = parent::maxCoeff(&r, &c);
@ -466,12 +476,12 @@ namespace rotgen
}
template<typename R2, int O2, typename S2>
value_type dot(map<R2, O2, S2> const& rhs) const
value_type _dot(map<R2, O2, S2> const& rhs) const
{
return base().dot(rhs.base());
}
template<int P> value_type lpNorm() const
template<int P> value_type _lpNorm() const
{
static_assert(P == 1 || P == 2 || P == Infinity);
return parent::template lpNorm<P>();

View file

@ -129,10 +129,10 @@ namespace rotgen
}
else
{
resize(other.rows(), other.cols());
resize(other._rows(), other._cols());
for (rotgen::Index r = 0; r < parent::rows(); ++r)
for (rotgen::Index c = 0; c < parent::cols(); ++c)
for (rotgen::Index r = 0; r < parent::_rows(); ++r)
for (rotgen::Index c = 0; c < parent::_cols(); ++c)
(*this)(r, c) = other(r, c);
}
}
@ -163,21 +163,21 @@ namespace rotgen
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; }
decltype(auto) noalias() { return *this; }
decltype(auto) _noalias() { return *this; }
Index innerStride() const noexcept { return 1; }
Index _innerStride() const noexcept { return 1; }
Index outerStride() const noexcept
Index _outerStride() const noexcept
{
if constexpr (IsVectorAtCompileTime) return this->size();
else
{
if constexpr (IsRowMajor) return this->cols();
else return this->rows();
if constexpr (IsRowMajor) return this->_cols();
else return this->_rows();
}
}
@ -199,7 +199,7 @@ namespace rotgen
else parent::resize(s, 1);
}
void conservativeResize(int r, int c)
void _conservativeResize(int r, int c)
{
if constexpr (Cols != -1)
ROTGEN_ASSERT(c == Cols,
@ -207,51 +207,51 @@ namespace rotgen
if constexpr (Rows != -1)
ROTGEN_ASSERT(r == Rows,
"Mismatched between dynamic and static row size");
parent::conservativeResize(r, c);
parent::_conservativeResize(r, c);
}
void conservativeResize(int s)
void _conservativeResize(int s)
requires(IsVectorAtCompileTime)
{
if constexpr (Rows == 1) parent::conservativeResize(1, s);
else parent::conservativeResize(s, 1);
if constexpr (Rows == 1) parent::_conservativeResize(1, s);
else parent::_conservativeResize(s, 1);
}
matrix normalized() const
matrix _normalized() const
requires(IsVectorAtCompileTime)
{
return matrix(base().normalized());
return matrix(base()._normalized());
}
transposed_type transpose() const
transposed_type _transpose() const
{
return transposed_type(base().transpose());
return transposed_type(base()._transpose());
}
matrix conjugate() const { return matrix(base().conjugate()); }
matrix _conjugate() const { return matrix(base()._conjugate()); }
transposed_type adjoint() const
transposed_type _adjoint() const
{
return transposed_type(base().adjoint());
return transposed_type(base()._adjoint());
}
void normalize()
void _normalize()
requires(IsVectorAtCompileTime)
{
parent::normalize();
parent::_normalize();
}
void transposeInPlace() { parent::transposeInPlace(); }
void _transposeInPlace() { parent::_transposeInPlace(); }
void adjointInPlace() { parent::adjointInPlace(); }
void _adjointInPlace() { parent::_adjointInPlace(); }
matrix cwiseAbs() const { return matrix(base().cwiseAbs()); }
matrix _cwiseAbs() const { return matrix(base()._cwiseAbs()); }
matrix cwiseAbs2() const { return matrix(base().cwiseAbs2()); }
matrix _cwiseAbs2() const { return matrix(base()._cwiseAbs2()); }
matrix cwiseInverse() const { return matrix(base().cwiseInverse()); }
matrix _cwiseInverse() const { return matrix(base()._cwiseInverse()); }
matrix cwiseSqrt() const { return matrix(base().cwiseSqrt()); }
matrix _cwiseSqrt() const { return matrix(base()._cwiseSqrt()); }
friend bool operator==(matrix const& lhs, matrix const& rhs)
{
@ -290,37 +290,37 @@ namespace rotgen
return *this;
}
auto minCoeff() const { return parent::minCoeff(); }
auto _minCoeff() const { return parent::_minCoeff(); }
auto maxCoeff() const { return parent::maxCoeff(); }
auto _maxCoeff() const { return parent::_maxCoeff(); }
template<std::integral IndexType>
auto minCoeff(IndexType* row, IndexType* col) const
auto _minCoeff(IndexType* row, IndexType* col) const
{
Index r, c;
auto result = parent::minCoeff(&r, &c);
auto result = parent::_minCoeff(&r, &c);
*row = r;
*col = c;
return result;
}
template<std::integral IndexType>
auto maxCoeff(IndexType* row, IndexType* col) const
auto _maxCoeff(IndexType* row, IndexType* col) const
{
Index r, c;
auto result = parent::maxCoeff(&r, &c);
auto result = parent::_maxCoeff(&r, &c);
*row = r;
*col = c;
return result;
}
static matrix Ones()
static matrix _Ones()
requires(Rows != -1 && Cols != -1)
{
return parent::Ones(Rows, Cols);
return parent::_Ones(Rows, Cols);
}
static matrix Ones(int rows, int cols)
static matrix _Ones(int rows, int cols)
{
if constexpr (Rows != -1)
ROTGEN_ASSERT(rows == Rows,
@ -328,16 +328,16 @@ namespace rotgen
if constexpr (Cols != -1)
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Ones(rows, cols);
return parent::_Ones(rows, cols);
}
static matrix Zero()
static matrix _Zero()
requires(Rows != -1 && Cols != -1)
{
return parent::Zero(Rows, Cols);
return parent::_Zero(Rows, Cols);
}
static matrix Zero(int rows, int cols)
static matrix _Zero(int rows, int cols)
{
if constexpr (Rows != -1)
ROTGEN_ASSERT(rows == Rows,
@ -345,16 +345,16 @@ namespace rotgen
if constexpr (Cols != -1)
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Zero(rows, cols);
return parent::_Zero(rows, cols);
}
static matrix Constant(Scalar value)
static matrix _Constant(Scalar value)
requires(Rows != -1 && Cols != -1)
{
return parent::Constant(Rows, Cols, static_cast<Scalar>(value));
return parent::_Constant(Rows, Cols, static_cast<Scalar>(value));
}
static matrix Constant(int rows, int cols, Scalar value)
static matrix _Constant(int rows, int cols, Scalar value)
{
if constexpr (Rows != -1)
ROTGEN_ASSERT(rows == Rows,
@ -362,16 +362,16 @@ namespace rotgen
if constexpr (Cols != -1)
ROTGEN_ASSERT(cols == Cols,
"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));
}
static matrix Random()
static matrix _Random()
requires(Rows != -1 && Cols != -1)
{
return parent::Random(Rows, Cols);
return parent::_Random(Rows, Cols);
}
static matrix Random(int rows, int cols)
static matrix _Random(int rows, int cols)
{
if constexpr (Rows != -1)
ROTGEN_ASSERT(rows == Rows,
@ -379,16 +379,16 @@ namespace rotgen
if constexpr (Cols != -1)
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Random(rows, cols);
return parent::_Random(rows, cols);
}
static matrix Identity()
static matrix _Identity()
requires(Rows != -1 && Cols != -1)
{
return parent::Identity(Rows, Cols);
return parent::_Identity(Rows, Cols);
}
static matrix Identity(int rows, int cols)
static matrix _Identity(int rows, int cols)
{
if constexpr (Rows != -1)
ROTGEN_ASSERT(rows == Rows,
@ -396,74 +396,74 @@ namespace rotgen
if constexpr (Cols != -1)
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Identity(rows, cols);
return parent::_Identity(rows, cols);
}
matrix& setOnes()
matrix& _setOnes()
{
parent::setOnes(parent::rows(), parent::cols());
parent::_setOnes(parent::_rows(), parent::_cols());
return *this;
}
matrix& setOnes(int rows, int cols)
matrix& _setOnes(int rows, int cols)
{
parent::setOnes(rows, cols);
parent::_setOnes(rows, cols);
return *this;
}
matrix& setZero()
matrix& _setZero()
{
parent::setZero(parent::rows(), parent::cols());
parent::_setZero(parent::_rows(), parent::_cols());
return *this;
}
matrix& setZero(int rows, int cols)
matrix& _setZero(int rows, int cols)
{
parent::setZero(rows, cols);
parent::_setZero(rows, cols);
return *this;
}
matrix& setConstant(Scalar v)
matrix& _setConstant(Scalar v)
{
parent::setConstant(parent::rows(), parent::cols(),
static_cast<Scalar>(v));
parent::_setConstant(parent::_rows(), parent::_cols(),
static_cast<Scalar>(v));
return *this;
}
matrix& setConstant(int rows, int cols, Scalar v)
matrix& _setConstant(int rows, int cols, Scalar v)
{
parent::setConstant(rows, cols, static_cast<Scalar>(v));
parent::_setConstant(rows, cols, static_cast<Scalar>(v));
return *this;
}
matrix& setRandom()
matrix& _setRandom()
{
parent::setRandom(parent::rows(), parent::cols());
parent::_setRandom(parent::_rows(), parent::_cols());
return *this;
}
matrix& setRandom(int rows, int cols)
matrix& _setRandom(int rows, int cols)
{
parent::setRandom(rows, cols);
parent::_setRandom(rows, cols);
return *this;
}
matrix& setIdentity()
matrix& _setIdentity()
{
parent::setIdentity(parent::rows(), parent::cols());
parent::_setIdentity(parent::_rows(), parent::_cols());
return *this;
}
matrix& setIdentity(int rows, int cols)
matrix& _setIdentity(int rows, int cols)
{
parent::setIdentity(rows, cols);
parent::_setIdentity(rows, cols);
return *this;
}
template<int P> Scalar lpNorm() const
template<int P> Scalar _lpNorm() const
{
static_assert(P == 1 || P == 2 || P == Infinity);
return parent::lp_norm(P);
return parent::_lp_norm(P);
}
parent& base() { return static_cast<parent&>(*this); }

View file

@ -28,39 +28,40 @@ public:
~CLASSNAME();
Index rows() const;
Index cols() const;
Index size() const;
Index _rows() const;
Index _cols() const;
void resize(Index new_rows, Index new_cols);
void conservativeResize(Index new_rows, Index new_cols);
void _conservativeResize(Index new_rows, Index new_cols);
CLASSNAME normalized() const;
CLASSNAME transpose() const;
CLASSNAME conjugate() const;
CLASSNAME adjoint() const;
CLASSNAME _normalized() const;
CLASSNAME _transpose() const;
CLASSNAME _conjugate() const;
CLASSNAME _adjoint() const;
CLASSNAME cwiseAbs() const;
CLASSNAME cwiseAbs2() const;
CLASSNAME cwiseInverse() const;
CLASSNAME cwiseSqrt() const;
CLASSNAME _cwiseAbs() const;
CLASSNAME _cwiseAbs2() const;
CLASSNAME _cwiseInverse() const;
CLASSNAME _cwiseSqrt() const;
void normalize();
void transposeInPlace();
void adjointInPlace();
void _normalize();
void _transposeInPlace();
void _adjointInPlace();
TYPE sum() const;
TYPE prod() const;
TYPE mean() const;
TYPE trace() const;
TYPE maxCoeff() const;
TYPE minCoeff() const;
TYPE maxCoeff(Index* row, Index* col) const;
TYPE minCoeff(Index* row, Index* col) const;
TYPE _sum() const;
TYPE _prod() const;
TYPE _mean() const;
TYPE _trace() const;
TYPE _maxCoeff() const;
TYPE _minCoeff() const;
TYPE _maxCoeff(Index* row, Index* col) const;
TYPE _minCoeff(Index* row, Index* col) const;
TYPE squaredNorm() const;
TYPE norm() const;
TYPE lp_norm(int p) const;
TYPE _squaredNorm() const;
TYPE _norm() const;
TYPE _lp_norm(int p) const;
TYPE& operator()(Index i, Index j);
TYPE const& operator()(Index i, Index j) const;
@ -87,17 +88,17 @@ public:
const TYPE* data() const;
TYPE* data();
static CLASSNAME Zero(Index rows, Index cols);
static CLASSNAME Ones(Index rows, Index cols);
static CLASSNAME Constant(Index rows, Index cols, TYPE value);
static CLASSNAME Random(Index rows, Index cols);
static CLASSNAME Identity(Index rows, Index cols);
static CLASSNAME _Zero(Index rows, Index cols);
static CLASSNAME _Ones(Index rows, Index cols);
static CLASSNAME _Constant(Index rows, Index cols, TYPE value);
static CLASSNAME _Random(Index rows, Index cols);
static CLASSNAME _Identity(Index rows, Index cols);
void setOnes(Index rows, Index cols);
void setZero(Index rows, Index cols);
void setConstant(Index rows, Index cols, TYPE value);
void setRandom(Index rows, Index cols);
void setIdentity(Index rows, Index cols);
void _setOnes(Index rows, Index cols);
void _setZero(Index rows, Index cols);
void _setConstant(Index rows, Index cols, TYPE value);
void _setRandom(Index rows, Index cols);
void _setIdentity(Index rows, Index cols);
void swap(CLASSNAME& other) { storage_.swap(other.storage_); }

View file

@ -100,12 +100,16 @@ namespace rotgen
matrix(Index r, Index c) : parent(r, c)
{
if constexpr (RowsAtCompileTime != -1)
{
ROTGEN_ASSERT(r == RowsAtCompileTime,
"Mismatched between dynamic and static row size");
}
if constexpr (ColsAtCompileTime != -1)
{
ROTGEN_ASSERT(c == ColsAtCompileTime,
"Mismatched between dynamic and static column size");
}
}
matrix(matrix const& other) = default;
@ -127,8 +131,11 @@ namespace rotgen
explicit matrix(Scalar v)
requires(Rows == 1 && Cols == 1)
: parent([&]() {
if constexpr (has_static_storage) return parent(v);
else return parent{1, 1};
if constexpr (has_static_storage) { return parent(v); }
else
{
return parent{1, 1};
}
}())
{
if constexpr (!has_static_storage) (*this)(0) = v;
@ -137,12 +144,18 @@ namespace rotgen
matrix(std::initializer_list<Scalar> init)
requires(IsVectorAtCompileTime)
: parent([&]() {
if constexpr (has_static_storage) return parent{};
else return parent{Rows, Cols};
if constexpr (has_static_storage) { return parent{}; }
else
{
return parent{Rows, Cols};
}
}())
{
auto first = init.begin();
for (rotgen::Index i = 0; i < parent::size(); i++) (*this)(i) = first[i];
for (rotgen::Index i = 0; i < parent::size(); i++)
{
(*this)(i) = first[i];
}
}
matrix(Scalar v0, Scalar v1, auto... vs)
@ -184,31 +197,34 @@ namespace rotgen
return *this;
}
using parent::innerStride;
using parent::outerStride;
parent& base() { return static_cast<parent&>(*this); }
parent const& base() const { return static_cast<parent const&>(*this); }
auto evaluate() const { return *this; }
auto _evaluate() const { return *this; }
decltype(auto) noalias() const
decltype(auto) _noalias() const
{
if constexpr (use_expression_templates) return base().noalias();
else return *this;
if constexpr (use_expression_templates) { return base().noalias(); }
else
{
return *this;
}
}
decltype(auto) noalias()
decltype(auto) _noalias()
{
if constexpr (use_expression_templates) return base().noalias();
else return *this;
if constexpr (use_expression_templates) { return base().noalias(); }
else
{
return *this;
}
}
auto normalized() const
auto _normalized() const
requires(IsVectorAtCompileTime)
{
if constexpr (use_expression_templates) return base().normalized();
if constexpr (use_expression_templates) { return base().normalized(); }
else
{
auto res = base().normalized();
@ -216,9 +232,9 @@ namespace rotgen
}
}
auto transpose() const
auto _transpose() const
{
if constexpr (use_expression_templates) return base().transpose();
if constexpr (use_expression_templates) { return base().transpose(); }
else
{
auto res = base().transpose();
@ -226,178 +242,232 @@ namespace rotgen
}
}
auto conjugate() const
auto _conjugate() const
{
auto res = base().conjugate();
return as_concrete_type<decltype(res)>(res);
}
auto adjoint() const
auto _adjoint() const
{
auto res = base().adjoint();
return as_concrete_type<decltype(res)>(res);
}
void normalize()
void _normalize()
requires(IsVectorAtCompileTime)
{
parent::normalize();
}
void transposeInPlace() { parent::transposeInPlace(); }
void _transposeInPlace() { parent::transposeInPlace(); }
void adjointInPlace() { parent::adjointInPlace(); }
void _adjointInPlace() { parent::adjointInPlace(); }
auto cwiseAbs() const
auto _cwiseAbs() const
{
if constexpr (!use_expression_templates)
{
return matrix{parent::cwiseAbs()};
else return base().cwiseAbs();
}
else
{
return base().cwiseAbs();
}
}
auto cwiseAbs2() const
auto _cwiseAbs2() const
{
if constexpr (!use_expression_templates)
{
return matrix{parent::cwiseAbs2()};
else return base().cwiseAbs2();
}
else
{
return base().cwiseAbs2();
}
}
auto cwiseInverse() const
auto _cwiseInverse() const
{
if constexpr (!use_expression_templates)
{
return matrix{parent::cwiseInverse()};
else return base().cwiseInverse();
}
else
{
return base().cwiseInverse();
}
}
auto cwiseSqrt() const
auto _cwiseSqrt() const
{
if constexpr (!use_expression_templates)
{
return matrix{parent::cwiseSqrt()};
else return base().cwiseSqrt();
}
else
{
return base().cwiseSqrt();
}
}
void resize(int s)
void resize(int new_size)
requires(IsVectorAtCompileTime)
{
if constexpr (Rows == 1) parent::resize(1, s);
else parent::resize(s, 1);
if constexpr (Rows == 1) { parent::resize(1, new_size); }
else
{
parent::resize(new_size, 1);
}
}
void resize(int r, int c)
void resize(int new_row_count, int new_col_count)
{
if constexpr (Cols != -1)
ROTGEN_ASSERT(c == Cols,
{
ROTGEN_ASSERT(new_col_count == Cols,
"Mismatched between dynamic and static col size");
}
if constexpr (Rows != -1)
ROTGEN_ASSERT(r == Rows,
{
ROTGEN_ASSERT(new_row_count == Rows,
"Mismatched between dynamic and static row size");
parent::resize(r, c);
}
parent::resize(new_row_count, new_col_count);
}
void conservativeResize(int s)
void _conservativeResize(int new_size)
requires(IsVectorAtCompileTime)
{
if constexpr (Rows == 1) parent::conservativeResize(1, s);
else parent::conservativeResize(s, 1);
if constexpr (Rows == 1) { parent::conservativeResize(1, new_size); }
else
{
parent::conservativeResize(new_size, 1);
}
}
void conservativeResize(int r, int c)
void _conservativeResize(int new_row_count, int new_col_count)
{
if constexpr (Cols != -1)
ROTGEN_ASSERT(c == Cols,
{
ROTGEN_ASSERT(new_col_count == Cols,
"Mismatched between dynamic and static col size");
}
if constexpr (Rows != -1)
ROTGEN_ASSERT(r == Rows,
{
ROTGEN_ASSERT(new_row_count == Rows,
"Mismatched between dynamic and static row size");
parent::conservativeResize(r, c);
}
parent::conservativeResize(new_row_count, new_col_count);
}
static matrix Constant(Scalar value)
static matrix _Constant(Scalar value)
requires(Rows != -1 && Cols != -1)
{
return parent::Constant(Rows, Cols, static_cast<Scalar>(value));
return parent::Constant(Rows, Cols, value);
}
static matrix Constant(int rows, int cols, Scalar value)
static matrix _Constant(int rows, int cols, Scalar value)
{
if constexpr (Rows != -1)
{
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
}
if constexpr (Cols != -1)
{
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
return parent::Constant(rows, cols, static_cast<Scalar>(value));
}
return parent::Constant(rows, cols, value);
}
static matrix Identity()
static matrix _Identity()
requires(Rows != -1 && Cols != -1)
{
return parent::Identity(Rows, Cols);
}
static matrix Identity(int rows, int cols)
static matrix _Identity(int rows, int cols)
{
if constexpr (Rows != -1)
{
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
}
if constexpr (Cols != -1)
{
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
}
return parent::Identity(rows, cols);
}
static matrix Ones()
static matrix _Ones()
requires(Rows != -1 && Cols != -1)
{
return parent::Ones(Rows, Cols);
}
static matrix Ones(int rows, int cols)
static matrix _Ones(int rows, int cols)
{
if constexpr (Rows != -1)
{
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
}
if constexpr (Cols != -1)
{
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
}
return parent::Ones(rows, cols);
}
static matrix Zero()
static matrix _Zero()
requires(Rows != -1 && Cols != -1)
{
return parent::Zero(Rows, Cols);
}
static matrix Zero(int rows, int cols)
static matrix _Zero(int rows, int cols)
{
if constexpr (Rows != -1)
{
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
}
if constexpr (Cols != -1)
{
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
}
return parent::Zero(rows, cols);
}
static matrix Random()
static matrix _Random()
requires(Rows != -1 && Cols != -1)
{
return parent::Random(Rows, Cols);
}
static matrix Random(int rows, int cols)
static matrix _Random(int rows, int cols)
{
if constexpr (Rows != -1)
{
ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
}
if constexpr (Cols != -1)
{
ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
}
return parent::Random(rows, cols);
}
template<int P> value_type lpNorm() const
template<int P> value_type _lpNorm() const
{
static_assert(P == 1 || P == 2 || P == Infinity);
return parent::template lpNorm<P>();
@ -416,96 +486,111 @@ namespace rotgen
}
using parent::operator();
using parent::cols;
using parent::data;
using parent::mean;
using parent::norm;
using parent::prod;
using parent::rows;
using parent::size;
using parent::squaredNorm;
using parent::sum;
using parent::trace;
auto minCoeff() const { return parent::minCoeff(); }
Index _cols() const { return parent::cols(); }
auto maxCoeff() const { return parent::maxCoeff(); }
Index _rows() const { return parent::rows(); }
// Reductions
value_type _mean() const { return parent::mean(); }
value_type _norm() const { return parent::norm(); }
value_type _squaredNorm() const { return parent::squaredNorm(); }
value_type _sum() const { return parent::sum(); }
value_type _prod() const { return parent::prod(); }
value_type _trace() const { return parent::trace(); }
Index _innerStride() const noexcept { return parent::innerStride(); };
Index _outerStride() const noexcept { return parent::outerStride(); };
auto _minCoeff() const { return parent::minCoeff(); }
auto _maxCoeff() const { return parent::maxCoeff(); }
template<std::integral IndexType>
auto minCoeff(IndexType* row, IndexType* col) const
auto _minCoeff(IndexType* row, IndexType* col) const
{
Index r, c;
auto result = parent::minCoeff(&r, &c);
*row = r;
*col = c;
Index result_row, result_col;
auto result = parent::minCoeff(&result_row, &result_col);
*row = result_row;
*col = result_col;
return result;
}
template<std::integral IndexType>
auto maxCoeff(IndexType* row, IndexType* col) const
auto _maxCoeff(IndexType* row, IndexType* col) const
{
Index r, c;
auto result = parent::maxCoeff(&r, &c);
*row = r;
*col = c;
Index result_row, result_col;
auto result = parent::maxCoeff(&result_row, &result_col);
*row = result_row;
*col = result_col;
return result;
}
matrix& setOnes()
matrix& _setOnes()
{
*this = parent::Ones(rows(), cols());
*this = parent::Ones(_rows(), _cols());
return *this;
}
matrix& setOnes(int r, int c)
matrix& _setOnes(int r, int c)
{
*this = parent::Ones(r, c);
return *this;
}
matrix& setZero()
matrix& _setZero()
{
*this = parent::Zero(rows(), cols());
*this = parent::Zero(_rows(), _cols());
return *this;
}
matrix& setZero(int r, int c)
matrix& _setZero(int r, int c)
{
*this = parent::Zero(r, c);
return *this;
}
matrix& setConstant(Scalar value)
matrix& _setConstant(Scalar value)
{
*this = parent::Constant(rows(), cols(), static_cast<Scalar>(value));
*this = parent::Constant(_rows(), _cols(), value);
return *this;
}
matrix& setConstant(int r, int c, Scalar value)
matrix& _setConstant(int r, int c, Scalar value)
{
*this = parent::Constant(r, c, static_cast<Scalar>(value));
*this = parent::Constant(r, c, value);
return *this;
}
matrix& setRandom()
matrix& _setRandom()
{
*this = parent::Random(rows(), cols());
*this = parent::Random(_rows(), _cols());
return *this;
}
matrix& setRandom(int r, int c)
matrix& _setRandom(int r, int c)
{
*this = parent::Random(r, c);
return *this;
}
matrix& setIdentity()
matrix& _setIdentity()
{
*this = parent::Identity(rows(), cols());
*this = parent::Identity(_rows(), _cols());
return *this;
}
matrix& setIdentity(int r, int c)
matrix& _setIdentity(int r, int c)
{
*this = parent::Identity(r, c);
return *this;

View file

@ -60,33 +60,33 @@ namespace rotgen
using parent::operator[];
// Size related functions
using parent::cols;
using parent::data;
using parent::innerStride;
using parent::outerStride;
using parent::rows;
using parent::size;
using parent::_cols;
using parent::_innerStride;
using parent::_outerStride;
using parent::_rows;
// Aliasing handling
using parent::evaluate;
using parent::noalias;
using parent::_evaluate;
using parent::_noalias;
// Reductions
using parent::lpNorm;
using parent::maxCoeff;
using parent::mean;
using parent::minCoeff;
using parent::norm;
using parent::prod;
using parent::squaredNorm;
using parent::sum;
using parent::trace;
using parent::_lpNorm;
using parent::_maxCoeff;
using parent::_mean;
using parent::_minCoeff;
using parent::_norm;
using parent::_prod;
using parent::_squaredNorm;
using parent::_sum;
using parent::_trace;
// Arithmetic
using parent::cwiseAbs;
using parent::cwiseAbs2;
using parent::cwiseInverse;
using parent::cwiseSqrt;
using parent::_cwiseAbs;
using parent::_cwiseAbs2;
using parent::_cwiseInverse;
using parent::_cwiseSqrt;
// Compound Operators
template<typename A, int O, typename S>
@ -128,27 +128,27 @@ namespace rotgen
}
// Shape modifications
using parent::adjoint;
using parent::conjugate;
using parent::normalized;
using parent::transpose;
using parent::_adjoint;
using parent::_conjugate;
using parent::_normalized;
using parent::_transpose;
// In-place Shape modifications
using parent::adjointInPlace;
using parent::normalize;
using parent::transposeInPlace;
using parent::_adjointInPlace;
using parent::_normalize;
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;
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;
using parent::operator=;
using parent::operator-;
@ -348,70 +348,70 @@ namespace rotgen
template<typename A, int O, typename S, typename B, int P, typename T>
auto min(ref<A, O, S> lhs, ref<B, P, T> rhs)
-> decltype(lhs.base().cwiseMin(rhs.base()))
-> decltype(lhs.base()._cwiseMin(rhs.base()))
{
return lhs.base().cwiseMin(rhs.base());
return lhs.base()._cwiseMin(rhs.base());
}
template<typename A, int O, typename S>
auto min(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
-> decltype(lhs.base().cwiseMin(s))
-> decltype(lhs.base()._cwiseMin(s))
{
return lhs.base().cwiseMin(s);
return lhs.base()._cwiseMin(s);
}
template<typename A, int O, typename S>
auto min(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs)
-> decltype(rhs.base().cwiseMin(s))
-> decltype(rhs.base()._cwiseMin(s))
{
return rhs.base().cwiseMin(s);
return rhs.base()._cwiseMin(s);
}
template<typename A, int O, typename S, typename B, int P, typename T>
auto max(ref<A, O, S> lhs, ref<B, P, T> rhs)
-> decltype(lhs.base().cwiseMax(rhs.base()))
-> decltype(lhs.base()._cwiseMax(rhs.base()))
{
return lhs.base().cwiseMax(rhs.base());
return lhs.base()._cwiseMax(rhs.base());
}
template<typename A, int O, typename S>
auto max(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
-> decltype(lhs.base().cwiseMax(s))
-> decltype(lhs.base()._cwiseMax(s))
{
return lhs.base().cwiseMax(s);
return lhs.base()._cwiseMax(s);
}
template<typename A, int O, typename S>
auto max(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs)
-> decltype(rhs.base().cwiseMax(s))
-> decltype(rhs.base()._cwiseMax(s))
{
return rhs.base().cwiseMax(s);
return rhs.base()._cwiseMax(s);
}
template<typename A, int O, typename S, typename B, int P, typename T>
auto mul(ref<A, O, S> lhs, ref<B, P, T> rhs)
-> decltype(lhs.base().cwiseProduct(rhs.base()))
-> decltype(lhs.base()._cwiseProduct(rhs.base()))
{
return lhs.base().cwiseProduct(rhs.base());
return lhs.base()._cwiseProduct(rhs.base());
}
template<typename A, int O, typename S, typename B, int P, typename T>
auto div(ref<A, O, S> lhs, ref<B, P, T> rhs)
-> decltype(lhs.base().cwiseQuotient(rhs.base()))
-> decltype(lhs.base()._cwiseQuotient(rhs.base()))
{
return lhs.base().cwiseQuotient(rhs.base());
return lhs.base()._cwiseQuotient(rhs.base());
}
template<typename A, int O, typename S>
auto inverse(ref<A, O, S> lhs) -> decltype(lhs.base().inverse())
auto inverse(ref<A, O, S> lhs) -> decltype(lhs.base()._inverse())
{
return lhs.base().inverse();
return lhs.base()._inverse();
}
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()))
-> decltype(lhs.base()._cross(rhs.base()))
{
return lhs.base().cross(rhs.base());
return lhs.base()._cross(rhs.base());
}
}

View file

@ -86,25 +86,30 @@ namespace rotgen
// Access to values
using parent::operator();
using parent::operator[];
// Size related functions
using parent::cols;
using parent::data;
using parent::innerStride;
using parent::outerStride;
using parent::rows;
using parent::size;
// Aliasing handling
auto evaluate() const { return T(base().eval()); }
// Size related functions
decltype(auto) noalias() const
Index _cols() const { return parent::cols(); }
Index _rows() const { return parent::rows(); }
Index _innerStride() const noexcept { return parent::innerStride(); };
Index _outerStride() const noexcept { return parent::outerStride(); };
// Aliasing handling
auto _evaluate() const { return T(base().eval()); }
decltype(auto) _noalias() const
{
if constexpr (use_expression_templates) return base().noalias();
else return *this;
}
decltype(auto) noalias()
decltype(auto) _noalias()
{
if constexpr (use_expression_templates) return base().noalias();
else return *this;
@ -113,36 +118,64 @@ namespace rotgen
// Numeric functions
auto operator-() const { return detail::concretize<matrix>(-base()); }
auto cwiseAbs() const
auto _cwiseAbs() const
{
return detail::concretize<matrix>(base().cwiseAbs());
}
auto cwiseAbs2() const
auto _cwiseAbs2() const
{
return detail::concretize<matrix>(base().cwiseAbs2());
}
auto cwiseInverse() const
auto _cwiseInverse() const
{
return detail::concretize<matrix>(base().cwiseInverse());
}
auto cwiseSqrt() const
auto _cwiseSqrt() const
{
return detail::concretize<matrix>(base().cwiseSqrt());
}
// Reductions
using parent::lpNorm;
using parent::maxCoeff;
using parent::mean;
using parent::minCoeff;
using parent::norm;
using parent::prod;
using parent::squaredNorm;
using parent::sum;
using parent::trace;
value_type _mean() const { return parent::mean(); }
value_type _norm() const { return parent::norm(); }
value_type _lpNorm() const { return parent::lpNorm(); }
value_type _squaredNorm() const { return parent::squaredNorm(); }
value_type _sum() const { return parent::sum(); }
value_type _prod() const { return parent::prod(); }
value_type _trace() const { return parent::trace(); }
auto _minCoeff() const { return parent::minCoeff(); }
auto _maxCoeff() const { return parent::maxCoeff(); }
template<std::integral IndexType>
auto _minCoeff(IndexType* row, IndexType* col) const
{
Index result_row, result_col;
auto result = parent::minCoeff(&result_row, &result_col);
*row = result_row;
*col = result_col;
return result;
}
template<std::integral IndexType>
auto _maxCoeff(IndexType* row, IndexType* col) const
{
Index result_row, result_col;
auto result = parent::maxCoeff(&result_row, &result_col);
*row = result_row;
*col = result_col;
return result;
}
// Compound Operators
template<typename A, int O, typename S>
@ -184,102 +217,109 @@ namespace rotgen
}
// Shape modifications
auto normalized() const
auto _normalized() const
requires(IsVectorAtCompileTime)
{
return detail::concretize<matrix>(base().normalized());
}
auto transpose() const
auto _transpose() const
{
return detail::concretize<matrix>(base().transpose());
}
auto adjoint() const
auto _adjoint() const
{
return detail::concretize<matrix>(base().adjoint());
}
auto conjugate() const
auto _conjugate() const
{
return detail::concretize<matrix>(base().conjugate());
}
// In-place Shape modifications
using parent::adjointInPlace;
using parent::normalize;
using parent::transposeInPlace;
void _adjointInPlace() { parent::adjointInPlace(); }
void _normalize()
requires(IsVectorAtCompileTime)
{
parent::normalize();
}
void _transposeInPlace() { parent::transposeInPlace(); }
// Generators
static auto Zero() { return detail::concretize<matrix>(parent::Zero()); }
static auto _Zero() { return detail::concretize<matrix>(parent::Zero()); }
static auto Zero(int rows, int cols)
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() { return detail::concretize<matrix>(parent::Ones()); }
static auto Ones(int rows, int cols)
static auto _Ones(int rows, int cols)
{
return detail::concretize<matrix>(parent::Ones(rows, cols));
}
static auto Constant(value_type value)
static auto _Constant(value_type value)
{
return detail::concretize<matrix>(parent::Constant(value));
}
static auto Constant(int rows, int cols, value_type value)
static auto _Constant(int rows, int cols, value_type value)
{
return detail::concretize<matrix>(parent::Constant(rows, cols, value));
}
static auto Random()
static auto _Random()
{
return detail::concretize<matrix>(parent::Random());
}
static auto Random(int rows, int cols)
static auto _Random(int rows, int cols)
{
return detail::concretize<matrix>(parent::Random(rows, cols));
}
static auto Identity()
static auto _Identity()
{
return detail::concretize<matrix>(parent::Identity());
}
static auto Identity(int rows, int cols)
static auto _Identity(int rows, int cols)
{
return detail::concretize<matrix>(parent::Identity(rows, cols));
}
ref& setOnes()
ref& _setOnes()
{
base() = parent::Ones(base().rows(), base().cols());
return *this;
}
ref& setZero()
ref& _setZero()
{
base() = parent::Zero(base().rows(), base().cols());
return *this;
}
ref& setConstant(value_type value)
ref& _setConstant(value_type value)
{
base() = parent::Constant(base().rows(), base().cols(), value);
return *this;
}
ref& setRandom()
ref& _setRandom()
{
base() = parent::Random(base().rows(), base().cols());
return *this;
}
ref& setIdentity()
ref& _setIdentity()
{
base() = parent::Identity(base().rows(), base().cols());
return *this;

View file

@ -7,6 +7,8 @@
//==================================================================================================
#pragma once
#include <rotgen/detail/helpers.hpp>
#include <type_traits>
namespace rotgen
@ -34,7 +36,18 @@ namespace rotgen
template<typename A, int O, typename S, typename B, int P, typename T>
auto dot(ref<A, O, S> const& lhs, ref<B, P, T> const& rhs)
{
return lhs.base().dot(rhs.base());
if constexpr (requires { lhs.base().dot(rhs.base()); })
{
return lhs.base().dot(rhs.base());
}
else if constexpr (requires { lhs.base()._dot(rhs.base()); })
{
return lhs.base()._dot(rhs.base());
}
else
{
return detail::unsupported_parameters<T>();
}
}
template<typename A, int O, typename S>

View file

@ -1,13 +1,16 @@
//==================================================================================================
//==============================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
//==============================================================================
#pragma once
#include <rotgen/concepts.hpp>
#include <rotgen/config.hpp>
#include <rotgen/container/matrix.hpp>
#include <rotgen/container/ref.hpp>
#include <type_traits>
@ -15,7 +18,7 @@ namespace rotgen
{
template<typename Scalar, int Options = AutoAlign> class quaternion;
//-------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Convert entity/eigen types to a proper ref so we can write less function
// overloads

View file

@ -9,6 +9,8 @@
#include <rotgen/detail/assert.hpp>
#include <rotgen/functions/functions.hpp>
#include <concepts>
namespace rotgen::detail
@ -73,34 +75,34 @@ namespace rotgen::detail
using parent = typename Ref::parent;
using map_base = typename parent::parent;
auto rows = in.rows();
auto cols = in.cols();
auto r = rows(in);
auto c = cols(in);
if (Ref::RowsAtCompileTime == 1)
{
ROTGEN_ASSERT(in.rows() == 1 || in.cols() == 1,
ROTGEN_ASSERT(rows(in) == 1 || cols(in) == 1,
"Incompatible rows/cols in ref binding");
rows = 1;
cols = in.size();
r = 1;
c = in.size();
}
else if (Ref::ColsAtCompileTime == 1)
{
ROTGEN_ASSERT(in.rows() == 1 || in.cols() == 1,
ROTGEN_ASSERT(rows(in) == 1 || cols(in) == 1,
"Incompatible rows/cols in ref binding");
rows = in.size();
cols = 1;
r = in.size();
c = 1;
}
// Verify that the sizes are valid.
ROTGEN_ASSERT((Ref::RowsAtCompileTime == Dynamic) ||
(Ref::RowsAtCompileTime == rows),
(Ref::RowsAtCompileTime == r),
"Incompatible static rows/cols in ref binding");
ROTGEN_ASSERT((Ref::ColsAtCompileTime == Dynamic) ||
(Ref::ColsAtCompileTime == cols),
(Ref::ColsAtCompileTime == c),
"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());
bool transpose = Ref::IsVectorAtCompileTime && (r != rows(in));
// Swap stride if storage ordder doesn't match
constexpr bool row_major = Ref::IsRowMajor;
@ -110,13 +112,13 @@ namespace rotgen::detail
bool swap_stride = (transpose != storage_differs);
// Determine expr's actual strides, resolving any defaults if zero.
Index inner_actual = proper_inner_stride(in.innerStride());
Index inner_actual = proper_inner_stride(innerStride(in));
Index outer_actual =
proper_outer_stride(inner_actual, in.outerStride(), in.rows(), in.cols(),
proper_outer_stride(inner_actual, outerStride(in), rows(in), cols(in),
Input::IsVectorAtCompileTime, input_row_major);
bool row_vector = (rows == 1);
bool col_vector = (cols == 1);
bool row_vector = (r == 1);
bool col_vector = (c == 1);
// Adapt inner stride based on row/col vector status
Index inner_stride =
@ -132,7 +134,7 @@ namespace rotgen::detail
((!row_major && col_vector) || (row_major && row_vector))
? (stride_type::OuterStrideAtCompileTime > 0
? stride_type::OuterStrideAtCompileTime
: rows * cols * inner_stride)
: r * c * inner_stride)
: swap_stride ? inner_actual
: outer_actual;
@ -147,7 +149,7 @@ namespace rotgen::detail
bool outer_valid =
(stride_type::OuterStrideAtCompileTime == Dynamic) ||
(proper_outer_stride(
inner_stride, Index(stride_type::OuterStrideAtCompileTime), rows, cols,
inner_stride, Index(stride_type::OuterStrideAtCompileTime), r, c,
Ref::IsVectorAtCompileTime != 0, row_major) == outer_stride);
if (!outer_valid) return false;
@ -156,7 +158,7 @@ namespace rotgen::detail
stride_type::OuterStrideAtCompileTime == 0 ? 1 : outer_stride,
stride_type::InnerStrideAtCompileTime == 0 ? 1 : inner_stride);
auto actual = map_base(in.data(), rows, cols, proper_stride);
auto actual = map_base(in.data(), r, c, proper_stride);
ref.base().base().storage().swap(actual.storage());

View file

@ -1,10 +1,10 @@
//==================================================================================================
//==============================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
//==============================================================================
#pragma once
#include <rotgen/config.hpp>
@ -15,6 +15,15 @@
namespace rotgen::detail
{
/// Returned when a function is called with unsupported parameters,
/// effectively triggering a compile error to avoid undefined behaviors in
/// cases where return directives are missing.
template<typename T> auto unsupported_parameters()
{
static_assert(sizeof(T) == 0,
"Function was called with unsupported parameters.");
};
template<typename T> constexpr int static_size()
{
auto rows = T::RowsAtCompileTime;

View file

@ -1,13 +1,17 @@
//==================================================================================================
//==============================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
//==============================================================================
#pragma once
#include <rotgen/detail/assert.hpp>
#include <rotgen/detail/helpers.hpp>
#include <rotgen/concepts.hpp>
#include <type_traits>
namespace rotgen
@ -23,9 +27,9 @@ namespace rotgen
{
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(),
ROTGEN_ASSERT(i0 + ni <= rows(e),
"block extraction rows is out of range.");
ROTGEN_ASSERT(j0 + nj <= e.cols(),
ROTGEN_ASSERT(j0 + nj <= cols(e),
"block extraction cols is out of range.");
}
}
@ -83,55 +87,55 @@ namespace rotgen
template<concepts::entity Entity>
auto topRightCorner(Entity&& e, Index ni, Index nj)
{
return extract(ROTGEN_FWD(e), 0, e.cols() - nj, ni, nj);
return extract(ROTGEN_FWD(e), 0, cols(e) - nj, ni, nj);
}
template<Index NI, Index NJ, concepts::entity Entity>
auto topRightCorner(Entity&& e)
{
return extract<NI, NJ>(ROTGEN_FWD(e), 0, e.cols() - NJ);
return extract<NI, NJ>(ROTGEN_FWD(e), 0, cols(e) - NJ);
}
//======================== BOTTOM LEFT CORNER ========================
template<concepts::entity Entity>
auto bottomLeftCorner(Entity&& e, Index ni, Index nj)
{
return extract(ROTGEN_FWD(e), e.rows() - ni, 0, ni, nj);
return extract(ROTGEN_FWD(e), rows(e) - ni, 0, ni, nj);
}
template<Index NI, Index NJ, concepts::entity Entity>
auto bottomLeftCorner(Entity&& e)
{
return extract<NI, NJ>(ROTGEN_FWD(e), e.rows() - NI, 0);
return extract<NI, NJ>(ROTGEN_FWD(e), rows(e) - NI, 0);
}
//======================== BOTTOM RIGHT CORNER ========================
template<concepts::entity Entity>
auto bottomRightCorner(Entity&& e, Index ni, Index nj)
{
return extract(ROTGEN_FWD(e), e.rows() - ni, e.cols() - nj, ni, nj);
return extract(ROTGEN_FWD(e), rows(e) - ni, cols(e) - nj, ni, nj);
}
template<Index NI, Index NJ, concepts::entity Entity>
auto bottomRightCorner(Entity&& e)
{
return extract<NI, NJ>(ROTGEN_FWD(e), e.rows() - NI, e.cols() - NJ);
return extract<NI, NJ>(ROTGEN_FWD(e), rows(e) - NI, cols(e) - NJ);
}
//======================== TOP ROWS ========================
template<concepts::entity Entity> auto topRows(Entity&& e, Index ni)
{
if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1)
return extract(ROTGEN_FWD(e), 0, 0, ni, e.cols());
return extract(ROTGEN_FWD(e), 0, 0, ni, cols(e));
else
return extract<-1, std::remove_cvref_t<Entity>::ColsAtCompileTime>(
ROTGEN_FWD(e), 0, 0, ni, e.cols());
ROTGEN_FWD(e), 0, 0, ni, cols(e));
}
template<Index NI, concepts::entity Entity> auto topRows(Entity&& e)
{
if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1)
return extract<NI, -1>(ROTGEN_FWD(e), 0, 0, NI, e.cols());
return extract<NI, -1>(ROTGEN_FWD(e), 0, 0, NI, cols(e));
else
return extract<NI, std::remove_cvref_t<Entity>::ColsAtCompileTime>(
ROTGEN_FWD(e), 0, 0);
@ -142,17 +146,17 @@ namespace rotgen
auto middleRows(Entity&& e, Index i0, Index ni)
{
if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1)
return extract(ROTGEN_FWD(e), i0, 0, ni, e.cols());
return extract(ROTGEN_FWD(e), i0, 0, ni, cols(e));
else
return extract<-1, std::remove_cvref_t<Entity>::ColsAtCompileTime>(
ROTGEN_FWD(e), i0, 0, ni, e.cols());
ROTGEN_FWD(e), i0, 0, ni, cols(e));
}
template<Index NI, concepts::entity Entity>
auto middleRows(Entity&& e, Index i0)
{
if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1)
return extract<NI, -1>(ROTGEN_FWD(e), i0, 0, NI, e.cols());
return extract<NI, -1>(ROTGEN_FWD(e), i0, 0, NI, cols(e));
else
return extract<NI, std::remove_cvref_t<Entity>::ColsAtCompileTime>(
ROTGEN_FWD(e), i0, 0);
@ -162,35 +166,35 @@ namespace rotgen
template<concepts::entity Entity> auto bottomRows(Entity&& e, Index ni)
{
if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1)
return extract(ROTGEN_FWD(e), e.rows() - ni, 0, ni, e.cols());
return extract(ROTGEN_FWD(e), rows(e) - ni, 0, ni, cols(e));
else
return extract<-1, std::remove_cvref_t<Entity>::ColsAtCompileTime>(
ROTGEN_FWD(e), e.rows() - ni, 0, ni, e.cols());
ROTGEN_FWD(e), rows(e) - ni, 0, ni, cols(e));
}
template<Index NI, concepts::entity Entity> auto bottomRows(Entity&& e)
{
if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1)
return extract<NI, -1>(ROTGEN_FWD(e), e.rows() - NI, 0, NI, e.cols());
return extract<NI, -1>(ROTGEN_FWD(e), rows(e) - NI, 0, NI, cols(e));
else
return extract<NI, std::remove_cvref_t<Entity>::ColsAtCompileTime>(
ROTGEN_FWD(e), e.rows() - NI, 0);
ROTGEN_FWD(e), rows(e) - NI, 0);
}
//======================== LEFT COLS ========================
template<concepts::entity Entity> auto leftCols(Entity&& e, Index nj)
{
if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1)
return extract(ROTGEN_FWD(e), 0, 0, e.rows(), nj);
return extract(ROTGEN_FWD(e), 0, 0, rows(e), nj);
else
return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, -1>(
ROTGEN_FWD(e), 0, 0, e.rows(), nj);
ROTGEN_FWD(e), 0, 0, rows(e), nj);
}
template<Index NJ, concepts::entity Entity> auto leftCols(Entity&& e)
{
if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1)
return extract<-1, NJ>(ROTGEN_FWD(e), 0, 0, e.rows(), NJ);
return extract<-1, NJ>(ROTGEN_FWD(e), 0, 0, rows(e), NJ);
else
return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, NJ>(
ROTGEN_FWD(e), 0, 0);
@ -201,17 +205,17 @@ namespace rotgen
auto middleCols(Entity&& e, Index j0, Index nj)
{
if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1)
return extract(ROTGEN_FWD(e), 0, j0, e.rows(), nj);
return extract(ROTGEN_FWD(e), 0, j0, rows(e), nj);
else
return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, -1>(
ROTGEN_FWD(e), 0, j0, e.rows(), nj);
ROTGEN_FWD(e), 0, j0, rows(e), nj);
}
template<Index NJ, concepts::entity Entity>
auto middleCols(Entity&& e, Index j0)
{
if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1)
return extract<-1, NJ>(ROTGEN_FWD(e), 0, j0, e.rows(), NJ);
return extract<-1, NJ>(ROTGEN_FWD(e), 0, j0, rows(e), NJ);
else
return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, NJ>(
ROTGEN_FWD(e), 0, j0);
@ -221,27 +225,27 @@ namespace rotgen
template<concepts::entity Entity> auto rightCols(Entity&& e, Index nj)
{
if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1)
return extract(ROTGEN_FWD(e), 0, e.cols() - nj, e.rows(), nj);
return extract(ROTGEN_FWD(e), 0, cols(e) - nj, rows(e), nj);
else
return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, -1>(
ROTGEN_FWD(e), 0, e.cols() - nj, e.rows(), nj);
ROTGEN_FWD(e), 0, cols(e) - nj, rows(e), nj);
;
}
template<Index NJ, concepts::entity Entity> auto rightCols(Entity&& e)
{
if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1)
return extract<-1, NJ>(ROTGEN_FWD(e), 0, e.cols() - NJ, e.rows(), NJ);
return extract<-1, NJ>(ROTGEN_FWD(e), 0, cols(e) - NJ, rows(e), NJ);
else
return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, NJ>(
ROTGEN_FWD(e), 0, e.cols() - NJ);
ROTGEN_FWD(e), 0, cols(e) - NJ);
}
//======================== ROW ========================
template<concepts::entity Entity> auto row(Entity&& e, Index i0)
{
if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1)
return extract<1, -1>(ROTGEN_FWD(e), i0, 0, 1, e.cols());
return extract<1, -1>(ROTGEN_FWD(e), i0, 0, 1, cols(e));
else
return extract<1, std::remove_cvref_t<Entity>::ColsAtCompileTime>(
ROTGEN_FWD(e), i0, 0);
@ -251,7 +255,7 @@ namespace rotgen
template<concepts::entity Entity> auto col(Entity&& e, Index j0)
{
if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1)
return extract<-1, 1>(ROTGEN_FWD(e), 0, j0, e.rows(), 1);
return extract<-1, 1>(ROTGEN_FWD(e), 0, j0, rows(e), 1);
else
return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, 1>(
ROTGEN_FWD(e), 0, j0);
@ -287,9 +291,9 @@ namespace rotgen
std::remove_cvref_t<Entity>::ColsAtCompileTime == 1)
{
if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == 1)
return extract<1, Dynamic>(ROTGEN_FWD(e), 0, e.cols() - n, 1, n);
return extract<1, Dynamic>(ROTGEN_FWD(e), 0, cols(e) - n, 1, n);
else if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == 1)
return extract<Dynamic, 1>(ROTGEN_FWD(e), e.rows() - n, 0, n, 1);
return extract<Dynamic, 1>(ROTGEN_FWD(e), rows(e) - n, 0, n, 1);
}
template<Index N, concepts::entity Entity>
@ -298,9 +302,9 @@ namespace rotgen
std::remove_cvref_t<Entity>::ColsAtCompileTime == 1)
{
if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == 1)
return extract<1, N>(ROTGEN_FWD(e), 0, e.cols() - N);
return extract<1, N>(ROTGEN_FWD(e), 0, cols(e) - N);
else if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == 1)
return extract<N, 1>(ROTGEN_FWD(e), e.rows() - N, 0);
return extract<N, 1>(ROTGEN_FWD(e), rows(e) - N, 0);
}
//======================== VECTOR SEGMENT ========================

View file

@ -1,187 +1,371 @@
//==================================================================================================
//==============================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
//==============================================================================
#pragma once
#include <rotgen/detail/helpers.hpp>
#include <rotgen/concepts.hpp>
#include <rotgen/container/ref/generalize.hpp>
namespace rotgen
{
//-----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Infos & Shape
//-----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------
/// Returns the row count of a matrix.
Index rows(auto const& m)
requires(requires { m.rows(); })
{
return m.rows();
if constexpr (requires { m.rows(); }) { return m.rows(); }
else if constexpr (requires { m._rows(); }) { return m._rows(); }
else
{
return detail::unsupported_parameters<decltype(m)>();
}
}
/// Returns the column count of a matrix.
Index cols(auto const& m)
requires(requires { m.cols(); })
{
return m.cols();
if constexpr (requires { m.cols(); }) { return m.cols(); }
else if constexpr (requires { m._cols(); }) { return m._cols(); }
else
{
return detail::unsupported_parameters<decltype(m)>();
}
}
Index startRow(auto const& m)
{
if constexpr (requires { m.startRow(); }) { return m.startRow(); }
else if constexpr (requires { m._startRow(); }) { return m._startRow(); }
else
{
return detail::unsupported_parameters<decltype(m)>();
}
}
Index startCol(auto const& m)
{
if constexpr (requires { m.startCol(); }) { return m.startCol(); }
else if constexpr (requires { m._startCol(); }) { return m._startCol(); }
else
{
return detail::unsupported_parameters<decltype(m)>();
}
}
/// Returns the size of a matrix.
Index size(auto const& m)
requires(requires { m.size(); })
{
return m.size();
}
void resize(auto& a, int s)
requires requires { a.resize(s); }
/// Resizes a matrix into a vector of size s.
void resize(auto& m, int s)
requires requires { m.resize(s); }
{
a.resize(s);
m.resize(s);
}
void resize(auto& a, int r, int c)
requires requires { a.resize(r, c); }
/// Resizes a matrix into with a given number of rows and columns.
void resize(auto& m, int r, int c)
requires requires { m.resize(r, c); }
{
a.resize(r, c);
m.resize(r, c);
}
void conservativeResize(auto& a, int s)
requires requires { a.conservativeResize(s); }
{
a.conservativeResize(s);
if constexpr (requires { a.conservativeResize(s); })
{
a.conservativeResize(s);
}
else if constexpr (requires { a._conservativeResize(s); })
{
a._conservativeResize(s);
}
else
{
return detail::unsupported_parameters<decltype(a)>();
}
}
void conservativeResize(auto& a, int r, int c)
requires requires { a.conservativeResize(r, c); }
{
a.conservativeResize(r, c);
if constexpr (requires { a.conservativeResize(r, c); })
{
a.conservativeResize(r, c);
}
else if constexpr (requires { a._conservativeResize(r, c); })
{
a._conservativeResize(r, c);
}
else
{
return detail::unsupported_parameters<decltype(a)>();
}
}
//-----------------------------------------------------------------------------------------------
// Global operations
//-----------------------------------------------------------------------------------------------
decltype(auto) normalized(auto const& m)
requires(requires { m.normalized(); })
Index innerStride(auto const& m)
{
return m.normalized();
if constexpr (requires { m.innerStride(); }) { return m.innerStride(); }
else if constexpr (requires { m._innerStride(); })
{
return m._innerStride();
}
else
{
return detail::unsupported_parameters<decltype(m)>();
}
}
Index outerStride(auto const& m)
{
if constexpr (requires { m.outerStride(); }) { return m.outerStride(); }
else if constexpr (requires { m._outerStride(); })
{
return m._outerStride();
}
else
{
return detail::unsupported_parameters<decltype(m)>();
}
}
//----------------------------------------------------------------------------
// Global operations
//----------------------------------------------------------------------------
decltype(auto) normalized(auto const& m)
{
if constexpr (requires { m.normalized(); }) { return m.normalized(); }
else if constexpr (requires { m._normalized(); })
{
return m._normalized();
}
else
{
return detail::unsupported_parameters<decltype(m)>();
}
}
decltype(auto) transpose(auto const& m)
requires(requires { m.transpose(); })
{
return m.transpose();
if constexpr (requires { m.transpose(); }) { return m.transpose(); }
else if constexpr (requires { m._transpose(); }) { return m._transpose(); }
else
{
return detail::unsupported_parameters<decltype(m)>();
}
}
decltype(auto) conjugate(auto const& m)
requires(requires { m.conjugate(); })
{
return m.conjugate();
if constexpr (requires { m.conjugate(); }) { return m.conjugate(); }
else if constexpr (requires { m._conjugate(); }) { return m._conjugate(); }
}
decltype(auto) adjoint(auto const& m)
requires(requires { m.adjoint(); })
{
return m.adjoint();
if constexpr (requires { m.adjoint(); }) { return m.adjoint(); }
else if constexpr (requires { m._adjoint(); }) { return m._adjoint(); }
else
{
return detail::unsupported_parameters<decltype(m)>();
}
}
void normalize(auto& a)
requires(requires { a.normalize(); })
{
a.normalize();
if constexpr (requires { a.normalize(); }) { a.normalize(); }
else if constexpr (requires { a._normalize(); }) // PROCESSME
{
a._normalize();
}
else
{
return detail::unsupported_parameters<decltype(a)>();
}
}
void transposeInPlace(auto& a)
requires(requires { a.transposeInPlace(); })
{
a.transposeInPlace();
if constexpr (requires { a.transposeInPlace(); }) { a.transposeInPlace(); }
else if constexpr (requires { a._transposeInPlace(); }) // PROCESSME
{
a._transposeInPlace();
}
else
{
return detail::unsupported_parameters<decltype(a)>();
}
}
void adjointInPlace(auto& a)
requires(requires { a.adjointInPlace(); })
{
a.adjointInPlace();
if constexpr (requires { a.adjointInPlace(); }) { a.adjointInPlace(); }
else if constexpr (requires { a._adjointInPlace(); }) // PROCESSME
{
a._adjointInPlace();
}
else
{
return detail::unsupported_parameters<decltype(a)>();
}
}
//-----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Component-wise functions
//-----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------
auto abs(auto const& arg)
requires(requires { arg.cwiseAbs(); })
{
return arg.cwiseAbs();
if constexpr (requires { arg.cwiseAbs(); }) { return arg.cwiseAbs(); }
else if constexpr (requires { arg._cwiseAbs(); })
{
return arg._cwiseAbs();
}
else
{
return detail::unsupported_parameters<decltype(arg)>();
}
}
auto abs2(auto const& arg)
requires(requires { arg.cwiseAbs2(); })
{
return arg.cwiseAbs2();
if constexpr (requires { arg.cwiseAbs2(); }) { return arg.cwiseAbs2(); }
else if constexpr (requires { arg._cwiseAbs2(); })
{
return arg._cwiseAbs2();
}
else
{
return detail::unsupported_parameters<decltype(arg)>();
}
}
auto rec(auto const& arg)
requires(requires { arg.cwiseInverse(); })
{
return arg.cwiseInverse();
if constexpr (requires { arg.cwiseInverse(); })
{
return arg.cwiseInverse();
}
else if constexpr (requires { arg._cwiseInverse(); })
{
return arg._cwiseInverse();
}
else
{
return detail::unsupported_parameters<decltype(arg)>();
}
}
auto sqrt(auto const& arg)
requires(requires { arg.cwiseSqrt(); })
{
return arg.cwiseSqrt();
if constexpr (requires { arg.cwiseSqrt(); }) { return arg.cwiseSqrt(); }
else if constexpr (requires { arg._cwiseSqrt(); })
{
return arg._cwiseSqrt();
}
}
template<concepts::entity A, concepts::entity B>
auto min(A const& a, B const& b)
{
if constexpr (!use_expression_templates)
{
return min(generalize_t<A const>(a), generalize_t<B const>(b));
else return base_of(a).cwiseMin(base_of(b));
}
else
{
return base_of(a).cwiseMin(base_of(b));
}
}
template<concepts::entity A>
auto min(A const& a, std::convertible_to<typename A::value_type> auto b)
{
if constexpr (!use_expression_templates)
{
return min(generalize_t<A const>(a), b);
else return base_of(a).cwiseMin(b);
}
else
{
return base_of(a).cwiseMin(b);
}
}
template<concepts::entity B>
auto min(std::convertible_to<typename B::value_type> auto a, B const& b)
{
if constexpr (!use_expression_templates)
{
return min(a, generalize_t<B const>(b));
else return base_of(b).cwiseMin(a);
}
else
{
return base_of(b).cwiseMin(a);
}
}
template<concepts::entity A, concepts::entity B>
auto max(A const& a, B const& b)
{
if constexpr (!use_expression_templates)
{
return max(generalize_t<A const>(a), generalize_t<B const>(b));
else return base_of(a).cwiseMax(base_of(b));
}
else
{
return base_of(a).cwiseMax(base_of(b));
}
}
template<concepts::entity A>
auto max(A const& a, std::convertible_to<typename A::value_type> auto b)
{
if constexpr (!use_expression_templates)
{
return max(generalize_t<A const>(a), b);
else return base_of(a).cwiseMax(b);
}
else
{
return base_of(a).cwiseMax(b);
}
}
template<concepts::entity B>
auto max(std::convertible_to<typename B::value_type> auto a, B const& b)
{
if constexpr (!use_expression_templates)
{
return max(a, generalize_t<B const>(b));
else return base_of(b).cwiseMax(a);
}
else
{
return base_of(b).cwiseMax(a);
}
}
template<concepts::entity A, concepts::entity B>
auto mul(A const& a, B const& b)
{
if constexpr (!use_expression_templates)
{
return mul(generalize_t<A const>(a), generalize_t<B const>(b));
else return base_of(a).cwiseProduct(base_of(b));
}
else
{
return base_of(a).cwiseProduct(base_of(b));
}
}
template<concepts::entity A>
@ -200,8 +384,13 @@ namespace rotgen
auto div(A const& a, B const& b)
{
if constexpr (!use_expression_templates)
{
return div(generalize_t<A const>(a), generalize_t<B const>(b));
else return base_of(a).array() / base_of(b).array();
}
else
{
return base_of(a).array() / base_of(b).array();
}
}
template<concepts::entity A>
@ -215,43 +404,71 @@ namespace rotgen
return mul(a, a);
}
//-----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Reductions
//-----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------
auto trace(auto const& arg)
requires requires { arg.trace(); }
{
return arg.trace();
if constexpr (requires { arg.trace(); }) { return arg.trace(); }
else if constexpr (requires { arg._trace(); }) { return arg._trace(); }
else
{
return detail::unsupported_parameters<decltype(arg)>();
}
}
auto squaredNorm(auto const& arg)
requires requires { arg.squaredNorm(); }
{
return arg.squaredNorm();
if constexpr (requires { arg.squaredNorm(); }) { return arg.squaredNorm(); }
else if constexpr (requires { arg._squaredNorm(); })
{
return arg._squaredNorm();
}
else
{
return detail::unsupported_parameters<decltype(arg)>();
}
}
auto norm(auto const& arg)
requires requires { arg.norm(); }
{
return arg.norm();
if constexpr (requires { arg.norm(); }) { return arg.norm(); }
else if constexpr (requires { arg._norm(); }) { return arg._norm(); }
else
{
return detail::unsupported_parameters<decltype(arg)>();
}
}
auto sum(auto const& arg)
requires requires { arg.sum(); }
{
return arg.sum();
if constexpr (requires { arg.sum(); }) { return arg.sum(); }
else if constexpr (requires { arg._sum(); }) { return arg._sum(); }
else
{
return detail::unsupported_parameters<decltype(arg)>();
}
}
auto prod(auto const& arg)
requires requires { arg.prod(); }
{
return arg.prod();
if constexpr (requires { arg.prod(); }) { return arg.prod(); }
else if constexpr (requires { arg._prod(); }) { return arg._prod(); }
else
{
return detail::unsupported_parameters<decltype(arg)>();
}
}
auto mean(auto const& arg)
requires requires { arg.mean(); }
{
return arg.mean();
if constexpr (requires { arg.mean(); }) { return arg.mean(); }
else if constexpr (requires { arg._mean(); }) { return arg._mean(); }
else
{
return detail::unsupported_parameters<decltype(arg)>();
}
}
template<concepts::entity A, concepts::entity B>
@ -260,89 +477,167 @@ namespace rotgen
std::same_as<typename A::value_type, typename B::value_type>)
{
if constexpr (!use_expression_templates)
{
return dot(generalize_t<A const>(a), generalize_t<B const>(b));
else return base_of(a).dot(base_of(b));
}
else
{
return base_of(a).dot(base_of(b));
}
}
auto maxCoeff(auto const& arg)
requires(requires { arg.maxCoeff(); })
{
return arg.maxCoeff();
if constexpr (requires { arg.maxCoeff(); }) { return arg.maxCoeff(); }
else if constexpr (requires { arg._maxCoeff(); })
{
return arg._maxCoeff();
}
else
{
return detail::unsupported_parameters<decltype(arg)>();
}
}
auto minCoeff(auto const& arg)
requires(requires { arg.minCoeff(); })
{
return arg.minCoeff();
if constexpr (requires { arg.minCoeff(); }) { return arg.minCoeff(); }
else if constexpr (requires { arg._minCoeff(); })
{
return arg._minCoeff();
}
else
{
return detail::unsupported_parameters<decltype(arg)>();
}
}
template<std::integral IndexType>
auto maxCoeff(auto const& arg, IndexType* row, IndexType* col)
requires(requires { arg.maxCoeff(row, col); })
{
return arg.maxCoeff(row, col);
if constexpr (requires { arg.maxCoeff(row, col); })
{
return arg.maxCoeff(row, col);
}
else if constexpr (requires { arg._maxCoeff(row, col); })
{
return arg._maxCoeff(row, col);
}
else
{
return detail::unsupported_parameters<decltype(arg)>();
}
}
template<std::integral IndexType>
auto minCoeff(auto const& arg, IndexType* row, IndexType* col)
requires(requires { arg.minCoeff(row, col); })
{
return arg.minCoeff(row, col);
if constexpr (requires { arg.minCoeff(row, col); })
{
return arg.minCoeff(row, col);
}
else if constexpr (requires { arg._minCoeff(row, col); })
{
return arg._minCoeff(row, col);
}
else
{
return detail::unsupported_parameters<decltype(arg)>();
}
}
template<int P, typename T>
auto lpNorm(T const& arg)
requires(requires { arg.template lpNorm<P>(); })
template<int P, typename T> auto lpNorm(T const& arg)
{
static_assert(P == 1 || P == 2 || P == Infinity);
return arg.template lpNorm<P>();
if constexpr (requires { arg.template lpNorm<P>(); })
{
static_assert(P == 1 || P == 2 || P == Infinity);
return arg.template lpNorm<P>();
}
else if constexpr (requires { arg.template _lpNorm<P>(); })
{
static_assert(P == 1 || P == 2 || P == Infinity);
return arg.template _lpNorm<P>();
}
else
{
return detail::unsupported_parameters<decltype(arg)>();
}
}
//-----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Expression handling
//-----------------------------------------------------------------------------------------------
template<typename T>
decltype(auto) noalias(T&& t)
requires(requires { std::forward<T>(t).noalias(); })
//----------------------------------------------------------------------------
template<typename T> decltype(auto) noalias(T&& t)
{
return std::forward<T>(t).noalias();
if constexpr (requires { std::forward<T>(t).noalias(); })
{
return std::forward<T>(t).noalias();
}
else if constexpr (requires { std::forward<T>(t)._noalias(); })
{
return std::forward<T>(t)._noalias();
}
else
{
return detail::unsupported_parameters<decltype(t)>();
}
}
template<typename T>
auto evaluate(T&& t)
requires(requires { std::forward<T>(t).evaluate(); })
template<typename T> auto evaluate(T&& t)
{
return std::forward<T>(t).evaluate();
if constexpr (requires { std::forward<T>(t).evaluate(); })
{
return std::forward<T>(t).evaluate();
}
else if constexpr (requires { std::forward<T>(t)._evaluate(); })
{
return std::forward<T>(t)._evaluate();
}
else if constexpr (requires { std::forward<T>(t).eval(); })
{
return std::forward<T>(t).eval();
}
else
{
return detail::unsupported_parameters<decltype(t)>();
}
}
template<typename T>
auto evaluate(T&& t)
requires(requires { std::forward<T>(t).eval(); })
{
return std::forward<T>(t).eval();
}
//-----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Others
// TODO: Adapt other functions ot behave as inverse and limit code in
// non-ref/non-map containers
//-----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------
template<typename A> auto inverse(A const& a)
{
if constexpr (!use_expression_templates)
{
return inverse(generalize_t<A const>(a));
else return base_of(a).inverse();
}
else
{
return base_of(a).inverse();
}
}
template<concepts::vectorND<3> L, concepts::vectorND<3> R>
auto cross(L const& l, R const& r)
{
if constexpr (!use_expression_templates)
{
return cross(generalize_t<R const>(l), generalize_t<R const>(r));
}
else if constexpr (
requires { typename L::rotgen_tag; } ||
requires { typename R::rotgen_tag; })
return base_of(l).cross(base_of(r));
else return l.cross(r);
{
return base_of(l)._cross(base_of(r));
}
else
{
return l._cross(r);
}
}
}

View file

@ -1,19 +1,22 @@
//==================================================================================================
//==============================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
//==============================================================================
#pragma once
#include <rotgen/detail/assert.hpp>
#include <rotgen/detail/helpers.hpp>
#include <rotgen/container/map.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;
@ -22,149 +25,264 @@ namespace rotgen
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());
m = map_t(data, rows(m), cols(m));
}
//-----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Generators
//-----------------------------------------------------------------------------------------------
template<typename T>
auto setZero(T&& t)
requires(requires { std::forward<T>(t).setZero(); })
//----------------------------------------------------------------------------
template<typename T> auto setZero(T&& t)
{
return std::forward<T>(t).setZero();
if constexpr (requires { std::forward<T>(t).setZero(); })
{
return std::forward<T>(t).setZero();
}
else if constexpr (requires { std::forward<T>(t)._setZero(); })
{
return std::forward<T>(t)._setZero();
}
else
{
return detail::unsupported_parameters<T>();
}
}
template<typename T>
auto setZero()
requires(requires { T::Zero(); })
template<typename T> auto setZero()
{
return T::Zero();
if constexpr (requires { T::Zero(); }) { return T::Zero(); }
else if constexpr (requires { T::_Zero(); }) { return T::_Zero(); }
else
{
return detail::unsupported_parameters<T>();
}
}
template<typename T>
auto setZero(std::integral auto n)
requires(requires { T::Zero(n); })
template<typename T> auto setZero(std::integral auto n)
{
return T::Zero(n);
if constexpr (requires { T::Zero(n); }) { return T::Zero(n); }
else if constexpr (requires { T::_Zero(n); }) { return T::_Zero(n); }
else
{
return detail::unsupported_parameters<T>();
}
}
template<typename T>
auto setZero(std::integral auto r, std::integral auto c)
requires(requires { T::Zero(r, c); })
template<typename T> auto setZero(std::integral auto r, std::integral auto c)
{
return T::Zero(r, c);
if constexpr (requires { T::Zero(r, c); }) { return T::Zero(r, c); }
else if constexpr (requires { T::_Zero(r, c); }) { return T::_Zero(r, c); }
else
{
return detail::unsupported_parameters<T>();
}
}
template<typename T>
auto setOnes(T&& t)
requires(requires { std::forward<T>(t).setOnes(); })
template<typename T> auto setOnes(T&& t)
{
return std::forward<T>(t).setOnes();
if constexpr (requires { std::forward<T>(t).setOnes(); })
{
return std::forward<T>(t).setOnes();
}
else if constexpr (requires { std::forward<T>(t)._setOnes(); })
{
return std::forward<T>(t)._setOnes();
}
else
{
return detail::unsupported_parameters<T>();
}
}
template<typename T>
auto setOnes()
requires(requires { T::Ones(); })
template<typename T> auto setOnes()
{
return T::Ones();
if constexpr (requires { T::Ones(); }) { return T::Ones(); }
else if constexpr (requires { T::_Ones(); }) { return T::_Ones(); }
else
{
return detail::unsupported_parameters<T>();
}
}
template<typename T>
auto setOnes(std::integral auto n)
requires(requires { T::Ones(n); })
template<typename T> auto setOnes(std::integral auto n)
{
return T::Ones(n);
if constexpr (requires { T::Ones(n); }) { return T::Ones(n); }
else if constexpr (requires { T::_Ones(n); }) { return T::_Ones(n); }
else
{
return detail::unsupported_parameters<T>();
}
}
template<typename T>
auto setOnes(std::integral auto r, std::integral auto c)
requires(requires { T::Ones(r, c); })
template<typename T> auto setOnes(std::integral auto r, std::integral auto c)
{
return T::Ones(r, c);
if constexpr (requires { T::Ones(r, c); }) { return T::Ones(r, c); }
else if constexpr (requires { T::_Ones(r, c); }) { return T::_Ones(r, c); }
else
{
return detail::unsupported_parameters<T>();
}
}
template<typename T>
auto setIdentity(T&& t)
requires(requires { std::forward<T>(t).setIdentity(); })
template<typename T> auto setIdentity(T&& t)
{
return std::forward<T>(t).setIdentity();
if constexpr (requires { std::forward<T>(t).setIdentity(); })
{
return std::forward<T>(t).setIdentity();
}
else if constexpr (requires { std::forward<T>(t)._setIdentity(); })
{
return std::forward<T>(t)._setIdentity();
}
else
{
return detail::unsupported_parameters<T>();
}
}
template<typename T>
auto setIdentity()
requires(requires { T::Identity(); })
template<typename T> auto setIdentity()
{
return T::Identity();
if constexpr (requires { T::Identity(); }) { return T::Identity(); }
else if constexpr (requires { T::_Identity(); }) { return T::_Identity(); }
else
{
return detail::unsupported_parameters<T>();
}
}
template<typename T>
auto setIdentity(std::integral auto n)
requires(requires { T::Identity(n); })
template<typename T> auto setIdentity(std::integral auto n)
{
return T::Identity(n);
if constexpr (requires { T::Identity(n); }) { return T::Identity(n); }
else if constexpr (requires { T::_Identity(n); })
{
return T::_Identity(n);
}
else
{
return detail::unsupported_parameters<T>();
}
}
template<typename T>
auto setIdentity(std::integral auto r, std::integral auto c)
requires(requires { T::Identity(r, c); })
{
return T::Identity(r, c);
if constexpr (requires { T::Identity(r, c); }) { return T::Identity(r, c); }
else if constexpr (requires { T::_Identity(r, c); })
{
return T::_Identity(r, c);
}
else
{
return detail::unsupported_parameters<T>();
}
}
template<typename T>
auto setRandom(T&& t)
requires(requires { std::forward<T>(t).setRandom(); })
template<typename T> auto setRandom(T&& t)
{
return std::forward<T>(t).setRandom();
if constexpr (requires { std::forward<T>(t).setRandom(); })
{
return std::forward<T>(t).setRandom();
}
else if constexpr (requires { std::forward<T>(t)._setRandom(); })
{
return std::forward<T>(t)._setRandom();
}
else
{
return detail::unsupported_parameters<T>();
}
}
template<typename T>
auto setRandom()
requires(requires { T::Random(); })
template<typename T> auto setRandom()
{
return T::Random();
if constexpr (requires { T::Random(); }) { return T::Random(); }
else if constexpr (requires { T::_Random(); }) { return T::_Random(); }
else
{
return detail::unsupported_parameters<T>();
}
}
template<typename T>
auto setRandom(std::integral auto n)
requires(requires { T::Random(n); })
template<typename T> auto setRandom(std::integral auto n)
{
return T::Random(n);
if constexpr (requires { T::Random(n); }) { return T::Random(n); }
else if constexpr (requires { T::_Random(n); }) { return T::_Random(n); }
else
{
return detail::unsupported_parameters<T>();
}
}
template<typename T>
auto setRandom(std::integral auto r, std::integral auto c)
requires(requires { T::Random(r, c); })
{
return T::Random(r, c);
if constexpr (requires { T::Random(r, c); }) { return T::Random(r, c); }
else if constexpr (requires { T::_Random(r, c); })
{
return T::_Random(r, c);
}
else
{
return detail::unsupported_parameters<T>();
}
}
template<typename T>
auto setConstant(T&& t, auto v)
requires(requires { std::forward<T>(t).setConstant(v); })
template<typename T> auto setConstant(T&& t, auto v)
{
return std::forward<T>(t).setConstant(v);
if constexpr (requires { std::forward<T>(t).setConstant(v); })
{
return std::forward<T>(t).setConstant(v);
}
else if constexpr (requires { std::forward<T>(t)._setConstant(v); })
{
return std::forward<T>(t)._setConstant(v);
}
else
{
return detail::unsupported_parameters<T>();
}
}
template<typename T>
auto setConstant(auto v)
requires(requires { T::Constant(v); })
template<typename T> auto setConstant(auto v)
{
return T::Constant(v);
if constexpr (requires { T::Constant(v); }) { return T::Constant(v); }
else if constexpr (requires { T::_Constant(v); })
{
return T::_Constant(v);
}
else
{
return detail::unsupported_parameters<T>();
}
}
template<typename T>
auto setConstant(std::integral auto n, auto v)
requires(requires { T::Constant(n, v); })
template<typename T> auto setConstant(std::integral auto n, auto v)
{
return T::Constant(n, v);
if constexpr (requires { T::Constant(n, v); }) { return T::Constant(n, v); }
else if constexpr (requires { T::_Constant(n, v); })
{
return T::_Constant(n, v);
}
else
{
return detail::unsupported_parameters<T>();
}
}
template<typename T>
auto setConstant(std::integral auto r, std::integral auto c, auto v)
requires(requires { T::Constant(r, c, v); })
{
return T::Constant(r, c, v);
if constexpr (requires { T::Constant(r, c, v); })
{
return T::Constant(r, c, v);
}
else if constexpr (requires { T::_Constant(r, c, v); })
{
return T::_Constant(r, c, v);
}
else
{
return detail::unsupported_parameters<T>();
}
}
}

View file

@ -7,6 +7,11 @@
//==================================================================================================
#pragma once
#include <rotgen/config.hpp>
#include <rotgen/functions/functions.hpp>
#include <type_traits>
namespace rotgen
{
template<typename Ref> struct rowwise_adaptor
@ -14,64 +19,64 @@ namespace rotgen
using concrete_type = typename std::remove_cvref_t<Ref>::concrete_type;
Ref& target_;
concrete_type sum() const
concrete_type _sum() const
{
concrete_type res(target_.rows(), 1);
apply([&](auto r, auto i) { res(i) = r.sum(); });
concrete_type res(rows(target_), 1);
apply([&](auto r, auto i) { res(i) = rotgen::sum(r); });
return res;
}
concrete_type mean() const
concrete_type _mean() const
{
concrete_type res(target_.rows(), 1);
apply([&](auto r, auto i) { res(i) = r.mean(); });
concrete_type res(rows(target_), 1);
apply([&](auto r, auto i) { res(i) = rotgen::mean(r); });
return res;
}
concrete_type prod() const
concrete_type _prod() const
{
concrete_type res(target_.rows(), 1);
apply([&](auto r, auto i) { res(i) = r.prod(); });
concrete_type res(rows(target_), 1);
apply([&](auto r, auto i) { res(i) = rotgen::prod(r); });
return res;
}
concrete_type maxCoeff() const
concrete_type _maxCoeff() const
{
concrete_type res(target_.rows(), 1);
apply([&](auto r, auto i) { res(i) = r.maxCoeff(); });
concrete_type res(rows(target_), 1);
apply([&](auto r, auto i) { res(i) = rotgen::maxCoeff(r); });
return res;
}
concrete_type minCoeff() const
concrete_type _minCoeff() const
{
concrete_type res(target_.rows(), 1);
apply([&](auto r, auto i) { res(i) = r.minCoeff(); });
concrete_type res(rows(target_), 1);
apply([&](auto r, auto i) { res(i) = rotgen::minCoeff(r); });
return res;
}
concrete_type squaredNorm() const
concrete_type _squaredNorm() const
{
concrete_type res(target_.rows(), 1);
apply([&](auto r, auto i) { res(i) = r.squaredNorm(); });
concrete_type res(rows(target_), 1);
apply([&](auto r, auto i) { res(i) = rotgen::squaredNorm(r); });
return res;
}
concrete_type norm() const
concrete_type _norm() const
{
concrete_type res(target_.rows(), 1);
apply([&](auto r, auto i) { res(i) = r.norm(); });
concrete_type res(rows(target_), 1);
apply([&](auto r, auto i) { res(i) = rotgen::norm(r); });
return res;
}
private:
template<typename Func> void apply(Func f)
{
for (Index i = 0; i < target_.rows(); ++i) f(row(target_, i), i);
for (Index i = 0; i < rows(target_); ++i) { f(row(target_, i), i); }
}
template<typename Func> void apply(Func f) const
{
for (Index i = 0; i < target_.rows(); ++i) f(row(target_, i), i);
for (Index i = 0; i < rows(target_); ++i) { f(row(target_, i), i); }
}
};
@ -80,76 +85,82 @@ namespace rotgen
using concrete_type = typename std::remove_cvref_t<Ref>::concrete_type;
Ref& target_;
concrete_type sum() const
concrete_type _sum() const
{
concrete_type res(1, target_.cols());
apply([&](auto r, auto i) { res(i) = r.sum(); });
concrete_type res(1, cols(target_));
apply([&](auto r, auto i) { res(i) = rotgen::sum(r); });
return res;
}
concrete_type mean() const
concrete_type _mean() const
{
concrete_type res(1, target_.cols());
apply([&](auto r, auto i) { res(i) = r.mean(); });
concrete_type res(1, cols(target_));
apply([&](auto r, auto i) { res(i) = rotgen::mean(r); });
return res;
}
concrete_type prod() const
concrete_type _prod() const
{
concrete_type res(1, target_.cols());
apply([&](auto r, auto i) { res(i) = r.prod(); });
concrete_type res(1, cols(target_));
apply([&](auto r, auto i) { res(i) = rotgen::prod(r); });
return res;
}
concrete_type maxCoeff() const
concrete_type _maxCoeff() const
{
concrete_type res(1, target_.cols());
apply([&](auto r, auto i) { res(i) = r.maxCoeff(); });
concrete_type res(1, cols(target_));
apply([&](auto r, auto i) { res(i) = rotgen::maxCoeff(r); });
return res;
}
concrete_type minCoeff() const
concrete_type _minCoeff() const
{
concrete_type res(1, target_.cols());
apply([&](auto r, auto i) { res(i) = r.minCoeff(); });
concrete_type res(1, cols(target_));
apply([&](auto r, auto i) { res(i) = rotgen::minCoeff(r); });
return res;
}
concrete_type squaredNorm() const
concrete_type _squaredNorm() const
{
concrete_type res(1, target_.cols());
apply([&](auto r, auto i) { res(i) = r.squaredNorm(); });
concrete_type res(1, cols(target_));
apply([&](auto r, auto i) { res(i) = rotgen::squaredNorm(r); });
return res;
}
concrete_type norm() const
concrete_type _norm() const
{
concrete_type res(1, target_.cols());
apply([&](auto r, auto i) { res(i) = r.norm(); });
concrete_type res(1, cols(target_));
apply([&](auto r, auto i) { res(i) = rotgen::norm(r); });
return res;
}
private:
template<typename Func> void apply(Func f)
{
for (Index i = 0; i < target_.cols(); ++i) f(col(target_, i), i);
for (Index i = 0; i < cols(target_); ++i) { f(col(target_, i), i); }
}
template<typename Func> void apply(Func f) const
{
for (Index i = 0; i < target_.cols(); ++i) f(col(target_, i), i);
for (Index i = 0; i < cols(target_); ++i) { f(col(target_, i), i); }
}
};
template<typename T> auto rowwise(T&& t)
{
if constexpr (use_expression_templates) return t.base().rowwise();
else return rowwise_adaptor<T>{t};
if constexpr (use_expression_templates) { return t.base().rowwise(); }
else
{
return rowwise_adaptor<T>{t};
}
}
template<typename T> auto colwise(T&& t)
{
if constexpr (use_expression_templates) return t.base().colwise();
else return colwise_adaptor<T>{t};
if constexpr (use_expression_templates) { return t.base().colwise(); }
else
{
return colwise_adaptor<T>{t};
}
}
}