327 lines
No EOL
9.4 KiB
C++
327 lines
No EOL
9.4 KiB
C++
//==================================================================================================
|
|
/*
|
|
ROTGEN - Runtime Overlay for Eigen
|
|
Copyright : CODE RECKONS
|
|
SPDX-License-Identifier: BSL-1.0
|
|
*/
|
|
//==================================================================================================
|
|
#pragma once
|
|
|
|
#include <Eigen/Dense>
|
|
#include <iostream>
|
|
|
|
namespace rotgen
|
|
{
|
|
namespace detail
|
|
{
|
|
template<typename Scalar, int Rows, int Cols, int Opts,int MaxRows, int MaxCols>
|
|
using storage_type = std::conditional_t < storage_status<Rows,Cols,MaxRows,MaxCols>
|
|
, Eigen::Matrix<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>
|
|
, Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Opts>
|
|
>;
|
|
}
|
|
|
|
template< typename Scalar
|
|
, int Rows = Dynamic , int Cols = Dynamic
|
|
, int Opts = ColMajor
|
|
, int MaxRows = Rows , int MaxCols = Cols
|
|
>
|
|
class matrix : private detail::storage_type<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>
|
|
{
|
|
public:
|
|
using rotgen_tag = void;
|
|
using parent = detail::storage_type<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>;
|
|
using value_type = Scalar;
|
|
using Index = typename parent::Index;
|
|
|
|
static constexpr auto storage_order = Opts & 1;
|
|
using concrete_type = matrix;
|
|
using concrete_dynamic_type = matrix<value_type>;
|
|
|
|
static constexpr auto Flags = parent::Flags;
|
|
static constexpr int RowsAtCompileTime = Rows;
|
|
static constexpr int ColsAtCompileTime = Cols;
|
|
static constexpr int Options = parent::Options;
|
|
|
|
template<typename ET>
|
|
using as_concrete_type = as_concrete_t<ET, matrix>;
|
|
|
|
static constexpr bool is_defined_static = Rows!=-1 && Cols!=-1;
|
|
static constexpr bool has_static_storage = storage_status<Rows,Cols,MaxRows,MaxCols>;
|
|
|
|
public:
|
|
|
|
matrix() requires(has_static_storage) {}
|
|
matrix() requires(!has_static_storage) : parent(Rows > 0 ? Rows : 0, Cols > 0 ? Cols : 0){}
|
|
matrix(Index r, Index c) requires(!has_static_storage) : parent(r, c) {}
|
|
|
|
matrix(const matrix& other) = default;
|
|
matrix(matrix&& other) = default;
|
|
matrix& operator=(const matrix&) = default;
|
|
matrix& operator=(matrix&&) = default;
|
|
|
|
matrix(std::initializer_list<std::initializer_list<Scalar>> init) : parent(init)
|
|
{}
|
|
|
|
template<std::convertible_to<Scalar>... S>
|
|
requires((Rows == 1 && Cols == (1+sizeof...(S))) || (Cols == 1 && Rows == (1+sizeof...(S))))
|
|
matrix(Scalar s0,S... init)
|
|
: parent ( [&]()
|
|
{
|
|
if constexpr(has_static_storage)
|
|
return parent{static_cast<Scalar>(s0),static_cast<Scalar>(init)...};
|
|
else return parent{Rows,Cols};
|
|
}()
|
|
)
|
|
{
|
|
if constexpr(!has_static_storage)
|
|
{
|
|
auto raw = {static_cast<Scalar>(s0),static_cast<Scalar>(init)...};
|
|
auto first = raw.begin();
|
|
for(rotgen::Index i=0; i < parent::size(); i++)
|
|
(*this)(i) = first[i];
|
|
}
|
|
}
|
|
|
|
matrix(concepts::entity auto const& other) : parent(other.base())
|
|
{}
|
|
|
|
template<typename OtherDerived>
|
|
matrix(const Eigen::MatrixBase<OtherDerived>& other) : parent(other)
|
|
{}
|
|
|
|
template<typename OtherDerived>
|
|
matrix(const Eigen::EigenBase<OtherDerived>& other) : parent(other)
|
|
{}
|
|
|
|
template<typename OtherDerived>
|
|
matrix& operator=(const Eigen::MatrixBase<OtherDerived>& other)
|
|
{
|
|
parent::operator=(other);
|
|
return *this;
|
|
}
|
|
|
|
template<typename OtherDerived>
|
|
matrix& operator=(const Eigen::EigenBase<OtherDerived>& other)
|
|
{
|
|
parent::operator=(other);
|
|
return *this;
|
|
}
|
|
|
|
matrix& operator=(concepts::entity auto const& other)
|
|
{
|
|
parent::operator=(other.base());
|
|
return *this;
|
|
}
|
|
|
|
parent& base() { return static_cast<parent&>(*this); }
|
|
parent const& base() const { return static_cast<const parent&>(*this); }
|
|
|
|
auto transpose() const
|
|
{
|
|
auto res = static_cast<parent const &>(*this).transpose();
|
|
return as_concrete_type<decltype(res)>(res);
|
|
}
|
|
|
|
auto conjugate() const
|
|
{
|
|
auto res = static_cast<parent const &>(*this).conjugate();
|
|
return as_concrete_type<decltype(res)>(res);
|
|
}
|
|
|
|
auto adjoint() const
|
|
{
|
|
auto res = static_cast<parent const &>(*this).adjoint();
|
|
return as_concrete_type<decltype(res)>(res);
|
|
}
|
|
|
|
void transposeInPlace() { parent::transposeInPlace(); }
|
|
void adjointInPlace() { parent::adjointInPlace(); }
|
|
|
|
void resize(int new_rows, int new_cols) requires(Rows == -1 && Cols == -1)
|
|
{
|
|
parent::resize(new_rows, new_cols);
|
|
}
|
|
|
|
void conservativeResize(int new_rows, int new_cols) requires(Rows == -1 && Cols == -1)
|
|
{
|
|
parent::conservativeResize(new_rows, new_cols);
|
|
}
|
|
|
|
static matrix Constant(Scalar value) requires (Rows != -1 && Cols != -1)
|
|
{
|
|
return parent::Constant(Rows, Cols, static_cast<Scalar>(value));
|
|
}
|
|
|
|
static matrix Constant(int rows, int cols, Scalar value)
|
|
{
|
|
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
|
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
|
return parent::Constant(rows, cols, static_cast<Scalar>(value));
|
|
}
|
|
|
|
static matrix Identity() requires (Rows != -1 && Cols != -1)
|
|
{
|
|
return parent::Identity(Rows, Cols);
|
|
}
|
|
|
|
static matrix Identity(int rows, int cols)
|
|
{
|
|
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
|
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
|
return parent::Identity(rows, cols);
|
|
}
|
|
|
|
static matrix Ones() requires (Rows != -1 && Cols != -1)
|
|
{
|
|
return parent::Ones(Rows, Cols);
|
|
}
|
|
|
|
static matrix Ones(int rows, int cols)
|
|
{
|
|
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
|
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
|
return parent::Ones(rows, cols);
|
|
}
|
|
|
|
static matrix Zero() requires (Rows != -1 && Cols != -1)
|
|
{
|
|
return parent::Zero(Rows, Cols);
|
|
}
|
|
|
|
static matrix Zero(int rows, int cols)
|
|
{
|
|
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
|
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
|
return parent::Zero(rows, cols);
|
|
}
|
|
|
|
static matrix Random() requires (Rows != -1 && Cols != -1)
|
|
{
|
|
return parent::Random(Rows, Cols);
|
|
}
|
|
|
|
static matrix Random(int rows, int cols)
|
|
{
|
|
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
|
|
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
|
|
return parent::Random(rows, cols);
|
|
}
|
|
|
|
template<int P>
|
|
value_type lpNorm() const
|
|
{
|
|
static_assert(P == 1 || P == 2 || P == Infinity);
|
|
return parent::template lpNorm<P>();
|
|
}
|
|
|
|
using parent::operator();
|
|
using parent::rows;
|
|
using parent::cols;
|
|
using parent::size;
|
|
using parent::prod;
|
|
using parent::mean;
|
|
using parent::trace;
|
|
using parent::maxCoeff;
|
|
using parent::minCoeff;
|
|
using parent::squaredNorm;
|
|
using parent::norm;
|
|
using parent::sum;
|
|
using parent::data;
|
|
|
|
matrix& setOnes()
|
|
{
|
|
*this = parent::Ones(rows(),cols());
|
|
return *this;
|
|
}
|
|
|
|
matrix& setOnes(int r, int c)
|
|
{
|
|
*this = parent::Ones(r, c);
|
|
return *this;
|
|
}
|
|
|
|
matrix& setZero()
|
|
{
|
|
*this = parent::Zero(rows(),cols());
|
|
return *this;
|
|
}
|
|
|
|
matrix& setZero(int r, int c)
|
|
{
|
|
*this = parent::Zero(r, c);
|
|
return *this;
|
|
}
|
|
|
|
matrix& setConstant(Scalar value)
|
|
{
|
|
*this = parent::Constant(rows(),cols(), static_cast<Scalar>(value));
|
|
return *this;
|
|
}
|
|
|
|
matrix& setConstant(int r, int c, Scalar value)
|
|
{
|
|
*this = parent::Constant(r, c, static_cast<Scalar>(value));
|
|
return *this;
|
|
}
|
|
|
|
matrix& setRandom()
|
|
{
|
|
*this = parent::Random(rows(),cols());
|
|
return *this;
|
|
}
|
|
|
|
matrix& setRandom(int r, int c)
|
|
{
|
|
*this = parent::Random(r, c);
|
|
return *this;
|
|
}
|
|
|
|
matrix& setIdentity()
|
|
{
|
|
*this = parent::Identity(rows(),cols());
|
|
return *this;
|
|
}
|
|
|
|
matrix& setIdentity(int r, int c)
|
|
{
|
|
*this = parent::Identity(r, c);
|
|
return *this;
|
|
}
|
|
|
|
matrix& operator+=(matrix const& rhs)
|
|
{
|
|
static_cast<parent&>(*this) += static_cast<parent const&>(rhs);
|
|
return *this;
|
|
}
|
|
|
|
matrix& operator-=(matrix const& rhs)
|
|
{
|
|
static_cast<parent&>(*this) -= static_cast<parent const&>(rhs);
|
|
return *this;
|
|
}
|
|
|
|
matrix operator-() const
|
|
{
|
|
return matrix(static_cast<parent const&>(*this).operator-());
|
|
}
|
|
|
|
matrix& operator*=(matrix const& rhs)
|
|
{
|
|
static_cast<parent&>(*this) *= static_cast<parent const&>(rhs);
|
|
return *this;
|
|
}
|
|
|
|
matrix& operator*=(Scalar rhs)
|
|
{
|
|
static_cast<parent&>(*this) *= rhs;
|
|
return *this;
|
|
}
|
|
|
|
matrix& operator/=(Scalar rhs)
|
|
{
|
|
static_cast<parent&>(*this) /= rhs;
|
|
return *this;
|
|
}
|
|
};
|
|
} |