//================================================================================================== /* ROTGEN - Runtime Overlay for Eigen Copyright : CODE RECKONS SPDX-License-Identifier: BSL-1.0 */ //================================================================================================== #pragma once #include #include #include #include namespace rotgen { template class map : public find_map { public: static_assert ( concepts::entity , "[ROTGEN][CRITICAL] - Map of non-rotgen type instanciated" ); using parent = find_map; using rotgen_tag = void; using value_type = typename std::remove_const_t::value_type; using concrete_type = typename std::remove_const_t::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; static constexpr bool is_defined_static = false; using ptr_type = std::conditional_t; using stride_type = Stride; static constexpr int RowsAtCompileTime = Ref::RowsAtCompileTime; static constexpr int ColsAtCompileTime = Ref::ColsAtCompileTime; static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime; static constexpr bool IsCompileTimeSized = RowsAtCompileTime != -1 && ColsAtCompileTime != -1; using transposed_type = matrix; map(ptr_type ptr, Index r, Index c, stride_type s) : parent(ptr, r, c, strides(s,r,c)) { if constexpr(RowsAtCompileTime != -1) assert(r == RowsAtCompileTime && "Mismatched between dynamic and static row size"); if constexpr(ColsAtCompileTime != -1) assert(c == ColsAtCompileTime && "Mismatched between dynamic and static column size"); } map(ptr_type ptr, Index r, Index c) : parent( ptr, r, c , [&]() { if constexpr(!std::same_as) return strides(Stride{},r,c); else return strides(r,c); }() ) {} map(ptr_type ptr, stride_type s) requires(IsCompileTimeSized) : parent(ptr,RowsAtCompileTime,ColsAtCompileTime, strides(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(IsCompileTimeSized) : map( ptr, RowsAtCompileTime, ColsAtCompileTime ) {} template map(map 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(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()); } transposed_type transpose() const { return transposed_type(base().transpose()); } concrete_type conjugate() const { return concrete_type(base().conjugate()); } transposed_type adjoint() const { return transposed_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()); } concrete_type cwiseMin(map const& rhs) const { return concrete_type(base().cwiseMin(rhs.base())); } concrete_type cwiseMax(map const& rhs) const { return concrete_type(base().cwiseMax(rhs.base())); } concrete_type cwiseQuotient(map const& rhs) const { return concrete_type(base().cwiseQuotient(rhs.base())); } concrete_type cwiseProduct(map const& rhs) const { return concrete_type(base().cwiseProduct(rhs.base())); } concrete_type cwiseMin(value_type s) const { return concrete_type(base().cwiseMin(s)); } concrete_type cwiseMax(value_type s) const { return concrete_type(base().cwiseMax(s)); } concrete_type inverse() const { return concrete_type(base().inverse()); } concrete_type cross(map const& other) const { concrete_type that; if constexpr(RowsAtCompileTime==-1) { that(0,0) = (*this)(1,0) * other(2,0) - (*this)(2,0) * other(1,0); that(1,0) = (*this)(2,0) * other(0,0) - (*this)(0,0) * other(2,0); that(2,0) = (*this)(0,0) * other(1,0) - (*this)(1,0) * other(0,0); } else { that(0,0) = (*this)(0,1) * other(0,2) - (*this)(0,2) * other(0,1); that(0,1) = (*this)(0,2) * other(0,0) - (*this)(0,0) * other(0,2); that(0,2) = (*this)(0,0) * other(0,1) - (*this)(0,1) * other(0,0); } return that; } void normalize() requires(!is_immutable && IsVectorAtCompileTime) { parent::normalize(); } void transposeInPlace() requires(!is_immutable) { parent::transposeInPlace(); } void adjointInPlace() requires(!is_immutable) { parent::adjointInPlace(); } template map& operator+=(map const& rhs) requires(!is_immutable) { base() += rhs.base(); return *this; } template map& operator-=(map const& rhs) requires(!is_immutable) { base() -= rhs.base(); return *this; } concrete_type operator-() const { return concrete_type(base().operator-()); } template map& operator*=(map const& rhs) requires(!is_immutable) { base() *= rhs.base(); 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 auto minCoeff(IndexType* row, IndexType* col) const { Index r,c; auto result = parent::minCoeff(&r, &c); *row = r; *col = c; return result; } template 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 double lpNorm() const { assert(P == 1 || P == 2 || P == Infinity); return parent::lpNorm(P); } parent& base() { return static_cast(*this); } parent const& base() const { return static_cast(*this); } concrete_type qr_solve(map const& rhs) const { return concrete_type(base().qr_solve(rhs.base())); }; }; template detail::composite_matrix_type operator+(map const& lhs, map const& rhs) { using map1_type = map; using map2_type = map; using concrete_type = detail::composite_matrix_type; return concrete_type(map1_type(lhs).base().add(map2_type(rhs))); } template detail::composite_matrix_type operator-(map const& lhs, map const& rhs) { using map1_type = map; using map2_type = map; using concrete_type = detail::composite_matrix_type; return concrete_type(map1_type(lhs).base().sub(map2_type(rhs))); } template matrix operator*(map const& lhs, map const& rhs) { using map1_type = map; using map2_type = map; using concrete_type = matrix< typename R1::value_type , R1::RowsAtCompileTime,R2::ColsAtCompileTime , R1::storage_order >; return concrete_type(map1_type(lhs).base().mul(map2_type(rhs).base())); } template typename map::concrete_type operator*(map const& lhs, std::convertible_to auto s) { using concrete_type = typename map::concrete_type; return concrete_type(lhs.base().mul(s)); } template typename map::concrete_type operator*(std::convertible_to auto s, map const& rhs) { using concrete_type = typename map::concrete_type; return concrete_type(rhs.base().mul(s)); } template typename map::concrete_type operator/(map const& lhs, std::convertible_to auto s) { using concrete_type = typename map::concrete_type; return concrete_type(lhs.base().div(s)); } template bool operator==(map const& lhs, map const& rhs) { return lhs.base() == rhs.base(); } template bool operator!=(map const& lhs, map const& rhs) { return lhs.base() != rhs.base(); } }