Implements block typs and related functions - First part
Co-authored-by: Karen <kkaspar@codereckons.com> Co-authored-by: Joel FALCOU <jfalcou@codereckons.com> See merge request oss/rotgen!9
This commit is contained in:
commit
b868398a77
28 changed files with 1814 additions and 114 deletions
|
|
@ -30,6 +30,7 @@ endif()
|
|||
##======================================================================================================================
|
||||
set ( SOURCES
|
||||
src/matrix.cpp
|
||||
src/block.cpp
|
||||
)
|
||||
|
||||
##======================================================================================================================
|
||||
|
|
|
|||
197
include/rotgen/block.hpp
Normal file
197
include/rotgen/block.hpp
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/impl/block.hpp>
|
||||
#include <rotgen/matrix.hpp>
|
||||
#include <initializer_list>
|
||||
#include <cassert>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
template<typename Ref, int Rows = Dynamic, int Cols = Dynamic, bool Inner = false, int ForceStorageOrder = -1>
|
||||
class block : public find_block<Ref>
|
||||
{
|
||||
using parent = find_block<Ref>;
|
||||
public:
|
||||
using scalar_type = typename Ref::scalar_type;
|
||||
static constexpr int storage_order = (ForceStorageOrder == -1) ? Ref::storage_order : ForceStorageOrder;
|
||||
using concrete_type = matrix<scalar_type,Rows,Cols,storage_order>;
|
||||
|
||||
static constexpr int RowsAtCompileTime = Rows;
|
||||
static constexpr int ColsAtCompileTime = Cols;
|
||||
|
||||
block(Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj) : parent(r,i0,j0,ni,nj)
|
||||
{}
|
||||
|
||||
block(Ref& r, std::size_t i0, std::size_t j0) requires(Rows != -1 && Cols != -1)
|
||||
: parent(r,i0,j0,Rows,Cols)
|
||||
{}
|
||||
|
||||
block(parent const& base) : parent(base) {}
|
||||
|
||||
/*
|
||||
block transpose() const
|
||||
{
|
||||
return block(static_cast<parent const&>(*this).transpose());
|
||||
}
|
||||
|
||||
block conjugate() const
|
||||
{
|
||||
return block(static_cast<parent const&>(*this).conjugate());
|
||||
}
|
||||
|
||||
block adjoint() const
|
||||
{
|
||||
return block(static_cast<parent const&>(*this).adjoint());
|
||||
}
|
||||
*/
|
||||
|
||||
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)
|
||||
{
|
||||
static_cast<parent&>(*this) += static_cast<parent const&>(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
block& operator-=(block const& rhs)
|
||||
{
|
||||
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)
|
||||
{
|
||||
static_cast<parent&>(*this) *= static_cast<parent const&>(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
block& operator*=(scalar_type rhs)
|
||||
{
|
||||
static_cast<parent&>(*this) *= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
block& operator/=(scalar_type rhs)
|
||||
{
|
||||
static_cast<parent&>(*this) /= 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 Constant(scalar_type value)
|
||||
requires (Rows != -1 && Cols != -1)
|
||||
{
|
||||
return parent::Constant(Rows, Cols, static_cast<double>(value));
|
||||
}
|
||||
|
||||
static concrete_type Constant(int rows, int cols, scalar_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);
|
||||
}
|
||||
|
||||
template<int P>
|
||||
double lpNorm() const
|
||||
{
|
||||
assert(P == 1 || P == 2 || P == Infinity);
|
||||
return parent::lpNorm(P);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
block<S,R,C,O,MR,MC> operator+(block<S,R,C,O,MR,MC> const& lhs, block<S,R,C,O,MR,MC> const& rhs)
|
||||
{
|
||||
block<S,R,C,O,MR,MC> that(lhs);
|
||||
return that += rhs;
|
||||
}
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
block<S,R,C,O,MR,MC> operator-(block<S,R,C,O,MR,MC> const& lhs, block<S,R,C,O,MR,MC> const& rhs)
|
||||
{
|
||||
block<S,R,C,O,MR,MC> that(lhs);
|
||||
return that -= rhs;
|
||||
}
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
block<S,R,C,O,MR,MC> operator*(block<S,R,C,O,MR,MC> const& lhs, block<S,R,C,O,MR,MC> const& rhs)
|
||||
{
|
||||
block<S,R,C,O,MR,MC> that(lhs);
|
||||
return that *= rhs;
|
||||
}
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
block<S,R,C,O,MR,MC> operator*(block<S,R,C,O,MR,MC> const& lhs, double rhs)
|
||||
{
|
||||
block<S,R,C,O,MR,MC> that(lhs);
|
||||
return that *= rhs;
|
||||
}
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
block<S,R,C,O,MR,MC> operator*(double lhs, block<S,R,C,O,MR,MC> const& rhs)
|
||||
{
|
||||
return rhs * lhs;
|
||||
}
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
block<S,R,C,O,MR,MC> operator/(block<S,R,C,O,MR,MC> const& lhs, double rhs)
|
||||
{
|
||||
block<S,R,C,O,MR,MC> that(lhs);
|
||||
return that /= rhs;
|
||||
}
|
||||
*/
|
||||
}
|
||||
235
include/rotgen/extract.hpp
Normal file
235
include/rotgen/extract.hpp
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/matrix.hpp>
|
||||
#include <rotgen/block.hpp>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
template< typename S, int R , int C
|
||||
, int Opts , int MaxR, int MaxC
|
||||
>
|
||||
auto extract(matrix<S,R,C,Opts,MaxR,MaxC>& m, int i0, int j0,int ni, int nj)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base>(m, i0,j0,ni,nj);
|
||||
}
|
||||
|
||||
template< int NI, int NJ
|
||||
, typename S, int R , int C
|
||||
, int Opts , int MaxR, int MaxC
|
||||
>
|
||||
auto extract(matrix<S,R,C,Opts,MaxR,MaxC>& m, int i0, int j0)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base,NI,NJ>(m,i0,j0);
|
||||
}
|
||||
|
||||
template< typename S, int R , int C
|
||||
, int Opts , int MaxR, int MaxC
|
||||
>
|
||||
auto topLeftCorner(matrix<S,R,C,Opts,MaxR,MaxC>& m, int ni, int nj)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base>(m,0,0,ni,nj);
|
||||
}
|
||||
|
||||
template< typename S, int R , int C
|
||||
, int Opts , int MaxR, int MaxC
|
||||
>
|
||||
auto topRightCorner(matrix<S,R,C,Opts,MaxR,MaxC>& m, int ni, int nj)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base>(m,0,m.cols()-nj,ni,nj);
|
||||
}
|
||||
|
||||
template< typename S, int R , int C
|
||||
, int Opts , int MaxR, int MaxC
|
||||
>
|
||||
auto bottomLeftCorner(matrix<S,R,C,Opts,MaxR,MaxC>& m, int ni, int nj)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base>(m,m.rows()-ni,0,ni,nj);
|
||||
}
|
||||
|
||||
template< typename S, int R , int C
|
||||
, int Opts , int MaxR, int MaxC
|
||||
>
|
||||
auto bottomRightCorner(matrix<S,R,C,Opts,MaxR,MaxC>& m, int ni, int nj)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base>(m,m.rows()-ni,m.cols()-nj,ni,nj);
|
||||
}
|
||||
|
||||
template< typename S, int R , int C
|
||||
, int Opts , int MaxR, int MaxC
|
||||
>
|
||||
auto topRows(matrix<S,R,C,Opts,MaxR,MaxC>& m, int ni)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base>(m,0,0,ni,m.cols());
|
||||
}
|
||||
|
||||
template< typename S, int R , int C,
|
||||
int Opts , int MaxR, int MaxC
|
||||
>
|
||||
auto middleRows(matrix<S,R,C,Opts,MaxR,MaxC>& m, int i0, int ni)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base>(m,i0,0,ni,m.cols());
|
||||
}
|
||||
|
||||
template< typename S, int R , int C
|
||||
, int Opts , int MaxR, int MaxC
|
||||
>
|
||||
auto bottomRows(matrix<S,R,C,Opts,MaxR,MaxC>& m, int ni)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base>(m,m.rows()-ni,0,ni,m.cols());
|
||||
}
|
||||
|
||||
template< typename S, int R , int C
|
||||
, int Opts , int MaxR, int MaxC
|
||||
>
|
||||
auto leftCols(matrix<S,R,C,Opts,MaxR,MaxC>& m, int nj)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base>(m,0,0,m.rows(),nj);
|
||||
}
|
||||
|
||||
template< typename S, int R , int C,
|
||||
int Opts , int MaxR, int MaxC
|
||||
>
|
||||
auto middleCols(matrix<S,R,C,Opts,MaxR,MaxC>& m, int j0, int nj)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base>(m,0,j0,m.rows(),nj);
|
||||
}
|
||||
|
||||
template< typename S, int R , int C
|
||||
, int Opts , int MaxR, int MaxC
|
||||
>
|
||||
auto rightCols(matrix<S,R,C,Opts,MaxR,MaxC>& m, int nj)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base>(m,0,m.cols()-nj,m.rows(),nj);
|
||||
}
|
||||
|
||||
template< typename S, int R, int C
|
||||
, int Opts , int MaxR, int MaxC
|
||||
>
|
||||
auto row(matrix<S,R,C,Opts,MaxR,MaxC>& m, int i0)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base,1, -1, false, 1>(m,i0,0, 1, m.cols());
|
||||
}
|
||||
|
||||
template< typename S, int R, int C
|
||||
, int Opts , int MaxR, int MaxC
|
||||
>
|
||||
auto col(matrix<S,R,C,Opts,MaxR,MaxC>& m, int j0)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base,-1,1, false, 0>(m,0,j0, m.rows(), 1);
|
||||
}
|
||||
|
||||
template< int NI, typename S, int R, int C,
|
||||
int Opts, int MaxR, int MaxC
|
||||
>
|
||||
auto topRows(matrix<S,R,C,Opts,MaxR,MaxC>& m)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base,NI,-1>(m,0,0, NI, m.cols());
|
||||
}
|
||||
|
||||
template< int NI, typename S, int R, int C,
|
||||
int Opts, int MaxR, int MaxC
|
||||
>
|
||||
auto bottomRows(matrix<S,R,C,Opts,MaxR,MaxC>& m)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base,NI,-1>(m,m.rows()-NI,0, NI, m.cols());
|
||||
}
|
||||
|
||||
template< int NI, typename S, int R, int C,
|
||||
int Opts , int MaxR, int MaxC
|
||||
>
|
||||
auto middleRows(matrix<S,R,C,Opts,MaxR,MaxC>& m, int i0)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base,NI,-1>(m,i0,0, NI, m.cols());
|
||||
}
|
||||
|
||||
template< int NJ, typename S, int R, int C,
|
||||
int Opts, int MaxR, int MaxC
|
||||
>
|
||||
auto leftCols(matrix<S,R,C,Opts,MaxR,MaxC>& m)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base,-1,NJ>(m,0,0, m.rows(), NJ);
|
||||
}
|
||||
|
||||
template< int NJ, typename S, int R, int C,
|
||||
int Opts, int MaxR, int MaxC
|
||||
>
|
||||
auto rightCols(matrix<S,R,C,Opts,MaxR,MaxC>& m)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base,-1,NJ>(m,0,m.cols()-NJ, m.rows(), NJ);
|
||||
}
|
||||
|
||||
template< int NJ, typename S, int R, int C,
|
||||
int Opts , int MaxR, int MaxC
|
||||
>
|
||||
auto middleCols(matrix<S,R,C,Opts,MaxR,MaxC>& m, int j0)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base,-1,NJ>(m,0,j0, m.rows(), NJ);
|
||||
}
|
||||
|
||||
template< int NI, int NJ
|
||||
, typename S, int R , int C
|
||||
, int Opts , int MaxR, int MaxC
|
||||
>
|
||||
auto topLeftCorner(matrix<S,R,C,Opts,MaxR,MaxC>& m)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base,NI,NJ>(m,0,0);
|
||||
}
|
||||
|
||||
template< int NI, int NJ
|
||||
, typename S, int R , int C
|
||||
, int Opts , int MaxR, int MaxC
|
||||
>
|
||||
auto topRightCorner(matrix<S,R,C,Opts,MaxR,MaxC>& m)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base,NI,NJ>(m,0,m.cols()-NJ);
|
||||
}
|
||||
|
||||
template< int NI, int NJ
|
||||
, typename S, int R , int C
|
||||
, int Opts , int MaxR, int MaxC
|
||||
>
|
||||
auto bottomLeftCorner(matrix<S,R,C,Opts,MaxR,MaxC>& m)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base,NI,NJ>(m,m.rows()-NI,0);
|
||||
}
|
||||
|
||||
template< int NI, int NJ
|
||||
, typename S, int R , int C
|
||||
, int Opts , int MaxR, int MaxC
|
||||
>
|
||||
auto bottomRightCorner(matrix<S,R,C,Opts,MaxR,MaxC>& m)
|
||||
{
|
||||
using base = matrix<S,R,C,Opts,MaxR,MaxC>;
|
||||
return block<base,NI,NJ>(m,m.rows()-NI,m.cols()-NJ);
|
||||
}
|
||||
}
|
||||
64
include/rotgen/impl/block.hpp
Normal file
64
include/rotgen/impl/block.hpp
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/detail/generators.hpp>
|
||||
#include <rotgen/detail/static_info.hpp>
|
||||
#include <rotgen/impl/matrix.hpp>
|
||||
#include <initializer_list>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
#define SIZE 64
|
||||
#define TYPE double
|
||||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(block_impl,SIZE,_col)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
||||
#include <rotgen/impl/block_model.hpp>
|
||||
#undef CLASSNAME
|
||||
#undef SOURCENAME
|
||||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(block_impl,SIZE,_row)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
||||
#include <rotgen/impl/block_model.hpp>
|
||||
#undef CLASSNAME
|
||||
#undef SOURCENAME
|
||||
|
||||
#undef SIZE
|
||||
#undef TYPE
|
||||
|
||||
#define SIZE 32
|
||||
#define TYPE float
|
||||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(block_impl,SIZE,_col)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
||||
#include <rotgen/impl/block_model.hpp>
|
||||
#undef CLASSNAME
|
||||
#undef SOURCENAME
|
||||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(block_impl,SIZE,_row)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
||||
#include <rotgen/impl/block_model.hpp>
|
||||
#undef CLASSNAME
|
||||
#undef SOURCENAME
|
||||
|
||||
#undef SIZE
|
||||
#undef TYPE
|
||||
|
||||
template<typename Scalar,int Options> struct find_block_impl;
|
||||
|
||||
template<> struct find_block_impl<float , ColMajor> { using type = block_impl32_col; };
|
||||
template<> struct find_block_impl<float , RowMajor> { using type = block_impl32_row; };
|
||||
template<> struct find_block_impl<double, ColMajor> { using type = block_impl64_col; };
|
||||
template<> struct find_block_impl<double, RowMajor> { using type = block_impl64_row; };
|
||||
|
||||
template<typename Ref>
|
||||
using find_block = typename find_block_impl<typename Ref::scalar_type, Ref::storage_order>::type;
|
||||
}
|
||||
81
include/rotgen/impl/block_model.hpp
Normal file
81
include/rotgen/impl/block_model.hpp
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
|
||||
//==================================================================================================
|
||||
/*
|
||||
This file is a X-File to generate various block_impl_* declarations variant
|
||||
*/
|
||||
//==================================================================================================
|
||||
class CLASSNAME
|
||||
{
|
||||
public:
|
||||
CLASSNAME(SOURCENAME& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj);
|
||||
|
||||
CLASSNAME(CLASSNAME const& other);
|
||||
CLASSNAME(CLASSNAME&&) noexcept;
|
||||
|
||||
CLASSNAME& operator=(CLASSNAME const& other);
|
||||
CLASSNAME& operator=(CLASSNAME&&) noexcept;
|
||||
|
||||
~CLASSNAME();
|
||||
|
||||
std::size_t rows() const;
|
||||
std::size_t cols() const;
|
||||
std::size_t size() const;
|
||||
|
||||
// CLASSNAME transpose() const;
|
||||
// CLASSNAME conjugate() const;
|
||||
// CLASSNAME adjoint() const;
|
||||
|
||||
// void transposeInPlace();
|
||||
// void adjointInPlace();
|
||||
|
||||
TYPE sum() const;
|
||||
TYPE prod() const;
|
||||
TYPE mean() const;
|
||||
TYPE trace() const;
|
||||
TYPE maxCoeff() const;
|
||||
TYPE minCoeff() const;
|
||||
TYPE maxCoeff(std::ptrdiff_t* row, std::ptrdiff_t* col) const;
|
||||
TYPE minCoeff(std::ptrdiff_t* row, std::ptrdiff_t* col) const;
|
||||
|
||||
TYPE squaredNorm() const;
|
||||
TYPE norm() const;
|
||||
TYPE lpNorm(int p) const;
|
||||
|
||||
TYPE& operator()(std::size_t i, std::size_t j);
|
||||
TYPE const& operator()(std::size_t i, std::size_t j) const;
|
||||
|
||||
// TYPE& operator()(std::size_t index);
|
||||
// TYPE const& operator()(std::size_t index) const;
|
||||
|
||||
CLASSNAME& operator+=(CLASSNAME const& rhs);
|
||||
CLASSNAME& operator-=(CLASSNAME const& rhs);
|
||||
SOURCENAME operator-() const;
|
||||
CLASSNAME& operator*=(CLASSNAME const& rhs);
|
||||
CLASSNAME& operator*=(TYPE d);
|
||||
CLASSNAME& operator/=(TYPE d);
|
||||
|
||||
friend std::ostream& operator<<(std::ostream&,CLASSNAME const&);
|
||||
friend bool operator==(CLASSNAME const& lhs, CLASSNAME const& rhs);
|
||||
|
||||
const TYPE* data() const;
|
||||
|
||||
static SOURCENAME Zero(std::size_t r, std::size_t c) { return SOURCENAME::Zero(r,c); }
|
||||
static SOURCENAME Constant(std::size_t r, std::size_t c, TYPE v) { return SOURCENAME::Constant(r,c,v); }
|
||||
static SOURCENAME Random(std::size_t r, std::size_t c) { return SOURCENAME::Random(r,c); }
|
||||
static SOURCENAME Identity(std::size_t r, std::size_t c) { return SOURCENAME::Identity(r,c); }
|
||||
|
||||
private:
|
||||
struct payload;
|
||||
std::unique_ptr<payload> storage_;
|
||||
|
||||
public:
|
||||
std::unique_ptr<payload>& storage() { return storage_; }
|
||||
std::unique_ptr<payload> const& storage() const { return storage_; }
|
||||
};
|
||||
|
|
@ -18,13 +18,13 @@ namespace rotgen
|
|||
#define SIZE 64
|
||||
#define TYPE double
|
||||
|
||||
#define MATRIX ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
||||
#include <rotgen/impl/matrix_model.hpp>
|
||||
#undef MATRIX
|
||||
#undef CLASSNAME
|
||||
|
||||
#define MATRIX ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
||||
#include <rotgen/impl/matrix_model.hpp>
|
||||
#undef MATRIX
|
||||
#undef CLASSNAME
|
||||
|
||||
#undef SIZE
|
||||
#undef TYPE
|
||||
|
|
@ -32,13 +32,13 @@ namespace rotgen
|
|||
#define SIZE 32
|
||||
#define TYPE float
|
||||
|
||||
#define MATRIX ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
||||
#include <rotgen/impl/matrix_model.hpp>
|
||||
#undef MATRIX
|
||||
#undef CLASSNAME
|
||||
|
||||
#define MATRIX ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
||||
#include <rotgen/impl/matrix_model.hpp>
|
||||
#undef MATRIX
|
||||
#undef CLASSNAME
|
||||
|
||||
#undef SIZE
|
||||
#undef TYPE
|
||||
|
|
|
|||
|
|
@ -8,24 +8,24 @@
|
|||
|
||||
//==================================================================================================
|
||||
/*
|
||||
This file is a X-File to generate various matrix_impl_* definitions variant
|
||||
This file is a X-File to generate various matrix_impl_* declarations variant
|
||||
*/
|
||||
//==================================================================================================
|
||||
class MATRIX
|
||||
class CLASSNAME
|
||||
{
|
||||
public:
|
||||
MATRIX(std::size_t rows = 0, std::size_t cols = 0);
|
||||
MATRIX(std::size_t rows, std::size_t cols,std::initializer_list<TYPE> init);
|
||||
CLASSNAME(std::size_t rows = 0, std::size_t cols = 0);
|
||||
CLASSNAME(std::size_t rows, std::size_t cols,std::initializer_list<TYPE> init);
|
||||
|
||||
MATRIX(std::initializer_list<std::initializer_list<TYPE>> init);
|
||||
CLASSNAME(std::initializer_list<std::initializer_list<TYPE>> init);
|
||||
|
||||
MATRIX(MATRIX const& other);
|
||||
MATRIX(MATRIX&&) noexcept;
|
||||
CLASSNAME(CLASSNAME const& other);
|
||||
CLASSNAME(CLASSNAME&&) noexcept;
|
||||
|
||||
MATRIX& operator=(MATRIX const& other);
|
||||
MATRIX& operator=(MATRIX&&) noexcept;
|
||||
CLASSNAME& operator=(CLASSNAME const& other);
|
||||
CLASSNAME& operator=(CLASSNAME&&) noexcept;
|
||||
|
||||
~MATRIX();
|
||||
~CLASSNAME();
|
||||
|
||||
std::size_t rows() const;
|
||||
std::size_t cols() const;
|
||||
|
|
@ -34,9 +34,9 @@ class MATRIX
|
|||
void resize(std::size_t new_rows, std::size_t new_cols);
|
||||
void conservativeResize(std::size_t new_rows, std::size_t new_cols);
|
||||
|
||||
MATRIX transpose() const;
|
||||
MATRIX conjugate() const;
|
||||
MATRIX adjoint() const;
|
||||
CLASSNAME transpose() const;
|
||||
CLASSNAME conjugate() const;
|
||||
CLASSNAME adjoint() const;
|
||||
|
||||
void transposeInPlace();
|
||||
void adjointInPlace();
|
||||
|
|
@ -60,24 +60,28 @@ class MATRIX
|
|||
TYPE& operator()(std::size_t index);
|
||||
TYPE const& operator()(std::size_t index) const;
|
||||
|
||||
MATRIX& operator+=(MATRIX const& rhs);
|
||||
MATRIX& operator-=(MATRIX const& rhs);
|
||||
MATRIX operator-() const;
|
||||
MATRIX& operator*=(MATRIX const& rhs);
|
||||
MATRIX& operator*=(TYPE d);
|
||||
MATRIX& operator/=(TYPE d);
|
||||
CLASSNAME& operator+=(CLASSNAME const& rhs);
|
||||
CLASSNAME& operator-=(CLASSNAME const& rhs);
|
||||
CLASSNAME operator-() const;
|
||||
CLASSNAME& operator*=(CLASSNAME const& rhs);
|
||||
CLASSNAME& operator*=(TYPE d);
|
||||
CLASSNAME& operator/=(TYPE d);
|
||||
|
||||
friend std::ostream& operator<<(std::ostream&,MATRIX const&);
|
||||
friend bool operator==(MATRIX const& lhs, MATRIX const& rhs);
|
||||
friend std::ostream& operator<<(std::ostream&,CLASSNAME const&);
|
||||
friend bool operator==(CLASSNAME const& lhs, CLASSNAME const& rhs);
|
||||
|
||||
const TYPE* data() const;
|
||||
|
||||
static MATRIX Zero(std::size_t rows, std::size_t cols);
|
||||
static MATRIX Constant(std::size_t rows, std::size_t cols, TYPE value);
|
||||
static MATRIX Random(std::size_t rows, std::size_t cols);
|
||||
static MATRIX Identity(std::size_t rows, std::size_t cols);
|
||||
static CLASSNAME Zero(std::size_t rows, std::size_t cols);
|
||||
static CLASSNAME Constant(std::size_t rows, std::size_t cols, TYPE value);
|
||||
static CLASSNAME Random(std::size_t rows, std::size_t cols);
|
||||
static CLASSNAME Identity(std::size_t rows, std::size_t cols);
|
||||
|
||||
private:
|
||||
struct payload;
|
||||
std::unique_ptr<payload> storage_;
|
||||
|
||||
public:
|
||||
std::unique_ptr<payload>& storage() { return storage_; }
|
||||
std::unique_ptr<payload> const& storage() const { return storage_; }
|
||||
};
|
||||
67
include/rotgen/impl/payload.hpp
Normal file
67
include/rotgen/impl/payload.hpp
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <rotgen/impl/matrix.hpp>
|
||||
#include <Eigen/Dense>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
//==================================================================================================
|
||||
// Internal payload - Requried for cross-referencing from block_impl*
|
||||
//==================================================================================================
|
||||
struct matrix_impl64_col::payload
|
||||
{
|
||||
using data_type = Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,Eigen::ColMajor>;
|
||||
|
||||
data_type data;
|
||||
payload(std::size_t r=0, std::size_t c=0) : data(r, c) {}
|
||||
payload(std::initializer_list<std::initializer_list<double>> init) : data(init) {}
|
||||
payload(data_type&& matrix) : data(std::move(matrix)) {}
|
||||
|
||||
void assign(Eigen::Block<data_type> ref) { data = ref; }
|
||||
};
|
||||
|
||||
struct matrix_impl64_row::payload
|
||||
{
|
||||
using data_type = Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor>;
|
||||
|
||||
data_type data;
|
||||
payload(std::size_t r=0, std::size_t c=0) : data(r, c) {}
|
||||
payload(std::initializer_list<std::initializer_list<double>> init) : data(init) {}
|
||||
payload(data_type&& matrix) : data(std::move(matrix)) {}
|
||||
|
||||
void assign(Eigen::Block<data_type> ref) { data = ref; }
|
||||
};
|
||||
|
||||
struct matrix_impl32_col::payload
|
||||
{
|
||||
using data_type = Eigen::Matrix<float,Eigen::Dynamic,Eigen::Dynamic,Eigen::ColMajor>;
|
||||
|
||||
data_type data;
|
||||
payload(std::size_t r=0, std::size_t c=0) : data(r, c) {}
|
||||
payload(std::initializer_list<std::initializer_list<float>> init) : data(init) {}
|
||||
payload(data_type&& matrix) : data(std::move(matrix)) {}
|
||||
|
||||
void assign(Eigen::Block<data_type> ref) { data = ref; }
|
||||
};
|
||||
|
||||
struct matrix_impl32_row::payload
|
||||
{
|
||||
using data_type = Eigen::Matrix<float,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor>;
|
||||
|
||||
data_type data;
|
||||
payload(std::size_t r=0, std::size_t c=0) : data(r, c) {}
|
||||
payload(std::initializer_list<std::initializer_list<float>> init) : data(init) {}
|
||||
payload(data_type&& matrix) : data(std::move(matrix)) {}
|
||||
|
||||
void assign(Eigen::Block<data_type> ref) { data = ref; }
|
||||
};
|
||||
}
|
||||
|
|
@ -20,10 +20,11 @@ namespace rotgen
|
|||
>
|
||||
class matrix : public find_matrix<Scalar,Options>
|
||||
{
|
||||
using parent = find_matrix<Scalar,Options>;
|
||||
using parent = find_matrix<Scalar,Options>;
|
||||
|
||||
public:
|
||||
using value_type = Scalar;
|
||||
using scalar_type = Scalar;
|
||||
static constexpr auto storage_order = Options & 1;
|
||||
|
||||
matrix() : parent(Rows==-1?0:Rows,Cols==-1?0:Cols) {}
|
||||
|
||||
|
|
|
|||
12
include/rotgen/rotgen.hpp
Normal file
12
include/rotgen/rotgen.hpp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/matrix.hpp>
|
||||
#include <rotgen/block.hpp>
|
||||
#include <rotgen/extract.hpp>
|
||||
58
src/block.cpp
Normal file
58
src/block.cpp
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#include <rotgen/detail/generators.hpp>
|
||||
#include <rotgen/impl/block.hpp>
|
||||
#include <rotgen/impl/payload.hpp>
|
||||
#include <Eigen/Dense>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
#define SIZE 64
|
||||
#define TYPE double
|
||||
#define STORAGE_ORDER Eigen::ColMajor
|
||||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(block_impl,SIZE,_col)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
||||
#include "block_model.cpp"
|
||||
#undef CLASSNAME
|
||||
#undef SOURCENAME
|
||||
#undef STORAGE_ORDER
|
||||
|
||||
#define STORAGE_ORDER Eigen::RowMajor
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(block_impl,SIZE,_row)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
||||
#include "block_model.cpp"
|
||||
#undef CLASSNAME
|
||||
#undef SOURCENAME
|
||||
#undef STORAGE_ORDER
|
||||
|
||||
#undef SIZE
|
||||
#undef TYPE
|
||||
|
||||
#define SIZE 32
|
||||
#define TYPE float
|
||||
#define STORAGE_ORDER Eigen::ColMajor
|
||||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(block_impl,SIZE,_col)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
||||
#include "block_model.cpp"
|
||||
#undef CLASSNAME
|
||||
#undef SOURCENAME
|
||||
#undef STORAGE_ORDER
|
||||
|
||||
#define STORAGE_ORDER Eigen::RowMajor
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(block_impl,SIZE,_row)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
||||
#include "block_model.cpp"
|
||||
#undef CLASSNAME
|
||||
#undef SOURCENAME
|
||||
#undef STORAGE_ORDER
|
||||
|
||||
#undef SIZE
|
||||
#undef TYPE
|
||||
}
|
||||
172
src/block_model.cpp
Normal file
172
src/block_model.cpp
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
|
||||
//==================================================================================================
|
||||
/*
|
||||
This file is a X-File to generate various block_impl_* definitions variant
|
||||
*/
|
||||
//==================================================================================================
|
||||
|
||||
//==================================================================================================
|
||||
// Internal payload
|
||||
//==================================================================================================
|
||||
struct CLASSNAME::payload
|
||||
{
|
||||
using base_type = Eigen::Matrix<TYPE,Eigen::Dynamic,Eigen::Dynamic,STORAGE_ORDER>;
|
||||
using data_type = Eigen::Block<base_type>;
|
||||
|
||||
data_type data;
|
||||
payload (data_type const& o) : data(o) {}
|
||||
|
||||
payload (base_type& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
||||
: data(r,i0,j0,ni,nj)
|
||||
{}
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
// Constructors & Special Members
|
||||
//==================================================================================================
|
||||
CLASSNAME::CLASSNAME(SOURCENAME& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
||||
: storage_(std::make_unique<payload>(r.storage()->data,i0,j0,ni,nj))
|
||||
{}
|
||||
|
||||
CLASSNAME::CLASSNAME(CLASSNAME const& o) : storage_(std::make_unique<payload>(o.storage_->data))
|
||||
{}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator=(CLASSNAME const& o)
|
||||
{
|
||||
if (this != &o) storage_->data = o.storage_->data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME::CLASSNAME(CLASSNAME&&) noexcept = default;
|
||||
CLASSNAME& CLASSNAME::operator=(CLASSNAME&&) noexcept = default;
|
||||
|
||||
CLASSNAME::~CLASSNAME() = default;
|
||||
|
||||
//==================================================================================================
|
||||
// Matrix API
|
||||
//==================================================================================================
|
||||
std::size_t CLASSNAME::rows() const { return static_cast<std::size_t>(storage_->data.rows()); }
|
||||
std::size_t CLASSNAME::cols() const { return static_cast<std::size_t>(storage_->data.cols()); }
|
||||
std::size_t CLASSNAME::size() const { return static_cast<std::size_t>(storage_->data.size()); }
|
||||
|
||||
TYPE& CLASSNAME::operator()(std::size_t i, std::size_t j) { return storage_->data(i,j); }
|
||||
TYPE const& CLASSNAME::operator()(std::size_t i, std::size_t j) const { return storage_->data(i,j); }
|
||||
|
||||
/*
|
||||
TYPE& CLASSNAME::operator()(std::size_t index) { return storage_->data(index); }
|
||||
TYPE const& CLASSNAME::operator()(std::size_t index) const { return storage_->data(index); }
|
||||
*/
|
||||
|
||||
const TYPE* CLASSNAME::data() const { return storage_->data.data(); }
|
||||
|
||||
/*
|
||||
CLASSNAME CLASSNAME::transpose() const
|
||||
{
|
||||
CLASSNAME result(*this);
|
||||
result.storage_->data.transposeInPlace();
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
CLASSNAME CLASSNAME::conjugate() const
|
||||
{
|
||||
CLASSNAME result(*this);
|
||||
result.storage_->data = storage_->data.conjugate();
|
||||
return result;
|
||||
}
|
||||
|
||||
CLASSNAME CLASSNAME::adjoint() const
|
||||
{
|
||||
CLASSNAME result(*this);
|
||||
result.storage_->data.adjointInPlace();
|
||||
return result;
|
||||
}
|
||||
|
||||
void CLASSNAME::transposeInPlace()
|
||||
{
|
||||
storage_->data.transposeInPlace();
|
||||
}
|
||||
|
||||
void CLASSNAME::adjointInPlace()
|
||||
{
|
||||
storage_->data.adjointInPlace();
|
||||
}
|
||||
*/
|
||||
|
||||
TYPE CLASSNAME::sum() const { return storage_->data.sum(); }
|
||||
TYPE CLASSNAME::prod() const { return storage_->data.prod(); }
|
||||
TYPE CLASSNAME::mean() const { return storage_->data.mean(); }
|
||||
TYPE CLASSNAME::trace() const { return storage_->data.trace(); }
|
||||
|
||||
TYPE CLASSNAME::minCoeff() const { return storage_->data.minCoeff(); }
|
||||
TYPE CLASSNAME::maxCoeff() const { return storage_->data.maxCoeff(); }
|
||||
|
||||
TYPE CLASSNAME::minCoeff(std::ptrdiff_t* row, std::ptrdiff_t* col) const { return storage_->data.minCoeff(row, col); }
|
||||
TYPE CLASSNAME::maxCoeff(std::ptrdiff_t* row, std::ptrdiff_t* col) const { return storage_->data.maxCoeff(row, col); }
|
||||
|
||||
TYPE CLASSNAME::squaredNorm() const { return storage_->data.squaredNorm(); }
|
||||
TYPE CLASSNAME::norm() const { return storage_->data.norm(); }
|
||||
|
||||
TYPE CLASSNAME::lpNorm(int p) const
|
||||
{
|
||||
if (p == 1) return storage_->data.lpNorm<1>();
|
||||
else if (p == 2) return storage_->data.lpNorm<2>();
|
||||
else return storage_->data.lpNorm<Eigen::Infinity>();
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
// Operators
|
||||
//==================================================================================================
|
||||
std::ostream& operator<<(std::ostream& os,CLASSNAME const& m)
|
||||
{
|
||||
return os << m.storage_->data;
|
||||
}
|
||||
|
||||
bool operator==(CLASSNAME const& lhs, CLASSNAME const& rhs)
|
||||
{
|
||||
return lhs.storage_->data == rhs.storage_->data;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator+=(CLASSNAME const& rhs)
|
||||
{
|
||||
storage_->data += rhs.storage_->data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator-=(CLASSNAME const& rhs)
|
||||
{
|
||||
storage_->data -= rhs.storage_->data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SOURCENAME CLASSNAME::operator-() const
|
||||
{
|
||||
SOURCENAME result;
|
||||
result.storage()->assign(storage_->data);
|
||||
return -result;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator*=(CLASSNAME const& rhs)
|
||||
{
|
||||
storage_->data *= rhs.storage_->data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator*=(TYPE s)
|
||||
{
|
||||
storage_->data *= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CLASSNAME& CLASSNAME::operator/=(TYPE s)
|
||||
{
|
||||
storage_->data /= s;
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
//==================================================================================================
|
||||
#include <rotgen/detail/generators.hpp>
|
||||
#include <rotgen/impl/matrix.hpp>
|
||||
#include <rotgen/impl/payload.hpp>
|
||||
#include <Eigen/Dense>
|
||||
|
||||
namespace rotgen
|
||||
|
|
@ -15,15 +16,15 @@ namespace rotgen
|
|||
#define TYPE double
|
||||
#define STORAGE_ORDER Eigen::ColMajor
|
||||
|
||||
#define MATRIX ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
||||
#include "matrix_model.cpp"
|
||||
#undef MATRIX
|
||||
#undef CLASSNAME
|
||||
#undef STORAGE_ORDER
|
||||
|
||||
#define STORAGE_ORDER Eigen::RowMajor
|
||||
#define MATRIX ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
||||
#include "matrix_model.cpp"
|
||||
#undef MATRIX
|
||||
#undef CLASSNAME
|
||||
#undef STORAGE_ORDER
|
||||
|
||||
#undef SIZE
|
||||
|
|
@ -33,15 +34,15 @@ namespace rotgen
|
|||
#define TYPE float
|
||||
#define STORAGE_ORDER Eigen::ColMajor
|
||||
|
||||
#define MATRIX ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_col)
|
||||
#include "matrix_model.cpp"
|
||||
#undef MATRIX
|
||||
#undef CLASSNAME
|
||||
#undef STORAGE_ORDER
|
||||
|
||||
#define STORAGE_ORDER Eigen::RowMajor
|
||||
#define MATRIX ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(matrix_impl,SIZE,_row)
|
||||
#include "matrix_model.cpp"
|
||||
#undef MATRIX
|
||||
#undef CLASSNAME
|
||||
#undef STORAGE_ORDER
|
||||
|
||||
#undef SIZE
|
||||
|
|
|
|||
|
|
@ -12,127 +12,114 @@
|
|||
*/
|
||||
//==================================================================================================
|
||||
|
||||
//==================================================================================================
|
||||
// Internal payload
|
||||
//==================================================================================================
|
||||
struct MATRIX::payload
|
||||
{
|
||||
using data_type = Eigen::Matrix<TYPE,Eigen::Dynamic,Eigen::Dynamic,STORAGE_ORDER>;
|
||||
|
||||
data_type data;
|
||||
payload(std::size_t r=0, std::size_t c=0) : data(r, c) {}
|
||||
payload(std::initializer_list<std::initializer_list<TYPE>> init) : data(init) {}
|
||||
payload(data_type&& matrix) : data(std::move(matrix)) {}
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
// Constructors & Special Members
|
||||
//==================================================================================================
|
||||
MATRIX::MATRIX(std::size_t r, std::size_t c) : storage_(std::make_unique<payload>(r,c)) {}
|
||||
CLASSNAME::CLASSNAME(std::size_t r, std::size_t c) : storage_(std::make_unique<payload>(r,c)) {}
|
||||
|
||||
MATRIX::MATRIX(std::initializer_list<std::initializer_list<TYPE>> init)
|
||||
CLASSNAME::CLASSNAME(std::initializer_list<std::initializer_list<TYPE>> init)
|
||||
: storage_(std::make_unique<payload>(init))
|
||||
{}
|
||||
|
||||
MATRIX::MATRIX(std::size_t r, std::size_t c,std::initializer_list<TYPE> init)
|
||||
: MATRIX(r,c)
|
||||
CLASSNAME::CLASSNAME(std::size_t r, std::size_t c,std::initializer_list<TYPE> init)
|
||||
: CLASSNAME(r,c)
|
||||
{
|
||||
auto first = init.begin();
|
||||
for(std::size_t i=0; i < init.size(); i++)
|
||||
(*this)(i) = first[i];
|
||||
}
|
||||
|
||||
MATRIX::MATRIX(MATRIX const& o)
|
||||
: MATRIX(o.rows(),o.cols())
|
||||
CLASSNAME::CLASSNAME(CLASSNAME const& o)
|
||||
: CLASSNAME(o.rows(),o.cols())
|
||||
{
|
||||
storage_->data = o.storage_->data;
|
||||
}
|
||||
|
||||
MATRIX::MATRIX(MATRIX&&) noexcept = default;
|
||||
CLASSNAME::CLASSNAME(CLASSNAME&&) noexcept = default;
|
||||
|
||||
|
||||
MATRIX& MATRIX::operator=(MATRIX const& o)
|
||||
CLASSNAME& CLASSNAME::operator=(CLASSNAME const& o)
|
||||
{
|
||||
if (this != &o) storage_->data = o.storage_->data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MATRIX& MATRIX::operator=(MATRIX&&) noexcept = default;
|
||||
CLASSNAME& CLASSNAME::operator=(CLASSNAME&&) noexcept = default;
|
||||
|
||||
MATRIX::~MATRIX() = default;
|
||||
CLASSNAME::~CLASSNAME() = default;
|
||||
|
||||
//==================================================================================================
|
||||
// Matrix API
|
||||
//==================================================================================================
|
||||
std::size_t MATRIX::rows() const { return static_cast<std::size_t>(storage_->data.rows()); }
|
||||
std::size_t MATRIX::cols() const { return static_cast<std::size_t>(storage_->data.cols()); }
|
||||
std::size_t MATRIX::size() const { return static_cast<std::size_t>(storage_->data.size()); }
|
||||
std::size_t CLASSNAME::rows() const { return static_cast<std::size_t>(storage_->data.rows()); }
|
||||
std::size_t CLASSNAME::cols() const { return static_cast<std::size_t>(storage_->data.cols()); }
|
||||
std::size_t CLASSNAME::size() const { return static_cast<std::size_t>(storage_->data.size()); }
|
||||
|
||||
void MATRIX::resize(std::size_t new_rows, std::size_t new_cols)
|
||||
void CLASSNAME::resize(std::size_t new_rows, std::size_t new_cols)
|
||||
{
|
||||
storage_->data.resize(new_rows, new_cols);
|
||||
}
|
||||
|
||||
void MATRIX::conservativeResize(std::size_t new_rows, std::size_t new_cols)
|
||||
void CLASSNAME::conservativeResize(std::size_t new_rows, std::size_t new_cols)
|
||||
{
|
||||
storage_->data.conservativeResize(new_rows, new_cols);
|
||||
}
|
||||
|
||||
TYPE& MATRIX::operator()(std::size_t i, std::size_t j) { return storage_->data(i,j); }
|
||||
TYPE const& MATRIX::operator()(std::size_t i, std::size_t j) const { return storage_->data(i,j); }
|
||||
TYPE& CLASSNAME::operator()(std::size_t i, std::size_t j) { return storage_->data(i,j); }
|
||||
TYPE const& CLASSNAME::operator()(std::size_t i, std::size_t j) const { return storage_->data(i,j); }
|
||||
|
||||
TYPE& MATRIX::operator()(std::size_t index) { return storage_->data(index); }
|
||||
TYPE const& MATRIX::operator()(std::size_t index) const { return storage_->data(index); }
|
||||
TYPE& CLASSNAME::operator()(std::size_t index) { return storage_->data(index); }
|
||||
TYPE const& CLASSNAME::operator()(std::size_t index) const { return storage_->data(index); }
|
||||
|
||||
const TYPE* MATRIX::data() const { return storage_->data.data(); }
|
||||
const TYPE* CLASSNAME::data() const { return storage_->data.data(); }
|
||||
|
||||
MATRIX MATRIX::transpose() const
|
||||
CLASSNAME CLASSNAME::transpose() const
|
||||
{
|
||||
MATRIX result(*this);
|
||||
CLASSNAME result(*this);
|
||||
result.storage_->data.transposeInPlace();
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
MATRIX MATRIX::conjugate() const
|
||||
CLASSNAME CLASSNAME::conjugate() const
|
||||
{
|
||||
MATRIX result(*this);
|
||||
CLASSNAME result(*this);
|
||||
result.storage_->data = storage_->data.conjugate();
|
||||
return result;
|
||||
}
|
||||
|
||||
MATRIX MATRIX::adjoint() const
|
||||
CLASSNAME CLASSNAME::adjoint() const
|
||||
{
|
||||
MATRIX result(*this);
|
||||
CLASSNAME result(*this);
|
||||
result.storage_->data.adjointInPlace();
|
||||
return result;
|
||||
}
|
||||
|
||||
void MATRIX::transposeInPlace()
|
||||
void CLASSNAME::transposeInPlace()
|
||||
{
|
||||
storage_->data.transposeInPlace();
|
||||
}
|
||||
|
||||
void MATRIX::adjointInPlace()
|
||||
void CLASSNAME::adjointInPlace()
|
||||
{
|
||||
storage_->data.adjointInPlace();
|
||||
}
|
||||
|
||||
TYPE MATRIX::sum() const { return storage_->data.sum(); }
|
||||
TYPE MATRIX::prod() const { return storage_->data.prod(); }
|
||||
TYPE MATRIX::mean() const { return storage_->data.mean(); }
|
||||
TYPE MATRIX::trace() const { return storage_->data.trace(); }
|
||||
TYPE CLASSNAME::sum() const { return storage_->data.sum(); }
|
||||
TYPE CLASSNAME::prod() const { return storage_->data.prod(); }
|
||||
TYPE CLASSNAME::mean() const { return storage_->data.mean(); }
|
||||
TYPE CLASSNAME::trace() const { return storage_->data.trace(); }
|
||||
|
||||
TYPE MATRIX::minCoeff() const { return storage_->data.minCoeff(); }
|
||||
TYPE MATRIX::maxCoeff() const { return storage_->data.maxCoeff(); }
|
||||
TYPE CLASSNAME::minCoeff() const { return storage_->data.minCoeff(); }
|
||||
TYPE CLASSNAME::maxCoeff() const { return storage_->data.maxCoeff(); }
|
||||
|
||||
TYPE MATRIX::minCoeff(std::ptrdiff_t* row, std::ptrdiff_t* col) const { return storage_->data.minCoeff(row, col); }
|
||||
TYPE MATRIX::maxCoeff(std::ptrdiff_t* row, std::ptrdiff_t* col) const { return storage_->data.maxCoeff(row, col); }
|
||||
TYPE CLASSNAME::minCoeff(std::ptrdiff_t* row, std::ptrdiff_t* col) const { return storage_->data.minCoeff(row, col); }
|
||||
TYPE CLASSNAME::maxCoeff(std::ptrdiff_t* row, std::ptrdiff_t* col) const { return storage_->data.maxCoeff(row, col); }
|
||||
|
||||
TYPE MATRIX::squaredNorm() const { return storage_->data.squaredNorm(); }
|
||||
TYPE MATRIX::norm() const { return storage_->data.norm(); }
|
||||
TYPE CLASSNAME::squaredNorm() const { return storage_->data.squaredNorm(); }
|
||||
TYPE CLASSNAME::norm() const { return storage_->data.norm(); }
|
||||
|
||||
TYPE MATRIX::lp_norm(int p) const
|
||||
TYPE CLASSNAME::lp_norm(int p) const
|
||||
{
|
||||
if (p == 1) return storage_->data.lpNorm<1>();
|
||||
else if (p == 2) return storage_->data.lpNorm<2>();
|
||||
|
|
@ -142,48 +129,48 @@ TYPE MATRIX::lp_norm(int p) const
|
|||
//==================================================================================================
|
||||
// Operators
|
||||
//==================================================================================================
|
||||
std::ostream& operator<<(std::ostream& os,MATRIX const& m)
|
||||
std::ostream& operator<<(std::ostream& os,CLASSNAME const& m)
|
||||
{
|
||||
return os << m.storage_->data;
|
||||
}
|
||||
|
||||
bool operator==(MATRIX const& lhs, MATRIX const& rhs)
|
||||
bool operator==(CLASSNAME const& lhs, CLASSNAME const& rhs)
|
||||
{
|
||||
return lhs.storage_->data == rhs.storage_->data;
|
||||
}
|
||||
|
||||
MATRIX& MATRIX::operator+=(MATRIX const& rhs)
|
||||
CLASSNAME& CLASSNAME::operator+=(CLASSNAME const& rhs)
|
||||
{
|
||||
storage_->data += rhs.storage_->data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MATRIX& MATRIX::operator-=(MATRIX const& rhs)
|
||||
CLASSNAME& CLASSNAME::operator-=(CLASSNAME const& rhs)
|
||||
{
|
||||
storage_->data -= rhs.storage_->data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MATRIX MATRIX::operator-() const
|
||||
CLASSNAME CLASSNAME::operator-() const
|
||||
{
|
||||
MATRIX result(*this);
|
||||
CLASSNAME result(*this);
|
||||
result.storage_->data = -result.storage_->data;
|
||||
return result;
|
||||
}
|
||||
|
||||
MATRIX& MATRIX::operator*=(MATRIX const& rhs)
|
||||
CLASSNAME& CLASSNAME::operator*=(CLASSNAME const& rhs)
|
||||
{
|
||||
storage_->data *= rhs.storage_->data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MATRIX& MATRIX::operator*=(TYPE s)
|
||||
CLASSNAME& CLASSNAME::operator*=(TYPE s)
|
||||
{
|
||||
storage_->data *= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MATRIX& MATRIX::operator/=(TYPE s)
|
||||
CLASSNAME& CLASSNAME::operator/=(TYPE s)
|
||||
{
|
||||
storage_->data /= s;
|
||||
return *this;
|
||||
|
|
@ -193,30 +180,30 @@ MATRIX& MATRIX::operator/=(TYPE s)
|
|||
// Static functions
|
||||
//==================================================================================================
|
||||
|
||||
MATRIX MATRIX::Zero(std::size_t rows, std::size_t cols)
|
||||
CLASSNAME CLASSNAME::Zero(std::size_t rows, std::size_t cols)
|
||||
{
|
||||
MATRIX m;
|
||||
CLASSNAME m;
|
||||
m.storage_ = std::make_unique<payload>(payload::data_type::Zero(rows, cols));
|
||||
return m;
|
||||
}
|
||||
|
||||
MATRIX MATRIX::Constant(std::size_t rows, std::size_t cols, TYPE value)
|
||||
CLASSNAME CLASSNAME::Constant(std::size_t rows, std::size_t cols, TYPE value)
|
||||
{
|
||||
MATRIX m;
|
||||
CLASSNAME m;
|
||||
m.storage_ = std::make_unique<payload>(payload::data_type::Constant(rows, cols, value));
|
||||
return m;
|
||||
}
|
||||
|
||||
MATRIX MATRIX::Random(std::size_t rows, std::size_t cols)
|
||||
CLASSNAME CLASSNAME::Random(std::size_t rows, std::size_t cols)
|
||||
{
|
||||
MATRIX m;
|
||||
CLASSNAME m;
|
||||
m.storage_ = std::make_unique<payload>(payload::data_type::Random(rows, cols));
|
||||
return m;
|
||||
}
|
||||
|
||||
MATRIX MATRIX::Identity(std::size_t rows, std::size_t cols)
|
||||
CLASSNAME CLASSNAME::Identity(std::size_t rows, std::size_t cols)
|
||||
{
|
||||
MATRIX m;
|
||||
CLASSNAME m;
|
||||
m.storage_ = std::make_unique<payload>(payload::data_type::Identity(rows, cols));
|
||||
return m;
|
||||
}
|
||||
|
|
@ -17,5 +17,6 @@ target_link_libraries(rotgen_test INTERFACE rotgen Eigen3::Eigen)
|
|||
##======================================================================================================================
|
||||
## Unit Tests registration
|
||||
##======================================================================================================================
|
||||
rotgen_glob_unit(PATTERN "unit/basic/*.cpp" INTERFACE rotgen_test)
|
||||
rotgen_glob_unit(PATTERN "unit/free_functions/*.cpp" INTERFACE rotgen_test)
|
||||
rotgen_glob_unit(PATTERN "unit/matrix/*.cpp" INTERFACE rotgen_test)
|
||||
rotgen_glob_unit(PATTERN "unit/block/*.cpp" INTERFACE rotgen_test)
|
||||
|
|
|
|||
97
test/unit/block/arithmetic_functions.cpp
Normal file
97
test/unit/block/arithmetic_functions.cpp
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#include "unit/tests.hpp"
|
||||
#include <rotgen/block.hpp>
|
||||
#include <rotgen/matrix.hpp>
|
||||
#include <rotgen/extract.hpp>
|
||||
#include <Eigen/Dense>
|
||||
|
||||
template<typename Block1, typename Block2>
|
||||
void compare_reductions(const Block1& block, const Block2& ref)
|
||||
{
|
||||
constexpr double epsilon = 0.0001;
|
||||
TTS_RELATIVE_EQUAL(block.sum(), ref.sum(), epsilon);
|
||||
TTS_RELATIVE_EQUAL(block.prod(), ref.prod(), epsilon);
|
||||
TTS_RELATIVE_EQUAL(block.mean(), ref.mean(), epsilon);
|
||||
TTS_EQUAL(block.trace(), ref.trace());
|
||||
TTS_EQUAL(block.minCoeff(), ref.minCoeff());
|
||||
TTS_EQUAL(block.maxCoeff(), ref.maxCoeff());
|
||||
|
||||
std::ptrdiff_t row, col, ref_row, ref_col;
|
||||
|
||||
TTS_EQUAL(block.minCoeff(&row, &col), ref.minCoeff(&ref_row, &ref_col));
|
||||
TTS_EQUAL(row, ref_row);
|
||||
TTS_EQUAL(col, ref_col);
|
||||
|
||||
TTS_EQUAL(block.maxCoeff(&row, &col), ref.maxCoeff(&ref_row, &ref_col));
|
||||
TTS_EQUAL(row, ref_row);
|
||||
TTS_EQUAL(col, ref_col);
|
||||
}
|
||||
|
||||
template <typename MatrixType, typename T>
|
||||
void test_dynamic_block_reductions(rotgen::tests::matrix_block_test_case<MatrixType> const& matrix_construct)
|
||||
{
|
||||
using EigenMatrix = Eigen::Matrix<typename MatrixType::scalar_type, Eigen::Dynamic, Eigen::Dynamic>;
|
||||
|
||||
MatrixType original(matrix_construct.rows, matrix_construct.cols);
|
||||
EigenMatrix ref(matrix_construct.rows, matrix_construct.cols);
|
||||
|
||||
for (std::size_t r = 0; r < matrix_construct.rows; ++r)
|
||||
for (std::size_t c = 0; c < matrix_construct.cols; ++c)
|
||||
ref(r, c) = original(r,c) = static_cast<T>(matrix_construct.init_fn(r, c));
|
||||
|
||||
std::vector<std::pair<rotgen::block<MatrixType>, Eigen::Block<EigenMatrix>>> test_cases {
|
||||
{ rotgen::extract(original, matrix_construct.i0, matrix_construct.j0,
|
||||
matrix_construct.ni, matrix_construct.nj),
|
||||
ref.block(matrix_construct.i0, matrix_construct.j0,
|
||||
matrix_construct.ni, matrix_construct.nj) },
|
||||
|
||||
{ rotgen::topLeftCorner(original, matrix_construct.ni, matrix_construct.nj),
|
||||
ref.topLeftCorner(matrix_construct.ni, matrix_construct.nj) },
|
||||
{ rotgen::topRightCorner(original, matrix_construct.ni, matrix_construct.nj),
|
||||
ref.topRightCorner(matrix_construct.ni, matrix_construct.nj) },
|
||||
{ rotgen::bottomLeftCorner(original, matrix_construct.ni, matrix_construct.nj),
|
||||
ref.bottomLeftCorner(matrix_construct.ni, matrix_construct.nj) },
|
||||
{ rotgen::bottomRightCorner(original, matrix_construct.ni, matrix_construct.nj),
|
||||
ref.bottomRightCorner(matrix_construct.ni, matrix_construct.nj) },
|
||||
|
||||
{ rotgen::topRows(original, matrix_construct.ni),
|
||||
ref.topRows(matrix_construct.ni) },
|
||||
{ rotgen::middleRows(original, matrix_construct.i0, matrix_construct.ni),
|
||||
ref.middleRows(matrix_construct.i0, matrix_construct.ni) },
|
||||
{ rotgen::bottomRows(original, matrix_construct.ni),
|
||||
ref.bottomRows(matrix_construct.ni) },
|
||||
};
|
||||
|
||||
for (const auto& [original_block, ref_block] : test_cases)
|
||||
compare_reductions(original_block, ref_block);
|
||||
}
|
||||
|
||||
TTS_CASE_TPL("Test dynamic block reductions", rotgen::tests::types)
|
||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
||||
{
|
||||
using mat_t = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>;
|
||||
|
||||
std::vector<rotgen::tests::matrix_block_test_case<mat_t>> test_cases =
|
||||
{
|
||||
{6, 5, [](auto r, auto c) {return r + c; }, 1, 2, 3, 2},
|
||||
{9, 11, [](auto r, auto c) {return r + c; }, 0, 1, 4, 9},
|
||||
{3, 3, [](auto , auto ) {return 0.0; }, 1, 1, 1, 1},
|
||||
{1, 4, [](auto r, auto c) {return -r -c*c - 1234; }, 0, 0, 1, 1},
|
||||
{4, 1, [](auto , auto ) {return 7.0; }, 2, 0, 2, 1},
|
||||
{1, 1, [](auto , auto ) {return 42.0; }, 0, 0, 1, 1},
|
||||
{12, 13, [](auto r, auto c) {return std::sin(r + c); }, 2, 3, 4, 5 },
|
||||
{4, 9, [](auto r, auto c) {return -1.5 * r + 2.56 * c; }, 0, 1, 2, 3 },
|
||||
{2, 5, [](auto r, auto c) {return (r == c ? 1.0 : 0.0); }, 1, 1, 1, 1},
|
||||
};
|
||||
|
||||
for (const auto& test_case : test_cases)
|
||||
test_dynamic_block_reductions<mat_t, T>(test_case);
|
||||
|
||||
|
||||
};
|
||||
266
test/unit/block/extract.cpp
Normal file
266
test/unit/block/extract.cpp
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#include "unit/tests.hpp"
|
||||
#include <rotgen/matrix.hpp>
|
||||
#include <rotgen/extract.hpp>
|
||||
|
||||
template<typename EigenType, typename F>
|
||||
void for_each_element(EigenType const& m, F&& f)
|
||||
{
|
||||
for(std::size_t i = 0; i < m.rows(); ++i)
|
||||
for(std::size_t j = 0; j < m.cols(); ++j)
|
||||
f(i, j, m(i,j));
|
||||
}
|
||||
|
||||
template<typename EigenType, typename F>
|
||||
void for_each_element(EigenType& m, F&& f)
|
||||
{
|
||||
for(std::size_t i = 0; i < m.rows(); ++i)
|
||||
for(std::size_t j = 0; j < m.cols(); ++j)
|
||||
f(i, j, m(i,j));
|
||||
}
|
||||
|
||||
template<typename MatrixType, typename T>
|
||||
MatrixType make_initialized_matrix(rotgen::tests::matrix_block_test_case<MatrixType> const& matrix_construct)
|
||||
{
|
||||
MatrixType matrix(matrix_construct.rows, matrix_construct.cols);
|
||||
|
||||
for(std::size_t i = 0; i < matrix_construct.rows; ++i)
|
||||
for(std::size_t j = 0; j < matrix_construct.cols; ++j)
|
||||
matrix(i, j) = static_cast<T>(matrix_construct.init_fn(i, j));
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
template<typename MatrixType, typename BlockType, typename T>
|
||||
void validate_block_behavior(MatrixType& matrix, BlockType& block,
|
||||
std::size_t i0, std::size_t j0,
|
||||
std::size_t ni, std::size_t nj)
|
||||
{
|
||||
TTS_EQUAL(block.rows(), ni);
|
||||
TTS_EQUAL(block.cols(), nj);
|
||||
TTS_EQUAL(block.size(), ni * nj);
|
||||
|
||||
// test block values
|
||||
for_each_element(block, [&](auto i, auto j, auto val) {
|
||||
TTS_EQUAL(val, matrix(i0 + i, j0 + j));
|
||||
});
|
||||
|
||||
// test aliasing
|
||||
T value = 1;
|
||||
for_each_element(block, [&](auto i, auto j, auto&) {
|
||||
block(i, j) = value++;
|
||||
});
|
||||
|
||||
value = 1;
|
||||
for_each_element(block, [&](auto i, auto j, auto&) {
|
||||
TTS_EQUAL(matrix(i0 + i, j0 + j), value++);
|
||||
});
|
||||
|
||||
for_each_element(block, [&](auto i, auto j, auto&) {
|
||||
matrix(i0 + i, j0 + j) = T(42);
|
||||
});
|
||||
|
||||
for_each_element(block, [&](auto&, auto&, auto val) {
|
||||
TTS_EQUAL(val, T(42));
|
||||
});
|
||||
}
|
||||
|
||||
template<typename MatrixType, typename T>
|
||||
void test_dynamic_block_extraction(rotgen::tests::matrix_block_test_case<MatrixType> const& matrix_construct)
|
||||
{
|
||||
MatrixType matrix = make_initialized_matrix<MatrixType, T>(matrix_construct);
|
||||
|
||||
auto block_main = rotgen::extract(matrix, matrix_construct.i0, matrix_construct.j0,
|
||||
matrix_construct.ni, matrix_construct.nj);
|
||||
auto block_top_left_corner = rotgen::topLeftCorner(matrix, matrix_construct.ni, matrix_construct.nj);
|
||||
auto block_top_right_corner = rotgen::topRightCorner(matrix, matrix_construct.ni, matrix_construct.nj);
|
||||
auto block_bottom_left_corner = rotgen::bottomLeftCorner(matrix, matrix_construct.ni, matrix_construct.nj);
|
||||
auto block_bottom_right_corner = rotgen::bottomRightCorner(matrix, matrix_construct.ni, matrix_construct.nj);
|
||||
|
||||
auto block_top_rows = rotgen::topRows(matrix, matrix_construct.ni);
|
||||
auto block_middle_rows = rotgen::middleRows(matrix, matrix_construct.i0, matrix_construct.ni);
|
||||
auto block_bottom_rows = rotgen::bottomRows(matrix, matrix_construct.ni);
|
||||
|
||||
auto block_left_cols = rotgen::leftCols(matrix, matrix_construct.nj);
|
||||
auto block_middle_cols = rotgen::middleCols(matrix, matrix_construct.j0, matrix_construct.nj);
|
||||
auto block_right_cols = rotgen::rightCols(matrix, matrix_construct.nj);
|
||||
|
||||
auto blocks = std::make_tuple(
|
||||
std::make_tuple(block_main, matrix_construct.i0, matrix_construct.j0, matrix_construct.ni, matrix_construct.nj),
|
||||
std::make_tuple(block_top_left_corner, 0, 0, matrix_construct.ni, matrix_construct.nj),
|
||||
std::make_tuple(block_top_right_corner, 0, matrix.cols() - matrix_construct.nj, matrix_construct.ni, matrix_construct.nj),
|
||||
std::make_tuple(block_bottom_left_corner, matrix.rows() - matrix_construct.ni, 0, matrix_construct.ni, matrix_construct.nj),
|
||||
std::make_tuple(block_bottom_right_corner, matrix.rows() - matrix_construct.ni, matrix.cols() - matrix_construct.nj,
|
||||
matrix_construct.ni, matrix_construct.nj),
|
||||
|
||||
std::make_tuple(block_top_rows, 0, 0, matrix_construct.ni, matrix.cols()),
|
||||
std::make_tuple(block_middle_rows, matrix_construct.i0, 0, matrix_construct.ni, matrix.cols()),
|
||||
std::make_tuple(block_bottom_rows, matrix.rows() - matrix_construct.ni, 0, matrix_construct.ni, matrix.cols()),
|
||||
|
||||
std::make_tuple(block_left_cols, 0, 0, matrix.rows(), matrix_construct.nj),
|
||||
std::make_tuple(block_middle_cols, 0, matrix_construct.j0, matrix.rows(), matrix_construct.nj),
|
||||
std::make_tuple(block_right_cols, 0, matrix.cols() - matrix_construct.nj, matrix.rows(), matrix_construct.nj)
|
||||
);
|
||||
|
||||
std::apply([&](auto&&... block_entries)
|
||||
{
|
||||
(([&]
|
||||
{
|
||||
auto&& [block, i_offset, j_offset, ni, nj] = block_entries;
|
||||
using block_t = std::remove_reference_t<decltype(block)>;
|
||||
|
||||
TTS_EQUAL(block_t::RowsAtCompileTime, rotgen::Dynamic);
|
||||
TTS_EQUAL(block_t::ColsAtCompileTime, rotgen::Dynamic);
|
||||
TTS_EQUAL(block_t::storage_order, MatrixType::storage_order);
|
||||
|
||||
validate_block_behavior<MatrixType, block_t, T>(matrix, block, i_offset, j_offset, ni, nj);
|
||||
})(), ...);
|
||||
}, blocks);
|
||||
|
||||
}
|
||||
|
||||
template<typename MatrixType, typename T, std::size_t NI, std::size_t NJ>
|
||||
void test_static_block_extraction(rotgen::tests::static_matrix_block_test_case<MatrixType, NI, NJ> const& matrix_construct)
|
||||
{
|
||||
MatrixType matrix(matrix_construct.rows, matrix_construct.cols);
|
||||
|
||||
for (std::size_t i = 0; i < matrix_construct.rows; ++i)
|
||||
for (std::size_t j = 0; j < matrix_construct.cols; ++j)
|
||||
matrix(i, j) = static_cast<T>(matrix_construct.init_fn(i, j));
|
||||
|
||||
auto block_main = rotgen::extract<NI, NJ>(matrix, matrix_construct.i0, matrix_construct.j0);
|
||||
auto block_top_left_corner = rotgen::topLeftCorner<NI, NJ>(matrix);
|
||||
auto block_top_right_corner = rotgen::topRightCorner<NI, NJ>(matrix);
|
||||
auto block_bottom_left_corner = rotgen::bottomLeftCorner<NI, NJ>(matrix);
|
||||
auto block_bottom_right_corner = rotgen::bottomRightCorner<NI, NJ>(matrix);
|
||||
|
||||
auto block_top_rows = rotgen::topRows<NI>(matrix);
|
||||
auto block_middle_rows = rotgen::middleRows<NI>(matrix, matrix_construct.i0);
|
||||
auto block_bottom_rows = rotgen::bottomRows<NI>(matrix);
|
||||
|
||||
auto block_left_cols = rotgen::leftCols<NJ>(matrix);
|
||||
auto block_middle_cols = rotgen::middleCols<NJ>(matrix, matrix_construct.j0);
|
||||
auto block_right_cols = rotgen::rightCols<NJ>(matrix);
|
||||
|
||||
auto block_row = rotgen::row(matrix, matrix_construct.i0);
|
||||
auto block_col = rotgen::col(matrix, matrix_construct.j0);
|
||||
|
||||
auto blocks = std::make_tuple(
|
||||
std::make_tuple(block_main, matrix_construct.i0, matrix_construct.j0,
|
||||
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ), -1),
|
||||
std::make_tuple(block_top_left_corner, 0, 0,
|
||||
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ), -1),
|
||||
std::make_tuple(block_top_right_corner, 0, matrix.cols() - matrix_construct.nj,
|
||||
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ), -1),
|
||||
std::make_tuple(block_bottom_left_corner, matrix.rows() - matrix_construct.ni, 0,
|
||||
matrix_construct.ni, matrix_construct.nj, int(NI), int(NJ), -1),
|
||||
std::make_tuple(block_bottom_right_corner, matrix.rows() - matrix_construct.ni,
|
||||
matrix.cols() - matrix_construct.nj, matrix_construct.ni,
|
||||
matrix_construct.nj, int(NI), int(NJ), -1),
|
||||
|
||||
std::make_tuple(block_top_rows, 0, 0, matrix_construct.ni, matrix.cols(), int(NI), rotgen::Dynamic, -1),
|
||||
std::make_tuple(block_middle_rows, matrix_construct.i0, 0, matrix_construct.ni,
|
||||
matrix.cols(), int(NI), rotgen::Dynamic, -1),
|
||||
std::make_tuple(block_bottom_rows, matrix.rows() - matrix_construct.ni,
|
||||
0, matrix_construct.ni, matrix.cols(), int(NI), rotgen::Dynamic, -1),
|
||||
|
||||
std::make_tuple(block_left_cols, 0, 0, matrix.rows(), matrix_construct.nj, rotgen::Dynamic, int(NJ), -1),
|
||||
std::make_tuple(block_middle_cols, 0, matrix_construct.j0,
|
||||
matrix.rows(), matrix_construct.nj, rotgen::Dynamic, int(NJ), -1),
|
||||
std::make_tuple(block_right_cols, 0, matrix.cols() - matrix_construct.nj,
|
||||
matrix.rows(), matrix_construct.nj, rotgen::Dynamic, int(NJ), -1),
|
||||
|
||||
std::make_tuple(block_row, matrix_construct.i0, 0,
|
||||
1, matrix.cols(), 1, rotgen::Dynamic, 1),
|
||||
std::make_tuple(block_col, 0, matrix_construct.j0,
|
||||
matrix.rows(), 1, rotgen::Dynamic, 1, 0)
|
||||
);
|
||||
|
||||
std::apply([&](auto&&... block_entries)
|
||||
{
|
||||
(([&]
|
||||
{
|
||||
auto&& [block, i_offset, j_offset, ni, nj, rows_ct, cols_ct, storage_order] = block_entries;
|
||||
using block_t = std::remove_reference_t<decltype(block)>;
|
||||
|
||||
TTS_EQUAL(block_t::RowsAtCompileTime, rows_ct);
|
||||
TTS_EQUAL(block_t::ColsAtCompileTime, cols_ct);
|
||||
|
||||
auto expected_storage_order = (storage_order == -1) ? MatrixType::storage_order : storage_order;
|
||||
TTS_EQUAL(block_t::storage_order, expected_storage_order);
|
||||
|
||||
validate_block_behavior<MatrixType, block_t, T>(matrix, block, i_offset, j_offset, ni, nj);
|
||||
})(), ...);
|
||||
}, blocks);
|
||||
}
|
||||
|
||||
TTS_CASE_TPL("Check all dynamic block extractions on a dynamic row-major matrix", rotgen::tests::types)
|
||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
||||
{
|
||||
using mat_t = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value, 1>;
|
||||
|
||||
std::vector<rotgen::tests::matrix_block_test_case<mat_t>> cases = {
|
||||
{ 6, 11, [](std::size_t i, std::size_t j) { return T(i * 10 + j); }, 1, 2, 3, 2 },
|
||||
{ 7, 10, [](std::size_t i, std::size_t j) { return T(std::sin(i + j)); }, 4, 4, 3, 3 },
|
||||
{ 5, 5, [](std::size_t i, std::size_t j) { return T((i + j) % 7); }, 0, 0, 5, 5 },
|
||||
{ 9, 14, [](std::size_t i, std::size_t j) { return T(i+j + 3*j); }, 3, 7, 1, 1 }
|
||||
};
|
||||
|
||||
for (auto const& matrix_case : cases) {
|
||||
test_dynamic_block_extraction<mat_t, T>(matrix_case);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
TTS_CASE_TPL("Check all dynamic block extractions on a static column-major matrix", rotgen::tests::types)
|
||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
||||
{
|
||||
using mat_t = rotgen::matrix<T,4,5,O::value, 0>;
|
||||
|
||||
std::vector<rotgen::tests::matrix_block_test_case<mat_t>> cases = {
|
||||
{ 4, 5, [](std::size_t i, std::size_t j) { return T(2*i + j*j*j - 42); }, 1, 2, 3, 2 },
|
||||
{ 4, 5, [](std::size_t i, std::size_t j) { return T(std::tan(i*i*j)); }, 0, 1, 2, 1 },
|
||||
{ 4, 5, [](std::size_t i, std::size_t j) { return T((i*i + j*j) / 6); }, 2, 0, 0, 0 }
|
||||
};
|
||||
|
||||
for (auto const& matrix_case : cases) {
|
||||
test_dynamic_block_extraction<mat_t, T>(matrix_case);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
TTS_CASE_TPL("Check all static block extractions", rotgen::tests::types)
|
||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
||||
{
|
||||
using mat_t = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value, 1>;
|
||||
|
||||
test_static_block_extraction<mat_t, T, 1, 2>(
|
||||
rotgen::tests::static_matrix_block_test_case<mat_t, 1, 2>{
|
||||
11, 11,
|
||||
[](std::size_t i, std::size_t j) { return T(i*i*i + 3*j - 127); },
|
||||
3, 2
|
||||
}
|
||||
);
|
||||
|
||||
test_static_block_extraction<mat_t, double, 4, 3>(
|
||||
rotgen::tests::static_matrix_block_test_case<mat_t, 4, 3>{
|
||||
14, 15,
|
||||
[](std::size_t i, std::size_t j) { return T(std::cos(i * j * 2)); },
|
||||
5, 1
|
||||
}
|
||||
);
|
||||
|
||||
test_static_block_extraction<mat_t, double, 0, 0>(
|
||||
rotgen::tests::static_matrix_block_test_case<mat_t, 0, 0>{
|
||||
5, 5,
|
||||
[](std::size_t i, std::size_t j) { return T((i + j) % 9); },
|
||||
0, 0
|
||||
}
|
||||
);
|
||||
};
|
||||
49
test/unit/block/norms.cpp
Normal file
49
test/unit/block/norms.cpp
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#include "unit/tests.hpp"
|
||||
#include <rotgen/matrix.hpp>
|
||||
#include <rotgen/extract.hpp>
|
||||
#include <Eigen/Dense>
|
||||
|
||||
TTS_CASE_TPL("Matrix norm-related operations", rotgen::tests::types)
|
||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
||||
{
|
||||
using mat_t = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>;
|
||||
|
||||
std::vector<rotgen::tests::matrix_block_test_case<mat_t>> test_cases =
|
||||
{
|
||||
{6, 5, [](auto r, auto c) {return r + c; }, 1, 2, 3, 2},
|
||||
{9, 11, [](auto r, auto c) {return r + c; }, 0, 1, 4, 9},
|
||||
{3, 3, [](auto , auto ) {return 0.0; }, 1, 1, 1, 1},
|
||||
{1, 4, [](auto r, auto c) {return -r -c*c - 1234; }, 0, 0, 1, 1},
|
||||
{4, 1, [](auto , auto ) {return 7.0; }, 2, 0, 2, 1},
|
||||
{1, 1, [](auto , auto ) {return 42.0; }, 0, 0, 1, 1},
|
||||
{12, 13, [](auto r, auto c) {return std::sin(r + c); }, 2, 3, 4, 5 },
|
||||
{4, 9, [](auto r, auto c) {return -1.5 * r + 2.56 * c; }, 0, 1, 2, 3 },
|
||||
{2, 5, [](auto r, auto c) {return (r == c ? 1.0 : 0.0); }, 1, 1, 1, 1},
|
||||
};
|
||||
|
||||
for (const auto& [rows, cols, fn, i0, j0, ni, nj] : test_cases)
|
||||
{
|
||||
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> original_matrix(rows, cols);
|
||||
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic,O::value> ref_matrix(rows, cols);
|
||||
|
||||
for (std::size_t r = 0; r < rows; ++r)
|
||||
for (std::size_t c = 0; c < cols; ++c)
|
||||
ref_matrix(r, c) = original_matrix(r, c) = fn(r,c);
|
||||
|
||||
auto original_block = rotgen::extract(original_matrix, i0, j0, ni, nj);
|
||||
auto ref_block = ref_matrix.block(i0, j0, ni, nj);
|
||||
|
||||
TTS_EQUAL(original_block.norm(), ref_block.norm());
|
||||
TTS_EQUAL(original_block.squaredNorm(), ref_block.squaredNorm());
|
||||
TTS_EQUAL(original_block.template lpNorm<1>() , ref_block.template lpNorm<1>());
|
||||
TTS_EQUAL(original_block.template lpNorm<2>() , ref_block.template lpNorm<2>());
|
||||
TTS_EQUAL(original_block.template lpNorm<rotgen::Infinity>(), ref_block.template lpNorm<Eigen::Infinity>());
|
||||
}
|
||||
};
|
||||
274
test/unit/block/operators.cpp
Normal file
274
test/unit/block/operators.cpp
Normal file
|
|
@ -0,0 +1,274 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#include "unit/tests.hpp"
|
||||
#include <rotgen/matrix.hpp>
|
||||
#include <rotgen/extract.hpp>
|
||||
#include <Eigen/Dense>
|
||||
|
||||
template <typename MatrixType, typename T>
|
||||
void test_block_matrix_operations(rotgen::tests::matrix_block_test_case<MatrixType> const& matrix_construct,
|
||||
auto b_init_fn, auto self_ops)
|
||||
{
|
||||
using EigenMatrix = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>;
|
||||
|
||||
MatrixType a(matrix_construct.rows, matrix_construct.cols);
|
||||
MatrixType b(matrix_construct.rows, matrix_construct.cols);
|
||||
EigenMatrix ref_a(matrix_construct.rows, matrix_construct.cols);
|
||||
EigenMatrix ref_b(matrix_construct.rows, matrix_construct.cols);
|
||||
|
||||
for (std::size_t r = 0; r < matrix_construct.rows; ++r)
|
||||
{
|
||||
for (std::size_t c = 0; c < matrix_construct.cols; ++c)
|
||||
{
|
||||
ref_a(r,c) = a(r,c) = static_cast<T>(matrix_construct.init_fn(r, c));
|
||||
ref_b(r,c) = b(r,c) = static_cast<T>(b_init_fn(r, c));
|
||||
}
|
||||
}
|
||||
|
||||
auto a_block = rotgen::extract(a, matrix_construct.i0, matrix_construct.j0,
|
||||
matrix_construct.ni, matrix_construct.nj);
|
||||
auto b_block = rotgen::extract(b, matrix_construct.i0, matrix_construct.j0,
|
||||
matrix_construct.ni, matrix_construct.nj);
|
||||
auto ref_a_block = ref_a.block(matrix_construct.i0, matrix_construct.j0,
|
||||
matrix_construct.ni, matrix_construct.nj);
|
||||
auto ref_b_block = ref_b.block(matrix_construct.i0, matrix_construct.j0,
|
||||
matrix_construct.ni, matrix_construct.nj);
|
||||
|
||||
/*auto result_block = ops(a_block, b_block);
|
||||
auto ref_result_block = ops(ref_a_block, ref_b_block);
|
||||
|
||||
for (std::size_t r = 0; r < matrix_construct.ni; ++r)
|
||||
for (std::size_t c = 0; c < matrix_construct.nj; ++c)
|
||||
TTS_EQUAL(result_block(r, c), ref_result_block(r, c));*/
|
||||
|
||||
self_ops(a_block,b_block);
|
||||
self_ops(ref_a_block, ref_b_block);
|
||||
|
||||
for (std::size_t r = 0; r < matrix_construct.ni; ++r)
|
||||
for (std::size_t c = 0; c < matrix_construct.nj; ++c)
|
||||
TTS_EQUAL(a_block(r, c), ref_a_block(r, c));
|
||||
|
||||
for (std::size_t r = 0; r < matrix_construct.rows; ++r)
|
||||
{
|
||||
for (std::size_t c = 0; c < matrix_construct.cols; ++c)
|
||||
{
|
||||
TTS_EQUAL(a(r, c), ref_a(r, c));
|
||||
TTS_EQUAL(b(r, c), ref_b(r, c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename MatrixType, typename T>
|
||||
void test_block_scalar_operations(rotgen::tests::matrix_block_test_case<MatrixType> const& matrix_construct,
|
||||
auto scalar, auto self_ops)
|
||||
{
|
||||
using EigenMatrix = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>;
|
||||
|
||||
MatrixType a(matrix_construct.rows, matrix_construct.cols);
|
||||
EigenMatrix ref_a(matrix_construct.rows, matrix_construct.cols);
|
||||
|
||||
for (std::size_t r = 0; r < matrix_construct.rows; ++r)
|
||||
for (std::size_t c = 0; c < matrix_construct.cols; ++c)
|
||||
ref_a(r,c) = a(r,c) = static_cast<T>(matrix_construct.init_fn(r, c));
|
||||
|
||||
auto a_block = rotgen::extract(a, matrix_construct.i0, matrix_construct.j0,
|
||||
matrix_construct.ni, matrix_construct.nj);
|
||||
auto ref_a_block = ref_a.block(matrix_construct.i0, matrix_construct.j0,
|
||||
matrix_construct.ni, matrix_construct.nj);
|
||||
|
||||
//TTS_EQUAL(ops(a, s), ref);
|
||||
|
||||
self_ops(a_block,scalar);
|
||||
self_ops(ref_a_block, scalar);
|
||||
|
||||
for (std::size_t r = 0; r < matrix_construct.ni; ++r)
|
||||
for (std::size_t c = 0; c < matrix_construct.nj; ++c)
|
||||
TTS_EQUAL(a_block(r, c), ref_a_block(r, c));
|
||||
|
||||
for (std::size_t r = 0; r < matrix_construct.rows; ++r)
|
||||
for (std::size_t c = 0; c < matrix_construct.cols; ++c)
|
||||
TTS_EQUAL(a(r, c), ref_a(r, c));
|
||||
}
|
||||
|
||||
template <typename MatrixType, typename T>
|
||||
void test_scalar_block_multiplications(rotgen::tests::matrix_block_test_case<MatrixType> const& matrix_construct,
|
||||
T scalar)
|
||||
{
|
||||
using EigenMatrix = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>;
|
||||
|
||||
MatrixType a(matrix_construct.rows, matrix_construct.cols);
|
||||
EigenMatrix ref_a(matrix_construct.rows, matrix_construct.cols);
|
||||
|
||||
for (std::size_t r = 0; r < matrix_construct.rows; ++r)
|
||||
for (std::size_t c = 0; c < matrix_construct.cols; ++c)
|
||||
ref_a(r,c) = a(r,c) = static_cast<T>(matrix_construct.init_fn(r, c));
|
||||
|
||||
auto a_block = rotgen::extract(a, matrix_construct.i0, matrix_construct.j0,
|
||||
matrix_construct.ni, matrix_construct.nj);
|
||||
auto ref_a_block = ref_a.block(matrix_construct.i0, matrix_construct.j0,
|
||||
matrix_construct.ni, matrix_construct.nj);
|
||||
|
||||
//TTS_EQUAL(a * s, ref);
|
||||
//TTS_EQUAL(s * a, ref);
|
||||
|
||||
a_block *= scalar;
|
||||
ref_a_block *= scalar;
|
||||
|
||||
for (std::size_t r = 0; r < matrix_construct.ni; ++r)
|
||||
for (std::size_t c = 0; c < matrix_construct.nj; ++c)
|
||||
TTS_EQUAL(a_block(r, c), ref_a_block(r, c));
|
||||
|
||||
for (std::size_t r = 0; r < matrix_construct.rows; ++r)
|
||||
for (std::size_t c = 0; c < matrix_construct.cols; ++c)
|
||||
TTS_EQUAL(a(r, c), ref_a(r, c));
|
||||
}
|
||||
|
||||
template <typename MatrixType, typename T>
|
||||
void test_block_multiplication(rotgen::tests::matrix_block_test_case<MatrixType> const& a_matrix_construct,
|
||||
rotgen::tests::matrix_block_test_case<MatrixType> const& b_matrix_construct)
|
||||
{
|
||||
using EigenMatrix = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>;
|
||||
|
||||
MatrixType a(a_matrix_construct.rows, a_matrix_construct.cols);
|
||||
MatrixType b(b_matrix_construct.rows, b_matrix_construct.cols);
|
||||
EigenMatrix ref_a(a_matrix_construct.rows, a_matrix_construct.cols);
|
||||
EigenMatrix ref_b(b_matrix_construct.rows, b_matrix_construct.cols);
|
||||
|
||||
for (std::size_t r = 0; r < a_matrix_construct.rows; ++r)
|
||||
for (std::size_t c = 0; c < a_matrix_construct.cols; ++c)
|
||||
ref_a(r,c) = a(r,c) = static_cast<T>(a_matrix_construct.init_fn(r, c));
|
||||
|
||||
for (std::size_t r = 0; r < b_matrix_construct.rows; ++r)
|
||||
for (std::size_t c = 0; c < b_matrix_construct.cols; ++c)
|
||||
ref_b(r,c) = b(r,c) = static_cast<T>(b_matrix_construct.init_fn(r, c));
|
||||
|
||||
|
||||
auto a_block = rotgen::extract(a, a_matrix_construct.i0, a_matrix_construct.j0,
|
||||
a_matrix_construct.ni, a_matrix_construct.nj);
|
||||
auto b_block = rotgen::extract(b, b_matrix_construct.i0, b_matrix_construct.j0,
|
||||
b_matrix_construct.ni, b_matrix_construct.nj);
|
||||
auto ref_a_block = ref_a.block(a_matrix_construct.i0, a_matrix_construct.j0,
|
||||
a_matrix_construct.ni, a_matrix_construct.nj);
|
||||
auto ref_b_block = ref_b.block(b_matrix_construct.i0, b_matrix_construct.j0,
|
||||
b_matrix_construct.ni, b_matrix_construct.nj);
|
||||
|
||||
// a * b
|
||||
a_block *= b_block;
|
||||
ref_a_block *= ref_b_block;
|
||||
|
||||
for (std::size_t r = 0; r < a_matrix_construct.ni; ++r)
|
||||
for (std::size_t c = 0; c < a_matrix_construct.nj; ++c)
|
||||
TTS_EQUAL(a_block(r, c), ref_a_block(r, c));
|
||||
|
||||
for (std::size_t r = 0; r < a_matrix_construct.rows; ++r)
|
||||
for (std::size_t c = 0; c < a_matrix_construct.cols; ++c)
|
||||
TTS_EQUAL(a(r, c), ref_a(r, c));
|
||||
|
||||
for (std::size_t r = 0; r < b_matrix_construct.rows; ++r)
|
||||
for (std::size_t c = 0; c < b_matrix_construct.cols; ++c)
|
||||
TTS_EQUAL(b(r, c), ref_b(r, c));
|
||||
}
|
||||
|
||||
// Basic initializers
|
||||
inline constexpr auto init_a = [](auto r, auto c) { return 9.9*r*r*r - 6*c -12; };
|
||||
inline constexpr auto init_b = [](auto r, auto c) { return 3.1*r + 4.2*c - 12.3; };
|
||||
inline constexpr auto init_0 = [](auto , auto ) { return 0; };
|
||||
|
||||
TTS_CASE_TPL("Check block addition", rotgen::tests::types)
|
||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
||||
{
|
||||
using mat_t = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>;
|
||||
//auto op = [](auto a, auto b) { return a + b; };
|
||||
auto s_op = [](auto& a, auto b) { return a += b; };
|
||||
|
||||
//test_block_matrix_operations<mat_t, T>({1 , 1, init_a, 0, 0, 1, 1}, init_b, op, s_op);
|
||||
test_block_matrix_operations<mat_t, T>({1 , 1, init_a, 0, 0, 1, 1}, init_b, s_op);
|
||||
test_block_matrix_operations<mat_t, T>({13 , 15, init_a, 1, 2, 3, 4}, init_b, s_op);
|
||||
test_block_matrix_operations<mat_t, T>({5 , 9, init_a, 2, 2, 2, 2}, init_b, s_op);
|
||||
test_block_matrix_operations<mat_t, T>({15 , 15, init_a, 3, 4, 5, 5}, init_b, s_op);
|
||||
test_block_matrix_operations<mat_t, T>({5 , 5, init_b, 1, 0, 3, 2}, init_a, s_op);
|
||||
test_block_matrix_operations<mat_t, T>({10, 1, init_a, 0, 0, 5, 1}, init_b, s_op);
|
||||
test_block_matrix_operations<mat_t, T>({1 , 10, init_a, 0, 0, 1, 5}, init_b, s_op);
|
||||
test_block_matrix_operations<mat_t, T>({21 , 5, init_0, 4, 4, 10, 1}, init_b, s_op);
|
||||
test_block_matrix_operations<mat_t, T>({11 , 7, init_a, 2, 0, 7, 5}, init_0, s_op);
|
||||
};
|
||||
|
||||
|
||||
TTS_CASE_TPL("Check block subtraction", rotgen::tests::types)
|
||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
||||
{
|
||||
using mat_t = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>;
|
||||
//auto op = [](auto a, auto b) { return a - b; };
|
||||
auto s_op = [](auto& a, auto b) { return a -= b; };
|
||||
|
||||
//test_block_matrix_operations<mat_t, T>({1 , 1, init_a, 0, 0, 1, 1}, init_b, op, s_op);
|
||||
test_block_matrix_operations<mat_t, T>({1 , 1, init_a, 0, 0, 1, 1}, init_b, s_op);
|
||||
test_block_matrix_operations<mat_t, T>({13 , 15, init_a, 1, 2, 3, 4}, init_b, s_op);
|
||||
test_block_matrix_operations<mat_t, T>({5 , 9, init_a, 2, 2, 2, 2}, init_b, s_op);
|
||||
test_block_matrix_operations<mat_t, T>({15 , 15, init_a, 3, 4, 5, 5}, init_b, s_op);
|
||||
test_block_matrix_operations<mat_t, T>({5 , 5, init_b, 1, 0, 3, 2}, init_a, s_op);
|
||||
test_block_matrix_operations<mat_t, T>({10, 1, init_a, 0, 0, 5, 1}, init_b, s_op);
|
||||
test_block_matrix_operations<mat_t, T>({1 , 10, init_a, 0, 0, 1, 5}, init_b,s_op);
|
||||
test_block_matrix_operations<mat_t, T>({21 , 5, init_0, 4, 4, 10, 1}, init_b, s_op);
|
||||
test_block_matrix_operations<mat_t, T>({11 , 7, init_a, 2, 0, 7, 5}, init_0, s_op);
|
||||
};
|
||||
|
||||
|
||||
TTS_CASE_TPL("Check block multiplications", rotgen::tests::types)
|
||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
||||
{
|
||||
using mat_t = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>;
|
||||
auto init_id = [](auto r, auto c) { return r == c ? 1 : 0; };
|
||||
|
||||
test_block_multiplication<mat_t, T>({1 , 1, init_a, 0, 0, 1, 1}, {1 , 1, init_b, 0, 0, 1, 1});
|
||||
test_block_multiplication<mat_t, T>({13 , 15, init_b, 1, 2, 4, 4}, {13 , 15, init_b, 0, 1, 4, 4});
|
||||
test_block_multiplication<mat_t, T>({6 , 9, init_a, 2, 2, 2, 2}, {5 , 9, init_b, 2, 2, 2, 2});
|
||||
test_block_multiplication<mat_t, T>({15 , 15, init_a, 3, 4, 5, 5}, {15 , 15, init_b, 0, 0, 5, 5});
|
||||
test_block_multiplication<mat_t, T>({5 , 5, init_b, 1, 0, 3, 3}, {5 , 5, init_a, 0, 0, 3, 3});
|
||||
test_block_multiplication<mat_t, T>({11 , 3, init_id, 2, 0, 2, 2}, {18 , 7, init_a, 2, 0, 2, 2});
|
||||
test_block_multiplication<mat_t, T>({10, 1, init_a, 0, 0, 1, 1}, {10, 1, init_a, 0, 0, 1, 1});
|
||||
test_block_multiplication<mat_t, T>({1 , 10, init_a, 0, 0, 1, 1}, {1 , 10, init_id, 0, 0, 1, 1});
|
||||
test_block_multiplication<mat_t, T>({21 , 5, init_0, 1, 1, 3, 3}, {12 , 7, init_0, 4, 4, 3, 3});
|
||||
test_block_multiplication<mat_t, T>({11 , 7, init_a, 2, 0, 7, 7}, {11 , 11, init_a, 2, 1, 7, 7});
|
||||
test_block_multiplication<mat_t, T>({11 , 7, init_a, 2, 0, 5, 5}, {11 , 12, init_id, 0, 0, 5, 5});
|
||||
};
|
||||
|
||||
TTS_CASE_TPL("Check block multiplication with scalar", rotgen::tests::types)
|
||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
||||
{
|
||||
using mat_t = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>;
|
||||
|
||||
test_scalar_block_multiplications<mat_t, T>({1 , 1, init_a, 0, 0, 1, 1}, T{ 3.5});
|
||||
test_scalar_block_multiplications<mat_t, T>({13 , 15, init_a, 1, 2, 3, 4}, T{ 0.});
|
||||
test_scalar_block_multiplications<mat_t, T>({5 , 9, init_a, 2, 2, 2, 2}, T{-2.5});
|
||||
test_scalar_block_multiplications<mat_t, T>({15 , 15, init_a, 3, 4, 5, 5}, T{ 42. });
|
||||
test_scalar_block_multiplications<mat_t, T>({5 , 5, init_b, 1, 0, 3, 2}, T{-5. });
|
||||
test_scalar_block_multiplications<mat_t, T>({10, 1, init_a, 0, 0, 5, 1}, T{ 1. });
|
||||
test_scalar_block_multiplications<mat_t, T>({1 , 10, init_a, 0, 0, 1, 5}, T{ 6. });
|
||||
test_scalar_block_multiplications<mat_t, T>({21 , 5, init_0, 4, 4, 10, 1}, T{ 10.1});
|
||||
test_scalar_block_multiplications<mat_t, T>({11 , 7, init_a, 2, 0, 7, 5}, T{-0.5});
|
||||
};
|
||||
|
||||
TTS_CASE_TPL("Check block division with scalar", rotgen::tests::types)
|
||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
||||
{
|
||||
using mat_t = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>;
|
||||
//auto op = [](auto a, auto b) { return a / b; };
|
||||
auto s_op = [](auto& a, auto b) { return a /= b; };
|
||||
|
||||
//test_block_scalar_operations<mat_t, T>({1 , 1, init_a, 0, 0, 1, 1}, T{ 3.5}, op, s_op);
|
||||
test_block_scalar_operations<mat_t, T>({1 , 1, init_a, 0, 0, 1, 1}, T{ 3.5}, s_op);
|
||||
test_block_scalar_operations<mat_t, T>({13 , 15, init_a, 1, 2, 3, 4}, T{-2.5}, s_op);
|
||||
test_block_scalar_operations<mat_t, T>({5 , 9, init_a, 2, 2, 2, 2}, T{ 42. }, s_op);
|
||||
test_block_scalar_operations<mat_t, T>({15 , 15, init_a, 3, 4, 5, 5}, T{-5. }, s_op);
|
||||
test_block_scalar_operations<mat_t, T>({5 , 5, init_b, 1, 0, 3, 2}, T{ 1. }, s_op);
|
||||
test_block_scalar_operations<mat_t, T>({10, 1, init_a, 0, 0, 5, 1}, T{ 0. }, s_op);
|
||||
test_block_scalar_operations<mat_t, T>({1 , 10, init_a, 0, 0, 1, 5}, T{ 6. },s_op);
|
||||
test_block_scalar_operations<mat_t, T>({21 , 5, init_0, 4, 4, 10, 1}, T{ 10.}, s_op);
|
||||
test_block_scalar_operations<mat_t, T>({11 , 7, init_a, 2, 0, 7, 5}, T{-0.5}, s_op);
|
||||
};
|
||||
115
test/unit/block/static_functions.cpp
Normal file
115
test/unit/block/static_functions.cpp
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#include "unit/tests.hpp"
|
||||
#include <rotgen/block.hpp>
|
||||
#include <rotgen/matrix.hpp>
|
||||
|
||||
void test_size(const auto& matrix, std::size_t rows, std::size_t cols)
|
||||
{
|
||||
TTS_EQUAL(matrix.rows(), rows);
|
||||
TTS_EQUAL(matrix.cols(), cols);
|
||||
TTS_EQUAL(matrix.size(), rows*cols);
|
||||
}
|
||||
|
||||
void test_value(const auto& matrix, std::size_t rows, std::size_t cols, auto constant)
|
||||
{
|
||||
test_size(matrix, rows, cols);
|
||||
for(std::size_t r=0;r<rows;++r)
|
||||
for(std::size_t c=0;c<cols;++c)
|
||||
TTS_EQUAL(matrix(r, c), constant);
|
||||
}
|
||||
|
||||
void test_random(const auto& matrix, std::size_t rows, std::size_t cols)
|
||||
{
|
||||
test_size(matrix, rows, cols);
|
||||
for(std::size_t r=0;r<rows;++r)
|
||||
for(std::size_t c=0;c<cols;++c)
|
||||
{
|
||||
TTS_GREATER_EQUAL(matrix(r, c), -1.0);
|
||||
TTS_LESS_EQUAL(matrix(r, c), 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
void test_identity(const auto& matrix, std::size_t rows, std::size_t cols)
|
||||
{
|
||||
test_size(matrix, rows, cols);
|
||||
for(std::size_t r=0;r<rows;++r)
|
||||
for(std::size_t c=0;c<cols;++c)
|
||||
TTS_EQUAL(matrix(r, c), r==c ? 1 : 0);
|
||||
}
|
||||
|
||||
TTS_CASE_TPL("Test zero", rotgen::tests::types)
|
||||
<typename T, typename O>( tts::type< tts::types<T,O>>)
|
||||
{
|
||||
test_value(rotgen::block<rotgen::matrix<T, 7, 8>, 3, 4>::Zero(), 3, 4, 0);
|
||||
test_value(rotgen::block<rotgen::matrix<T, 72, 2>, 1, 1>::Zero(), 1, 1, 0);
|
||||
test_value(rotgen::block<rotgen::matrix<T, 21, 33>, 10, 10>::Zero(), 10, 10, 0);
|
||||
test_value(rotgen::block<rotgen::matrix<T, 3, 4>, 3, 4>::Zero(3, 4), 3, 4, 0);
|
||||
test_value(rotgen::block<rotgen::matrix<T, 17, 4>, 3, 3>::Zero(3, 3), 3, 3, 0);
|
||||
test_value(rotgen::block<rotgen::matrix<T, 2, 2>, 2, 2>::Zero(2, 2), 2, 2, 0);
|
||||
test_value(rotgen::block<rotgen::matrix<T, 8, 7>, rotgen::Dynamic, rotgen::Dynamic>::Zero(2, 3), 2, 3, 0);
|
||||
test_value(rotgen::block<rotgen::matrix<T, 3, 4>, 0, 0>::Zero(0, 0), 0, 0, 0);
|
||||
test_value(rotgen::block<decltype(rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic, O::value>::Identity(2, 7)),
|
||||
rotgen::Dynamic, 7>::Zero(3, 7), 3, 7, 0);
|
||||
test_value(rotgen::block<decltype(rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic, O::value>::Random(14, 3)),
|
||||
4, rotgen::Dynamic>::Zero(4, 3), 4, 3, 0);
|
||||
};
|
||||
|
||||
|
||||
TTS_CASE_TPL("Test constant", rotgen::tests::types)
|
||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
||||
{
|
||||
test_value(rotgen::block<rotgen::matrix<T, 3, 4>, 3, 4>::Constant(5.12), 3, 4, T(5.12));
|
||||
test_value(rotgen::block<rotgen::matrix<T, 88, 81>, 1, 1>::Constant(2.2), 1, 1, T(2.2));
|
||||
test_value(rotgen::block<rotgen::matrix<T, 21, 33>, 10, 10>::Constant(13), 10, 10, T(13));
|
||||
test_value(rotgen::block<rotgen::matrix<T, 3, 4>, rotgen::Dynamic, rotgen::Dynamic>::Constant(2, 7, 5.6), 2, 7, T(5.6));
|
||||
test_value(rotgen::block<rotgen::matrix<T, 17, 5>, 2, 2>::Constant(2, 2, 2.0), 2, 2, T(2.0));
|
||||
test_value(rotgen::block<rotgen::matrix<T, 144, 109>, rotgen::Dynamic, 9>::Constant(9, 9, 1.1), 9, 9, T(1.1));
|
||||
test_value(rotgen::block<rotgen::matrix<T, 8, 11>, 5, rotgen::Dynamic>::Constant(5, 9, 42), 5, 9, T(42));
|
||||
test_value(rotgen::block<rotgen::matrix<T, 4, 3>, 4, 3>::Constant(4, 3, 0), 4, 3, 0);
|
||||
test_value(rotgen::block<decltype(rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic, O::value>::Identity(3, 7)),
|
||||
rotgen::Dynamic, 7>::Constant(3, 7, 88), 3, 7, T(88));
|
||||
test_value(rotgen::block<decltype(rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic, O::value>::Random(14, 3)),
|
||||
4, rotgen::Dynamic>::Constant(4, 3, 3.99), 4, 3, T(3.99));
|
||||
};
|
||||
|
||||
|
||||
TTS_CASE_TPL("Test random", rotgen::tests::types)
|
||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
||||
{
|
||||
test_random(rotgen::block<rotgen::matrix<T, 3, 4>, 3, 3>::Random(), 3, 3);
|
||||
test_random(rotgen::block<rotgen::matrix<T, 1, 1>, 1, 1>::Random(), 1, 1);
|
||||
test_random(rotgen::block<rotgen::matrix<T, 13, 12>, 3, 4>::Random(), 3, 4);
|
||||
test_random(rotgen::block<rotgen::matrix<T, 3, 4>, rotgen::Dynamic, rotgen::Dynamic>::Random(1, 5), 1, 5);
|
||||
test_random(rotgen::block<rotgen::matrix<T, 17, 11>, 2, 1>::Random(2, 1), 2, 1);
|
||||
test_random(rotgen::block<rotgen::matrix<T, 109, 117>, rotgen::Dynamic, 9>::Random(3, 9), 3, 9);
|
||||
test_random(rotgen::block<rotgen::matrix<T, 9, 11>, 5, rotgen::Dynamic>::Random(5, 2), 5, 2);
|
||||
test_random(rotgen::block<rotgen::matrix<T, 4, 3>, 4, 3>::Random(4, 3), 4, 3);
|
||||
test_random(rotgen::block<decltype(rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic, O::value>::Identity(3, 7)),
|
||||
rotgen::Dynamic, 7>::Random(3, 7), 3, 7);
|
||||
test_random(rotgen::block<decltype(rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic, O::value>::Random(14, 15)),
|
||||
4, rotgen::Dynamic>::Random(4, 11), 4, 11);
|
||||
};
|
||||
|
||||
|
||||
TTS_CASE_TPL("Test identity", rotgen::tests::types)
|
||||
<typename T, typename O>( tts::type< tts::types<T,O>> )
|
||||
{
|
||||
test_identity(rotgen::block<rotgen::matrix<T, 3, 4>, 3, 3>::Identity(), 3, 3);
|
||||
test_identity(rotgen::block<rotgen::matrix<T, 1, 1>, 1, 1>::Identity(), 1, 1);
|
||||
test_identity(rotgen::block<rotgen::matrix<T, 13, 12>, 3, 4>::Identity(), 3, 4);
|
||||
test_identity(rotgen::block<rotgen::matrix<T, 3, 4>, rotgen::Dynamic, rotgen::Dynamic>::Identity(1, 5), 1, 5);
|
||||
test_identity(rotgen::block<rotgen::matrix<T, 17, 11>, 2, 1>::Identity(2, 1), 2, 1);
|
||||
test_identity(rotgen::block<rotgen::matrix<T, 109, 117>, rotgen::Dynamic, 9>::Identity(3, 9), 3, 9);
|
||||
test_identity(rotgen::block<rotgen::matrix<T, 9, 11>, 5, rotgen::Dynamic>::Identity(5, 2), 5, 2);
|
||||
test_identity(rotgen::block<rotgen::matrix<T, 4, 3>, 4, 3>::Identity(4, 3), 4, 3);
|
||||
test_identity(rotgen::block<decltype(rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic, O::value>::Identity(3, 7)),
|
||||
rotgen::Dynamic, 7>::Identity(3, 7), 3, 7);
|
||||
test_identity(rotgen::block<decltype(rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic, O::value>::Random(14, 15)),
|
||||
4, rotgen::Dynamic>::Identity(4, 11), 4, 11);
|
||||
};
|
||||
|
|
@ -59,7 +59,7 @@ TTS_CASE_TPL("Test transpotion related operations", rotgen::tests::types)
|
|||
template <typename MatrixType>
|
||||
void test_matrix_reductions(std::size_t rows, std::size_t cols, auto const& init_fn)
|
||||
{
|
||||
using EigenMatrix = Eigen::Matrix<typename MatrixType::value_type, Eigen::Dynamic, Eigen::Dynamic>;
|
||||
using EigenMatrix = Eigen::Matrix<typename MatrixType::scalar_type, Eigen::Dynamic, Eigen::Dynamic>;
|
||||
|
||||
MatrixType original(rows, cols);
|
||||
EigenMatrix ref(rows, cols);
|
||||
|
|
@ -28,4 +28,22 @@ namespace rotgen::tests
|
|||
std::size_t rows, cols;
|
||||
std::function<double(std::size_t,std::size_t)> init_fn;
|
||||
};
|
||||
|
||||
template<typename MatrixType>
|
||||
struct matrix_block_test_case
|
||||
{
|
||||
std::size_t rows, cols;
|
||||
std::function<typename MatrixType::scalar_type(std::size_t, std::size_t)> init_fn;
|
||||
std::size_t i0, j0, ni, nj;
|
||||
};
|
||||
|
||||
template<typename MatrixType, std::size_t NI, std::size_t NJ>
|
||||
struct static_matrix_block_test_case
|
||||
{
|
||||
std::size_t rows, cols;
|
||||
std::function<typename MatrixType::scalar_type(std::size_t, std::size_t)> init_fn;
|
||||
static constexpr std::size_t ni = NI;
|
||||
static constexpr std::size_t nj = NJ;
|
||||
std::size_t i0, j0;
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue