330 lines
No EOL
11 KiB
C++
330 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/block.hpp>
|
|
#include <rotgen/dynamic/matrix.hpp>
|
|
#include <initializer_list>
|
|
#include <cassert>
|
|
|
|
namespace rotgen
|
|
{
|
|
template<typename Ref, int Rows = Dynamic, int Cols = Dynamic, bool Inner = false>
|
|
class block : public find_block<Ref>
|
|
{
|
|
public:
|
|
static_assert ( concepts::entity<Ref>
|
|
, "[ROTGEN][CRITICAL] - Block of non-rotgen type instanciated"
|
|
);
|
|
|
|
using parent = find_block<Ref>;
|
|
using rotgen_tag = void;
|
|
using rotgen_block_tag = void;
|
|
using value_type = typename std::remove_const_t<Ref>::value_type;
|
|
|
|
static constexpr int storage_order = Ref::storage_order;
|
|
static constexpr bool is_immutable = std::is_const_v<Ref>;
|
|
using concrete_type = matrix<value_type,Rows,Cols,storage_order>;
|
|
using concrete_dynamic_type = matrix<value_type,Dynamic,Dynamic,storage_order>;
|
|
|
|
static constexpr int RowsAtCompileTime = Rows;
|
|
static constexpr int ColsAtCompileTime = Cols;
|
|
static constexpr int Options = Ref::Options;
|
|
static constexpr bool IsRowMajor = (storage_order & RowMajor) == RowMajor;
|
|
|
|
static constexpr bool is_defined_static = false;
|
|
static constexpr bool has_static_storage = false;
|
|
|
|
using parent::operator=;
|
|
block& 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;
|
|
}
|
|
|
|
block(Ref const& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
|
requires( !requires{typename Ref::rotgen_block_tag; } && is_immutable)
|
|
: parent(r,i0,j0,ni,nj)
|
|
{}
|
|
|
|
block(Ref const& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
|
requires( requires{typename Ref::rotgen_block_tag; } && is_immutable)
|
|
: parent(*r.storage(),i0,j0,ni,nj)
|
|
{}
|
|
|
|
block(Ref const& r, std::size_t i0, std::size_t j0)
|
|
requires(!requires{typename Ref::rotgen_block_tag; } && Rows != -1 && Cols != -1 && is_immutable)
|
|
: parent(r,i0,j0,Rows,Cols)
|
|
{}
|
|
|
|
block(Ref const& r, std::size_t i0, std::size_t j0)
|
|
requires(requires{typename Ref::rotgen_block_tag; } && Rows != -1 && Cols != -1 && is_immutable)
|
|
: parent(*r.storage(),i0,j0,Rows,Cols)
|
|
{}
|
|
|
|
block(Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
|
requires( !requires{typename Ref::rotgen_block_tag; } && !is_immutable)
|
|
: parent(r,i0,j0,ni,nj)
|
|
{}
|
|
|
|
block(Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
|
requires( requires{typename Ref::rotgen_block_tag; } && !is_immutable)
|
|
: parent(*r.storage(),i0,j0,ni,nj)
|
|
{}
|
|
|
|
block(Ref& r, std::size_t i0, std::size_t j0)
|
|
requires(!requires{typename Ref::rotgen_block_tag; } && Rows != -1 && Cols != -1 && !is_immutable)
|
|
: parent(r,i0,j0,Rows,Cols)
|
|
{}
|
|
|
|
block(Ref& r, std::size_t i0, std::size_t j0)
|
|
requires(requires{typename Ref::rotgen_block_tag; } && Rows != -1 && Cols != -1 && !is_immutable)
|
|
: parent(*r.storage(),i0,j0,Rows,Cols)
|
|
{}
|
|
|
|
block(parent const& base) : parent(base) {}
|
|
|
|
bool is_contiguous_linear() const
|
|
{
|
|
if(parent::innerStride() != 1) return false;
|
|
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 parent::operator()(i,j); }
|
|
|
|
value_type& operator()(Index i) requires(!is_immutable)
|
|
{
|
|
assert(is_contiguous_linear());
|
|
return parent::operator()(i);
|
|
}
|
|
|
|
value_type operator()(Index i, Index j) const { return parent::operator()(i,j); }
|
|
|
|
value_type operator()(Index i) const
|
|
{
|
|
assert(is_contiguous_linear());
|
|
return parent::operator()(i);
|
|
}
|
|
|
|
concrete_type transpose() const
|
|
{
|
|
return concrete_type(static_cast<parent const &>(*this).transpose());
|
|
}
|
|
|
|
concrete_type conjugate() const
|
|
{
|
|
return concrete_type(static_cast<parent const &>(*this).conjugate());
|
|
}
|
|
|
|
concrete_type adjoint() const
|
|
{
|
|
return concrete_type(static_cast<parent const&>(*this).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 transposeInPlace() requires(!is_immutable) { parent::transposeInPlace(); }
|
|
void adjointInPlace() requires(!is_immutable) { parent::adjointInPlace(); }
|
|
|
|
friend bool operator==(block const& lhs, block const& rhs)
|
|
{
|
|
return static_cast<parent const&>(lhs) == static_cast<parent const&>(rhs);
|
|
}
|
|
|
|
block& operator+=(block const& rhs) requires(!is_immutable)
|
|
{
|
|
base() += static_cast<parent const&>(rhs);
|
|
return *this;
|
|
}
|
|
|
|
block& operator-=(block const& rhs) requires(!is_immutable)
|
|
{
|
|
base() -= 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)
|
|
{
|
|
base() *= static_cast<parent const&>(rhs);
|
|
return *this;
|
|
}
|
|
|
|
block& operator*=(value_type rhs) requires(!is_immutable)
|
|
{
|
|
base() *= rhs;
|
|
return *this;
|
|
}
|
|
|
|
block& operator/=(value_type rhs) requires(!is_immutable)
|
|
{
|
|
base() /= rhs;
|
|
return *this;
|
|
}
|
|
|
|
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 Constant(value_type value)
|
|
requires (Rows != -1 && Cols != -1)
|
|
{
|
|
return parent::Constant(Rows, Cols, static_cast<double>(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<double>(value));
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
block& setOnes() requires(!is_immutable)
|
|
{
|
|
parent::assign(parent::Ones(parent::rows(), parent::cols()));
|
|
return *this;
|
|
}
|
|
|
|
block& setZero() requires(!is_immutable)
|
|
{
|
|
parent::assign(parent::Zero(parent::rows(), parent::cols()));
|
|
return *this;
|
|
}
|
|
|
|
block& setConstant(value_type value) requires(!is_immutable)
|
|
{
|
|
parent::assign(parent::Constant(parent::rows(), parent::cols(), value));
|
|
return *this;
|
|
}
|
|
|
|
block& setRandom() requires(!is_immutable)
|
|
{
|
|
parent::assign(parent::Random(parent::rows(), parent::cols()));
|
|
return *this;
|
|
}
|
|
|
|
block& setIdentity() requires(!is_immutable)
|
|
{
|
|
parent::assign(parent::Identity(parent::rows(), parent::cols()));
|
|
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); }
|
|
};
|
|
|
|
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().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));
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
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));
|
|
}
|
|
} |