346 lines
No EOL
11 KiB
C++
346 lines
No EOL
11 KiB
C++
//==================================================================================================
|
|
/*
|
|
ROTGEN - Runtime Overlay for Eigen
|
|
Copyright : CODE RECKONS
|
|
SPDX-License-Identifier: BSL-1.0
|
|
*/
|
|
//==================================================================================================
|
|
#pragma once
|
|
|
|
#include <rotgen/concepts.hpp>
|
|
#include <rotgen/impl/map.hpp>
|
|
#include <cassert>
|
|
|
|
namespace rotgen
|
|
{
|
|
template<typename Ref, int Options = Unaligned, typename Stride = rotgen::stride>
|
|
class map : public find_map<Ref>
|
|
{
|
|
public:
|
|
|
|
static_assert ( concepts::entity<Ref>
|
|
, "[ROTGEN][CRITICAL] - Map of non-rotgen type instanciated"
|
|
);
|
|
|
|
using parent = find_map<Ref>;
|
|
using rotgen_tag = void;
|
|
using value_type = typename std::remove_const_t<Ref>::value_type;
|
|
using concrete_type = typename std::remove_const_t<Ref>::concrete_type;
|
|
|
|
static constexpr bool IsRowMajor = Ref::IsRowMajor;
|
|
static constexpr int storage_order = Ref::storage_order;
|
|
static constexpr bool has_static_storage = false;
|
|
|
|
static constexpr bool is_immutable = std::is_const_v<Ref>;
|
|
static constexpr bool is_defined_static = false;
|
|
|
|
using ptr_type = std::conditional_t<is_immutable, value_type const*, value_type*>;
|
|
using stride_type = Stride;
|
|
|
|
static constexpr int RowsAtCompileTime = Ref::RowsAtCompileTime;
|
|
static constexpr int ColsAtCompileTime = Ref::ColsAtCompileTime;
|
|
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
|
|
|
|
map(ptr_type ptr, Index r, Index c, stride_type s) : parent(ptr, r, c, strides<storage_order>(s,r,c)) {}
|
|
map(ptr_type ptr, Index r, Index c)
|
|
: parent( ptr, r, c
|
|
, [&]()
|
|
{
|
|
if constexpr(!std::same_as<Stride,stride>) return strides<storage_order>(Stride{},r,c);
|
|
else return strides<storage_order>(r,c);
|
|
}()
|
|
)
|
|
{}
|
|
|
|
map(ptr_type ptr, stride_type s) requires(RowsAtCompileTime!=-1 && ColsAtCompileTime!=-1)
|
|
: parent(ptr,RowsAtCompileTime,ColsAtCompileTime, strides<storage_order>(s))
|
|
{}
|
|
|
|
map(ptr_type ptr, Index size) requires(RowsAtCompileTime==1 || ColsAtCompileTime==1)
|
|
: map( ptr, RowsAtCompileTime==1?1:size, ColsAtCompileTime==1?1:size)
|
|
{}
|
|
|
|
map(ptr_type ptr) requires(RowsAtCompileTime!=-1 && ColsAtCompileTime!=-1)
|
|
: map( ptr, RowsAtCompileTime, ColsAtCompileTime )
|
|
{}
|
|
|
|
template<typename R2, int O2, typename S2>
|
|
map(map<R2,O2,S2> const& other) : map ( other.data(), other.rows(), other.cols()
|
|
, stride{other.outerStride(),other.innerStride()}
|
|
)
|
|
{}
|
|
|
|
map(parent const& base) : parent(base) {}
|
|
|
|
map(map const& other) : parent(other)
|
|
{}
|
|
|
|
map& operator=(map const& other) requires(!is_immutable)
|
|
{
|
|
base() = static_cast<parent const &>(*other);
|
|
return *this;
|
|
}
|
|
|
|
map& operator=(concepts::entity auto const& other) requires(!is_immutable)
|
|
{
|
|
assert(parent::rows() == other.rows() && parent::cols() == other.cols());
|
|
for (rotgen::Index r = 0; r < parent::rows(); ++r)
|
|
for (rotgen::Index c = 0; c < parent::cols(); ++c)
|
|
(*this)(r, c) = other(r, c);
|
|
|
|
return *this;
|
|
}
|
|
|
|
value_type& operator()(Index i, Index j) requires(!is_immutable) { return parent::operator()(i,j); }
|
|
value_type& operator()(Index i) requires(!is_immutable && IsVectorAtCompileTime)
|
|
{
|
|
assert( parent::innerStride() == 1
|
|
&& parent::outerStride() ==(storage_order == RowMajor ? parent::cols() : parent::rows())
|
|
);
|
|
return parent::operator()(i);
|
|
}
|
|
|
|
value_type& operator[](Index i) requires(!is_immutable && IsVectorAtCompileTime)
|
|
{
|
|
return (*this)(i);
|
|
}
|
|
|
|
value_type operator()(Index i, Index j) const { return parent::operator()(i,j); }
|
|
value_type operator()(Index i) const requires(IsVectorAtCompileTime)
|
|
{
|
|
assert( parent::innerStride() == 1
|
|
&& parent::outerStride() ==(storage_order == RowMajor ? parent::cols() : parent::rows())
|
|
);
|
|
return parent::operator()(i);
|
|
}
|
|
|
|
value_type operator[](Index i) const requires(IsVectorAtCompileTime)
|
|
{
|
|
return (*this)(i);
|
|
}
|
|
|
|
auto evaluate() const { return *this; }
|
|
decltype(auto) noalias() const { return *this; }
|
|
decltype(auto) noalias() { return *this; }
|
|
|
|
concrete_type normalized() const requires(IsVectorAtCompileTime)
|
|
{
|
|
return concrete_type(base().normalized());
|
|
}
|
|
|
|
concrete_type transpose() const { return concrete_type(base().transpose()); }
|
|
concrete_type conjugate() const { return concrete_type(base().conjugate()); }
|
|
concrete_type adjoint() const { return concrete_type(base().adjoint()); }
|
|
|
|
concrete_type cwiseAbs() const { return concrete_type(base().cwiseAbs()); }
|
|
concrete_type cwiseAbs2() const { return concrete_type(base().cwiseAbs2()); }
|
|
concrete_type cwiseInverse() const { return concrete_type(base().cwiseInverse()); }
|
|
concrete_type cwiseSqrt() const { return concrete_type(base().cwiseSqrt()); }
|
|
|
|
void normalize() requires(!is_immutable && IsVectorAtCompileTime)
|
|
{
|
|
parent::normalize();
|
|
}
|
|
void transposeInPlace() requires(!is_immutable) { parent::transposeInPlace(); }
|
|
void adjointInPlace() requires(!is_immutable) { parent::adjointInPlace(); }
|
|
|
|
map& operator+=(map const& rhs) requires(!is_immutable)
|
|
{
|
|
base() += static_cast<parent const&>(rhs);
|
|
return *this;
|
|
}
|
|
|
|
map& operator-=(map const& rhs) requires(!is_immutable)
|
|
{
|
|
base() -= static_cast<parent const&>(rhs);
|
|
return *this;
|
|
}
|
|
|
|
concrete_type operator-() const
|
|
{
|
|
return concrete_type(base().operator-());
|
|
}
|
|
|
|
map& operator*=(map const& rhs) requires(!is_immutable)
|
|
{
|
|
base() *= static_cast<parent const&>(rhs);
|
|
return *this;
|
|
}
|
|
|
|
map& operator*=(value_type rhs) requires(!is_immutable)
|
|
{
|
|
base() *= rhs;
|
|
return *this;
|
|
}
|
|
|
|
map& operator/=(value_type rhs) requires(!is_immutable)
|
|
{
|
|
base() /= rhs;
|
|
return *this;
|
|
}
|
|
|
|
auto minCoeff() const { return parent::minCoeff(); }
|
|
auto maxCoeff() const { return parent::maxCoeff(); }
|
|
|
|
template<std::integral IndexType>
|
|
auto minCoeff(IndexType* row, IndexType* col) const
|
|
{
|
|
Index 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
|
|
{
|
|
Index r,c;
|
|
auto result = parent::maxCoeff(&r, &c);
|
|
*row = r;
|
|
*col = c;
|
|
return result;
|
|
}
|
|
|
|
static auto Zero() requires( requires {Ref::Zero();} )
|
|
{
|
|
return Ref::Zero();
|
|
}
|
|
|
|
static auto Zero(int rows, int cols)
|
|
{
|
|
return Ref::Zero(rows,cols);
|
|
}
|
|
|
|
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)
|
|
{
|
|
return Ref::Constant(rows, cols, value);
|
|
}
|
|
|
|
static auto Random() requires( requires {Ref::Random();} )
|
|
{
|
|
return Ref::Random();
|
|
}
|
|
|
|
static auto Random(int rows, int cols)
|
|
{
|
|
return Ref::Random(rows, cols);
|
|
}
|
|
|
|
static auto Identity() requires( requires {Ref::Identity();} )
|
|
{
|
|
return Ref::Identity();
|
|
}
|
|
|
|
static auto Identity(int rows, int cols)
|
|
{
|
|
return Ref::Identity(rows, cols);
|
|
}
|
|
|
|
map& setZero() requires(!is_immutable)
|
|
{
|
|
parent::setZero();
|
|
return *this;
|
|
}
|
|
|
|
map& setOnes() requires(!is_immutable)
|
|
{
|
|
parent::setOnes();
|
|
return *this;
|
|
}
|
|
|
|
map& setIdentity() requires(!is_immutable)
|
|
{
|
|
parent::setIdentity();
|
|
return *this;
|
|
}
|
|
|
|
map& setRandom() requires(!is_immutable)
|
|
{
|
|
parent::setRandom();
|
|
return *this;
|
|
}
|
|
|
|
map& setConstant(value_type s) requires(!is_immutable)
|
|
{
|
|
parent::setConstant(s);
|
|
return *this;
|
|
}
|
|
|
|
template<int P>
|
|
double lpNorm() const
|
|
{
|
|
assert(P == 1 || P == 2 || P == Infinity);
|
|
return parent::lpNorm(P);
|
|
}
|
|
|
|
parent& base() { return static_cast<parent&>(*this); }
|
|
parent const& base() const { return static_cast<parent const&>(*this); }
|
|
|
|
concrete_type qr_solve(map const& rhs) const
|
|
{
|
|
return concrete_type(base().qr_solve(rhs.base()));
|
|
};
|
|
};
|
|
|
|
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
|
|
typename map<R1,O1,S1>::concrete_type operator+(map<R1,O1,S1> const& lhs, map<R2,O2,S2> const& rhs)
|
|
{
|
|
using concrete_type = typename map<R1,O1,S1>::concrete_type;
|
|
return concrete_type(lhs.base().add(map<R1,O1,S1>(rhs)));
|
|
}
|
|
|
|
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
|
|
typename map<R1,O1,S1>::concrete_type operator-(map<R1,O1,S1> const& lhs, map<R2,O2,S2> const& rhs)
|
|
{
|
|
using concrete_type = typename map<R1,O1,S1>::concrete_type;
|
|
return concrete_type(lhs.base().sub(map<R1,O1,S1>(rhs)));
|
|
}
|
|
|
|
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
|
|
typename map<R1,O1,S1>::concrete_type operator*(map<R1,O1,S1> const& lhs, map<R2,O2,S2> const& rhs)
|
|
{
|
|
using concrete_type = typename map<R1,O1,S1>::concrete_type;
|
|
return concrete_type(lhs.base().mul(map<R1,O1,S1>(rhs)));
|
|
}
|
|
|
|
template<typename R, int O, typename S>
|
|
typename map<R,O,S>::concrete_type
|
|
operator*(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));
|
|
}
|
|
|
|
template<typename R, int O, typename S>
|
|
typename map<R,O,S>::concrete_type
|
|
operator*(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));
|
|
}
|
|
|
|
template<typename R, int O, typename S>
|
|
typename map<R,O,S>::concrete_type
|
|
operator/(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));
|
|
}
|
|
|
|
template<typename R1, int O1, typename S1, typename R2, int O2, typename S2>
|
|
bool operator==(map<R1,O1,S1> const& lhs, map<R2,O2,S2> const& rhs)
|
|
{
|
|
return lhs.base() == rhs.base();
|
|
}
|
|
template<typename R1, int O1, typename S1, typename R2, int O2, typename S2>
|
|
bool operator!=(map<R1,O1,S1> const& lhs, map<R2,O2,S2> const& rhs)
|
|
{
|
|
return lhs.base() != rhs.base();
|
|
}
|
|
} |