rotgen/include/rotgen/fixed/block.hpp

370 lines
No EOL
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//==================================================================================================
/*
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 Ref, int Rows, int Cols, bool Inner, bool IsConst>
struct compute_block_type
{
using ref_t = std::conditional_t<IsConst, typename Ref::parent const, typename Ref::parent>;
using type = std::conditional_t < storage_status<Rows,Cols,Rows,Cols>
, Eigen::Block<ref_t, Rows, Cols, Inner>
, Eigen::Block<ref_t, Eigen::Dynamic, Eigen::Dynamic, Inner>
>;
};
template<typename Ref, int Rows, int Cols, bool Inner, bool IsConst>
using block_type = typename compute_block_type<Ref,Rows,Cols,Inner,IsConst>::type;
}
template< typename Ref
, int Rows = Dynamic, int Cols = Dynamic
, bool Inner = false , int ForceStorageOrder = -1
>
class block : private detail::block_type<std::remove_const_t<Ref>, Rows, Cols, Inner,std::is_const_v<Ref> >
{
static_assert ( concepts::entity<Ref>
, "[ROTGEN][CRITICAL] - Block of non-rotgen type instanciated"
);
public:
using rotgen_tag = void;
using rotgen_block_tag = void;
using parent = detail::block_type<std::remove_const_t<Ref>, Rows, Cols, Inner,std::is_const_v<Ref>>;
using value_type = typename parent::value_type;
using Index = typename parent::Index;
static constexpr int storage_order = (ForceStorageOrder == -1) ? Ref::storage_order : ForceStorageOrder;
static constexpr bool is_immutable = std::is_const_v<Ref>;
static constexpr bool IsRowMajor = parent::IsRowMajor;
using concrete_type = matrix<value_type,Rows,Cols,storage_order>;
using concrete_dynamic_type = matrix<value_type,Dynamic,Dynamic,storage_order>;
template<typename ET>
using as_concrete_type = as_concrete_t<ET, matrix>;
static constexpr auto Flags = Ref::Flags;
static constexpr int Options = Ref::Options;
static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols;
static constexpr bool is_defined_static = Rows!=-1 && Cols!=-1;
static constexpr bool has_static_storage = storage_status<Rows,Cols,Rows,Cols>;
public:
block(const block& other) = default;
block(block&& other) = default;
block& operator=(const block&) = default;
block& operator=(block&&) = default;
block(Ref const& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
requires(is_immutable)
: parent(r.base(),i0,j0,ni,nj)
{}
block(Ref const& r, std::size_t i0, std::size_t j0)
requires(Rows != -1 && Cols != -1 && is_immutable)
: parent(r.base(),i0,j0,Rows,Cols)
{}
block(Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
requires(!is_immutable)
: parent(r.base(),i0,j0,ni,nj)
{}
block(Ref& r, std::size_t i0, std::size_t j0)
requires(Rows != -1 && Cols != -1 && !is_immutable)
: parent(r.base(),i0,j0,Rows,Cols)
{}
template<typename B, int R, int C, bool I, int FS>
block(block<B,R,C,I,FS> const& other) : parent(other.base())
{}
template<typename OtherDerived>
block(const Eigen::MatrixBase<OtherDerived>& other) : parent(other) {}
template<typename OtherDerived>
block(const Eigen::EigenBase<OtherDerived>& other) : parent(other) {}
template<typename OtherDerived>
block& operator=(const Eigen::MatrixBase<OtherDerived>& other)
{
parent::operator=(other);
return *this;
}
template<typename OtherDerived>
block& operator=(const Eigen::EigenBase<OtherDerived>& other)
{
parent::operator=(other);
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() requires(!is_immutable) { parent::transposeInPlace(); }
void adjointInPlace() requires(!is_immutable) { parent::adjointInPlace(); }
auto cwiseAbs() const
{
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseAbs()};
else return base().cwiseAbs();
}
auto cwiseAbs2() const
{
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseAbs2()};
else return base().cwiseAbs2();
}
auto cwiseInverse() const
{
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseInverse()};
else return base().cwiseInverse();
}
auto cwiseSqrt() const
{
if constexpr(!use_expression_templates) return concrete_type{parent::cwiseSqrt()};
else return base().cwiseSqrt();
}
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)
{
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<value_type>(value));
}
static concrete_type Identity() requires (Rows != -1 && Cols != -1)
{
return parent::Identity(Rows, Cols);
}
static concrete_type 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 concrete_type Zero() requires (Rows != -1 && Cols != -1)
{
return parent::Zero(Rows, Cols);
}
static concrete_type 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 concrete_type Ones() requires (Rows != -1 && Cols != -1)
{
return parent::Ones(Rows, Cols);
}
static concrete_type 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 concrete_type Random() requires (Rows != -1 && Cols != -1)
{
return parent::Random(Rows, Cols);
}
static concrete_type 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);
}
block& setOnes() requires(!is_immutable)
{
*this = parent::Ones(rows(), cols());
return *this;
}
block& setOnes(int r, int c) requires(!is_immutable)
{
*this = parent::Ones(r, c);
return *this;
}
block& setZero() requires(!is_immutable)
{
*this = parent::Zero(rows(), cols());
return *this;
}
block& setZero(int r, int c) requires(!is_immutable)
{
*this = parent::Zero(r,c);
return *this;
}
block& setConstant(value_type value) requires(!is_immutable)
{
*this = parent::Constant(rows(), cols(), value);
return *this;
}
block& setConstant(int r, int c, value_type value) requires(!is_immutable)
{
*this = parent::Constant(r,c, value);
return *this;
}
block& setRandom() requires(!is_immutable)
{
*this = parent::Random(rows(),cols());
return *this;
}
block& setRandom(int r, int c) requires(!is_immutable)
{
*this = parent::Random(r,c);
return *this;
}
block& setIdentity() requires(!is_immutable)
{
*this = parent::Identity(rows(),cols());
return *this;
}
block& setIdentity(int r, int c) requires(!is_immutable)
{
*this = parent::Identity(r,c);
return *this;
}
template<int P>
value_type lpNorm() const
{
static_assert(P == 1 || P == 2 || P == Infinity);
return parent::template lpNorm<P>();
}
bool is_contiguous_linear() const
{
if(parent::innerStride() != 1) return false;
// outerstride must equal the “innerdimension length”
if constexpr(storage_order) return parent::outerStride() == parent::cols();
else return parent::outerStride() == parent::rows();
}
value_type& operator()(Index i, Index j) requires(!is_immutable) { return base()(i,j); }
value_type operator()(Index i, Index j) const { return base()(i,j); }
value_type& operator()(Index i) requires(!is_immutable)
{
assert(is_contiguous_linear());
return base().data()[i];
}
value_type operator()(Index i) const
{
assert(is_contiguous_linear());
return base().data()[i];
}
using parent::innerStride;
using parent::outerStride;
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;
Index startRow() const { return base().startRow(); }
Index startCol() const { return base().startCol(); }
block& operator+=(block const& rhs) requires(!is_immutable)
{
static_cast<parent&>(*this) += static_cast<parent const&>(rhs);
return *this;
}
block& operator-=(block const& rhs) requires(!is_immutable)
{
static_cast<parent&>(*this) -= static_cast<parent const&>(rhs);
return *this;
}
concrete_type operator-() const
{
return concrete_type(static_cast<parent const&>(*this).operator-());
}
block& operator*=(block const& rhs) requires(!is_immutable)
{
static_cast<parent&>(*this) *= static_cast<parent const&>(rhs);
return *this;
}
block& operator*=(value_type rhs) requires(!is_immutable)
{
static_cast<parent&>(*this) *= rhs;
return *this;
}
block& operator/=(value_type rhs) requires(!is_immutable)
{
static_cast<parent&>(*this) /= rhs;
return *this;
}
};
}