Fix a lot of ref issues reagrding extarction, rvalueness and proper use of temporary memory.
This commit is contained in:
parent
d5c41bf43e
commit
379d77ebef
50 changed files with 2945 additions and 1397 deletions
|
|
@ -261,4 +261,10 @@ QualifierOrder:
|
|||
- inline
|
||||
- static
|
||||
- type
|
||||
- const
|
||||
- const
|
||||
StatementMacros:
|
||||
- TTS_CASE
|
||||
- TTS_CASE_TPL
|
||||
- TTS_CASE_WITH
|
||||
- TTS_AND_THEN
|
||||
- TTS_WHEN
|
||||
|
|
@ -6,12 +6,12 @@
|
|||
include(GNUInstallDirs)
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
set(MAIN_DEST "${CMAKE_INSTALL_LIBDIR}/rotgen")
|
||||
set(MAIN_DEST "${CMAKE_INSTALL_LIBDIR}")
|
||||
set(INSTALL_DEST "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
set(DOC_DEST "${CMAKE_INSTALL_DOCDIR}")
|
||||
|
||||
write_basic_package_version_file( "${CMAKE_CURRENT_BINARY_DIR}/rotgen-config-version.cmake"
|
||||
VERSION "${EVE_VERSION}"
|
||||
VERSION "${ROTGEN_VERSION}"
|
||||
COMPATIBILITY ExactVersion
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,6 @@ namespace rotgen::solver
|
|||
auto r_x = generalize_t<X>(x);
|
||||
auto r_m = generalize_t<M const>(m);
|
||||
auto r_rhs = generalize_t<RHS const>(rhs);
|
||||
r_x = r_m.base().qr_solve(r_rhs.base());
|
||||
r_x = r_m.qr_solve(r_rhs);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@
|
|||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <concepts>
|
||||
#include <type_traits>
|
||||
|
||||
namespace rotgen::concepts
|
||||
{
|
||||
//================================================================================================
|
||||
|
|
|
|||
|
|
@ -10,45 +10,68 @@
|
|||
#include <rotgen/concepts.hpp>
|
||||
#include <rotgen/container/block/dynamic/impl.hpp>
|
||||
#include <rotgen/container/matrix/dynamic.hpp>
|
||||
#include <initializer_list>
|
||||
|
||||
#include <cassert>
|
||||
#include <initializer_list>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
template<typename T, int Options = T::storage_order, typename Stride = stride>
|
||||
template<typename T,
|
||||
int Options = 0,
|
||||
typename Stride = std::conditional_t<T::IsVectorAtCompileTime,
|
||||
inner_stride<1>,
|
||||
outer_stride<>>>
|
||||
class ref;
|
||||
|
||||
template<typename Ref,
|
||||
int Rows = Dynamic,
|
||||
int Cols = Dynamic,
|
||||
bool Inner = false>
|
||||
class block : public find_block<Ref>
|
||||
class block : public find_block<Ref, Rows, Cols>
|
||||
{
|
||||
public:
|
||||
static_assert(concepts::entity<Ref>,
|
||||
"[ROTGEN][CRITICAL] - Block of non-rotgen type instanciated");
|
||||
|
||||
using parent = find_block<Ref>;
|
||||
using parent = find_block<Ref, Rows, Cols>;
|
||||
using rotgen_tag = void;
|
||||
using rotgen_block_tag = void;
|
||||
using value_type = typename std::remove_const_t<Ref>::value_type;
|
||||
|
||||
static constexpr int storage_order = Ref::storage_order;
|
||||
static constexpr int RowsAtCompileTime = Rows;
|
||||
static constexpr int ColsAtCompileTime = Cols;
|
||||
static constexpr int MaxRowsAtCompileTime =
|
||||
(Rows != Dynamic) ? Rows : Ref::MaxRowsAtCompileTime;
|
||||
static constexpr int MaxColsAtCompileTime =
|
||||
(Cols != Dynamic) ? Cols : Ref::MaxColsAtCompileTime;
|
||||
static constexpr bool IsRowMajor =
|
||||
(MaxRowsAtCompileTime == 1 && MaxColsAtCompileTime != 1) ? true
|
||||
: (MaxColsAtCompileTime == 1 && MaxRowsAtCompileTime != 1)
|
||||
? false
|
||||
: Ref::IsRowMajor;
|
||||
|
||||
static constexpr int storage_order = IsRowMajor ? RowMajor : ColMajor;
|
||||
|
||||
static constexpr bool has_same_storage_order =
|
||||
storage_order == Ref::storage_order;
|
||||
static constexpr int InnerStrideAtCompileTime =
|
||||
has_same_storage_order ? Ref::InnerStrideAtCompileTime
|
||||
: Ref::OuterStrideAtCompileTime;
|
||||
static constexpr int OuterStrideAtCompileTime =
|
||||
has_same_storage_order ? Ref::OuterStrideAtCompileTime
|
||||
: Ref::InnerStrideAtCompileTime;
|
||||
|
||||
static constexpr bool is_immutable = std::is_const_v<Ref>;
|
||||
using concrete_type = matrix<value_type, Rows, Cols, storage_order>;
|
||||
using transposed_type = matrix<value_type, Cols, Rows, storage_order>;
|
||||
using concrete_dynamic_type =
|
||||
matrix<value_type, Dynamic, Dynamic, storage_order>;
|
||||
|
||||
static constexpr int RowsAtCompileTime = Rows;
|
||||
static constexpr int ColsAtCompileTime = Cols;
|
||||
static constexpr int MaxRowsAtCompileTime = Rows;
|
||||
static constexpr int MaxColsAtCompileTime = Cols;
|
||||
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
|
||||
static constexpr int Options = Ref::Options;
|
||||
static constexpr bool IsRowMajor = (storage_order & RowMajor) == RowMajor;
|
||||
static constexpr bool IsVectorAtCompileTime =
|
||||
(RowsAtCompileTime == 1) || (ColsAtCompileTime == 1);
|
||||
static constexpr int Options = IsRowMajor ? RowMajor : ColMajor;
|
||||
|
||||
static constexpr bool is_defined_static = false;
|
||||
static constexpr bool is_defined_static = Rows != -1 && Cols != -1;
|
||||
static constexpr bool has_static_storage = false;
|
||||
|
||||
using parent::operator=;
|
||||
|
|
@ -80,7 +103,7 @@ namespace rotgen
|
|||
std::size_t ni,
|
||||
std::size_t nj)
|
||||
requires(requires { typename Ref::rotgen_block_tag; } && is_immutable)
|
||||
: parent(*r.storage(), i0, j0, ni, nj)
|
||||
: parent(r.base(), i0, j0, ni, nj)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +117,7 @@ namespace rotgen
|
|||
block(Ref const& r, std::size_t i0, std::size_t j0)
|
||||
requires(requires { typename Ref::rotgen_block_tag; } && Rows != -1 &&
|
||||
Cols != -1 && is_immutable)
|
||||
: parent(*r.storage(), i0, j0, Rows, Cols)
|
||||
: parent(r.base(), i0, j0, Rows, Cols)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -108,7 +131,7 @@ namespace rotgen
|
|||
block(
|
||||
Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj)
|
||||
requires(requires { typename Ref::rotgen_block_tag; } && !is_immutable)
|
||||
: parent(*r.storage(), i0, j0, ni, nj)
|
||||
: parent(r.base(), i0, j0, ni, nj)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -122,7 +145,7 @@ namespace rotgen
|
|||
block(Ref& r, std::size_t i0, std::size_t j0)
|
||||
requires(requires { typename Ref::rotgen_block_tag; } && Rows != -1 &&
|
||||
Cols != -1 && !is_immutable)
|
||||
: parent(*r.storage(), i0, j0, Rows, Cols)
|
||||
: parent(r.base(), i0, j0, Rows, Cols)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -131,8 +154,7 @@ namespace rotgen
|
|||
bool is_contiguous_linear() const
|
||||
{
|
||||
if (parent::innerStride() != 1) return false;
|
||||
if constexpr (storage_order)
|
||||
return parent::outerStride() == parent::cols();
|
||||
if constexpr (IsRowMajor) return parent::outerStride() == parent::cols();
|
||||
else return parent::outerStride() == parent::rows();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,10 +8,14 @@
|
|||
#pragma once
|
||||
|
||||
#include <rotgen/detail/generators.hpp>
|
||||
|
||||
// clang-format off
|
||||
#include <rotgen/container/matrix/dynamic.hpp>
|
||||
#include <rotgen/container/map/dynamic.hpp>
|
||||
#include <initializer_list>
|
||||
// clang-format on
|
||||
|
||||
#include <cstddef>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
|
||||
namespace rotgen
|
||||
|
|
@ -21,6 +25,15 @@ namespace rotgen
|
|||
class matrix_impl32_row;
|
||||
class matrix_impl32_col;
|
||||
|
||||
class block_impl64_row;
|
||||
class block_impl64_col;
|
||||
class block_impl32_row;
|
||||
class block_impl32_col;
|
||||
class block_const_impl64_row;
|
||||
class block_const_impl64_col;
|
||||
class block_const_impl32_row;
|
||||
class block_const_impl32_col;
|
||||
|
||||
#define USE_CONST
|
||||
#define CONST const
|
||||
#define BASENAME block_const_impl
|
||||
|
|
@ -81,9 +94,24 @@ namespace rotgen
|
|||
using type = block_impl64_row;
|
||||
};
|
||||
|
||||
template<typename Ref>
|
||||
template<typename Ref, int Rows, int Cols>
|
||||
constexpr auto block_storage_order()
|
||||
{
|
||||
int MaxRowsAtCompileTime =
|
||||
(Rows != Dynamic) ? Rows : Ref::MaxRowsAtCompileTime;
|
||||
int MaxColsAtCompileTime =
|
||||
(Cols != Dynamic) ? Cols : Ref::MaxColsAtCompileTime;
|
||||
bool IsRowMajor = (MaxRowsAtCompileTime == 1 && MaxColsAtCompileTime != 1)
|
||||
? true
|
||||
: (MaxColsAtCompileTime == 1 && MaxRowsAtCompileTime != 1)
|
||||
? false
|
||||
: Ref::IsRowMajor;
|
||||
return IsRowMajor ? RowMajor : ColMajor;
|
||||
}
|
||||
|
||||
template<typename Ref, int Rows, int Cols>
|
||||
using find_block =
|
||||
typename find_block_impl<typename std::remove_const_t<Ref>::value_type,
|
||||
Ref::storage_order,
|
||||
block_storage_order<Ref, Rows, Cols>(),
|
||||
std::is_const_v<Ref>>::type;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,22 +2,26 @@
|
|||
#define TYPE double
|
||||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
||||
#include <rotgen/container/block/dynamic/model.hpp>
|
||||
#undef CLASSNAME
|
||||
#undef TRANSSOURCENAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef TRANSNAME
|
||||
#undef SOURCENAME
|
||||
#undef MAPNAME
|
||||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
||||
#include <rotgen/container/block/dynamic/model.hpp>
|
||||
#undef CLASSNAME
|
||||
#undef TRANSSOURCENAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef TRANSNAME
|
||||
#undef SOURCENAME
|
||||
#undef MAPNAME
|
||||
|
||||
|
|
@ -28,22 +32,26 @@
|
|||
#define TYPE float
|
||||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
||||
#include <rotgen/container/block/dynamic/model.hpp>
|
||||
#undef CLASSNAME
|
||||
#undef TRANSSOURCENAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef TRANSNAME
|
||||
#undef SOURCENAME
|
||||
#undef MAPNAME
|
||||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
||||
#include <rotgen/container/block/dynamic/model.hpp>
|
||||
#undef CLASSNAME
|
||||
#undef TRANSSOURCENAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef TRANSNAME
|
||||
#undef SOURCENAME
|
||||
#undef MAPNAME
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,10 @@ private:
|
|||
|
||||
public:
|
||||
CLASSNAME(SOURCENAME CONST& r, Index i0, Index j0, Index ni, Index nj);
|
||||
CLASSNAME(TRANSNAME CONST& r, Index i0, Index j0, Index ni, Index nj);
|
||||
CLASSNAME(MAPNAME CONST& r, Index i0, Index j0, Index ni, Index nj);
|
||||
CLASSNAME(payload const& r, Index i0, Index j0, Index ni, Index nj);
|
||||
CLASSNAME(CLASSNAME CONST& r, Index i0, Index j0, Index ni, Index nj);
|
||||
CLASSNAME(TRANSCLASSNAME CONST& r, Index i0, Index j0, Index ni, Index nj);
|
||||
|
||||
CLASSNAME(CLASSNAME const& other);
|
||||
CLASSNAME(CLASSNAME&&) noexcept;
|
||||
|
|
|
|||
|
|
@ -8,12 +8,17 @@
|
|||
#pragma once
|
||||
|
||||
#include <rotgen/container/strides.hpp>
|
||||
|
||||
#include <Eigen/Dense>
|
||||
#include <iostream>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
template<typename T, int Options = T::storage_order, typename Stride = stride>
|
||||
template<typename T,
|
||||
int Options = 0,
|
||||
typename Stride = std::conditional_t<T::IsVectorAtCompileTime,
|
||||
inner_stride<1>,
|
||||
outer_stride<>>>
|
||||
class ref;
|
||||
|
||||
namespace detail
|
||||
|
|
@ -31,22 +36,6 @@ namespace rotgen
|
|||
Eigen::Block<ref_t, Eigen::Dynamic, Eigen::Dynamic, Inner>>;
|
||||
};
|
||||
|
||||
template<typename T,
|
||||
int O,
|
||||
typename S,
|
||||
int Rows,
|
||||
int Cols,
|
||||
bool Inner,
|
||||
bool IsConst>
|
||||
struct compute_block_type<ref<T, O, S>, Rows, Cols, Inner, IsConst>
|
||||
: compute_block_type<typename ref<T, O, S>::parent,
|
||||
Rows,
|
||||
Cols,
|
||||
Inner,
|
||||
IsConst>
|
||||
{
|
||||
};
|
||||
|
||||
template<typename Ref, int Rows, int Cols, bool Inner, bool IsConst>
|
||||
using block_type =
|
||||
typename compute_block_type<Ref, Rows, Cols, Inner, IsConst>::type;
|
||||
|
|
@ -77,29 +66,43 @@ namespace rotgen
|
|||
using value_type = typename parent::value_type;
|
||||
using Index = typename parent::Index;
|
||||
|
||||
static constexpr int storage_order =
|
||||
(ForceStorageOrder == -1) ? Ref::storage_order : ForceStorageOrder;
|
||||
static constexpr bool is_immutable = std::is_const_v<Ref>;
|
||||
|
||||
static constexpr bool IsRowMajor = parent::IsRowMajor;
|
||||
|
||||
using concrete_type = matrix<value_type, Rows, Cols, storage_order>;
|
||||
using concrete_dynamic_type =
|
||||
matrix<value_type, Dynamic, Dynamic, storage_order>;
|
||||
|
||||
template<typename ET>
|
||||
using as_concrete_type = detail::as_concrete_t<ET, matrix>;
|
||||
|
||||
static constexpr int Options = Ref::Options;
|
||||
static constexpr int RowsAtCompileTime = Rows;
|
||||
static constexpr int ColsAtCompileTime = Cols;
|
||||
static constexpr int MaxRowsAtCompileTime = Ref::MaxRowsAtCompileTime;
|
||||
static constexpr int MaxColsAtCompileTime = Ref::MaxColsAtCompileTime;
|
||||
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
|
||||
static constexpr int MaxRowsAtCompileTime =
|
||||
(Rows != Dynamic) ? Rows : Ref::MaxRowsAtCompileTime;
|
||||
static constexpr int MaxColsAtCompileTime =
|
||||
(Cols != Dynamic) ? Cols : Ref::MaxColsAtCompileTime;
|
||||
static constexpr bool IsVectorAtCompileTime =
|
||||
(RowsAtCompileTime == 1) || (ColsAtCompileTime == 1);
|
||||
static constexpr bool is_defined_static = Rows != -1 && Cols != -1;
|
||||
static constexpr bool has_static_storage =
|
||||
storage_status<Rows, Cols, Rows, Cols>;
|
||||
|
||||
static constexpr bool IsRowMajor =
|
||||
(MaxRowsAtCompileTime == 1 && MaxColsAtCompileTime != 1) ? true
|
||||
: (MaxColsAtCompileTime == 1 && MaxRowsAtCompileTime != 1)
|
||||
? false
|
||||
: Ref::IsRowMajor;
|
||||
|
||||
static constexpr int storage_order = IsRowMajor ? RowMajor : ColMajor;
|
||||
static constexpr bool has_same_storage_order =
|
||||
storage_order == Ref::storage_order;
|
||||
static constexpr int InnerStrideAtCompileTime =
|
||||
has_same_storage_order ? Ref::InnerStrideAtCompileTime
|
||||
: Ref::OuterStrideAtCompileTime;
|
||||
static constexpr int OuterStrideAtCompileTime =
|
||||
has_same_storage_order ? Ref::OuterStrideAtCompileTime
|
||||
: Ref::InnerStrideAtCompileTime;
|
||||
static constexpr bool is_immutable = std::is_const_v<Ref>;
|
||||
|
||||
using concrete_type = matrix<value_type, Rows, Cols, storage_order>;
|
||||
using concrete_dynamic_type =
|
||||
matrix<value_type, Dynamic, Dynamic, storage_order>;
|
||||
|
||||
public:
|
||||
block(block const& other) = default;
|
||||
block(block&& other) = default;
|
||||
|
|
|
|||
|
|
@ -7,16 +7,25 @@
|
|||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/detail/helpers.hpp>
|
||||
|
||||
#include <rotgen/concepts.hpp>
|
||||
#include <rotgen/container/map/dynamic/impl.hpp>
|
||||
#include <rotgen/detail/helpers.hpp>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
struct postpone
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
template<typename Ref,
|
||||
int Options = Unaligned,
|
||||
typename Stride = rotgen::stride>
|
||||
typename Stride = rotgen::stride<0, 0>>
|
||||
class map : public find_map<Ref>
|
||||
{
|
||||
public:
|
||||
|
|
@ -33,7 +42,6 @@ namespace rotgen
|
|||
static constexpr bool has_static_storage = false;
|
||||
|
||||
static constexpr bool is_immutable = std::is_const_v<Ref>;
|
||||
static constexpr bool is_defined_static = false;
|
||||
|
||||
using ptr_type =
|
||||
std::conditional_t<is_immutable, value_type const*, value_type*>;
|
||||
|
|
@ -44,13 +52,25 @@ namespace rotgen
|
|||
static constexpr int MaxRowsAtCompileTime = Ref::MaxRowsAtCompileTime;
|
||||
static constexpr int MaxColsAtCompileTime = Ref::MaxColsAtCompileTime;
|
||||
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
|
||||
static constexpr bool IsCompileTimeSized =
|
||||
static constexpr bool is_defined_static =
|
||||
RowsAtCompileTime != -1 && ColsAtCompileTime != -1;
|
||||
static constexpr int inner_size =
|
||||
Ref::IsRowMajor ? ColsAtCompileTime : RowsAtCompileTime;
|
||||
|
||||
static constexpr int InnerStrideAtCompileTime =
|
||||
Stride::InnerStrideAtCompileTime == 0 ? Ref::InnerStrideAtCompileTime
|
||||
: Stride::InnerStrideAtCompileTime;
|
||||
static constexpr int OuterStrideAtCompileTime =
|
||||
Stride::OuterStrideAtCompileTime == 0
|
||||
? (InnerStrideAtCompileTime == -1 || inner_size == -1)
|
||||
? Dynamic
|
||||
: InnerStrideAtCompileTime * inner_size
|
||||
: Stride::OuterStrideAtCompileTime;
|
||||
|
||||
using transposed_type =
|
||||
matrix<value_type, ColsAtCompileTime, RowsAtCompileTime, storage_order>;
|
||||
|
||||
map(ptr_type ptr, Index r, Index c, stride_type s)
|
||||
map(ptr_type ptr, Index r, Index c, dynamic_stride s)
|
||||
: parent(ptr, r, c, strides<storage_order>(s, r, c))
|
||||
{
|
||||
if constexpr (RowsAtCompileTime != -1)
|
||||
|
|
@ -62,9 +82,18 @@ namespace rotgen
|
|||
"Mismatched between dynamic and static column size");
|
||||
}
|
||||
|
||||
// Used to properly delay ref dynamic construction
|
||||
map(detail::postpone const&) {}
|
||||
|
||||
map(ptr_type ptr, Index r, Index c, stride_type s)
|
||||
requires(!std::same_as<stride_type, dynamic_stride>)
|
||||
: map(ptr, r, c, strides<storage_order>(s, r, c))
|
||||
{
|
||||
}
|
||||
|
||||
map(ptr_type ptr, Index r, Index c)
|
||||
: parent(ptr, r, c, [&]() {
|
||||
if constexpr (!std::same_as<Stride, stride>)
|
||||
if constexpr (!std::same_as<Stride, stride<0, 0>>)
|
||||
return strides<storage_order>(Stride{}, r, c);
|
||||
else return strides<storage_order>(r, c);
|
||||
}())
|
||||
|
|
@ -72,7 +101,7 @@ namespace rotgen
|
|||
}
|
||||
|
||||
map(ptr_type ptr, stride_type s)
|
||||
requires(IsCompileTimeSized)
|
||||
requires(is_defined_static)
|
||||
: parent(
|
||||
ptr, RowsAtCompileTime, ColsAtCompileTime, strides<storage_order>(s))
|
||||
{
|
||||
|
|
@ -87,7 +116,7 @@ namespace rotgen
|
|||
}
|
||||
|
||||
map(ptr_type ptr)
|
||||
requires(IsCompileTimeSized)
|
||||
requires(is_defined_static)
|
||||
: map(ptr, RowsAtCompileTime, ColsAtCompileTime)
|
||||
{
|
||||
}
|
||||
|
|
@ -97,7 +126,7 @@ namespace rotgen
|
|||
: map(other.data(),
|
||||
other.rows(),
|
||||
other.cols(),
|
||||
stride{other.outerStride(), other.innerStride()})
|
||||
dynamic_stride{other.outerStride(), other.innerStride()})
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -116,9 +145,17 @@ namespace rotgen
|
|||
requires(!is_immutable)
|
||||
{
|
||||
assert(parent::rows() == other.rows() && parent::cols() == other.cols());
|
||||
for (rotgen::Index r = 0; r < parent::rows(); ++r)
|
||||
for (rotgen::Index c = 0; c < parent::cols(); ++c)
|
||||
(*this)(r, c) = other(r, c);
|
||||
if constexpr (IsVectorAtCompileTime)
|
||||
{
|
||||
for (rotgen::Index i = 0; i < parent::size(); ++i)
|
||||
(*this)(i) = other(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (rotgen::Index r = 0; r < parent::rows(); ++r)
|
||||
for (rotgen::Index c = 0; c < parent::cols(); ++c)
|
||||
(*this)(r, c) = other(r, c);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -132,9 +169,6 @@ namespace rotgen
|
|||
value_type& operator()(Index i)
|
||||
requires(!is_immutable && IsVectorAtCompileTime)
|
||||
{
|
||||
assert(parent::innerStride() == 1 &&
|
||||
parent::outerStride() ==
|
||||
(storage_order == RowMajor ? parent::cols() : parent::rows()));
|
||||
return parent::operator()(i);
|
||||
}
|
||||
|
||||
|
|
@ -152,9 +186,6 @@ namespace rotgen
|
|||
value_type operator()(Index i) const
|
||||
requires(IsVectorAtCompileTime)
|
||||
{
|
||||
assert(parent::innerStride() == 1 &&
|
||||
parent::outerStride() ==
|
||||
(storage_order == RowMajor ? parent::cols() : parent::rows()));
|
||||
return parent::operator()(i);
|
||||
}
|
||||
|
||||
|
|
@ -349,8 +380,16 @@ namespace rotgen
|
|||
return Ref::Zero();
|
||||
}
|
||||
|
||||
static auto Ones()
|
||||
requires(requires { Ref::Ones(); })
|
||||
{
|
||||
return Ref::Ones();
|
||||
}
|
||||
|
||||
static auto Zero(int rows, int cols) { return Ref::Zero(rows, cols); }
|
||||
|
||||
static auto Ones(int rows, int cols) { return Ref::Ones(rows, cols); }
|
||||
|
||||
static auto Constant(value_type value)
|
||||
requires(requires { Ref::Constant(value); })
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,8 +14,9 @@
|
|||
class ROTGEN_EXPORT CLASSNAME
|
||||
{
|
||||
public:
|
||||
CLASSNAME();
|
||||
CLASSNAME(TYPE CONST* ptr, Index r, Index c);
|
||||
CLASSNAME(TYPE CONST* ptr, Index r, Index c, stride s);
|
||||
CLASSNAME(TYPE CONST* ptr, Index r, Index c, dynamic_stride s);
|
||||
|
||||
CLASSNAME(CLASSNAME const& other);
|
||||
CLASSNAME(CLASSNAME&&) noexcept;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ namespace rotgen
|
|||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename Ref, int Options, bool isConst> struct compute_map_type
|
||||
template<typename Ref, int Options, bool isConst, typename Stride>
|
||||
struct compute_map_type
|
||||
{
|
||||
using base = Eigen::Matrix<typename Ref::value_type,
|
||||
Ref::RowsAtCompileTime,
|
||||
|
|
@ -22,22 +23,26 @@ namespace rotgen
|
|||
Ref::storage_order>;
|
||||
|
||||
using ref_t = std::conditional_t<isConst, base const, base>;
|
||||
using type = Eigen::Map<ref_t, Options, Eigen::Stride<-1, -1>>;
|
||||
using type = Eigen::Map<ref_t, Options, Stride>;
|
||||
};
|
||||
|
||||
template<typename Ref, int Options, bool isConst>
|
||||
using map_type = typename compute_map_type<Ref, Options, isConst>::type;
|
||||
template<typename Ref, int Options, bool isConst, typename Stride>
|
||||
using map_type =
|
||||
typename compute_map_type<Ref, Options, isConst, Stride>::type;
|
||||
}
|
||||
|
||||
template<typename Ref, int Options = Unaligned, typename Stride = stride>
|
||||
template<typename Ref,
|
||||
int Options = Unaligned,
|
||||
typename Stride = rotgen::stride<0, 0>>
|
||||
class map : private detail::map_type<std::remove_const_t<Ref>,
|
||||
Options,
|
||||
std::is_const_v<Ref>>
|
||||
std::is_const_v<Ref>,
|
||||
Stride>
|
||||
{
|
||||
public:
|
||||
using rotgen_tag = void;
|
||||
using parent =
|
||||
detail::map_type<std::remove_const_t<Ref>, Options, std::is_const_v<Ref>>;
|
||||
using parent = detail::
|
||||
map_type<std::remove_const_t<Ref>, Options, std::is_const_v<Ref>, Stride>;
|
||||
using value_type = typename std::remove_const_t<Ref>::value_type;
|
||||
using concrete_type = typename std::remove_const_t<Ref>::concrete_type;
|
||||
|
||||
|
|
@ -47,10 +52,23 @@ namespace rotgen
|
|||
static constexpr int MaxColsAtCompileTime = Ref::MaxColsAtCompileTime;
|
||||
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
|
||||
static constexpr bool has_static_storage = Ref::has_static_storage;
|
||||
static constexpr bool IsRowMajor = Ref::IsRowMajor;
|
||||
static constexpr int storage_order = Ref::storage_order;
|
||||
static constexpr bool is_immutable = std::is_const_v<Ref>;
|
||||
static constexpr bool is_defined_static = Ref::is_defined_static;
|
||||
|
||||
static constexpr int inner_size =
|
||||
Ref::IsRowMajor ? ColsAtCompileTime : RowsAtCompileTime;
|
||||
static constexpr int InnerStrideAtCompileTime =
|
||||
Stride::InnerStrideAtCompileTime == 0 ? Ref::InnerStrideAtCompileTime
|
||||
: Stride::InnerStrideAtCompileTime;
|
||||
static constexpr int OuterStrideAtCompileTime =
|
||||
Stride::OuterStrideAtCompileTime == 0
|
||||
? (InnerStrideAtCompileTime == -1 || inner_size == -1)
|
||||
? Dynamic
|
||||
: InnerStrideAtCompileTime * inner_size
|
||||
: Stride::OuterStrideAtCompileTime;
|
||||
|
||||
template<typename ET>
|
||||
using as_concrete_type = detail::as_concrete_t<ET, matrix>;
|
||||
|
||||
|
|
@ -63,24 +81,13 @@ namespace rotgen
|
|||
map& operator=(map const&) = default;
|
||||
map& operator=(map&&) = default;
|
||||
|
||||
map(ptr_type ptr, Index r, Index c, stride_type s)
|
||||
: parent(ptr, r, c, strides<storage_order>(s, r, c))
|
||||
{
|
||||
}
|
||||
map(ptr_type ptr, Index r, Index c, stride_type s) : parent(ptr, r, c, s) {}
|
||||
|
||||
map(ptr_type ptr, Index r, Index c)
|
||||
: parent(ptr, r, c, [&]() {
|
||||
if constexpr (!std::same_as<Stride, stride>)
|
||||
return strides<storage_order>(Stride{}, r, c);
|
||||
else return strides<storage_order>(r, c);
|
||||
}())
|
||||
{
|
||||
}
|
||||
map(ptr_type ptr, Index r, Index c) : parent(ptr, r, c) {}
|
||||
|
||||
map(ptr_type ptr, stride_type s)
|
||||
requires(RowsAtCompileTime != -1 && ColsAtCompileTime != -1)
|
||||
: parent(ptr,
|
||||
strides<storage_order>(s, RowsAtCompileTime, ColsAtCompileTime))
|
||||
: parent(ptr, s)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -115,6 +122,12 @@ namespace rotgen
|
|||
return as_concrete_type<decltype(res)>(res);
|
||||
}
|
||||
|
||||
auto evaluate()
|
||||
{
|
||||
auto res = static_cast<parent&>(*this).eval();
|
||||
return as_concrete_type<decltype(res)>(res);
|
||||
}
|
||||
|
||||
decltype(auto) noalias() const
|
||||
{
|
||||
if constexpr (use_expression_templates) return base().noalias();
|
||||
|
|
|
|||
|
|
@ -7,10 +7,13 @@
|
|||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/container/matrix/dynamic/impl.hpp>
|
||||
#include <rotgen/detail/helpers.hpp>
|
||||
|
||||
#include <rotgen/concepts.hpp>
|
||||
#include <initializer_list>
|
||||
#include <rotgen/container/matrix/dynamic/impl.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <initializer_list>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
|
|
@ -31,24 +34,29 @@ namespace rotgen
|
|||
static constexpr auto storage_order = Opts & 1;
|
||||
static constexpr int RowsAtCompileTime = Rows;
|
||||
static constexpr int ColsAtCompileTime = Cols;
|
||||
static constexpr int SizeAtCompileTime = detail::static_size<matrix>();
|
||||
static constexpr int MaxRowsAtCompileTime = MaxRows;
|
||||
static constexpr int MaxColsAtCompileTime = MaxCols;
|
||||
static constexpr bool IsCompileTimeSized = Rows != -1 && Cols != -1;
|
||||
static constexpr bool IsVectorAtCompileTime =
|
||||
(RowsAtCompileTime == 1) || (ColsAtCompileTime == 1);
|
||||
static constexpr bool IsVectorAtCompileTime = (Rows == 1) || (Cols == 1);
|
||||
static constexpr int Options = Opts;
|
||||
static constexpr bool IsRowMajor = (Opts & RowMajor) == RowMajor;
|
||||
static constexpr bool is_defined_static = false;
|
||||
static constexpr int InnerSizeAtCompileTime =
|
||||
IsVectorAtCompileTime ? SizeAtCompileTime
|
||||
: IsRowMajor ? ColsAtCompileTime
|
||||
: RowsAtCompileTime;
|
||||
|
||||
static constexpr bool is_defined_static = Rows != -1 && Cols != -1;
|
||||
static constexpr bool has_static_storage = false;
|
||||
static constexpr bool is_immutable = false;
|
||||
static constexpr int InnerStrideAtCompileTime = 1;
|
||||
static constexpr int OuterStrideAtCompileTime =
|
||||
IsRowMajor ? ColsAtCompileTime : RowsAtCompileTime;
|
||||
|
||||
using transposed_type = matrix<value_type, Cols, Rows, storage_order>;
|
||||
|
||||
matrix() : parent(Rows == -1 ? 0 : Rows, Cols == -1 ? 0 : Cols) {}
|
||||
|
||||
matrix(Index r, Index c)
|
||||
requires(!IsCompileTimeSized)
|
||||
: parent(r, c)
|
||||
matrix(Index r, Index c) : parent(r, c)
|
||||
{
|
||||
if constexpr (Rows != -1)
|
||||
assert(r == Rows && "Mismatched between dynamic and static row size");
|
||||
|
|
@ -145,6 +153,15 @@ namespace rotgen
|
|||
|
||||
decltype(auto) noalias() { return *this; }
|
||||
|
||||
Index innerStride() const noexcept { return 1; }
|
||||
|
||||
Index outerStride() const noexcept
|
||||
{
|
||||
return IsVectorAtCompileTime ? this->size()
|
||||
: IsRowMajor ? this->cols()
|
||||
: this->rows();
|
||||
}
|
||||
|
||||
void resize(int r, int c)
|
||||
{
|
||||
if constexpr (Rows == 1)
|
||||
|
|
@ -361,62 +378,62 @@ namespace rotgen
|
|||
|
||||
matrix& setOnes()
|
||||
{
|
||||
*this = parent::Ones(parent::rows(), parent::cols());
|
||||
parent::setOnes(parent::rows(), parent::cols());
|
||||
return *this;
|
||||
}
|
||||
|
||||
matrix& setOnes(int rows, int cols)
|
||||
{
|
||||
*this = parent::Ones(rows, cols);
|
||||
parent::setOnes(rows, cols);
|
||||
return *this;
|
||||
}
|
||||
|
||||
matrix& setZero()
|
||||
{
|
||||
*this = parent::Zero(parent::rows(), parent::cols());
|
||||
parent::setZero(parent::rows(), parent::cols());
|
||||
return *this;
|
||||
}
|
||||
|
||||
matrix& setZero(int rows, int cols)
|
||||
{
|
||||
*this = parent::Zero(rows, cols);
|
||||
parent::setZero(rows, cols);
|
||||
return *this;
|
||||
}
|
||||
|
||||
matrix& setConstant(Scalar value)
|
||||
matrix& setConstant(Scalar v)
|
||||
{
|
||||
*this = parent::Constant(parent::rows(), parent::cols(),
|
||||
static_cast<Scalar>(value));
|
||||
parent::setConstant(parent::rows(), parent::cols(),
|
||||
static_cast<Scalar>(v));
|
||||
return *this;
|
||||
}
|
||||
|
||||
matrix& setConstant(int rows, int cols, Scalar value)
|
||||
matrix& setConstant(int rows, int cols, Scalar v)
|
||||
{
|
||||
*this = parent::Constant(rows, cols, static_cast<Scalar>(value));
|
||||
parent::setConstant(rows, cols, static_cast<Scalar>(v));
|
||||
return *this;
|
||||
}
|
||||
|
||||
matrix& setRandom()
|
||||
{
|
||||
*this = parent::Random(parent::rows(), parent::cols());
|
||||
parent::setRandom(parent::rows(), parent::cols());
|
||||
return *this;
|
||||
}
|
||||
|
||||
matrix& setRandom(int rows, int cols)
|
||||
{
|
||||
*this = parent::Random(rows, cols);
|
||||
parent::setRandom(rows, cols);
|
||||
return *this;
|
||||
}
|
||||
|
||||
matrix& setIdentity()
|
||||
{
|
||||
*this = parent::Identity(parent::rows(), parent::cols());
|
||||
parent::setIdentity(parent::rows(), parent::cols());
|
||||
return *this;
|
||||
}
|
||||
|
||||
matrix& setIdentity(int rows, int cols)
|
||||
{
|
||||
*this = parent::Identity(rows, cols);
|
||||
parent::setIdentity(rows, cols);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -95,6 +95,12 @@ public:
|
|||
static CLASSNAME Random(std::size_t rows, std::size_t cols);
|
||||
static CLASSNAME Identity(std::size_t rows, std::size_t cols);
|
||||
|
||||
void setOnes(std::size_t rows, std::size_t cols);
|
||||
void setZero(std::size_t rows, std::size_t cols);
|
||||
void setConstant(std::size_t rows, std::size_t cols, TYPE value);
|
||||
void setRandom(std::size_t rows, std::size_t cols);
|
||||
void setIdentity(std::size_t rows, std::size_t cols);
|
||||
|
||||
private:
|
||||
struct payload;
|
||||
std::unique_ptr<payload> storage_;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <rotgen/detail/helpers.hpp>
|
||||
|
||||
#include <Eigen/Dense>
|
||||
#include <iostream>
|
||||
|
||||
|
|
@ -49,13 +50,21 @@ namespace rotgen
|
|||
|
||||
static constexpr int RowsAtCompileTime = Rows;
|
||||
static constexpr int ColsAtCompileTime = Cols;
|
||||
static constexpr int SizeAtCompileTime = detail::static_size<matrix>();
|
||||
static constexpr int MaxRowsAtCompileTime = MaxRows;
|
||||
static constexpr int MaxColsAtCompileTime = MaxCols;
|
||||
static constexpr bool IsCompileTimeSized = Rows != -1 && Cols != -1;
|
||||
static constexpr bool IsVectorAtCompileTime =
|
||||
(RowsAtCompileTime == 1) || (ColsAtCompileTime == 1);
|
||||
static constexpr int Options = parent::Options;
|
||||
static constexpr bool IsRowMajor = parent::IsRowMajor;
|
||||
static constexpr int InnerStrideAtCompileTime = 1;
|
||||
static constexpr int OuterStrideAtCompileTime =
|
||||
IsRowMajor ? ColsAtCompileTime : RowsAtCompileTime;
|
||||
|
||||
static constexpr int InnerSizeAtCompileTime =
|
||||
IsVectorAtCompileTime ? SizeAtCompileTime
|
||||
: IsRowMajor ? ColsAtCompileTime
|
||||
: RowsAtCompileTime;
|
||||
|
||||
template<typename ET>
|
||||
using as_concrete_type = detail::as_concrete_t<ET, matrix>;
|
||||
|
|
@ -77,10 +86,15 @@ namespace rotgen
|
|||
{
|
||||
}
|
||||
|
||||
matrix(Index r, Index c)
|
||||
requires(!IsCompileTimeSized)
|
||||
: parent(r, c)
|
||||
matrix(Index r, Index c) : parent(r, c)
|
||||
{
|
||||
if constexpr (RowsAtCompileTime != -1)
|
||||
assert(r == RowsAtCompileTime &&
|
||||
"Mismatched between dynamic and static row size");
|
||||
|
||||
if constexpr (ColsAtCompileTime != -1)
|
||||
assert(c == ColsAtCompileTime &&
|
||||
"Mismatched between dynamic and static column size");
|
||||
}
|
||||
|
||||
matrix(matrix const& other) = default;
|
||||
|
|
@ -99,7 +113,7 @@ namespace rotgen
|
|||
{
|
||||
}
|
||||
|
||||
matrix(Scalar v)
|
||||
explicit matrix(Scalar v)
|
||||
requires(Rows == 1 && Cols == 1)
|
||||
: parent([&]() {
|
||||
if constexpr (has_static_storage) return parent(v);
|
||||
|
|
@ -109,7 +123,7 @@ namespace rotgen
|
|||
if constexpr (!has_static_storage) (*this)(0) = v;
|
||||
}
|
||||
|
||||
explicit matrix(std::initializer_list<Scalar> init)
|
||||
matrix(std::initializer_list<Scalar> init)
|
||||
requires(IsVectorAtCompileTime)
|
||||
: parent([&]() {
|
||||
if constexpr (has_static_storage) return parent{};
|
||||
|
|
@ -159,6 +173,9 @@ namespace rotgen
|
|||
return *this;
|
||||
}
|
||||
|
||||
using parent::innerStride;
|
||||
using parent::outerStride;
|
||||
|
||||
parent& base() { return static_cast<parent&>(*this); }
|
||||
|
||||
parent const& base() const { return static_cast<parent const&>(*this); }
|
||||
|
|
|
|||
|
|
@ -7,501 +7,13 @@
|
|||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <type_traits>
|
||||
#include <rotgen/config.hpp>
|
||||
|
||||
#if !defined(ROTGEN_FORCE_DYNAMIC)
|
||||
#include <Eigen/Dense>
|
||||
#if defined(ROTGEN_FORCE_DYNAMIC)
|
||||
#include <rotgen/container/ref/dynamic.hpp>
|
||||
#else
|
||||
#include <rotgen/container/ref/fixed.hpp>
|
||||
#endif
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
// Primary template: mutable ref
|
||||
template<typename T, int Options, typename Stride>
|
||||
class ref : private map<T, Options, Stride>
|
||||
{
|
||||
public:
|
||||
using parent = map<T, Options, Stride>;
|
||||
using value_type = typename T::value_type;
|
||||
using rotgen_tag = void;
|
||||
using rotgen_ref_tag = void;
|
||||
|
||||
static constexpr int storage_order = T::storage_order;
|
||||
static constexpr int RowsAtCompileTime = T::RowsAtCompileTime;
|
||||
static constexpr int ColsAtCompileTime = T::ColsAtCompileTime;
|
||||
static constexpr bool IsVectorAtCompileTime = T::IsVectorAtCompileTime;
|
||||
static constexpr bool is_immutable = T::is_immutable;
|
||||
|
||||
using parent::evaluate;
|
||||
using parent::noalias;
|
||||
using parent::operator();
|
||||
using parent::operator[];
|
||||
using parent::cols;
|
||||
using parent::cwiseAbs;
|
||||
using parent::cwiseAbs2;
|
||||
using parent::cwiseInverse;
|
||||
using parent::cwiseSqrt;
|
||||
using parent::data;
|
||||
using parent::lpNorm;
|
||||
using parent::maxCoeff;
|
||||
using parent::mean;
|
||||
using parent::minCoeff;
|
||||
using parent::norm;
|
||||
using parent::normalize;
|
||||
using parent::prod;
|
||||
using parent::rows;
|
||||
using parent::size;
|
||||
using parent::squaredNorm;
|
||||
using parent::sum;
|
||||
using parent::trace;
|
||||
using parent::transpose;
|
||||
using parent::operator+=;
|
||||
using parent::operator-=;
|
||||
using parent::operator*=;
|
||||
using parent::operator/=;
|
||||
using parent::Constant;
|
||||
using parent::Identity;
|
||||
using parent::innerStride;
|
||||
using parent::outerStride;
|
||||
using parent::Random;
|
||||
using parent::setConstant;
|
||||
using parent::setIdentity;
|
||||
using parent::setRandom;
|
||||
using parent::setZero;
|
||||
using parent::Zero;
|
||||
|
||||
using parent::operator=;
|
||||
|
||||
using stride_type = typename parent::stride_type;
|
||||
|
||||
parent const& base() const { return static_cast<parent const&>(*this); }
|
||||
|
||||
parent& base() { return static_cast<parent&>(*this); }
|
||||
|
||||
template<std::same_as<value_type> S, int R, int C, int O, int MR, int MC>
|
||||
ref(matrix<S, R, C, O, MR, MC>& m)
|
||||
: parent(m.data(), m.rows(), m.cols(), strides(m))
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Ref, int R, int C, bool I>
|
||||
requires(std::same_as<value_type, typename Ref::value_type> &&
|
||||
(Ref::storage_order & 1) == storage_order)
|
||||
ref(block<Ref, R, C, I>&& b)
|
||||
: parent(b.data(),
|
||||
b.rows(),
|
||||
b.cols(),
|
||||
stride_type{b.outerStride(), b.innerStride()})
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Ref, int R, int C, bool I>
|
||||
requires(std::same_as<value_type, typename Ref::value_type> &&
|
||||
(Ref::storage_order & 1) == storage_order)
|
||||
ref(block<Ref, R, C, I>& b)
|
||||
: parent(b.data(),
|
||||
b.rows(),
|
||||
b.cols(),
|
||||
stride_type{b.outerStride(), b.innerStride()})
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Ref, int O, typename S>
|
||||
requires(std::same_as<value_type, typename Ref::value_type> &&
|
||||
(Ref::storage_order & 1) == storage_order)
|
||||
ref(map<Ref, O, S>& b)
|
||||
: parent(b.data(),
|
||||
b.rows(),
|
||||
b.cols(),
|
||||
stride_type{b.outerStride(), b.innerStride()})
|
||||
{
|
||||
}
|
||||
|
||||
template<typename TT, int OO, typename SS>
|
||||
ref(ref<TT, OO, SS>& b)
|
||||
requires(std::same_as<value_type, typename TT::value_type> &&
|
||||
(TT::storage_order & 1) == storage_order)
|
||||
: parent(b.data(),
|
||||
b.rows(),
|
||||
b.cols(),
|
||||
stride_type{b.outerStride(), b.innerStride()})
|
||||
{
|
||||
}
|
||||
|
||||
ref(parent& m) : parent(m.data(), m.rows(), m.cols()) {}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, ref const& r)
|
||||
{
|
||||
return os << r.base();
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, format<ref> const& r)
|
||||
{
|
||||
return os << format{r.matrix_.base(), r.format_};
|
||||
}
|
||||
};
|
||||
|
||||
// Specialization for const matrix type
|
||||
template<typename T, int Options, typename Stride>
|
||||
class ref<T const, Options, Stride> : private map<T const, Options, Stride>
|
||||
{
|
||||
public:
|
||||
using parent = map<T const, Options, Stride>;
|
||||
using value_type = typename T::value_type;
|
||||
using rotgen_tag = void;
|
||||
using rotgen_ref_tag = void;
|
||||
|
||||
static constexpr int storage_order = T::storage_order;
|
||||
static constexpr int RowsAtCompileTime = T::RowsAtCompileTime;
|
||||
static constexpr int ColsAtCompileTime = T::ColsAtCompileTime;
|
||||
static constexpr bool IsVectorAtCompileTime = T::IsVectorAtCompileTime;
|
||||
static constexpr bool is_immutable = T::is_immutable;
|
||||
|
||||
using parent::evaluate;
|
||||
using parent::noalias;
|
||||
using parent::operator();
|
||||
using parent::operator[];
|
||||
using parent::cols;
|
||||
using parent::cwiseAbs;
|
||||
using parent::cwiseAbs2;
|
||||
using parent::cwiseInverse;
|
||||
using parent::cwiseSqrt;
|
||||
using parent::data;
|
||||
using parent::lpNorm;
|
||||
using parent::maxCoeff;
|
||||
using parent::mean;
|
||||
using parent::minCoeff;
|
||||
using parent::norm;
|
||||
using parent::normalize;
|
||||
using parent::prod;
|
||||
using parent::rows;
|
||||
using parent::size;
|
||||
using parent::squaredNorm;
|
||||
using parent::sum;
|
||||
using parent::trace;
|
||||
using parent::transpose;
|
||||
using parent::operator+=;
|
||||
using parent::operator-=;
|
||||
using parent::operator*=;
|
||||
using parent::operator/=;
|
||||
using parent::Constant;
|
||||
using parent::Identity;
|
||||
using parent::innerStride;
|
||||
using parent::outerStride;
|
||||
using parent::Random;
|
||||
using parent::Zero;
|
||||
|
||||
using parent::operator=;
|
||||
|
||||
using stride_type = typename parent::stride_type;
|
||||
static constexpr bool has_static_storage = parent::has_static_storage;
|
||||
|
||||
parent const& base() const { return static_cast<parent const&>(*this); }
|
||||
|
||||
template<std::same_as<value_type> S, int R, int C, int O, int MR, int MC>
|
||||
ref(matrix<S, R, C, O, MR, MC> const& m)
|
||||
: parent(m.data(), m.rows(), m.cols(), strides(m))
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Ref, int R, int C, bool I>
|
||||
ref(block<Ref, R, C, I> const& b)
|
||||
requires(std::same_as<value_type, typename Ref::value_type> &&
|
||||
(Ref::storage_order & 1) == storage_order)
|
||||
: parent(b.data(),
|
||||
b.rows(),
|
||||
b.cols(),
|
||||
stride_type{b.outerStride(), b.innerStride()})
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Ref, int O, typename S>
|
||||
ref(map<Ref, O, S> const& b)
|
||||
requires(std::same_as<value_type, typename Ref::value_type> &&
|
||||
(Ref::storage_order & 1) == storage_order)
|
||||
: parent(b.data(),
|
||||
b.rows(),
|
||||
b.cols(),
|
||||
stride_type{b.outerStride(), b.innerStride()})
|
||||
{
|
||||
}
|
||||
|
||||
template<typename TT, int OO, typename SS>
|
||||
ref(ref<TT, OO, SS> const& b)
|
||||
requires(std::same_as<value_type, typename TT::value_type> &&
|
||||
(TT::storage_order & 1) == storage_order)
|
||||
: parent(b.data(),
|
||||
b.rows(),
|
||||
b.cols(),
|
||||
stride_type{b.outerStride(), b.innerStride()})
|
||||
{
|
||||
}
|
||||
|
||||
ref(parent const& m) : parent(m.data(), m.rows(), m.cols()) {}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, ref const& r)
|
||||
{
|
||||
return os << r.base();
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, format<ref> const& r)
|
||||
{
|
||||
return os << format{r.matrix_.base(), r.format_};
|
||||
}
|
||||
};
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
ref(matrix<S, R, C, O, MR, MC>&) -> ref<matrix<S>>;
|
||||
|
||||
template<typename Ref, int R, int C, bool I>
|
||||
ref(block<Ref, R, C, I>& b) -> ref<Ref>;
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
ref(matrix<S, R, C, O, MR, MC> const&) -> ref<matrix<S> const>;
|
||||
|
||||
template<typename Ref, int R, int C, bool I>
|
||||
ref(block<Ref, R, C, I> const& b) -> ref<Ref const>;
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
bool operator==(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
return lhs.base() == rhs.base();
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
bool operator!=(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
return lhs.base() != rhs.base();
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto operator+(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
-> decltype(lhs.base() + rhs.base())
|
||||
{
|
||||
return lhs.base() + rhs.base();
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto operator+=(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
-> decltype(lhs.base() += rhs.base())
|
||||
{
|
||||
return lhs.base() += rhs.base();
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto operator-(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
return lhs.base() - rhs.base();
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto operator-=(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
-> decltype(lhs.base() -= rhs.base())
|
||||
{
|
||||
return lhs.base() -= rhs.base();
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto operator*(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
return lhs.base() * rhs.base();
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto operator*=(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
-> decltype(lhs.base() *= rhs.base())
|
||||
{
|
||||
return lhs.base() *= rhs.base();
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto operator*(ref<A, O, S> lhs,
|
||||
std::convertible_to<typename A::value_type> auto s)
|
||||
{
|
||||
return lhs.base() * s;
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto operator*(std::convertible_to<typename A::value_type> auto s,
|
||||
ref<A, O, S> rhs)
|
||||
{
|
||||
return s * rhs.base();
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto operator/(ref<A, O, S> lhs,
|
||||
std::convertible_to<typename A::value_type> auto s)
|
||||
{
|
||||
return lhs.base() / s;
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto dot(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
return lhs.base().dot(rhs.base());
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto min(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
-> decltype(lhs.base().cwiseMin(rhs.base()))
|
||||
{
|
||||
return lhs.base().cwiseMin(rhs.base());
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto min(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
|
||||
-> decltype(lhs.base().cwiseMin(s))
|
||||
{
|
||||
return lhs.base().cwiseMin(s);
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto min(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs)
|
||||
-> decltype(rhs.base().cwiseMin(s))
|
||||
{
|
||||
return rhs.base().cwiseMin(s);
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto max(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
-> decltype(lhs.base().cwiseMax(rhs.base()))
|
||||
{
|
||||
return lhs.base().cwiseMax(rhs.base());
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto max(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
|
||||
-> decltype(lhs.base().cwiseMax(s))
|
||||
{
|
||||
return lhs.base().cwiseMax(s);
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto max(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs)
|
||||
-> decltype(rhs.base().cwiseMax(s))
|
||||
{
|
||||
return rhs.base().cwiseMax(s);
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto mul(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
-> decltype(lhs.base().cwiseProduct(rhs.base()))
|
||||
{
|
||||
return lhs.base().cwiseProduct(rhs.base());
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto mul(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
|
||||
-> decltype(lhs * s)
|
||||
{
|
||||
return lhs * s;
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto mul(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs)
|
||||
-> decltype(s * rhs)
|
||||
{
|
||||
return s * rhs;
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto div(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
-> decltype(lhs.base().cwiseQuotient(rhs.base()))
|
||||
{
|
||||
return lhs.base().cwiseQuotient(rhs.base());
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto div(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
|
||||
-> decltype(lhs / s)
|
||||
{
|
||||
return lhs / s;
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto inverse(ref<A, O, S> lhs) -> decltype(lhs.base().inverse())
|
||||
{
|
||||
return lhs.base().inverse();
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto cross(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
-> decltype(lhs.base().cross(rhs.base()))
|
||||
{
|
||||
return lhs.base().cross(rhs.base());
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
// Convert entity/eigen types to a proper ref so we can write less function
|
||||
// overloads
|
||||
template<typename T> struct generalize;
|
||||
|
||||
template<typename T>
|
||||
requires(std::is_arithmetic_v<std::remove_cvref_t<T>>)
|
||||
struct generalize<T>
|
||||
{
|
||||
using type = std::remove_cvref_t<T>;
|
||||
};
|
||||
|
||||
template<typename T> using generalize_t = typename generalize<T>::type;
|
||||
|
||||
template<concepts::entity T> struct generalize<T>
|
||||
{
|
||||
static constexpr bool is_const = std::is_const_v<T>;
|
||||
using base = matrix<typename T::value_type,
|
||||
T::RowsAtCompileTime,
|
||||
T::ColsAtCompileTime,
|
||||
T::storage_order>;
|
||||
using type = std::conditional_t<is_const, ref<base const>, ref<base>>;
|
||||
};
|
||||
|
||||
template<typename T, int O, typename S> struct generalize<ref<T, O, S>>
|
||||
{
|
||||
using type = ref<T, O, S>;
|
||||
};
|
||||
|
||||
template<typename T, int O, typename S> struct generalize<ref<T, O, S> const>
|
||||
{
|
||||
using type = ref<T, O, S>;
|
||||
};
|
||||
|
||||
template<concepts::entity T> typename T::parent& base_of(T& a)
|
||||
{
|
||||
return a.base();
|
||||
}
|
||||
|
||||
template<concepts::entity T> typename T::parent const& base_of(T const& a)
|
||||
{
|
||||
return a.base();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T base_of(T a)
|
||||
requires(std::is_arithmetic_v<T>)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
#if !defined(ROTGEN_FORCE_DYNAMIC)
|
||||
template<concepts::eigen_compatible T> struct generalize<T>
|
||||
{
|
||||
static constexpr bool is_const = std::is_const_v<T>;
|
||||
using concrete_type = decltype(std::declval<T>().eval());
|
||||
using base = matrix<typename T::Scalar,
|
||||
T::RowsAtCompileTime,
|
||||
T::ColsAtCompileTime,
|
||||
concrete_type::Options & 1>;
|
||||
using type = std::conditional_t<is_const, ref<base const>, ref<base>>;
|
||||
};
|
||||
|
||||
template<concepts::eigen_compatible T> auto const& base_of(T const& a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
template<concepts::eigen_compatible T> auto& base_of(T& a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#include <rotgen/container/ref/functions.hpp>
|
||||
#include <rotgen/container/ref/generalize.hpp>
|
||||
|
|
|
|||
353
include/rotgen/container/ref/dynamic.hpp
Normal file
353
include/rotgen/container/ref/dynamic.hpp
Normal file
|
|
@ -0,0 +1,353 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(ROTGEN_FORCE_DYNAMIC)
|
||||
#include <Eigen/Dense>
|
||||
#endif
|
||||
|
||||
#include <rotgen/detail/accept_as_ref.hpp>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
template<typename T, int Options, typename Stride>
|
||||
class ref : private map<T, Options, Stride>
|
||||
{
|
||||
public:
|
||||
using parent = map<T, Options, Stride>;
|
||||
using referee = std::remove_const_t<T>;
|
||||
using value_type = typename referee::value_type;
|
||||
using rotgen_tag = void;
|
||||
using rotgen_ref_tag = void;
|
||||
|
||||
static constexpr int storage_order = referee::storage_order;
|
||||
static constexpr int RowsAtCompileTime = referee::RowsAtCompileTime;
|
||||
static constexpr int ColsAtCompileTime = referee::ColsAtCompileTime;
|
||||
static constexpr int MaxRowsAtCompileTime = referee::MaxRowsAtCompileTime;
|
||||
static constexpr int MaxColsAtCompileTime = referee::MaxColsAtCompileTime;
|
||||
static constexpr bool IsRowMajor = referee::IsRowMajor;
|
||||
static constexpr bool IsVectorAtCompileTime =
|
||||
referee::IsVectorAtCompileTime;
|
||||
static constexpr bool is_immutable = std::is_const_v<T>;
|
||||
|
||||
static constexpr int InnerStrideAtCompileTime =
|
||||
parent::InnerStrideAtCompileTime;
|
||||
static constexpr int OuterStrideAtCompileTime =
|
||||
parent::OuterStrideAtCompileTime;
|
||||
|
||||
static constexpr bool may_map_object =
|
||||
(Stride::InnerStrideAtCompileTime == 0 ||
|
||||
Stride::InnerStrideAtCompileTime == 1 ||
|
||||
Stride::InnerStrideAtCompileTime == Dynamic) &&
|
||||
(referee::IsVectorAtCompileTime ||
|
||||
Stride::OuterStrideAtCompileTime == 0 ||
|
||||
Stride::OuterStrideAtCompileTime == Dynamic ||
|
||||
Stride::OuterStrideAtCompileTime == referee::InnerSizeAtCompileTime ||
|
||||
referee::InnerSizeAtCompileTime == Dynamic);
|
||||
|
||||
// Access to values
|
||||
using parent::operator();
|
||||
using parent::operator[];
|
||||
|
||||
// Size related functions
|
||||
using parent::cols;
|
||||
using parent::data;
|
||||
using parent::innerStride;
|
||||
using parent::outerStride;
|
||||
using parent::rows;
|
||||
using parent::size;
|
||||
|
||||
// Aliasing handling
|
||||
using parent::evaluate;
|
||||
using parent::noalias;
|
||||
|
||||
// Reductions
|
||||
using parent::lpNorm;
|
||||
using parent::maxCoeff;
|
||||
using parent::mean;
|
||||
using parent::minCoeff;
|
||||
using parent::norm;
|
||||
using parent::prod;
|
||||
using parent::squaredNorm;
|
||||
using parent::sum;
|
||||
using parent::trace;
|
||||
|
||||
// Arithmetic
|
||||
using parent::cwiseAbs;
|
||||
using parent::cwiseAbs2;
|
||||
using parent::cwiseInverse;
|
||||
using parent::cwiseSqrt;
|
||||
|
||||
// Shape modifications
|
||||
using parent::adjoint;
|
||||
using parent::conjugate;
|
||||
using parent::normalized;
|
||||
using parent::transpose;
|
||||
|
||||
// In-place Shape modifications
|
||||
using parent::adjointInPlace;
|
||||
using parent::normalize;
|
||||
using parent::transposeInPlace;
|
||||
|
||||
// Generators
|
||||
using parent::Constant;
|
||||
using parent::Identity;
|
||||
using parent::Ones;
|
||||
using parent::Random;
|
||||
using parent::setConstant;
|
||||
using parent::setIdentity;
|
||||
using parent::setOnes;
|
||||
using parent::setRandom;
|
||||
using parent::setZero;
|
||||
using parent::Zero;
|
||||
|
||||
using parent::operator=;
|
||||
|
||||
template<typename RO, int OO, typename SO>
|
||||
auto qr_solve(ref<RO, OO, SO> rhs) const
|
||||
{
|
||||
return parent::qr_solve(rhs.base());
|
||||
};
|
||||
|
||||
using stride_type = typename parent::stride_type;
|
||||
|
||||
parent const& base() const { return static_cast<parent const&>(*this); }
|
||||
|
||||
parent& base() { return static_cast<parent&>(*this); }
|
||||
|
||||
parent const& as_map() const { return base(); }
|
||||
|
||||
parent& as_map() { return base(); }
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
requires(detail::accept_as_ref<ref, matrix<S, R, C, O, MR, MC>>)
|
||||
ref(matrix<S, R, C, O, MR, MC>& m) : parent(detail::postpone{})
|
||||
{
|
||||
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, m);
|
||||
assert(correct_ref_setup);
|
||||
}
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
requires(is_immutable &&
|
||||
detail::same_scalar<ref, matrix<S, R, C, O, MR, MC>> &&
|
||||
(detail::accept_as_ref<ref, matrix<S, R, C, O, MR, MC>> ||
|
||||
may_map_object))
|
||||
ref(matrix<S, R, C, O, MR, MC> const& m) : parent(detail::postpone{})
|
||||
{
|
||||
if (!detail::validate_ref(*this, m))
|
||||
{
|
||||
potential_local_copy = m;
|
||||
detail::validate_ref(*this, potential_local_copy);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Ref, int R, int C, bool I>
|
||||
requires(detail::accept_as_ref<ref, block<Ref, R, C, I>>)
|
||||
ref(block<Ref, R, C, I>&& b) : parent(detail::postpone{})
|
||||
{
|
||||
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
|
||||
assert(correct_ref_setup);
|
||||
}
|
||||
|
||||
template<typename Ref, int R, int C, bool I>
|
||||
requires(detail::accept_as_ref<ref, block<Ref, R, C, I>>)
|
||||
ref(block<Ref, R, C, I>& b) : parent(detail::postpone{})
|
||||
{
|
||||
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
|
||||
assert(correct_ref_setup);
|
||||
}
|
||||
|
||||
template<typename Ref, int R, int C, bool I>
|
||||
requires(is_immutable && detail::same_scalar<ref, block<Ref, R, C, I>> &&
|
||||
(detail::accept_as_ref<ref, block<Ref, R, C, I>> ||
|
||||
may_map_object))
|
||||
ref(block<Ref, R, C, I> const& b) : parent(detail::postpone{})
|
||||
{
|
||||
if (!detail::validate_ref(*this, b))
|
||||
{
|
||||
potential_local_copy = b;
|
||||
detail::validate_ref(*this, potential_local_copy);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Ref, int O, typename S>
|
||||
requires(detail::accept_as_ref<ref, map<Ref, O, S>>)
|
||||
ref(map<Ref, O, S>& b) : parent(detail::postpone{})
|
||||
{
|
||||
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
|
||||
assert(correct_ref_setup);
|
||||
}
|
||||
|
||||
template<typename Ref, int O, typename S>
|
||||
requires(is_immutable && detail::same_scalar<ref, map<Ref, O, S>> &&
|
||||
(detail::accept_as_ref<ref, map<Ref, O, S>> || may_map_object))
|
||||
ref(map<Ref, O, S> const& b) : parent(detail::postpone{})
|
||||
{
|
||||
if (!detail::validate_ref(*this, b))
|
||||
{
|
||||
potential_local_copy = b;
|
||||
detail::validate_ref(*this, potential_local_copy);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TT, int OO, typename SS>
|
||||
requires(detail::accept_as_ref<ref, ref<TT, OO, SS>>)
|
||||
ref(ref<TT, OO, SS>& b) : parent(detail::postpone{})
|
||||
{
|
||||
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
|
||||
assert(correct_ref_setup);
|
||||
}
|
||||
|
||||
template<typename TT, int OO, typename SS>
|
||||
requires(is_immutable && detail::same_scalar<ref, ref<TT, OO, SS>> &&
|
||||
(detail::accept_as_ref<ref, ref<TT, OO, SS>> || may_map_object))
|
||||
ref(ref<TT, OO, SS> const& b) : parent(detail::postpone{})
|
||||
{
|
||||
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
|
||||
assert(correct_ref_setup);
|
||||
}
|
||||
|
||||
ref(parent& m) : parent(m.data(), m.rows(), m.cols()) {}
|
||||
|
||||
ref(parent const& m)
|
||||
requires(is_immutable)
|
||||
: parent(m.data(), m.rows(), m.cols())
|
||||
{
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, ref const& r)
|
||||
{
|
||||
return os << r.base();
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, format<ref> const& r)
|
||||
{
|
||||
return os << format{r.matrix_.base(), r.format_};
|
||||
}
|
||||
|
||||
private:
|
||||
referee potential_local_copy;
|
||||
};
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
ref(matrix<S, R, C, O, MR, MC>&) -> ref<matrix<S>>;
|
||||
|
||||
template<typename Ref, int R, int C, bool I>
|
||||
ref(block<Ref, R, C, I>& b) -> ref<Ref>;
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
ref(matrix<S, R, C, O, MR, MC> const&) -> ref<matrix<S> const>;
|
||||
|
||||
template<typename Ref, int R, int C, bool I>
|
||||
ref(block<Ref, R, C, I> const& b) -> ref<Ref const>;
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto operator+(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
-> decltype(lhs.base() + rhs.base())
|
||||
{
|
||||
return lhs.base() + rhs.base();
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto operator-(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
return lhs.base() - rhs.base();
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto operator*(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
return lhs.base() * rhs.base();
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto operator*(ref<A, O, S> lhs,
|
||||
std::convertible_to<typename A::value_type> auto s)
|
||||
{
|
||||
return lhs.base() * s;
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto operator/(ref<A, O, S> lhs,
|
||||
std::convertible_to<typename A::value_type> auto s)
|
||||
{
|
||||
return lhs.base() / s;
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto min(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
-> decltype(lhs.base().cwiseMin(rhs.base()))
|
||||
{
|
||||
return lhs.base().cwiseMin(rhs.base());
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto min(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
|
||||
-> decltype(lhs.base().cwiseMin(s))
|
||||
{
|
||||
return lhs.base().cwiseMin(s);
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto min(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs)
|
||||
-> decltype(rhs.base().cwiseMin(s))
|
||||
{
|
||||
return rhs.base().cwiseMin(s);
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto max(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
-> decltype(lhs.base().cwiseMax(rhs.base()))
|
||||
{
|
||||
return lhs.base().cwiseMax(rhs.base());
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto max(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
|
||||
-> decltype(lhs.base().cwiseMax(s))
|
||||
{
|
||||
return lhs.base().cwiseMax(s);
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto max(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs)
|
||||
-> decltype(rhs.base().cwiseMax(s))
|
||||
{
|
||||
return rhs.base().cwiseMax(s);
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto mul(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
-> decltype(lhs.base().cwiseProduct(rhs.base()))
|
||||
{
|
||||
return lhs.base().cwiseProduct(rhs.base());
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto div(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
-> decltype(lhs.base().cwiseQuotient(rhs.base()))
|
||||
{
|
||||
return lhs.base().cwiseQuotient(rhs.base());
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto inverse(ref<A, O, S> lhs) -> decltype(lhs.base().inverse())
|
||||
{
|
||||
return lhs.base().inverse();
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto cross(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
-> decltype(lhs.base().cross(rhs.base()))
|
||||
{
|
||||
return lhs.base().cross(rhs.base());
|
||||
}
|
||||
}
|
||||
397
include/rotgen/container/ref/fixed.hpp
Normal file
397
include/rotgen/container/ref/fixed.hpp
Normal file
|
|
@ -0,0 +1,397 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/detail/helpers.hpp>
|
||||
|
||||
#include <Eigen/Dense>
|
||||
#include <type_traits>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename T, int Options, typename Stride> struct compile_ref;
|
||||
|
||||
template<typename Scalar,
|
||||
int Rows,
|
||||
int Cols,
|
||||
int Opts,
|
||||
int MaxRows,
|
||||
int MaxCols,
|
||||
int Options,
|
||||
typename Stride>
|
||||
struct compile_ref<matrix<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>,
|
||||
Options,
|
||||
Stride>
|
||||
{
|
||||
using base = Eigen::Matrix<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>;
|
||||
using type = Eigen::Ref<base, Options, Stride>;
|
||||
};
|
||||
|
||||
template<typename Scalar,
|
||||
int Rows,
|
||||
int Cols,
|
||||
int Opts,
|
||||
int MaxRows,
|
||||
int MaxCols,
|
||||
int Options,
|
||||
typename Stride>
|
||||
struct compile_ref<matrix<Scalar, Rows, Cols, Opts, MaxRows, MaxCols> const,
|
||||
Options,
|
||||
Stride>
|
||||
{
|
||||
using base = Eigen::Matrix<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>;
|
||||
using type = Eigen::Ref<base const, Options, Stride>;
|
||||
};
|
||||
|
||||
template<typename T, int Options, typename Stride>
|
||||
using compile_ref_t = typename compile_ref<T, Options, Stride>::type;
|
||||
}
|
||||
|
||||
template<typename T, int Options, typename Stride>
|
||||
class ref : private detail::compile_ref_t<T, Options, Stride>
|
||||
{
|
||||
public:
|
||||
using parent = detail::compile_ref_t<T, Options, Stride>;
|
||||
using referee = std::remove_const_t<T>;
|
||||
using value_type = typename referee::value_type;
|
||||
using rotgen_tag = void;
|
||||
using rotgen_ref_tag = void;
|
||||
using stride_type = Stride;
|
||||
|
||||
static constexpr int RowsAtCompileTime = parent::RowsAtCompileTime;
|
||||
static constexpr int ColsAtCompileTime = parent::ColsAtCompileTime;
|
||||
static constexpr int MaxRowsAtCompileTime = parent::MaxRowsAtCompileTime;
|
||||
static constexpr int MaxColsAtCompileTime = parent::MaxColsAtCompileTime;
|
||||
static constexpr int InnerStrideAtCompileTime =
|
||||
parent::InnerStrideAtCompileTime;
|
||||
static constexpr int OuterStrideAtCompileTime =
|
||||
parent::OuterStrideAtCompileTime;
|
||||
static constexpr bool IsRowMajor = parent::IsRowMajor;
|
||||
static constexpr bool IsVectorAtCompileTime = parent::IsVectorAtCompileTime;
|
||||
static constexpr int storage_order = IsRowMajor ? RowMajor : ColMajor;
|
||||
static constexpr bool is_immutable = std::is_const_v<T>;
|
||||
|
||||
// Access to values
|
||||
using parent::operator();
|
||||
using parent::operator[];
|
||||
|
||||
// Size related functions
|
||||
using parent::cols;
|
||||
using parent::data;
|
||||
using parent::innerStride;
|
||||
using parent::outerStride;
|
||||
using parent::rows;
|
||||
using parent::size;
|
||||
|
||||
// Aliasing handling
|
||||
auto evaluate() const
|
||||
{
|
||||
auto res = static_cast<parent const&>(*this).eval();
|
||||
return as_concrete_type<decltype(res)>(res);
|
||||
}
|
||||
|
||||
auto evaluate()
|
||||
{
|
||||
auto res = static_cast<parent&>(*this).eval();
|
||||
return as_concrete_type<decltype(res)>(res);
|
||||
}
|
||||
|
||||
decltype(auto) noalias() const
|
||||
{
|
||||
if constexpr (use_expression_templates) return base().noalias();
|
||||
else return *this;
|
||||
}
|
||||
|
||||
decltype(auto) noalias()
|
||||
{
|
||||
if constexpr (use_expression_templates) return base().noalias();
|
||||
else return *this;
|
||||
}
|
||||
|
||||
// Numeric functions
|
||||
using parent::cwiseAbs;
|
||||
using parent::cwiseAbs2;
|
||||
using parent::cwiseInverse;
|
||||
using parent::cwiseSqrt;
|
||||
|
||||
// Reductions
|
||||
using parent::lpNorm;
|
||||
using parent::maxCoeff;
|
||||
using parent::mean;
|
||||
using parent::minCoeff;
|
||||
using parent::norm;
|
||||
using parent::prod;
|
||||
using parent::squaredNorm;
|
||||
using parent::sum;
|
||||
using parent::trace;
|
||||
|
||||
// Shape modifications
|
||||
using parent::adjoint;
|
||||
using parent::conjugate;
|
||||
using parent::normalized;
|
||||
using parent::transpose;
|
||||
|
||||
// In-place Shape modifications
|
||||
using parent::adjointInPlace;
|
||||
using parent::normalize;
|
||||
using parent::transposeInPlace;
|
||||
|
||||
// Generators
|
||||
using parent::Constant;
|
||||
using parent::Identity;
|
||||
using parent::Ones;
|
||||
using parent::Random;
|
||||
using parent::setConstant;
|
||||
using parent::setIdentity;
|
||||
using parent::setOnes;
|
||||
using parent::setRandom;
|
||||
using parent::setZero;
|
||||
using parent::Zero;
|
||||
|
||||
auto qr_solve(auto const& rhs) const
|
||||
{
|
||||
// Can't store the result of this .solve has it's some deep E.T
|
||||
return detail::as_concrete_t<
|
||||
decltype(base().colPivHouseholderQr().solve(rhs.base())), matrix>(
|
||||
base().colPivHouseholderQr().solve(rhs.base()));
|
||||
};
|
||||
|
||||
// using parent::operator=;
|
||||
ref& operator=(concepts::entity auto const& e)
|
||||
{
|
||||
base() = e.base();
|
||||
return *this;
|
||||
}
|
||||
|
||||
parent const& base() const { return static_cast<parent const&>(*this); }
|
||||
|
||||
parent& base() { return static_cast<parent&>(*this); }
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
ref(matrix<S, R, C, O, MR, MC>& m)
|
||||
requires(requires { parent(m.base()); })
|
||||
: parent(m.base())
|
||||
{
|
||||
}
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
ref(matrix<S, R, C, O, MR, MC> const& m)
|
||||
requires(requires { parent(m.base()); } && is_immutable)
|
||||
: parent(m.base())
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Ref, int R, int C, bool I>
|
||||
ref(block<Ref, R, C, I>&& b)
|
||||
requires(requires { parent(b.base()); })
|
||||
: parent(b.base())
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Ref, int R, int C, bool I>
|
||||
ref(block<Ref, R, C, I>& b)
|
||||
requires(requires { parent(b.base()); })
|
||||
: parent(b.base())
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Ref, int R, int C, bool I>
|
||||
ref(block<Ref, R, C, I> const& b)
|
||||
requires(requires { parent(b.base()); } && is_immutable)
|
||||
: parent(b.base())
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Ref, int O, typename S>
|
||||
ref(map<Ref, O, S>& m)
|
||||
requires(requires { parent(m.base()); })
|
||||
: parent(m.base())
|
||||
{
|
||||
}
|
||||
|
||||
template<typename Ref, int O, typename S>
|
||||
ref(map<Ref, O, S> const& m)
|
||||
requires(requires { parent(m.base()); } && is_immutable)
|
||||
: parent(m.base())
|
||||
{
|
||||
}
|
||||
|
||||
template<typename TT, int OO, typename SS>
|
||||
ref(ref<TT, OO, SS>& r)
|
||||
requires(requires { parent(r.base()); })
|
||||
: parent(r.base())
|
||||
{
|
||||
}
|
||||
|
||||
template<typename TT, int OO, typename SS>
|
||||
ref(ref<TT, OO, SS> const& r)
|
||||
requires(requires { parent(r.base()); } && is_immutable)
|
||||
: parent(r.base())
|
||||
{
|
||||
}
|
||||
|
||||
ref(parent& m) : parent(m) {}
|
||||
|
||||
ref(parent const& m)
|
||||
requires(is_immutable)
|
||||
: parent(m)
|
||||
{
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, ref const& r)
|
||||
{
|
||||
return os << r.base();
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, format<ref> const& r)
|
||||
{
|
||||
return os << format{r.matrix_.base(), r.format_};
|
||||
}
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
// Deduction Guides
|
||||
//============================================================================
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
ref(matrix<S, R, C, O, MR, MC>&) -> ref<matrix<S>>;
|
||||
|
||||
template<typename Ref, int R, int C, bool I>
|
||||
ref(block<Ref, R, C, I>& b) -> ref<Ref>;
|
||||
|
||||
template<typename S, int R, int C, int O, int MR, int MC>
|
||||
ref(matrix<S, R, C, O, MR, MC> const&) -> ref<matrix<S> const>;
|
||||
|
||||
template<typename Ref, int R, int C, bool I>
|
||||
ref(block<Ref, R, C, I> const& b) -> ref<Ref const>;
|
||||
|
||||
//============================================================================
|
||||
// Operators
|
||||
//============================================================================
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto operator+(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
return detail::concretize<matrix>(lhs.base() + rhs.base());
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto operator-(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
return detail::concretize<matrix>(lhs.base() - rhs.base());
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto operator*(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
return detail::concretize<matrix>(lhs.base() * rhs.base());
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto operator*(ref<A, O, S> lhs,
|
||||
std::convertible_to<typename A::value_type> auto s)
|
||||
{
|
||||
return detail::concretize<matrix>(lhs.base() * s);
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto operator/(ref<A, O, S> lhs,
|
||||
std::convertible_to<typename A::value_type> auto s)
|
||||
{
|
||||
return detail::concretize<matrix>(lhs.base() / s);
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto mul(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
return detail::concretize<matrix>(lhs.base().cwiseProduct(rhs.base()));
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto div(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
return detail::concretize<matrix>(lhs.base().cwiseQuotient(rhs.base()));
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// Functions
|
||||
//============================================================================
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto min(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
return detail::concretize<matrix>(lhs.base().cwiseMin(rhs.base()));
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto min(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
|
||||
{
|
||||
return detail::concretize<matrix>(lhs.base().cwiseMin(s));
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto min(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs)
|
||||
{
|
||||
return detail::concretize<matrix>(rhs.base().cwiseMin(s));
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto max(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
return detail::concretize<matrix>(lhs.base().cwiseMax(rhs.base()));
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto max(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
|
||||
{
|
||||
return detail::concretize<matrix>(lhs.base().cwiseMax(s));
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto max(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs)
|
||||
{
|
||||
return detail::concretize<matrix>(rhs.base().cwiseMax(s));
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S> auto inverse(ref<A, O, S> lhs)
|
||||
{
|
||||
return detail::concretize<matrix>(lhs.base().inverse());
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto cross(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
-> decltype(lhs.base().cross(rhs.base()))
|
||||
{
|
||||
return detail::concretize<matrix>(lhs.base().cross(rhs.base()));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
// Convert entity/eigen types to a proper ref so we can write less function
|
||||
// overloads
|
||||
template<typename T> struct generalize;
|
||||
|
||||
template<concepts::eigen_compatible T> struct generalize<T>
|
||||
{
|
||||
static constexpr bool is_const = std::is_const_v<T>;
|
||||
using concrete_type = decltype(std::declval<T>().eval());
|
||||
using base = matrix<typename T::Scalar,
|
||||
T::RowsAtCompileTime,
|
||||
T::ColsAtCompileTime,
|
||||
concrete_type::Options & 1>;
|
||||
using type = std::conditional_t<is_const, ref<base const>, ref<base>>;
|
||||
};
|
||||
|
||||
template<concepts::eigen_compatible T> auto const& base_of(T const& a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
template<concepts::eigen_compatible T> auto& base_of(T& a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
}
|
||||
88
include/rotgen/container/ref/functions.hpp
Normal file
88
include/rotgen/container/ref/functions.hpp
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
bool operator==(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
return lhs.base() == rhs.base();
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
bool operator!=(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
return lhs.base() != rhs.base();
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto operator+=(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
lhs.base() += rhs.base();
|
||||
return lhs;
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto operator-=(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
lhs.base() -= rhs.base();
|
||||
return lhs;
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto operator*=(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
lhs.base() *= rhs.base();
|
||||
return lhs;
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto operator/=(ref<A, O, S> lhs,
|
||||
std::convertible_to<typename A::value_type> auto s)
|
||||
{
|
||||
lhs.base() /= s;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto operator*(std::convertible_to<typename A::value_type> auto s,
|
||||
ref<A, O, S> rhs)
|
||||
{
|
||||
return rhs * s;
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S, typename B, int P, typename T>
|
||||
auto dot(ref<A, O, S> lhs, ref<B, P, T> rhs)
|
||||
{
|
||||
return lhs.base().dot(rhs.base());
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto mul(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
|
||||
-> decltype(lhs * s)
|
||||
{
|
||||
return lhs * s;
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto mul(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs)
|
||||
-> decltype(s * rhs)
|
||||
{
|
||||
return s * rhs;
|
||||
}
|
||||
|
||||
template<typename A, int O, typename S>
|
||||
auto div(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
|
||||
-> decltype(lhs / s)
|
||||
{
|
||||
return lhs / s;
|
||||
}
|
||||
}
|
||||
65
include/rotgen/container/ref/generalize.hpp
Normal file
65
include/rotgen/container/ref/generalize.hpp
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
//-------------------------------------------------------------------------------------------
|
||||
// Convert entity/eigen types to a proper ref so we can write less function
|
||||
// overloads
|
||||
|
||||
template<typename T> struct generalize;
|
||||
|
||||
template<typename T>
|
||||
requires(std::is_arithmetic_v<std::remove_cvref_t<T>>)
|
||||
struct generalize<T>
|
||||
{
|
||||
using type = std::remove_cvref_t<T>;
|
||||
};
|
||||
|
||||
template<typename T> using generalize_t = typename generalize<T>::type;
|
||||
|
||||
template<concepts::entity T> struct generalize<T>
|
||||
{
|
||||
static constexpr bool is_const = std::is_const_v<T>;
|
||||
using base = matrix<typename T::value_type,
|
||||
T::RowsAtCompileTime,
|
||||
T::ColsAtCompileTime,
|
||||
T::storage_order>;
|
||||
using type = std::conditional_t<is_const, ref<base const>, ref<base>>;
|
||||
};
|
||||
|
||||
template<typename T, int O, typename S> struct generalize<ref<T, O, S>>
|
||||
{
|
||||
using type = ref<T, O, S>;
|
||||
};
|
||||
|
||||
template<typename T, int O, typename S> struct generalize<ref<T, O, S> const>
|
||||
{
|
||||
using type = ref<T, O, S>;
|
||||
};
|
||||
|
||||
template<concepts::entity T> typename T::parent& base_of(T& a)
|
||||
{
|
||||
return a.base();
|
||||
}
|
||||
|
||||
template<concepts::entity T> typename T::parent const& base_of(T const& a)
|
||||
{
|
||||
return a.base();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T base_of(T a)
|
||||
requires(std::is_arithmetic_v<T>)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
|
@ -7,76 +7,10 @@
|
|||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/concepts.hpp>
|
||||
#include <rotgen/config.hpp>
|
||||
|
||||
#if !defined(ROTGEN_FORCE_DYNAMIC)
|
||||
#include <Eigen/Dense>
|
||||
#endif
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
#if !defined(ROTGEN_FORCE_DYNAMIC)
|
||||
using stride = Eigen::Stride<-1, -1>;
|
||||
#if defined(ROTGEN_FORCE_DYNAMIC)
|
||||
#include <rotgen/container/strides/dynamic.hpp>
|
||||
#else
|
||||
struct stride
|
||||
{
|
||||
static constexpr bool is_dynamic = true;
|
||||
|
||||
stride() : outer_(-1), inner_(1) {}
|
||||
|
||||
stride(Index s, Index i) : outer_(s), inner_(i) {}
|
||||
|
||||
Index inner() const { return inner_; }
|
||||
|
||||
Index outer() const { return outer_; }
|
||||
|
||||
private:
|
||||
Index outer_;
|
||||
Index inner_;
|
||||
};
|
||||
#include <rotgen/container/strides/fixed.hpp>
|
||||
#endif
|
||||
|
||||
template<Index Value = Dynamic> struct inner_stride : stride
|
||||
{
|
||||
static constexpr bool is_dynamic = Value == Dynamic;
|
||||
|
||||
inner_stride() : stride(-1, Value) {}
|
||||
|
||||
inner_stride(Index v) : stride(0, v) {}
|
||||
};
|
||||
|
||||
template<Index Value = Dynamic> struct outer_stride : stride
|
||||
{
|
||||
static constexpr bool is_dynamic = Value == Dynamic;
|
||||
|
||||
outer_stride() : stride(Value, 0) {}
|
||||
|
||||
outer_stride(Index v) : stride(v, 0) {}
|
||||
};
|
||||
|
||||
inner_stride(Index) -> inner_stride<Dynamic>;
|
||||
outer_stride(Index) -> outer_stride<Dynamic>;
|
||||
|
||||
template<int Order> stride strides(Index r, Index c)
|
||||
{
|
||||
if constexpr (Order == RowMajor) return {c, 1};
|
||||
else return {r, 1};
|
||||
}
|
||||
|
||||
template<int Order> stride strides(stride const& original, Index, Index)
|
||||
{
|
||||
return original;
|
||||
}
|
||||
|
||||
template<int Order, Index N>
|
||||
stride strides(outer_stride<N> const& original, Index r, Index c)
|
||||
{
|
||||
if constexpr (N == 0) return stride{Order == ColMajor ? r : c, 1};
|
||||
else return {original.outer(), 1};
|
||||
}
|
||||
|
||||
template<concepts::entity E> auto strides(E const& e)
|
||||
{
|
||||
return strides<E::storage_order>(e.rows(), e.cols());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
84
include/rotgen/container/strides/dynamic.hpp
Normal file
84
include/rotgen/container/strides/dynamic.hpp
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/concepts.hpp>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
template<int Outer = 0, int Inner = 0> struct stride
|
||||
{
|
||||
static constexpr int InnerStrideAtCompileTime = Inner;
|
||||
static constexpr int OuterStrideAtCompileTime = Outer;
|
||||
|
||||
constexpr stride()
|
||||
requires(Inner != Dynamic && Outer != Dynamic)
|
||||
: outer_(Outer), inner_(Inner)
|
||||
{
|
||||
}
|
||||
|
||||
stride(Index o, Index i) : outer_(o), inner_(i) {}
|
||||
|
||||
constexpr Index outer() const { return outer_; }
|
||||
|
||||
constexpr Index inner() const { return inner_; }
|
||||
|
||||
protected:
|
||||
Index outer_;
|
||||
Index inner_;
|
||||
};
|
||||
|
||||
template<int Value = Dynamic> struct inner_stride : stride<0, Value>
|
||||
{
|
||||
using parent = stride<0, Value>;
|
||||
|
||||
inner_stride() : parent() {}
|
||||
|
||||
inner_stride(int v) : parent(0, v) {}
|
||||
};
|
||||
|
||||
template<int Value = Dynamic> struct outer_stride : stride<Value, 0>
|
||||
{
|
||||
using parent = stride<Value, 0>;
|
||||
|
||||
outer_stride() : parent() {}
|
||||
|
||||
outer_stride(int v) : parent(v, 0) {}
|
||||
};
|
||||
|
||||
using dynamic_stride = stride<-1, -1>;
|
||||
|
||||
template<int Order> dynamic_stride strides(Index r, Index c)
|
||||
{
|
||||
if constexpr (Order == RowMajor) return {c, 1};
|
||||
else return {r, 1};
|
||||
}
|
||||
|
||||
template<int Order, concepts::entity E> dynamic_stride strides(E const& e)
|
||||
{
|
||||
return strides<Order>(e.rows(), e.cols());
|
||||
}
|
||||
|
||||
template<int Order, int O, int I>
|
||||
dynamic_stride strides(stride<O, I> const& original, Index, Index)
|
||||
{
|
||||
return {original.outer(), original.inner()};
|
||||
}
|
||||
|
||||
template<int Order, int N>
|
||||
dynamic_stride strides(outer_stride<N> const& original, Index r, Index c)
|
||||
{
|
||||
if constexpr (N == 0) return {Order == ColMajor ? r : c, 1};
|
||||
else return {original.outer(), 1};
|
||||
}
|
||||
|
||||
template<concepts::entity E> auto strides(E const& e)
|
||||
{
|
||||
return strides<E::storage_order>(e.rows(), e.cols());
|
||||
}
|
||||
}
|
||||
40
include/rotgen/container/strides/fixed.hpp
Normal file
40
include/rotgen/container/strides/fixed.hpp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/concepts.hpp>
|
||||
|
||||
#include <Eigen/Dense>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
template<int Outer, int Inner> struct stride : Eigen::Stride<Outer, Inner>
|
||||
{
|
||||
using parent = Eigen::Stride<Outer, Inner>;
|
||||
using parent::parent;
|
||||
};
|
||||
|
||||
template<int Value = Eigen::Dynamic>
|
||||
struct inner_stride : Eigen::InnerStride<Value>
|
||||
{
|
||||
using parent = Eigen::InnerStride<Value>;
|
||||
using parent::parent;
|
||||
};
|
||||
|
||||
template<int Value = Eigen::Dynamic>
|
||||
struct outer_stride : Eigen::OuterStride<Value>
|
||||
{
|
||||
using parent = Eigen::OuterStride<Value>;
|
||||
using parent::parent;
|
||||
};
|
||||
|
||||
inner_stride(int) -> inner_stride<-1>;
|
||||
outer_stride(int) -> outer_stride<-1>;
|
||||
|
||||
using dynamic_stride = stride<-1, -1>;
|
||||
}
|
||||
160
include/rotgen/detail/accept_as_ref.hpp
Normal file
160
include/rotgen/detail/accept_as_ref.hpp
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <concepts>
|
||||
|
||||
namespace rotgen::detail
|
||||
{
|
||||
// We split each sub-check into its own concept to improve
|
||||
// diagnostic messages
|
||||
template<typename Ref, typename Input>
|
||||
concept same_scalar =
|
||||
std::same_as<typename Ref::value_type, typename Input::value_type>;
|
||||
|
||||
template<typename Ref, typename Input>
|
||||
concept any_is_vector =
|
||||
Ref::IsVectorAtCompileTime || Input::IsVectorAtCompileTime;
|
||||
|
||||
template<typename Ref, typename Input>
|
||||
concept compatible_storage =
|
||||
any_is_vector<Ref, Input> || (Ref::storage_order == Input::storage_order);
|
||||
|
||||
template<typename Ref, typename Input>
|
||||
concept compatible_inner_stride =
|
||||
(Ref::InnerStrideAtCompileTime == rotgen::Dynamic) ||
|
||||
(Ref::InnerStrideAtCompileTime == Input::InnerStrideAtCompileTime) ||
|
||||
(Ref::InnerStrideAtCompileTime == 0 &&
|
||||
Input::InnerStrideAtCompileTime == 1);
|
||||
|
||||
template<typename Ref, typename Input>
|
||||
concept compatible_outer_stride =
|
||||
any_is_vector<Ref, Input> ||
|
||||
(Ref::OuterStrideAtCompileTime == rotgen::Dynamic) ||
|
||||
(Ref::OuterStrideAtCompileTime == Input::OuterStrideAtCompileTime);
|
||||
|
||||
// Check what we can actually pass to ref<>
|
||||
template<typename Ref, typename Input>
|
||||
concept accept_as_ref =
|
||||
same_scalar<Ref, Input> && compatible_storage<Ref, Input> &&
|
||||
compatible_inner_stride<Ref, Input> && compatible_outer_stride<Ref, Input>;
|
||||
|
||||
// Local helpersto compute some strides related runtime values
|
||||
constexpr Index proper_inner_stride(Index inner)
|
||||
{
|
||||
return inner == 0 ? 1 : inner;
|
||||
}
|
||||
|
||||
constexpr Index proper_outer_stride(Index inner,
|
||||
Index outer,
|
||||
Index rows,
|
||||
Index cols,
|
||||
bool isVectorAtCompileTime,
|
||||
bool isRowMajor)
|
||||
{
|
||||
return outer == 0 ? isVectorAtCompileTime ? inner * rows * cols
|
||||
: isRowMajor ? inner * cols
|
||||
: inner * rows
|
||||
: outer;
|
||||
}
|
||||
|
||||
// Helper used to runtime validate some properties of ref adn tells ref
|
||||
// if a local copy and reconstruction needs to be done
|
||||
template<typename Ref, typename Input> bool validate_ref(Ref& ref, Input& in)
|
||||
{
|
||||
using stride_type = typename Ref::stride_type;
|
||||
using parent = typename Ref::parent;
|
||||
using map_base = typename parent::parent;
|
||||
|
||||
auto rows = in.rows();
|
||||
auto cols = in.cols();
|
||||
|
||||
if (Ref::RowsAtCompileTime == 1)
|
||||
{
|
||||
assert(in.rows() == 1 || in.cols() == 1);
|
||||
rows = 1;
|
||||
cols = in.size();
|
||||
}
|
||||
else if (Ref::ColsAtCompileTime == 1)
|
||||
{
|
||||
assert(in.rows() == 1 || in.cols() == 1);
|
||||
rows = in.size();
|
||||
cols = 1;
|
||||
}
|
||||
|
||||
// Verify that the sizes are valid.
|
||||
assert((Ref::RowsAtCompileTime == Dynamic) ||
|
||||
(Ref::RowsAtCompileTime == rows));
|
||||
assert((Ref::ColsAtCompileTime == Dynamic) ||
|
||||
(Ref::ColsAtCompileTime == cols));
|
||||
|
||||
// Swap stride if we are a vector and we changed rows as such
|
||||
bool transpose = Ref::IsVectorAtCompileTime && (rows != in.rows());
|
||||
|
||||
// Swap stride if storage ordder doesn't match
|
||||
constexpr bool row_major = Ref::IsRowMajor;
|
||||
constexpr bool input_row_major = Input::IsRowMajor;
|
||||
constexpr bool storage_differs = (row_major != input_row_major);
|
||||
|
||||
bool swap_stride = (transpose != storage_differs);
|
||||
|
||||
// Determine expr's actual strides, resolving any defaults if zero.
|
||||
Index inner_actual = proper_inner_stride(in.innerStride());
|
||||
Index outer_actual =
|
||||
proper_outer_stride(inner_actual, in.outerStride(), in.rows(), in.cols(),
|
||||
Input::IsVectorAtCompileTime, input_row_major);
|
||||
|
||||
bool row_vector = (rows == 1);
|
||||
bool col_vector = (cols == 1);
|
||||
|
||||
// Adapt inner stride based on row/col vector status
|
||||
Index inner_stride =
|
||||
((!row_major && row_vector) || (row_major && col_vector))
|
||||
? (stride_type::InnerStrideAtCompileTime > 0
|
||||
? stride_type::InnerStrideAtCompileTime
|
||||
: 1)
|
||||
: swap_stride ? outer_actual
|
||||
: inner_actual;
|
||||
|
||||
// Adapt outer stride based on row/col vector status
|
||||
Index outer_stride =
|
||||
((!row_major && col_vector) || (row_major && row_vector))
|
||||
? (stride_type::OuterStrideAtCompileTime > 0
|
||||
? stride_type::OuterStrideAtCompileTime
|
||||
: rows * cols * inner_stride)
|
||||
: swap_stride ? inner_actual
|
||||
: outer_actual;
|
||||
|
||||
// Validate compatibility of strides with compile-time strides
|
||||
bool inner_valid =
|
||||
(stride_type::InnerStrideAtCompileTime == Dynamic) ||
|
||||
(proper_inner_stride(Index(stride_type::InnerStrideAtCompileTime)) ==
|
||||
inner_stride);
|
||||
|
||||
if (!inner_valid) return false;
|
||||
|
||||
bool outer_valid =
|
||||
(stride_type::OuterStrideAtCompileTime == Dynamic) ||
|
||||
(proper_outer_stride(
|
||||
inner_stride, Index(stride_type::OuterStrideAtCompileTime), rows, cols,
|
||||
Ref::IsVectorAtCompileTime != 0, row_major) == outer_stride);
|
||||
|
||||
if (!outer_valid) return false;
|
||||
|
||||
dynamic_stride proper_stride(
|
||||
stride_type::OuterStrideAtCompileTime == 0 ? 1 : outer_stride,
|
||||
stride_type::InnerStrideAtCompileTime == 0 ? 1 : inner_stride);
|
||||
|
||||
auto actual = map_base(in.data(), rows, cols, proper_stride);
|
||||
|
||||
ref.base().base().storage().swap(actual.storage());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -7,8 +7,21 @@
|
|||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/config.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace rotgen::detail
|
||||
{
|
||||
template<typename T> constexpr int static_size()
|
||||
{
|
||||
auto rows = T::RowsAtCompileTime;
|
||||
auto cols = T::ColsAtCompileTime;
|
||||
if (rows == 0 || cols == 0) return 0;
|
||||
if (rows == -1 || cols == -1) return -1;
|
||||
return rows * cols;
|
||||
}
|
||||
|
||||
template<typename EigenType,
|
||||
template<typename, int, int, int, int, int> typename Wrapper>
|
||||
struct as_concrete
|
||||
|
|
@ -26,6 +39,13 @@ namespace rotgen::detail
|
|||
using as_concrete_t =
|
||||
typename as_concrete<std::remove_cvref_t<EigenType>, Wrapper>::type;
|
||||
|
||||
template<template<typename, int, int, int, int, int> typename Wrapper>
|
||||
decltype(auto) concretize(auto const& t)
|
||||
{
|
||||
if constexpr (use_expression_templates) return t;
|
||||
else return as_concrete_t<std::remove_cvref_t<decltype(t)>, Wrapper>(t);
|
||||
}
|
||||
|
||||
template<typename M, typename N>
|
||||
inline constexpr bool has_same_vector_size = []() {
|
||||
// No vector = noo size
|
||||
|
|
@ -42,13 +62,13 @@ namespace rotgen::detail
|
|||
|
||||
template<typename T>
|
||||
using propagate_const =
|
||||
std::conditional_t<T::is_immutable || std::is_const_v<T>,
|
||||
std::add_const_t<T>,
|
||||
T>;
|
||||
std::conditional_t<std::remove_cvref_t<T>::is_immutable ||
|
||||
std::is_const_v<T>,
|
||||
std::add_const_t<std::remove_cvref_t<T>>,
|
||||
std::remove_cvref_t<T>>;
|
||||
|
||||
template<auto M, auto N>
|
||||
inline constexpr auto select_static =
|
||||
(M == rotgen::Dynamic || N == rotgen::Dynamic) ? rotgen::Dynamic : M;
|
||||
inline constexpr auto select_static = (M == -1 || N == -1) ? -1 : M;
|
||||
|
||||
template<typename M1,
|
||||
typename M2,
|
||||
|
|
|
|||
|
|
@ -7,263 +7,13 @@
|
|||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <rotgen/container/matrix/dynamic/impl.hpp>
|
||||
#include <rotgen/container/map/dynamic/impl.hpp>
|
||||
#include <Eigen/Dense>
|
||||
#include <Eigen/Core>
|
||||
#include <rotgen/detail/payload/block.hpp>
|
||||
#include <rotgen/detail/payload/map.hpp>
|
||||
#include <rotgen/detail/payload/matrix.hpp>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
//==================================================================================================
|
||||
// Internal payload - Required 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; }
|
||||
|
||||
void assign(data_type const& mat) { data = mat; }
|
||||
|
||||
void assign(data_type&& mat) { data = std::move(mat); }
|
||||
};
|
||||
|
||||
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; }
|
||||
|
||||
void assign(data_type const& mat) { data = mat; }
|
||||
|
||||
void assign(data_type&& mat) { data = std::move(mat); }
|
||||
};
|
||||
|
||||
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; }
|
||||
|
||||
void assign(data_type const& mat) { data = mat; }
|
||||
|
||||
void assign(data_type&& mat) { data = std::move(mat); }
|
||||
};
|
||||
|
||||
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; }
|
||||
|
||||
void assign(data_type const& mat) { data = mat; }
|
||||
|
||||
void assign(data_type&& mat) { data = std::move(mat); }
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
// Internal payload - Required for cross-referencing from mixed order on map
|
||||
// operators
|
||||
//==================================================================================================
|
||||
struct map_const_impl32_col::payload
|
||||
{
|
||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||
using base_type =
|
||||
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
|
||||
using data_type =
|
||||
Eigen::Map<base_type const, Eigen::Unaligned, stride_type>;
|
||||
|
||||
data_type data;
|
||||
|
||||
payload(data_type const& o) : data(o) {}
|
||||
|
||||
payload(float const* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||
|
||||
payload(float const* ptr, Index r, Index c, stride_type s)
|
||||
: data(ptr, r, c, s)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct map_const_impl32_row::payload
|
||||
{
|
||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||
using base_type =
|
||||
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
|
||||
using data_type =
|
||||
Eigen::Map<base_type const, Eigen::Unaligned, stride_type>;
|
||||
|
||||
data_type data;
|
||||
|
||||
payload(data_type const& o) : data(o) {}
|
||||
|
||||
payload(float const* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||
|
||||
payload(float const* ptr, Index r, Index c, stride_type s)
|
||||
: data(ptr, r, c, s)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct map_impl32_col::payload
|
||||
{
|
||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||
using base_type =
|
||||
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
|
||||
using data_type = Eigen::Map<base_type, Eigen::Unaligned, stride_type>;
|
||||
|
||||
data_type data;
|
||||
|
||||
payload(data_type const& o) : data(o) {}
|
||||
|
||||
payload(float* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||
|
||||
payload(float* ptr, Index r, Index c, stride_type s) : data(ptr, r, c, s) {}
|
||||
};
|
||||
|
||||
struct map_impl32_row::payload
|
||||
{
|
||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||
using base_type =
|
||||
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
|
||||
using data_type = Eigen::Map<base_type, Eigen::Unaligned, stride_type>;
|
||||
|
||||
data_type data;
|
||||
|
||||
payload(data_type const& o) : data(o) {}
|
||||
|
||||
payload(float* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||
|
||||
payload(float* ptr, Index r, Index c, stride_type s) : data(ptr, r, c, s) {}
|
||||
};
|
||||
|
||||
struct map_const_impl64_col::payload
|
||||
{
|
||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||
using base_type =
|
||||
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
|
||||
using data_type =
|
||||
Eigen::Map<base_type const, Eigen::Unaligned, stride_type>;
|
||||
|
||||
data_type data;
|
||||
|
||||
payload(data_type const& o) : data(o) {}
|
||||
|
||||
payload(double const* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||
|
||||
payload(double const* ptr, Index r, Index c, stride_type s)
|
||||
: data(ptr, r, c, s)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct map_const_impl64_row::payload
|
||||
{
|
||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||
using base_type =
|
||||
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
|
||||
using data_type =
|
||||
Eigen::Map<base_type const, Eigen::Unaligned, stride_type>;
|
||||
|
||||
data_type data;
|
||||
|
||||
payload(data_type const& o) : data(o) {}
|
||||
|
||||
payload(double const* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||
|
||||
payload(double const* ptr, Index r, Index c, stride_type s)
|
||||
: data(ptr, r, c, s)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct map_impl64_col::payload
|
||||
{
|
||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||
using base_type =
|
||||
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
|
||||
using data_type = Eigen::Map<base_type, Eigen::Unaligned, stride_type>;
|
||||
|
||||
data_type data;
|
||||
|
||||
payload(data_type const& o) : data(o) {}
|
||||
|
||||
payload(double* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||
|
||||
payload(double* ptr, Index r, Index c, stride_type s) : data(ptr, r, c, s)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct map_impl64_row::payload
|
||||
{
|
||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||
using base_type =
|
||||
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
|
||||
using data_type = Eigen::Map<base_type, Eigen::Unaligned, stride_type>;
|
||||
|
||||
data_type data;
|
||||
|
||||
payload(data_type const& o) : data(o) {}
|
||||
|
||||
payload(double* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||
|
||||
payload(double* ptr, Index r, Index c, stride_type s) : data(ptr, r, c, s)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// IO Formatting paylod
|
||||
struct ioformat::payload
|
||||
{
|
||||
Eigen::IOFormat instance;
|
||||
|
|
|
|||
209
include/rotgen/detail/payload/block.hpp
Normal file
209
include/rotgen/detail/payload/block.hpp
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/container/block/dynamic/impl.hpp>
|
||||
|
||||
#include <Eigen/Core>
|
||||
#include <Eigen/Dense>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <variant>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
struct source_t
|
||||
{
|
||||
};
|
||||
|
||||
struct trans_t
|
||||
{
|
||||
};
|
||||
|
||||
struct map_t
|
||||
{
|
||||
};
|
||||
|
||||
struct matrix_t
|
||||
{
|
||||
};
|
||||
|
||||
//================================================================================================
|
||||
// Template payload implementation
|
||||
//================================================================================================
|
||||
template<typename ScalarType, int StorageOrder, bool IsConst>
|
||||
struct payload_impl
|
||||
{
|
||||
using row_matrix_type = Eigen::
|
||||
Matrix<ScalarType, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
|
||||
using col_matrix_type = Eigen::
|
||||
Matrix<ScalarType, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
|
||||
|
||||
using source_matrix_type =
|
||||
std::conditional_t<StorageOrder == Eigen::RowMajor,
|
||||
row_matrix_type,
|
||||
col_matrix_type>;
|
||||
using trans_matrix_type =
|
||||
std::conditional_t<StorageOrder != Eigen::RowMajor,
|
||||
row_matrix_type,
|
||||
col_matrix_type>;
|
||||
|
||||
template<typename T>
|
||||
using maybe_const = std::conditional_t<IsConst, T const, T>;
|
||||
|
||||
using source_matrix_block_type =
|
||||
Eigen::Block<maybe_const<source_matrix_type>>;
|
||||
using trans_matrix_block_type =
|
||||
Eigen::Block<maybe_const<trans_matrix_type>>;
|
||||
using source_matrix_storage_t =
|
||||
std::pair<source_matrix_block_type, maybe_const<source_matrix_type>*>;
|
||||
using trans_matrix_storage_t =
|
||||
std::pair<trans_matrix_block_type, maybe_const<trans_matrix_type>*>;
|
||||
|
||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||
|
||||
using source_map_type = Eigen::
|
||||
Map<maybe_const<source_matrix_type>, Eigen::Unaligned, stride_type>;
|
||||
using trans_map_type =
|
||||
Eigen::Map<maybe_const<trans_matrix_type>, Eigen::Unaligned, stride_type>;
|
||||
using source_map_block_type = Eigen::Block<maybe_const<source_map_type>>;
|
||||
using trans_map_block_type = Eigen::Block<maybe_const<trans_map_type>>;
|
||||
using source_map_storage_t =
|
||||
std::pair<source_map_block_type, maybe_const<source_map_type>*>;
|
||||
using trans_map_storage_t =
|
||||
std::pair<trans_map_block_type, maybe_const<trans_map_type>*>;
|
||||
|
||||
using data_type = std::variant<source_matrix_storage_t,
|
||||
trans_matrix_storage_t,
|
||||
source_map_storage_t,
|
||||
trans_map_storage_t>;
|
||||
|
||||
data_type data;
|
||||
rotgen::Index abs_i0 = 0;
|
||||
rotgen::Index abs_j0 = 0;
|
||||
rotgen::Index rel_i0 = 0;
|
||||
rotgen::Index rel_j0 = 0;
|
||||
|
||||
template<typename Func> void apply(Func f)
|
||||
{
|
||||
std::visit([&](auto& blk) { return f(blk.first); }, data);
|
||||
}
|
||||
|
||||
template<typename Func> void apply(Func f) const
|
||||
{
|
||||
std::visit([&](auto const& blk) { return f(blk.first); }, data);
|
||||
}
|
||||
|
||||
payload_impl(data_type const& o) : data(o) {}
|
||||
|
||||
payload_impl(auto const& o,
|
||||
rotgen::Index i0,
|
||||
rotgen::Index j0,
|
||||
rotgen::Index ni,
|
||||
rotgen::Index nj,
|
||||
matrix_t const&,
|
||||
source_t const&)
|
||||
: data(source_matrix_storage_t{
|
||||
source_matrix_block_type{o.storage()->data, i0, j0, ni, nj},
|
||||
&o.storage()->data}),
|
||||
abs_i0(i0), abs_j0(j0), rel_i0(i0), rel_j0(j0)
|
||||
{
|
||||
}
|
||||
|
||||
payload_impl(auto const& o,
|
||||
rotgen::Index i0,
|
||||
rotgen::Index j0,
|
||||
rotgen::Index ni,
|
||||
rotgen::Index nj,
|
||||
matrix_t const&,
|
||||
trans_t const&)
|
||||
: data(trans_matrix_storage_t{
|
||||
trans_matrix_block_type{o.storage()->data, i0, j0, ni, nj},
|
||||
&o.storage()->data}),
|
||||
abs_i0(i0), abs_j0(j0), rel_i0(i0), rel_j0(j0)
|
||||
{
|
||||
}
|
||||
|
||||
payload_impl(auto const& o,
|
||||
rotgen::Index i0,
|
||||
rotgen::Index j0,
|
||||
rotgen::Index ni,
|
||||
rotgen::Index nj,
|
||||
map_t const&,
|
||||
source_t const&)
|
||||
: data(source_map_storage_t{
|
||||
source_map_block_type{o.storage()->data, i0, j0, ni, nj},
|
||||
&o.storage()->data}),
|
||||
abs_i0(i0), abs_j0(j0), rel_i0(i0), rel_j0(j0)
|
||||
{
|
||||
}
|
||||
|
||||
payload_impl(auto const& o,
|
||||
rotgen::Index i0,
|
||||
rotgen::Index j0,
|
||||
rotgen::Index ni,
|
||||
rotgen::Index nj,
|
||||
map_t const&,
|
||||
trans_t const&)
|
||||
: data(trans_map_storage_t{
|
||||
trans_map_block_type{o.storage()->data, i0, j0, ni, nj},
|
||||
&o.storage()->data}),
|
||||
abs_i0(i0), abs_j0(j0), rel_i0(i0), rel_j0(j0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//================================================================================================
|
||||
// Concrete payload definitions
|
||||
//================================================================================================
|
||||
struct block_const_impl64_col::payload
|
||||
: payload_impl<double, Eigen::ColMajor, true>
|
||||
{
|
||||
using payload_impl::payload_impl;
|
||||
};
|
||||
|
||||
struct block_const_impl64_row::payload
|
||||
: payload_impl<double, Eigen::RowMajor, true>
|
||||
{
|
||||
using payload_impl::payload_impl;
|
||||
};
|
||||
|
||||
struct block_const_impl32_col::payload
|
||||
: payload_impl<float, Eigen::ColMajor, true>
|
||||
{
|
||||
using payload_impl::payload_impl;
|
||||
};
|
||||
|
||||
struct block_const_impl32_row::payload
|
||||
: payload_impl<float, Eigen::RowMajor, true>
|
||||
{
|
||||
using payload_impl::payload_impl;
|
||||
};
|
||||
|
||||
struct block_impl64_col::payload
|
||||
: payload_impl<double, Eigen::ColMajor, false>
|
||||
{
|
||||
using payload_impl::payload_impl;
|
||||
};
|
||||
|
||||
struct block_impl64_row::payload
|
||||
: payload_impl<double, Eigen::RowMajor, false>
|
||||
{
|
||||
using payload_impl::payload_impl;
|
||||
};
|
||||
|
||||
struct block_impl32_col::payload : payload_impl<float, Eigen::ColMajor, false>
|
||||
{
|
||||
using payload_impl::payload_impl;
|
||||
};
|
||||
|
||||
struct block_impl32_row::payload : payload_impl<float, Eigen::RowMajor, false>
|
||||
{
|
||||
using payload_impl::payload_impl;
|
||||
};
|
||||
}
|
||||
170
include/rotgen/detail/payload/map.hpp
Normal file
170
include/rotgen/detail/payload/map.hpp
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/container/map/dynamic/impl.hpp>
|
||||
|
||||
#include <Eigen/Core>
|
||||
#include <Eigen/Dense>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
//==================================================================================================
|
||||
// Internal payload - Required for cross-referencing from mixed order on map
|
||||
// operators
|
||||
//==================================================================================================
|
||||
struct map_const_impl32_col::payload
|
||||
{
|
||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||
using base_type =
|
||||
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
|
||||
using data_type =
|
||||
Eigen::Map<base_type const, Eigen::Unaligned, stride_type>;
|
||||
|
||||
data_type data;
|
||||
|
||||
payload(data_type const& o) : data(o) {}
|
||||
|
||||
payload(float const* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||
|
||||
payload(float const* ptr, Index r, Index c, stride_type s)
|
||||
: data(ptr, r, c, s)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct map_const_impl32_row::payload
|
||||
{
|
||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||
using base_type =
|
||||
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
|
||||
using data_type =
|
||||
Eigen::Map<base_type const, Eigen::Unaligned, stride_type>;
|
||||
|
||||
data_type data;
|
||||
|
||||
payload(data_type const& o) : data(o) {}
|
||||
|
||||
payload(float const* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||
|
||||
payload(float const* ptr, Index r, Index c, stride_type s)
|
||||
: data(ptr, r, c, s)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct map_impl32_col::payload
|
||||
{
|
||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||
using base_type =
|
||||
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
|
||||
using data_type = Eigen::Map<base_type, Eigen::Unaligned, stride_type>;
|
||||
|
||||
data_type data;
|
||||
|
||||
payload(data_type const& o) : data(o) {}
|
||||
|
||||
payload(float* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||
|
||||
payload(float* ptr, Index r, Index c, stride_type s) : data(ptr, r, c, s) {}
|
||||
};
|
||||
|
||||
struct map_impl32_row::payload
|
||||
{
|
||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||
using base_type =
|
||||
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
|
||||
using data_type = Eigen::Map<base_type, Eigen::Unaligned, stride_type>;
|
||||
|
||||
data_type data;
|
||||
|
||||
payload(data_type const& o) : data(o) {}
|
||||
|
||||
payload(float* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||
|
||||
payload(float* ptr, Index r, Index c, stride_type s) : data(ptr, r, c, s) {}
|
||||
};
|
||||
|
||||
struct map_const_impl64_col::payload
|
||||
{
|
||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||
using base_type =
|
||||
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
|
||||
using data_type =
|
||||
Eigen::Map<base_type const, Eigen::Unaligned, stride_type>;
|
||||
|
||||
data_type data;
|
||||
|
||||
payload(data_type const& o) : data(o) {}
|
||||
|
||||
payload(double const* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||
|
||||
payload(double const* ptr, Index r, Index c, stride_type s)
|
||||
: data(ptr, r, c, s)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct map_const_impl64_row::payload
|
||||
{
|
||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||
using base_type =
|
||||
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
|
||||
using data_type =
|
||||
Eigen::Map<base_type const, Eigen::Unaligned, stride_type>;
|
||||
|
||||
data_type data;
|
||||
|
||||
payload(data_type const& o) : data(o) {}
|
||||
|
||||
payload(double const* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||
|
||||
payload(double const* ptr, Index r, Index c, stride_type s)
|
||||
: data(ptr, r, c, s)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct map_impl64_col::payload
|
||||
{
|
||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||
using base_type =
|
||||
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
|
||||
using data_type = Eigen::Map<base_type, Eigen::Unaligned, stride_type>;
|
||||
|
||||
data_type data;
|
||||
|
||||
payload(data_type const& o) : data(o) {}
|
||||
|
||||
payload(double* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||
|
||||
payload(double* ptr, Index r, Index c, stride_type s) : data(ptr, r, c, s)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct map_impl64_row::payload
|
||||
{
|
||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||
using base_type =
|
||||
Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
|
||||
using data_type = Eigen::Map<base_type, Eigen::Unaligned, stride_type>;
|
||||
|
||||
data_type data;
|
||||
|
||||
payload(data_type const& o) : data(o) {}
|
||||
|
||||
payload(double* ptr, Index r, Index c) : data(ptr, r, c) {}
|
||||
|
||||
payload(double* ptr, Index r, Index c, stride_type s) : data(ptr, r, c, s)
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
113
include/rotgen/detail/payload/matrix.hpp
Normal file
113
include/rotgen/detail/payload/matrix.hpp
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/container/matrix/dynamic/impl.hpp>
|
||||
|
||||
#include <Eigen/Core>
|
||||
#include <Eigen/Dense>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
//==================================================================================================
|
||||
// Internal payload - Required 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; }
|
||||
|
||||
void assign(data_type const& mat) { data = mat; }
|
||||
|
||||
void assign(data_type&& mat) { data = std::move(mat); }
|
||||
};
|
||||
|
||||
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; }
|
||||
|
||||
void assign(data_type const& mat) { data = mat; }
|
||||
|
||||
void assign(data_type&& mat) { data = std::move(mat); }
|
||||
};
|
||||
|
||||
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; }
|
||||
|
||||
void assign(data_type const& mat) { data = mat; }
|
||||
|
||||
void assign(data_type&& mat) { data = std::move(mat); }
|
||||
};
|
||||
|
||||
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; }
|
||||
|
||||
void assign(data_type const& mat) { data = mat; }
|
||||
|
||||
void assign(data_type&& mat) { data = std::move(mat); }
|
||||
};
|
||||
}
|
||||
|
|
@ -9,5 +9,6 @@
|
|||
|
||||
#include <rotgen/functions/extract.hpp>
|
||||
#include <rotgen/functions/functions.hpp>
|
||||
#include <rotgen/functions/generators.hpp>
|
||||
#include <rotgen/functions/operators.hpp>
|
||||
#include <rotgen/functions/reshaper.hpp>
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ namespace rotgen
|
|||
auto extract(Entity& e, Index i0, Index j0, Index ni, Index nj)
|
||||
{
|
||||
detail::validate_extract(e, i0, j0, ni, nj);
|
||||
if constexpr (concepts::reference<Entity>)
|
||||
return extract(e.base(), i0, j0, ni, nj);
|
||||
if constexpr (requires { e.as_map(); })
|
||||
return extract(e.as_map(), i0, j0, ni, nj);
|
||||
else return block<detail::propagate_const<Entity>>(e, i0, j0, ni, nj);
|
||||
}
|
||||
|
||||
|
|
@ -41,8 +41,8 @@ namespace rotgen
|
|||
auto extract(Entity& e, Index i0, Index j0)
|
||||
{
|
||||
detail::validate_extract(e, i0, j0, NI, NJ);
|
||||
if constexpr (concepts::reference<Entity>)
|
||||
return extract<NI, NJ>(e.base(), i0, j0);
|
||||
if constexpr (requires { e.as_map(); })
|
||||
return extract<NI, NJ>(e.as_map(), i0, j0);
|
||||
else return block<detail::propagate_const<Entity>, NI, NJ>(e, i0, j0);
|
||||
}
|
||||
|
||||
|
|
@ -51,8 +51,8 @@ namespace rotgen
|
|||
auto extract(Entity& e, Index i0, Index j0, Index ni, Index nj)
|
||||
{
|
||||
detail::validate_extract(e, i0, j0, ni, nj);
|
||||
if constexpr (concepts::reference<Entity>)
|
||||
return extract<NI, NJ>(e.base(), i0, j0, ni, nj);
|
||||
if constexpr (requires { e.as_map(); })
|
||||
return extract<NI, NJ>(e.as_map(), i0, j0, ni, nj);
|
||||
else
|
||||
return block<detail::propagate_const<Entity>, NI, NJ>(e, i0, j0, ni, nj);
|
||||
}
|
||||
|
|
@ -112,83 +112,116 @@ namespace rotgen
|
|||
//======================== TOP ROWS ========================
|
||||
template<concepts::entity Entity> auto topRows(Entity& e, Index ni)
|
||||
{
|
||||
return extract(e, 0, 0, ni, e.cols());
|
||||
if constexpr (Entity::ColsAtCompileTime == -1)
|
||||
return extract(e, 0, 0, ni, e.cols());
|
||||
else return extract<-1, Entity::ColsAtCompileTime>(e, 0, 0, ni, e.cols());
|
||||
}
|
||||
|
||||
template<Index NI, concepts::entity Entity> auto topRows(Entity& e)
|
||||
{
|
||||
return extract<NI, -1>(e, 0, 0, NI, e.cols());
|
||||
if constexpr (Entity::ColsAtCompileTime == -1)
|
||||
return extract<NI, -1>(e, 0, 0, NI, e.cols());
|
||||
else return extract<NI, Entity::ColsAtCompileTime>(e, 0, 0);
|
||||
}
|
||||
|
||||
//======================== MIDDLE ROWS ========================
|
||||
template<concepts::entity Entity>
|
||||
auto middleRows(Entity& e, Index i0, Index ni)
|
||||
{
|
||||
return extract(e, i0, 0, ni, e.cols());
|
||||
if constexpr (Entity::ColsAtCompileTime == -1)
|
||||
return extract(e, i0, 0, ni, e.cols());
|
||||
else return extract<-1, Entity::ColsAtCompileTime>(e, i0, 0, ni, e.cols());
|
||||
}
|
||||
|
||||
template<Index NI, concepts::entity Entity>
|
||||
auto middleRows(Entity& e, Index i0)
|
||||
{
|
||||
return extract<NI, -1>(e, i0, 0, NI, e.cols());
|
||||
if constexpr (Entity::ColsAtCompileTime == -1)
|
||||
return extract<NI, -1>(e, i0, 0, NI, e.cols());
|
||||
else return extract<NI, Entity::ColsAtCompileTime>(e, i0, 0);
|
||||
}
|
||||
|
||||
//======================== BOTTOM ROWS ========================
|
||||
template<concepts::entity Entity> auto bottomRows(Entity& e, Index ni)
|
||||
{
|
||||
return extract(e, e.rows() - ni, 0, ni, e.cols());
|
||||
if constexpr (Entity::ColsAtCompileTime == -1)
|
||||
return extract(e, e.rows() - ni, 0, ni, e.cols());
|
||||
else
|
||||
return extract<-1, Entity::ColsAtCompileTime>(e, e.rows() - ni, 0, ni,
|
||||
e.cols());
|
||||
}
|
||||
|
||||
template<Index NI, concepts::entity Entity> auto bottomRows(Entity& e)
|
||||
{
|
||||
return extract<NI, -1>(e, e.rows() - NI, 0, NI, e.cols());
|
||||
if constexpr (Entity::ColsAtCompileTime == -1)
|
||||
return extract<NI, -1>(e, e.rows() - NI, 0, NI, e.cols());
|
||||
else return extract<NI, Entity::ColsAtCompileTime>(e, e.rows() - NI, 0);
|
||||
}
|
||||
|
||||
//======================== LEFT COLS ========================
|
||||
template<concepts::entity Entity> auto leftCols(Entity& e, Index nj)
|
||||
{
|
||||
return extract(e, 0, 0, e.rows(), nj);
|
||||
if constexpr (Entity::RowsAtCompileTime == -1)
|
||||
return extract(e, 0, 0, e.rows(), nj);
|
||||
else return extract<Entity::RowsAtCompileTime, -1>(e, 0, 0, e.rows(), nj);
|
||||
}
|
||||
|
||||
template<Index NJ, concepts::entity Entity> auto leftCols(Entity& e)
|
||||
{
|
||||
return extract<-1, NJ>(e, 0, 0, e.rows(), NJ);
|
||||
if constexpr (Entity::RowsAtCompileTime == -1)
|
||||
return extract<-1, NJ>(e, 0, 0, e.rows(), NJ);
|
||||
else return extract<Entity::RowsAtCompileTime, NJ>(e, 0, 0);
|
||||
}
|
||||
|
||||
//======================== MIDDLE COLS ========================
|
||||
template<concepts::entity Entity>
|
||||
auto middleCols(Entity& e, Index j0, Index nj)
|
||||
{
|
||||
return extract(e, 0, j0, e.rows(), nj);
|
||||
if constexpr (Entity::RowsAtCompileTime == -1)
|
||||
return extract(e, 0, j0, e.rows(), nj);
|
||||
else return extract<Entity::RowsAtCompileTime, -1>(e, 0, j0, e.rows(), nj);
|
||||
}
|
||||
|
||||
template<Index NJ, concepts::entity Entity>
|
||||
auto middleCols(Entity& e, Index j0)
|
||||
{
|
||||
return extract<-1, NJ>(e, 0, j0, e.rows(), NJ);
|
||||
if constexpr (Entity::RowsAtCompileTime == -1)
|
||||
return extract<-1, NJ>(e, 0, j0, e.rows(), NJ);
|
||||
else return extract<Entity::RowsAtCompileTime, NJ>(e, 0, j0);
|
||||
}
|
||||
|
||||
//======================== RIGHT COLS ========================
|
||||
template<concepts::entity Entity> auto rightCols(Entity& e, Index nj)
|
||||
{
|
||||
return extract(e, 0, e.cols() - nj, e.rows(), nj);
|
||||
if constexpr (Entity::RowsAtCompileTime == -1)
|
||||
return extract(e, 0, e.cols() - nj, e.rows(), nj);
|
||||
else
|
||||
return extract<Entity::RowsAtCompileTime, -1>(e, 0, e.cols() - nj,
|
||||
e.rows(), nj);
|
||||
;
|
||||
}
|
||||
|
||||
template<Index NJ, concepts::entity Entity> auto rightCols(Entity& e)
|
||||
{
|
||||
return extract<-1, NJ>(e, 0, e.cols() - NJ, e.rows(), NJ);
|
||||
if constexpr (Entity::RowsAtCompileTime == -1)
|
||||
return extract<-1, NJ>(e, 0, e.cols() - NJ, e.rows(), NJ);
|
||||
else return extract<Entity::RowsAtCompileTime, NJ>(e, 0, e.cols() - NJ);
|
||||
}
|
||||
|
||||
//======================== ROW ========================
|
||||
template<concepts::entity Entity> auto row(Entity& e, Index i0)
|
||||
{
|
||||
return extract<1, -1>(e, i0, 0, 1, e.cols());
|
||||
if constexpr (Entity::ColsAtCompileTime == -1)
|
||||
return extract<1, -1>(e, i0, 0, 1, e.cols());
|
||||
else return extract<1, Entity::ColsAtCompileTime>(e, i0, 0);
|
||||
}
|
||||
|
||||
//======================== COL ========================
|
||||
template<concepts::entity Entity> auto col(Entity& e, Index j0)
|
||||
{
|
||||
return extract<-1, 1>(e, 0, j0, e.rows(), 1);
|
||||
if constexpr (Entity::RowsAtCompileTime == -1)
|
||||
return extract<-1, 1>(e, 0, j0, e.rows(), 1);
|
||||
else return extract<Entity::RowsAtCompileTime, 1>(e, 0, j0);
|
||||
}
|
||||
|
||||
//======================== VECTOR HEAD ========================
|
||||
|
|
|
|||
|
|
@ -322,149 +322,6 @@ namespace rotgen
|
|||
return std::forward<T>(t).eval();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
// Generators
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
auto setZero(T&& t)
|
||||
requires(requires { std::forward<T>(t).setZero(); })
|
||||
{
|
||||
return std::forward<T>(t).setZero();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setZero()
|
||||
requires(requires { T::Zero(); })
|
||||
{
|
||||
return T::Zero();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setZero(std::integral auto n)
|
||||
requires(requires { T::Zero(n); })
|
||||
{
|
||||
return T::Zero(n);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setZero(std::integral auto r, std::integral auto c)
|
||||
requires(requires { T::Zero(r, c); })
|
||||
{
|
||||
return T::Zero(r, c);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setOnes(T&& t)
|
||||
requires(requires { std::forward<T>(t).setOnes(); })
|
||||
{
|
||||
return std::forward<T>(t).setOnes();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setOnes()
|
||||
requires(requires { T::Ones(); })
|
||||
{
|
||||
return T::Ones();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setOnes(std::integral auto n)
|
||||
requires(requires { T::Ones(n); })
|
||||
{
|
||||
return T::Ones(n);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setOnes(std::integral auto r, std::integral auto c)
|
||||
requires(requires { T::Ones(r, c); })
|
||||
{
|
||||
return T::Ones(r, c);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setIdentity(T&& t)
|
||||
requires(requires { std::forward<T>(t).setIdentity(); })
|
||||
{
|
||||
return std::forward<T>(t).setIdentity();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setIdentity()
|
||||
requires(requires { T::Identity(); })
|
||||
{
|
||||
return T::Identity();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setIdentity(std::integral auto n)
|
||||
requires(requires { T::Identity(n); })
|
||||
{
|
||||
return T::Identity(n);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setIdentity(std::integral auto r, std::integral auto c)
|
||||
requires(requires { T::Identity(r, c); })
|
||||
{
|
||||
return T::Identity(r, c);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setRandom(T&& t)
|
||||
requires(requires { std::forward<T>(t).setRandom(); })
|
||||
{
|
||||
return std::forward<T>(t).setRandom();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setRandom()
|
||||
requires(requires { T::Random(); })
|
||||
{
|
||||
return T::Random();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setRandom(std::integral auto n)
|
||||
requires(requires { T::Random(n); })
|
||||
{
|
||||
return T::Random(n);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setRandom(std::integral auto r, std::integral auto c)
|
||||
requires(requires { T::Random(r, c); })
|
||||
{
|
||||
return T::Random(r, c);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setConstant(T&& t, auto v)
|
||||
requires(requires { std::forward<T>(t).setConstant(v); })
|
||||
{
|
||||
return std::forward<T>(t).setConstant(v);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setConstant(auto v)
|
||||
requires(requires { T::Constant(v); })
|
||||
{
|
||||
return T::Constant(v);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setConstant(std::integral auto n, auto v)
|
||||
requires(requires { T::Constant(n, v); })
|
||||
{
|
||||
return T::Constant(n, v);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setConstant(std::integral auto r, std::integral auto c, auto v)
|
||||
requires(requires { T::Constant(r, c, v); })
|
||||
{
|
||||
return T::Constant(r, c, v);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
// Others
|
||||
// TODO: Adapt other functions ot behave as inverse and limit code in
|
||||
|
|
@ -474,9 +331,7 @@ namespace rotgen
|
|||
{
|
||||
if constexpr (!use_expression_templates)
|
||||
return inverse(generalize_t<A const>(a));
|
||||
else if constexpr (requires { typename A::rotgen_tag; })
|
||||
return base_of(a).inverse();
|
||||
else return a.inverse();
|
||||
else return base_of(a).inverse();
|
||||
}
|
||||
|
||||
template<concepts::vectorND<3> L, concepts::vectorND<3> R>
|
||||
|
|
|
|||
156
include/rotgen/functions/generators.hpp
Normal file
156
include/rotgen/functions/generators.hpp
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#pragma once
|
||||
|
||||
#include <rotgen/detail/helpers.hpp>
|
||||
|
||||
namespace rotgen
|
||||
{
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
// Generators
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
template<typename T>
|
||||
auto setZero(T&& t)
|
||||
requires(requires { std::forward<T>(t).setZero(); })
|
||||
{
|
||||
return std::forward<T>(t).setZero();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setZero()
|
||||
requires(requires { T::Zero(); })
|
||||
{
|
||||
return T::Zero();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setZero(std::integral auto n)
|
||||
requires(requires { T::Zero(n); })
|
||||
{
|
||||
return T::Zero(n);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setZero(std::integral auto r, std::integral auto c)
|
||||
requires(requires { T::Zero(r, c); })
|
||||
{
|
||||
return T::Zero(r, c);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setOnes(T&& t)
|
||||
requires(requires { std::forward<T>(t).setOnes(); })
|
||||
{
|
||||
return std::forward<T>(t).setOnes();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setOnes()
|
||||
requires(requires { T::Ones(); })
|
||||
{
|
||||
return T::Ones();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setOnes(std::integral auto n)
|
||||
requires(requires { T::Ones(n); })
|
||||
{
|
||||
return T::Ones(n);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setOnes(std::integral auto r, std::integral auto c)
|
||||
requires(requires { T::Ones(r, c); })
|
||||
{
|
||||
return T::Ones(r, c);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setIdentity(T&& t)
|
||||
requires(requires { std::forward<T>(t).setIdentity(); })
|
||||
{
|
||||
return std::forward<T>(t).setIdentity();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setIdentity()
|
||||
requires(requires { T::Identity(); })
|
||||
{
|
||||
return T::Identity();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setIdentity(std::integral auto n)
|
||||
requires(requires { T::Identity(n); })
|
||||
{
|
||||
return T::Identity(n);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setIdentity(std::integral auto r, std::integral auto c)
|
||||
requires(requires { T::Identity(r, c); })
|
||||
{
|
||||
return T::Identity(r, c);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setRandom(T&& t)
|
||||
requires(requires { std::forward<T>(t).setRandom(); })
|
||||
{
|
||||
return std::forward<T>(t).setRandom();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setRandom()
|
||||
requires(requires { T::Random(); })
|
||||
{
|
||||
return T::Random();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setRandom(std::integral auto n)
|
||||
requires(requires { T::Random(n); })
|
||||
{
|
||||
return T::Random(n);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setRandom(std::integral auto r, std::integral auto c)
|
||||
requires(requires { T::Random(r, c); })
|
||||
{
|
||||
return T::Random(r, c);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setConstant(T&& t, auto v)
|
||||
requires(requires { std::forward<T>(t).setConstant(v); })
|
||||
{
|
||||
return std::forward<T>(t).setConstant(v);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setConstant(auto v)
|
||||
requires(requires { T::Constant(v); })
|
||||
{
|
||||
return T::Constant(v);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setConstant(std::integral auto n, auto v)
|
||||
requires(requires { T::Constant(n, v); })
|
||||
{
|
||||
return T::Constant(n, v);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto setConstant(std::integral auto r, std::integral auto c, auto v)
|
||||
requires(requires { T::Constant(r, c, v); })
|
||||
{
|
||||
return T::Constant(r, c, v);
|
||||
}
|
||||
}
|
||||
|
|
@ -10,24 +10,28 @@
|
|||
#define STORAGE_ORDER Eigen::ColMajor
|
||||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
||||
#include "model.cpp"
|
||||
#undef CLASSNAME
|
||||
#undef TRANSSOURCENAME
|
||||
#undef TRANSNAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef SOURCENAME
|
||||
#undef MAPNAME
|
||||
#undef STORAGE_ORDER
|
||||
|
||||
#define STORAGE_ORDER Eigen::RowMajor
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
||||
#include "model.cpp"
|
||||
#undef CLASSNAME
|
||||
#undef TRANSSOURCENAME
|
||||
#undef TRANSNAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef SOURCENAME
|
||||
#undef MAPNAME
|
||||
#undef STORAGE_ORDER
|
||||
|
|
@ -40,24 +44,28 @@
|
|||
#define STORAGE_ORDER Eigen::ColMajor
|
||||
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
|
||||
#include "model.cpp"
|
||||
#undef CLASSNAME
|
||||
#undef TRANSSOURCENAME
|
||||
#undef TRANSNAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef SOURCENAME
|
||||
#undef MAPNAME
|
||||
#undef STORAGE_ORDER
|
||||
|
||||
#define STORAGE_ORDER Eigen::RowMajor
|
||||
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
|
||||
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
|
||||
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
|
||||
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
|
||||
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
|
||||
#include "model.cpp"
|
||||
#undef CLASSNAME
|
||||
#undef TRANSSOURCENAME
|
||||
#undef TRANSNAME
|
||||
#undef TRANSCLASSNAME
|
||||
#undef SOURCENAME
|
||||
#undef MAPNAME
|
||||
#undef STORAGE_ORDER
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@
|
|||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#include <rotgen/detail/generators.hpp>
|
||||
#include <rotgen/container/block/dynamic/impl.hpp>
|
||||
|
||||
#include <rotgen/detail/generators.hpp>
|
||||
#include <rotgen/detail/payload.hpp>
|
||||
|
||||
#include <Eigen/Dense>
|
||||
#include <variant>
|
||||
|
||||
|
|
|
|||
|
|
@ -12,80 +12,65 @@
|
|||
*/
|
||||
//==================================================================================================
|
||||
|
||||
//==================================================================================================
|
||||
// Internal payload
|
||||
//==================================================================================================
|
||||
struct CLASSNAME::payload
|
||||
{
|
||||
using stride_type = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;
|
||||
using matrix_type =
|
||||
Eigen::Matrix<TYPE, Eigen::Dynamic, Eigen::Dynamic, STORAGE_ORDER>;
|
||||
using matrix_block_type = Eigen::Block<matrix_type CONST>;
|
||||
using matrix_storage_t = std::pair<matrix_block_type, matrix_type CONST*>;
|
||||
using map_type = Eigen::Map<matrix_type CONST, Eigen::Unaligned, stride_type>;
|
||||
using map_block_type = Eigen::Block<map_type CONST>;
|
||||
using map_storage_t = std::pair<map_block_type, map_type CONST*>;
|
||||
using data_type = std::variant<matrix_storage_t, map_storage_t>;
|
||||
|
||||
data_type data;
|
||||
rotgen::Index abs_i0 = 0; // absolute start row in original matrix
|
||||
rotgen::Index abs_j0 = 0; // absolute start col in original matrix
|
||||
rotgen::Index rel_i0 = 0; // relative start row in original matrix
|
||||
rotgen::Index rel_j0 = 0; // relative start col in original matrix
|
||||
|
||||
template<typename Func> void apply(Func f)
|
||||
{
|
||||
std::visit([&](auto& blk) { return f(blk.first); }, data);
|
||||
}
|
||||
|
||||
template<typename Func> void apply(Func f) const
|
||||
{
|
||||
std::visit([&](auto const& blk) { return f(blk.first); }, data);
|
||||
}
|
||||
|
||||
payload(data_type const& o) : data(o) {}
|
||||
|
||||
payload(SOURCENAME CONST& o,
|
||||
rotgen::Index i0,
|
||||
rotgen::Index j0,
|
||||
rotgen::Index ni,
|
||||
rotgen::Index nj)
|
||||
: data(
|
||||
matrix_storage_t{matrix_block_type{o.storage()->data, i0, j0, ni, nj},
|
||||
&o.storage()->data}),
|
||||
abs_i0(i0), abs_j0(j0), rel_i0(i0), rel_j0(j0)
|
||||
{
|
||||
}
|
||||
|
||||
payload(MAPNAME CONST& o,
|
||||
rotgen::Index i0,
|
||||
rotgen::Index j0,
|
||||
rotgen::Index ni,
|
||||
rotgen::Index nj)
|
||||
: data(map_storage_t{map_block_type{o.storage()->data, i0, j0, ni, nj},
|
||||
&o.storage()->data}),
|
||||
abs_i0(i0), abs_j0(j0), rel_i0(i0), rel_j0(j0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
// Constructors & Special Members
|
||||
//==================================================================================================
|
||||
CLASSNAME::CLASSNAME(
|
||||
SOURCENAME CONST& r, Index i0, Index j0, Index ni, Index nj)
|
||||
: storage_(std::make_unique<payload>(r, i0, j0, ni, nj))
|
||||
: storage_(
|
||||
std::make_unique<payload>(r, i0, j0, ni, nj, matrix_t{}, source_t{}))
|
||||
{
|
||||
}
|
||||
|
||||
CLASSNAME::CLASSNAME(TRANSNAME CONST& r, Index i0, Index j0, Index ni, Index nj)
|
||||
: storage_(
|
||||
std::make_unique<payload>(r, i0, j0, ni, nj, matrix_t{}, trans_t{}))
|
||||
{
|
||||
}
|
||||
|
||||
CLASSNAME::CLASSNAME(MAPNAME CONST& r, Index i0, Index j0, Index ni, Index nj)
|
||||
: storage_(std::make_unique<payload>(r, i0, j0, ni, nj))
|
||||
: storage_(std::make_unique<payload>(r, i0, j0, ni, nj, map_t{}, source_t{}))
|
||||
{
|
||||
}
|
||||
|
||||
// We're building a block from a block - So we have to dig around the internals
|
||||
CLASSNAME::CLASSNAME(payload const& o, Index i0, Index j0, Index ni, Index nj)
|
||||
CLASSNAME::CLASSNAME(
|
||||
TRANSCLASSNAME CONST& p, Index i0, Index j0, Index ni, Index nj)
|
||||
{
|
||||
auto const& o = *(p.storage());
|
||||
|
||||
// Compute absolute indices from the parent stored block
|
||||
Index abs_i0 = 0;
|
||||
Index abs_j0 = 0;
|
||||
std::visit(
|
||||
[&](auto const& blk) {
|
||||
abs_i0 = blk.first.startRow() + i0;
|
||||
abs_j0 = blk.first.startCol() + j0;
|
||||
},
|
||||
o.data);
|
||||
|
||||
// Build a payload::data_type that holds the child block using absolute
|
||||
// indices
|
||||
payload::data_type new_data = std::visit(
|
||||
[&]<typename T>(T const& blk) -> payload::data_type {
|
||||
auto& [parent_block, ref] = blk;
|
||||
using block_type = typename T::first_type;
|
||||
return T{block_type{*ref, abs_i0, abs_j0, ni, nj}, ref};
|
||||
},
|
||||
o.data);
|
||||
|
||||
storage_ = std::make_unique<payload>(new_data);
|
||||
storage_->abs_i0 = abs_i0;
|
||||
storage_->abs_j0 = abs_j0;
|
||||
storage_->rel_i0 = i0;
|
||||
storage_->rel_j0 = j0;
|
||||
}
|
||||
|
||||
// We're building a block from a block - So we have to dig around the internals
|
||||
CLASSNAME::CLASSNAME(CLASSNAME CONST& p, Index i0, Index j0, Index ni, Index nj)
|
||||
{
|
||||
auto const& o = *(p.storage());
|
||||
|
||||
// Compute absolute indices from the parent stored block
|
||||
Index abs_i0 = 0;
|
||||
Index abs_j0 = 0;
|
||||
|
|
@ -495,50 +480,54 @@ CLASSNAME& CLASSNAME::operator/=(TYPE s)
|
|||
SOURCENAME CLASSNAME::add(CLASSNAME const& rhs) const
|
||||
{
|
||||
SOURCENAME result;
|
||||
result.storage()->assign(std::visit(
|
||||
[](auto const& lhs_blk, auto const& rhs_blk) {
|
||||
return (lhs_blk.first + rhs_blk.first).eval();
|
||||
std::visit(
|
||||
[&](auto const& lhs_blk, auto const& rhs_blk) {
|
||||
result.storage()->assign((lhs_blk.first + rhs_blk.first).eval());
|
||||
},
|
||||
storage_->data, rhs.storage_->data));
|
||||
storage_->data, rhs.storage_->data);
|
||||
return result;
|
||||
}
|
||||
|
||||
SOURCENAME CLASSNAME::sub(CLASSNAME const& rhs) const
|
||||
{
|
||||
SOURCENAME result;
|
||||
result.storage()->assign(std::visit(
|
||||
[](auto const& lhs_blk, auto const& rhs_blk) {
|
||||
return (lhs_blk.first - rhs_blk.first).eval();
|
||||
std::visit(
|
||||
[&](auto const& lhs_blk, auto const& rhs_blk) {
|
||||
result.storage()->assign((lhs_blk.first - rhs_blk.first).eval());
|
||||
},
|
||||
storage_->data, rhs.storage_->data));
|
||||
storage_->data, rhs.storage_->data);
|
||||
return result;
|
||||
}
|
||||
|
||||
SOURCENAME CLASSNAME::mul(CLASSNAME const& rhs) const
|
||||
{
|
||||
SOURCENAME result;
|
||||
result.storage()->assign(std::visit(
|
||||
[](auto const& lhs_blk, auto const& rhs_blk) {
|
||||
return (lhs_blk.first * rhs_blk.first).eval();
|
||||
std::visit(
|
||||
[&](auto const& lhs_blk, auto const& rhs_blk) {
|
||||
result.storage()->assign((lhs_blk.first * rhs_blk.first).eval());
|
||||
},
|
||||
storage_->data, rhs.storage_->data));
|
||||
storage_->data, rhs.storage_->data);
|
||||
return result;
|
||||
}
|
||||
|
||||
SOURCENAME CLASSNAME::mul(TYPE s) const
|
||||
{
|
||||
SOURCENAME result;
|
||||
result.storage()->assign(
|
||||
std::visit([s](auto const& lhs_blk) { return (lhs_blk.first * s).eval(); },
|
||||
storage_->data));
|
||||
std::visit(
|
||||
[&](auto const& lhs_blk) {
|
||||
result.storage()->assign((lhs_blk.first * s).eval());
|
||||
},
|
||||
storage_->data);
|
||||
return result;
|
||||
}
|
||||
|
||||
SOURCENAME CLASSNAME::div(TYPE s) const
|
||||
{
|
||||
SOURCENAME result;
|
||||
result.storage()->assign(
|
||||
std::visit([s](auto const& lhs_blk) { return (lhs_blk.first / s).eval(); },
|
||||
storage_->data));
|
||||
std::visit(
|
||||
[&](auto const& lhs_blk) {
|
||||
result.storage()->assign((lhs_blk.first / s).eval());
|
||||
},
|
||||
storage_->data);
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,11 @@
|
|||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#include <rotgen/detail/generators.hpp>
|
||||
#include <rotgen/container/map/dynamic/impl.hpp>
|
||||
|
||||
#include <rotgen/detail/generators.hpp>
|
||||
#include <rotgen/detail/payload.hpp>
|
||||
|
||||
#include <Eigen/Dense>
|
||||
#include <Eigen/LU>
|
||||
|
||||
|
|
|
|||
|
|
@ -19,12 +19,14 @@
|
|||
//==================================================================================================
|
||||
// Constructors & Special Members
|
||||
//==================================================================================================
|
||||
CLASSNAME::CLASSNAME() {}
|
||||
|
||||
CLASSNAME::CLASSNAME(TYPE CONST* ptr, Index r, Index c)
|
||||
: storage_(std::make_unique<payload>(ptr, r, c))
|
||||
{
|
||||
}
|
||||
|
||||
CLASSNAME::CLASSNAME(TYPE CONST* ptr, Index r, Index c, stride s)
|
||||
CLASSNAME::CLASSNAME(TYPE CONST* ptr, Index r, Index c, dynamic_stride s)
|
||||
: storage_(std::make_unique<payload>(
|
||||
ptr, r, c, payload::stride_type{s.outer(), s.inner()}))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@
|
|||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#include <rotgen/detail/generators.hpp>
|
||||
#include <rotgen/container/matrix/dynamic/impl.hpp>
|
||||
|
||||
#include <rotgen/detail/generators.hpp>
|
||||
#include <rotgen/detail/payload.hpp>
|
||||
#include <rotgen/config.hpp>
|
||||
|
||||
#include <Eigen/Dense>
|
||||
|
||||
namespace rotgen
|
||||
|
|
|
|||
|
|
@ -300,10 +300,37 @@ CLASSNAME& CLASSNAME::operator/=(TYPE s)
|
|||
return *this;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
// Static functions
|
||||
//==================================================================================================
|
||||
//==============================================================================
|
||||
// Generators functions
|
||||
//==============================================================================
|
||||
void CLASSNAME::setOnes(std::size_t rows, std::size_t cols)
|
||||
{
|
||||
storage_->assign(payload::data_type::Ones(rows, cols).eval());
|
||||
}
|
||||
|
||||
void CLASSNAME::setZero(std::size_t rows, std::size_t cols)
|
||||
{
|
||||
storage_->assign(payload::data_type::Zero(rows, cols).eval());
|
||||
}
|
||||
|
||||
void CLASSNAME::setConstant(std::size_t rows, std::size_t cols, TYPE value)
|
||||
{
|
||||
storage_->assign(payload::data_type::Constant(rows, cols, value).eval());
|
||||
}
|
||||
|
||||
void CLASSNAME::setRandom(std::size_t rows, std::size_t cols)
|
||||
{
|
||||
storage_->assign(payload::data_type::Random(rows, cols).eval());
|
||||
}
|
||||
|
||||
void CLASSNAME::setIdentity(std::size_t rows, std::size_t cols)
|
||||
{
|
||||
storage_->assign(payload::data_type::Identity(rows, cols).eval());
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// Static functions
|
||||
//==============================================================================
|
||||
CLASSNAME CLASSNAME::Ones(std::size_t rows, std::size_t cols)
|
||||
{
|
||||
CLASSNAME m;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ rotgen_glob_unit(QUIET PATTERN "unit/*.cpp" INTERFACE rotgen_test)
|
|||
rotgen_glob_unit(QUIET PATTERN "unit/matrix/*.cpp" INTERFACE rotgen_test)
|
||||
rotgen_glob_unit(QUIET PATTERN "unit/block/*.cpp" INTERFACE rotgen_test)
|
||||
rotgen_glob_unit(QUIET PATTERN "unit/map/*.cpp" INTERFACE rotgen_test)
|
||||
rotgen_glob_unit(QUIET PATTERN "unit/meta/*.cpp" INTERFACE rotgen_test)
|
||||
rotgen_glob_unit(QUIET PATTERN "unit/functions/*.cpp" INTERFACE rotgen_test)
|
||||
|
||||
##======================================================================================================================
|
||||
|
|
|
|||
|
|
@ -5,12 +5,13 @@
|
|||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#include "unit/tests.hpp"
|
||||
#include <rotgen/rotgen.hpp>
|
||||
|
||||
TTS_CASE_TPL("Chains of extraction",
|
||||
rotgen::tests::types)<typename T, typename O>(
|
||||
tts::type<tts::types<T, O>>)
|
||||
#include "unit/tests.hpp"
|
||||
|
||||
TTS_CASE_TPL("Chains of extraction", rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
constexpr int N = 8;
|
||||
auto a = rotgen::matrix<T, N, N, O::value>::Random();
|
||||
|
|
@ -44,6 +45,9 @@ TTS_CASE_TPL("Chains of extraction",
|
|||
setConstant(bbbb, 0.125);
|
||||
|
||||
TTS_EQUAL(a(3, 3), 0.125);
|
||||
|
||||
bool verbose = ::tts::arguments()[{"--verbose"}];
|
||||
if (verbose) std::cout << a << "\n\n";
|
||||
};
|
||||
|
||||
auto ref_extract(rotgen::ref<rotgen::matrix<float>> m)
|
||||
|
|
@ -66,9 +70,10 @@ TTS_CASE("Extraction of ref/ref const")
|
|||
for (rotgen::Index r = 0; r < 3; r++)
|
||||
for (rotgen::Index c = 0; c < 4; c++) TTS_EQUAL(m(r, c), 1.f);
|
||||
|
||||
auto sliced = ref_cextract(m);
|
||||
rotgen::extract(m, 3, 4, 4, 3) =
|
||||
rotgen::setConstant<rotgen::matrix<float, 4, 3>>(5);
|
||||
auto sliced = ref_cextract(m);
|
||||
|
||||
for (rotgen::Index r = 0; r < 4; r++)
|
||||
for (rotgen::Index c = 0; c < 3; c++) TTS_EQUAL(sliced(r, c), 5.f);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@
|
|||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#include "unit/tests.hpp"
|
||||
#include <rotgen/rotgen.hpp>
|
||||
|
||||
#include "unit/tests.hpp"
|
||||
#include <iostream>
|
||||
|
||||
TTS_CASE_TPL("outer_stride<0> interactions",
|
||||
|
|
@ -54,49 +55,3 @@ TTS_CASE_TPL("outer_stride<0> interactions",
|
|||
TTS_EQUAL(dp, sp);
|
||||
}
|
||||
};
|
||||
|
||||
void process_ref(rotgen::ref<rotgen::matrix<float> const>) {}
|
||||
|
||||
void process_ref(rotgen::ref<rotgen::matrix<double> const>) {}
|
||||
|
||||
void process_ref(
|
||||
rotgen::ref<
|
||||
rotgen::
|
||||
matrix<float, rotgen::Dynamic, rotgen::Dynamic, rotgen::RowMajor> const>)
|
||||
{
|
||||
}
|
||||
|
||||
void process_ref(
|
||||
rotgen::ref<
|
||||
rotgen::
|
||||
matrix<double, rotgen::Dynamic, rotgen::Dynamic, rotgen::RowMajor> const>)
|
||||
{
|
||||
}
|
||||
|
||||
TTS_CASE_TPL("Extraction of outer_stride<?> blocks",
|
||||
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>;
|
||||
|
||||
if constexpr (O::value == rotgen::ColMajor)
|
||||
{
|
||||
T padded[] = {1, 2, 3, 4, 99, 5, 6, 7, 8, 99, 9, 10, 11, 12};
|
||||
rotgen::map<mat_t, 0, rotgen::outer_stride<5>> sp(&padded[0], 4, 3);
|
||||
rotgen::map<mat_t, 0, rotgen::outer_stride<>> dp(&padded[0], 4, 3,
|
||||
rotgen::outer_stride(5));
|
||||
|
||||
TTS_EXPECT_COMPILES(sp, { process_ref(extract(sp, 0, 0, 3, 2)); });
|
||||
TTS_EXPECT_COMPILES(dp, { process_ref(extract(dp, 0, 0, 3, 2)); });
|
||||
}
|
||||
else
|
||||
{
|
||||
T padded[] = {1, 2, 3, 99, 4, 5, 6, 99, 7, 8, 9, 99, 10, 11, 12};
|
||||
rotgen::map<mat_t, 0, rotgen::outer_stride<4>> sp(&padded[0], 4, 3);
|
||||
rotgen::map<mat_t, 0, rotgen::outer_stride<>> dp(&padded[0], 4, 3,
|
||||
rotgen::outer_stride(4));
|
||||
|
||||
TTS_EXPECT_COMPILES(sp, { process_ref(extract(sp, 0, 0, 3, 2)); });
|
||||
TTS_EXPECT_COMPILES(dp, { process_ref(extract(dp, 0, 0, 3, 2)); });
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,9 +5,10 @@
|
|||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#include "unit/tests.hpp"
|
||||
#include <rotgen/rotgen.hpp>
|
||||
|
||||
#include "unit/tests.hpp"
|
||||
|
||||
template<int size = rotgen::Dynamic,
|
||||
typename Scalar = float,
|
||||
int maxSize = size>
|
||||
|
|
@ -63,3 +64,34 @@ TTS_CASE("Reference of reference check")
|
|||
TTS_EQUAL(v2[0], sum2);
|
||||
TTS_EQUAL(v3[0], sum3);
|
||||
};
|
||||
|
||||
int f(rotgen::ref<rotgen::matrix<float, 1, 3, rotgen::RowMajor>>)
|
||||
{
|
||||
return +2;
|
||||
}
|
||||
|
||||
template<int N>
|
||||
int g(rotgen::ref<rotgen::matrix<float, -1, N, rotgen::ColMajor>>)
|
||||
{
|
||||
return +1;
|
||||
}
|
||||
|
||||
template<int N>
|
||||
int g(rotgen::ref<rotgen::matrix<float, -1, N, rotgen::RowMajor>>)
|
||||
requires(N > 1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
TTS_CASE("Reference overload on stroage order check")
|
||||
{
|
||||
rotgen::matrix<float> mat_dyn(1, 3);
|
||||
rotgen::matrix<float, -1, 3, rotgen::ColMajor> mat_col(1, 3);
|
||||
rotgen::matrix<float, -1, 3, rotgen::RowMajor> mat_row(1, 3);
|
||||
|
||||
TTS_EQUAL(f(mat_dyn), +2);
|
||||
|
||||
TTS_EQUAL(g<3>(mat_dyn), +1);
|
||||
TTS_EQUAL(g<3>(mat_col), +1);
|
||||
TTS_EQUAL(g<3>(mat_row), -1);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,9 +5,10 @@
|
|||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#include "unit/tests.hpp"
|
||||
#include <rotgen/rotgen.hpp>
|
||||
|
||||
#include "unit/tests.hpp"
|
||||
|
||||
template<typename EigenType, typename F>
|
||||
void for_each_element(EigenType const& m, F&& f)
|
||||
{
|
||||
|
|
@ -137,68 +138,81 @@ void test_dynamic_block_extraction(
|
|||
auto blocks = std::make_tuple(
|
||||
// --- CONST TESTS
|
||||
std::make_tuple(c_block_main, matrix_construct.i0, matrix_construct.j0,
|
||||
matrix_construct.ni, matrix_construct.nj),
|
||||
matrix_construct.ni, matrix_construct.nj, rotgen::Dynamic,
|
||||
rotgen::Dynamic),
|
||||
std::make_tuple(c_block_top_left_corner, 0, 0, matrix_construct.ni,
|
||||
matrix_construct.nj),
|
||||
matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic),
|
||||
std::make_tuple(c_block_top_right_corner, 0,
|
||||
matrix.cols() - matrix_construct.nj, matrix_construct.ni,
|
||||
matrix_construct.nj),
|
||||
matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic),
|
||||
std::make_tuple(c_block_bottom_left_corner,
|
||||
matrix.rows() - matrix_construct.ni, 0, matrix_construct.ni,
|
||||
matrix_construct.nj),
|
||||
matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic),
|
||||
std::make_tuple(c_block_bottom_right_corner,
|
||||
matrix.rows() - matrix_construct.ni,
|
||||
matrix.cols() - matrix_construct.nj, matrix_construct.ni,
|
||||
matrix_construct.nj),
|
||||
matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic),
|
||||
|
||||
std::make_tuple(c_block_top_rows, 0, 0, matrix_construct.ni, matrix.cols()),
|
||||
std::make_tuple(c_block_top_rows, 0, 0, matrix_construct.ni, matrix.cols(),
|
||||
rotgen::Dynamic, MatrixType::ColsAtCompileTime),
|
||||
std::make_tuple(c_block_middle_rows, matrix_construct.i0, 0,
|
||||
matrix_construct.ni, matrix.cols()),
|
||||
matrix_construct.ni, matrix.cols(), rotgen::Dynamic,
|
||||
MatrixType::ColsAtCompileTime),
|
||||
std::make_tuple(c_block_bottom_rows, matrix.rows() - matrix_construct.ni, 0,
|
||||
matrix_construct.ni, matrix.cols()),
|
||||
|
||||
std::make_tuple(c_block_left_cols, 0, 0, matrix.rows(),
|
||||
matrix_construct.nj),
|
||||
matrix_construct.ni, matrix.cols(), rotgen::Dynamic,
|
||||
MatrixType::ColsAtCompileTime),
|
||||
std::make_tuple(c_block_left_cols, 0, 0, matrix.rows(), matrix_construct.nj,
|
||||
MatrixType::RowsAtCompileTime, rotgen::Dynamic),
|
||||
std::make_tuple(c_block_middle_cols, 0, matrix_construct.j0, matrix.rows(),
|
||||
matrix_construct.nj),
|
||||
matrix_construct.nj, MatrixType::RowsAtCompileTime,
|
||||
rotgen::Dynamic),
|
||||
std::make_tuple(c_block_right_cols, 0, matrix.cols() - matrix_construct.nj,
|
||||
matrix.rows(), matrix_construct.nj),
|
||||
matrix.rows(), matrix_construct.nj,
|
||||
MatrixType::RowsAtCompileTime, rotgen::Dynamic),
|
||||
|
||||
// --- REGULAR TESTS
|
||||
std::make_tuple(block_main, matrix_construct.i0, matrix_construct.j0,
|
||||
matrix_construct.ni, matrix_construct.nj),
|
||||
matrix_construct.ni, matrix_construct.nj, rotgen::Dynamic,
|
||||
rotgen::Dynamic),
|
||||
std::make_tuple(block_top_left_corner, 0, 0, matrix_construct.ni,
|
||||
matrix_construct.nj),
|
||||
matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic),
|
||||
std::make_tuple(block_top_right_corner, 0,
|
||||
matrix.cols() - matrix_construct.nj, matrix_construct.ni,
|
||||
matrix_construct.nj),
|
||||
matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic),
|
||||
std::make_tuple(block_bottom_left_corner,
|
||||
matrix.rows() - matrix_construct.ni, 0, matrix_construct.ni,
|
||||
matrix_construct.nj),
|
||||
matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic),
|
||||
std::make_tuple(block_bottom_right_corner,
|
||||
matrix.rows() - matrix_construct.ni,
|
||||
matrix.cols() - matrix_construct.nj, matrix_construct.ni,
|
||||
matrix_construct.nj),
|
||||
matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic),
|
||||
|
||||
std::make_tuple(block_top_rows, 0, 0, matrix_construct.ni, matrix.cols()),
|
||||
std::make_tuple(block_top_rows, 0, 0, matrix_construct.ni, matrix.cols(),
|
||||
rotgen::Dynamic, MatrixType::ColsAtCompileTime),
|
||||
std::make_tuple(block_middle_rows, matrix_construct.i0, 0,
|
||||
matrix_construct.ni, matrix.cols()),
|
||||
matrix_construct.ni, matrix.cols(), rotgen::Dynamic,
|
||||
MatrixType::ColsAtCompileTime),
|
||||
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),
|
||||
matrix_construct.ni, matrix.cols(), rotgen::Dynamic,
|
||||
MatrixType::ColsAtCompileTime),
|
||||
std::make_tuple(block_left_cols, 0, 0, matrix.rows(), matrix_construct.nj,
|
||||
MatrixType::RowsAtCompileTime, rotgen::Dynamic),
|
||||
std::make_tuple(block_middle_cols, 0, matrix_construct.j0, matrix.rows(),
|
||||
matrix_construct.nj),
|
||||
matrix_construct.nj, MatrixType::RowsAtCompileTime,
|
||||
rotgen::Dynamic),
|
||||
std::make_tuple(block_right_cols, 0, matrix.cols() - matrix_construct.nj,
|
||||
matrix.rows(), matrix_construct.nj));
|
||||
matrix.rows(), matrix_construct.nj,
|
||||
MatrixType::RowsAtCompileTime, rotgen::Dynamic));
|
||||
|
||||
std::apply(
|
||||
[&](auto&&... block_entries) {
|
||||
(([&] {
|
||||
auto&& [block, i_offset, j_offset, ni, nj] = block_entries;
|
||||
auto&& [block, i_offset, j_offset, ni, nj, rows_ct, cols_ct] =
|
||||
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::RowsAtCompileTime, rows_ct);
|
||||
TTS_EQUAL(block_t::ColsAtCompileTime, cols_ct);
|
||||
TTS_EQUAL(block_t::storage_order, MatrixType::storage_order);
|
||||
|
||||
validate_block_behavior(matrix, block, i_offset, j_offset, ni, nj);
|
||||
|
|
@ -346,7 +360,7 @@ TTS_CASE_TPL(
|
|||
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>;
|
||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, rotgen::RowMajor>;
|
||||
|
||||
std::vector<rotgen::tests::matrix_block_test_case<mat_t>> cases = {
|
||||
{{6, 11, [](rotgen::Index i, rotgen::Index j) { return T(i * 10 + j); }},
|
||||
|
|
@ -381,7 +395,7 @@ 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>;
|
||||
using mat_t = rotgen::matrix<T, 4, 5, rotgen::ColMajor>;
|
||||
|
||||
std::vector<rotgen::tests::matrix_block_test_case<mat_t>> cases = {
|
||||
{{4, 5, [](auto i, auto j) { return T(2 * i + j * j * j - 42); }},
|
||||
|
|
@ -447,7 +461,7 @@ TTS_CASE_TPL("Check vector-only extractions",
|
|||
|
||||
if constexpr (O::value == rotgen::RowMajor)
|
||||
{
|
||||
using mat_t = rotgen::matrix<T, 1, rotgen::Dynamic, O::value>;
|
||||
using mat_t = rotgen::matrix<T, 1, rotgen::Dynamic>;
|
||||
mat_t m(1, 11);
|
||||
|
||||
for (rotgen::Index i = 0; i < 11; ++i) m(i) = 1 + i;
|
||||
|
|
@ -473,7 +487,7 @@ TTS_CASE_TPL("Check vector-only extractions",
|
|||
}
|
||||
else
|
||||
{
|
||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, 1, O::value>;
|
||||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, 1>;
|
||||
mat_t m(11, 1);
|
||||
|
||||
for (rotgen::Index i = 0; i < 11; ++i) m(i) = 1 + i;
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@
|
|||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#include "unit/tests.hpp"
|
||||
#include <rotgen/rotgen.hpp>
|
||||
#include <vector>
|
||||
|
||||
#include "unit/tests.hpp"
|
||||
#include <Eigen/Core>
|
||||
#include <vector>
|
||||
|
||||
auto generate_data(int rows, int cols)
|
||||
{
|
||||
|
|
@ -26,7 +27,7 @@ using r_mat_t = rotgen::matrix<float, rotgen::Dynamic, rotgen::Dynamic, O>;
|
|||
template<int O>
|
||||
using e_mat_t = Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, O>;
|
||||
|
||||
template<typename M, typename S = rotgen::stride>
|
||||
template<typename M, typename S = rotgen::stride<0, 0>>
|
||||
using r_map_t = rotgen::map<M, 0, S>;
|
||||
template<typename M, typename S = Eigen::Stride<0, 0>>
|
||||
using e_map_t = Eigen::Map<M, 0, S>;
|
||||
|
|
@ -56,7 +57,7 @@ TTS_CASE("Validate Column Major Map with specific outer stride behavior")
|
|||
auto buffer = generate_data(rows, cols);
|
||||
|
||||
r_map_t<r_mat_t<rotgen::ColMajor>, rotgen::outer_stride<>> r_map(
|
||||
buffer.data(), rows, cols, rotgen::outer_stride(rows + 1));
|
||||
buffer.data(), rows, cols, rotgen::outer_stride<>(rows + 1));
|
||||
|
||||
TTS_EQUAL(r_map.innerStride(), 1);
|
||||
TTS_EQUAL(r_map.outerStride(), 4);
|
||||
|
|
@ -75,8 +76,8 @@ TTS_CASE("Validate Column Major Map with specific inner stride behavior")
|
|||
auto cols = 4;
|
||||
auto buffer = generate_data(rows, cols);
|
||||
|
||||
r_map_t<r_mat_t<rotgen::ColMajor>> r_map(buffer.data(), rows, cols,
|
||||
rotgen::stride(rows, 2));
|
||||
r_map_t<r_mat_t<rotgen::ColMajor>, rotgen::dynamic_stride> r_map(
|
||||
buffer.data(), rows, cols, rotgen::dynamic_stride(rows, 2));
|
||||
|
||||
TTS_EQUAL(r_map.innerStride(), 2);
|
||||
TTS_EQUAL(r_map.outerStride(), 3);
|
||||
|
|
@ -116,7 +117,7 @@ TTS_CASE("Validate Row Major Map with specific outer stride behavior")
|
|||
auto buffer = generate_data(rows, cols);
|
||||
|
||||
r_map_t<r_mat_t<rotgen::RowMajor>, rotgen::outer_stride<>> r_map(
|
||||
buffer.data(), rows, cols, rotgen::outer_stride(cols + 1));
|
||||
buffer.data(), rows, cols, rotgen::outer_stride<>(cols + 1));
|
||||
|
||||
TTS_EQUAL(r_map.innerStride(), 1);
|
||||
TTS_EQUAL(r_map.outerStride(), 5);
|
||||
|
|
@ -135,8 +136,8 @@ TTS_CASE("Validate Row Major Map with specific inner stride behavior")
|
|||
auto cols = 4;
|
||||
auto buffer = generate_data(rows, cols);
|
||||
|
||||
r_map_t<r_mat_t<rotgen::RowMajor>, rotgen::stride> r_map(
|
||||
buffer.data(), rows, cols, rotgen::stride(2, cols));
|
||||
r_map_t<r_mat_t<rotgen::RowMajor>, rotgen::dynamic_stride> r_map(
|
||||
buffer.data(), rows, cols, rotgen::dynamic_stride(2, cols));
|
||||
|
||||
TTS_EQUAL(r_map.innerStride(), 4);
|
||||
TTS_EQUAL(r_map.outerStride(), 2);
|
||||
|
|
|
|||
|
|
@ -5,12 +5,13 @@
|
|||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#include "unit/tests.hpp"
|
||||
#include <rotgen/rotgen.hpp>
|
||||
|
||||
TTS_CASE_TPL("Default matrix dynamic constructor",
|
||||
rotgen::tests::types)<typename T, typename O>(
|
||||
tts::type<tts::types<T, O>>)
|
||||
#include "unit/tests.hpp"
|
||||
|
||||
TTS_CASE_TPL("Default matrix dynamic constructor", rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> matrix;
|
||||
|
||||
|
|
@ -18,9 +19,9 @@ TTS_CASE_TPL("Default matrix dynamic constructor",
|
|||
TTS_EQUAL(matrix.cols(), rotgen::Index{0});
|
||||
};
|
||||
|
||||
TTS_CASE_TPL("Default matrix static constructor",
|
||||
rotgen::tests::types)<typename T, typename O>(
|
||||
tts::type<tts::types<T, O>>)
|
||||
TTS_CASE_TPL("Default matrix static constructor", rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
rotgen::matrix<T, 4, 9, O::value> matrix;
|
||||
|
||||
|
|
@ -29,8 +30,9 @@ TTS_CASE_TPL("Default matrix static constructor",
|
|||
};
|
||||
|
||||
TTS_CASE_TPL("Dynamic matrix constructor with row and columns",
|
||||
rotgen::tests::types)<typename T, typename O>(
|
||||
tts::type<tts::types<T, O>>)
|
||||
rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> matrix(10, 5);
|
||||
|
||||
|
|
@ -38,12 +40,12 @@ TTS_CASE_TPL("Dynamic matrix constructor with row and columns",
|
|||
TTS_EQUAL(matrix.cols(), rotgen::Index{5});
|
||||
};
|
||||
|
||||
TTS_CASE_TPL("Static matrix constructor with row and columns",
|
||||
float,
|
||||
double)<typename T>(tts::type<T>)
|
||||
TTS_CASE_TPL("Static matrix constructor with row and columns", float, double)
|
||||
|
||||
<typename T>(tts::type<T>)
|
||||
{
|
||||
rotgen::matrix<T, 1, 2> v2(6, 11);
|
||||
rotgen::matrix<T, 2, 1> w2(6, 11);
|
||||
rotgen::matrix<T, 1, 2> v2 = {6, 11};
|
||||
rotgen::matrix<T, 2, 1> w2 = {6, 11};
|
||||
|
||||
TTS_EQUAL(v2(0), T{6});
|
||||
TTS_EQUAL(v2(1), T{11});
|
||||
|
|
@ -51,8 +53,8 @@ TTS_CASE_TPL("Static matrix constructor with row and columns",
|
|||
TTS_EQUAL(w2(0), T{6});
|
||||
TTS_EQUAL(w2(1), T{11});
|
||||
|
||||
rotgen::matrix<T, 1, 3> v3(6, 11, 125);
|
||||
rotgen::matrix<T, 3, 1> w3(6, 11, 125);
|
||||
rotgen::matrix<T, 1, 3> v3 = {6, 11, 125};
|
||||
rotgen::matrix<T, 3, 1> w3 = {6, 11, 125};
|
||||
|
||||
TTS_EQUAL(v3(0), T{6});
|
||||
TTS_EQUAL(v3(1), T{11});
|
||||
|
|
@ -64,8 +66,9 @@ TTS_CASE_TPL("Static matrix constructor with row and columns",
|
|||
};
|
||||
|
||||
TTS_CASE_TPL("Copy constructor produces identical but independent matrix",
|
||||
rotgen::tests::types)<typename T, typename O>(
|
||||
tts::type<tts::types<T, O>>)
|
||||
rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(3, 3);
|
||||
|
||||
|
|
@ -88,9 +91,9 @@ TTS_CASE_TPL("Copy constructor produces identical but independent matrix",
|
|||
TTS_NOT_EQUAL(b(0, 0), a(0, 0));
|
||||
};
|
||||
|
||||
TTS_CASE_TPL("Copy constructor on default matrix",
|
||||
rotgen::tests::types)<typename T, typename O>(
|
||||
tts::type<tts::types<T, O>>)
|
||||
TTS_CASE_TPL("Copy constructor on default matrix", rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a;
|
||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b = a;
|
||||
|
|
@ -98,9 +101,9 @@ TTS_CASE_TPL("Copy constructor on default matrix",
|
|||
TTS_EQUAL(b.cols(), rotgen::Index{0});
|
||||
};
|
||||
|
||||
TTS_CASE_TPL("Copy constructor from const matrix",
|
||||
rotgen::tests::types)<typename T, typename O>(
|
||||
tts::type<tts::types<T, O>>)
|
||||
TTS_CASE_TPL("Copy constructor from const matrix", rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> const a(2, 2);
|
||||
auto b = a;
|
||||
|
|
@ -108,9 +111,9 @@ TTS_CASE_TPL("Copy constructor from const matrix",
|
|||
TTS_EQUAL(b.cols(), rotgen::Index{2});
|
||||
};
|
||||
|
||||
TTS_CASE_TPL("Copy constructor on static matrix",
|
||||
rotgen::tests::types)<typename T, typename O>(
|
||||
tts::type<tts::types<T, O>>)
|
||||
TTS_CASE_TPL("Copy constructor on static matrix", rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
rotgen::matrix<T, 2, 5> a;
|
||||
rotgen::matrix<T, 2, 5> b = a;
|
||||
|
|
@ -118,9 +121,9 @@ TTS_CASE_TPL("Copy constructor on static matrix",
|
|||
TTS_EQUAL(b.cols(), rotgen::Index{5});
|
||||
};
|
||||
|
||||
TTS_CASE_TPL("Copy constructor on static/dynamic matrix",
|
||||
rotgen::tests::types)<typename T, typename O>(
|
||||
tts::type<tts::types<T, O>>)
|
||||
TTS_CASE_TPL("Copy constructor on static/dynamic matrix", rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
rotgen::matrix<T, 11, 4, O::value> a;
|
||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b = a;
|
||||
|
|
@ -128,9 +131,9 @@ TTS_CASE_TPL("Copy constructor on static/dynamic matrix",
|
|||
TTS_EQUAL(b.cols(), 4);
|
||||
};
|
||||
|
||||
TTS_CASE_TPL("Copy constructor on dynamic/static matrix",
|
||||
rotgen::tests::types)<typename T, typename O>(
|
||||
tts::type<tts::types<T, O>>)
|
||||
TTS_CASE_TPL("Copy constructor on dynamic/static matrix", rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(5, 7);
|
||||
rotgen::matrix<T, 5, 7, O::value> b = a;
|
||||
|
|
@ -138,9 +141,9 @@ TTS_CASE_TPL("Copy constructor on dynamic/static matrix",
|
|||
TTS_EQUAL(b.cols(), 7);
|
||||
};
|
||||
|
||||
TTS_CASE_TPL("Move constructor transfers contents",
|
||||
rotgen::tests::types)<typename T, typename O>(
|
||||
tts::type<tts::types<T, O>>)
|
||||
TTS_CASE_TPL("Move constructor transfers contents", rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(3, 3);
|
||||
a(1, 1) = 7;
|
||||
|
|
@ -155,9 +158,9 @@ TTS_CASE_TPL("Move constructor transfers contents",
|
|||
TTS_EXPECT(b.data() == ptr);
|
||||
};
|
||||
|
||||
TTS_CASE_TPL("Move constructor from Rvalue",
|
||||
rotgen::tests::types)<typename T, typename O>(
|
||||
tts::type<tts::types<T, O>>)
|
||||
TTS_CASE_TPL("Move constructor from Rvalue", rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b =
|
||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>(2, 2);
|
||||
|
|
@ -165,9 +168,9 @@ TTS_CASE_TPL("Move constructor from Rvalue",
|
|||
TTS_EQUAL(b.cols(), rotgen::Index{2});
|
||||
};
|
||||
|
||||
TTS_CASE_TPL("Constructor from Initializer list",
|
||||
rotgen::tests::types)<typename T, typename O>(
|
||||
tts::type<tts::types<T, O>>)
|
||||
TTS_CASE_TPL("Constructor from Initializer list", rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
rotgen::matrix<T, 1, 1, O::value> b1{3.5};
|
||||
TTS_EQUAL(b1.rows(), rotgen::Index{1});
|
||||
|
|
@ -193,9 +196,9 @@ TTS_CASE_TPL("Constructor from Initializer list",
|
|||
TTS_EQUAL(b13(2), T(3.4));
|
||||
};
|
||||
|
||||
TTS_CASE_TPL("Constructor from Initializer list of rows",
|
||||
rotgen::tests::types)<typename T, typename O>(
|
||||
tts::type<tts::types<T, O>>)
|
||||
TTS_CASE_TPL("Constructor from Initializer list of rows", rotgen::tests::types)
|
||||
|
||||
<typename T, typename O>(tts::type<tts::types<T, O>>)
|
||||
{
|
||||
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b1{{3.5}};
|
||||
TTS_EQUAL(b1.rows(), rotgen::Index{1});
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
//==================================================================================================
|
||||
#include <rotgen/rotgen.hpp>
|
||||
|
||||
#include "unit/common/arithmetic.hpp"
|
||||
#include "unit/tests.hpp"
|
||||
|
||||
TTS_CASE_TPL("Test dynamic matrix inverse",
|
||||
|
|
@ -17,52 +16,50 @@ TTS_CASE_TPL("Test dynamic matrix inverse",
|
|||
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
|
||||
auto eps = std::numeric_limits<T>::epsilon();
|
||||
|
||||
auto const cases = rotgen::tests::generate_matrix_references();
|
||||
for (auto const& [r, c, fn] : cases)
|
||||
for (int n = 2; n < 15; n *= 1.5)
|
||||
{
|
||||
if (r == c)
|
||||
{
|
||||
auto input = mat_t::Random(r, c);
|
||||
auto inv = rotgen::inverse(input);
|
||||
auto input = 10 * rotgen::setRandom<mat_t>(n, n);
|
||||
auto inv = rotgen::inverse(input);
|
||||
|
||||
auto rec = input * inv;
|
||||
auto id = mat_t::Identity(rotgen::rows(rec), rotgen::cols(rec));
|
||||
auto error = rec - id;
|
||||
auto rec = input * inv;
|
||||
auto id = mat_t::Identity(rotgen::rows(rec), rotgen::cols(rec));
|
||||
auto error = rec - id;
|
||||
|
||||
TTS_LESS_EQUAL(rotgen::maxCoeff(rotgen::abs(error)) / eps, 64.)
|
||||
<< "Result:\n"
|
||||
<< rec << "\n"
|
||||
<< "Residuals:\n"
|
||||
<< error << "\n";
|
||||
}
|
||||
TTS_LESS_EQUAL(rotgen::maxCoeff(rotgen::abs(error)) / eps, 256.)
|
||||
<< "Result:\n"
|
||||
<< rec << "\n"
|
||||
<< "Residuals:\n"
|
||||
<< error << "\n";
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename O, int N> void check_static_inverse()
|
||||
{
|
||||
using mat_t = rotgen::matrix<T, N, N, O::value>;
|
||||
auto eps = std::numeric_limits<T>::epsilon();
|
||||
|
||||
auto input = rotgen::setRandom<mat_t>();
|
||||
auto inv = rotgen::inverse(input);
|
||||
|
||||
auto rec = input * inv;
|
||||
auto id = mat_t::Identity(rotgen::rows(rec), rotgen::cols(rec));
|
||||
auto error = rec - id;
|
||||
|
||||
TTS_LESS_EQUAL(rotgen::maxCoeff(rotgen::abs(error)) / eps, 256.)
|
||||
<< "Result:\n"
|
||||
<< rec << "\n"
|
||||
<< "Residuals:\n"
|
||||
<< error << "\n";
|
||||
}
|
||||
|
||||
TTS_CASE_TPL("Test static matrix inverse",
|
||||
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 eps = std::numeric_limits<T>::epsilon();
|
||||
auto const cases = rotgen::tests::generate_static_matrix_references();
|
||||
|
||||
auto process = [&]<typename D>(D const&) {
|
||||
if constexpr (D::rows == D::cols)
|
||||
{
|
||||
auto input = rotgen::matrix<T, D::rows, D::cols, O::value>::Random();
|
||||
auto inv = rotgen::inverse(input);
|
||||
|
||||
auto rec = input * inv;
|
||||
auto id = mat_t::Identity(rotgen::rows(rec), rotgen::cols(rec));
|
||||
auto error = rec - id;
|
||||
|
||||
TTS_LESS_EQUAL(rotgen::maxCoeff(rotgen::abs(error)) / eps, 64.)
|
||||
<< "Result:\n"
|
||||
<< rec << "\n"
|
||||
<< "Residuals:\n"
|
||||
<< error << "\n";
|
||||
}
|
||||
};
|
||||
|
||||
std::apply([&](auto const&... d) { (process(d), ...); }, cases);
|
||||
check_static_inverse<T, O, 2>();
|
||||
check_static_inverse<T, O, 3>();
|
||||
check_static_inverse<T, O, 4>();
|
||||
check_static_inverse<T, O, 6>();
|
||||
check_static_inverse<T, O, 9>();
|
||||
check_static_inverse<T, O, 13>();
|
||||
};
|
||||
|
|
|
|||
211
test/unit/meta/properties.cpp
Normal file
211
test/unit/meta/properties.cpp
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#include <rotgen/rotgen.hpp>
|
||||
|
||||
#include "unit/tests.hpp"
|
||||
#include <Eigen/Core>
|
||||
|
||||
template<typename RType, typename EType> void check_size_properties()
|
||||
{
|
||||
TTS_CONSTEXPR_EQUAL(RType::RowsAtCompileTime, EType::RowsAtCompileTime)
|
||||
<< tts::typename_<RType> << " vs " << tts::typename_<EType> << "\n";
|
||||
TTS_CONSTEXPR_EQUAL(RType::ColsAtCompileTime, EType::ColsAtCompileTime)
|
||||
<< tts::typename_<RType> << " vs " << tts::typename_<EType> << "\n";
|
||||
TTS_CONSTEXPR_EQUAL(RType::MaxRowsAtCompileTime, EType::MaxRowsAtCompileTime)
|
||||
<< tts::typename_<RType> << " vs " << tts::typename_<EType> << "\n";
|
||||
TTS_CONSTEXPR_EQUAL(RType::MaxColsAtCompileTime, EType::MaxColsAtCompileTime)
|
||||
<< tts::typename_<RType> << " vs " << tts::typename_<EType> << "\n";
|
||||
TTS_CONSTEXPR_EQUAL(RType::IsVectorAtCompileTime,
|
||||
EType::IsVectorAtCompileTime)
|
||||
<< tts::typename_<RType> << " vs " << tts::typename_<EType> << "\n";
|
||||
TTS_CONSTEXPR_EQUAL(RType::InnerStrideAtCompileTime,
|
||||
EType::InnerStrideAtCompileTime)
|
||||
<< tts::typename_<RType> << " vs " << tts::typename_<EType> << "\n";
|
||||
TTS_CONSTEXPR_EQUAL(RType::OuterStrideAtCompileTime,
|
||||
EType::OuterStrideAtCompileTime)
|
||||
<< tts::typename_<RType> << " vs " << tts::typename_<EType> << "\n";
|
||||
}
|
||||
|
||||
TTS_CASE("Compile-Time informations conformance w/r to Eigen - matrix")
|
||||
{
|
||||
using namespace rotgen;
|
||||
using namespace Eigen;
|
||||
|
||||
check_size_properties<matrixXf, MatrixXf>();
|
||||
check_size_properties<matrix<float, -1, -1, 0, 3, 3>,
|
||||
Matrix<float, -1, -1, 0, 3, 3>>();
|
||||
check_size_properties<matrix<float, 4, 9>, Matrix<float, 4, 9>>();
|
||||
check_size_properties<vector4f, Vector4f>();
|
||||
check_size_properties<matrix<float, 1, -1>, Matrix<float, 1, -1>>();
|
||||
check_size_properties<row_vector4f, RowVector4f>();
|
||||
check_size_properties<matrix<float, -1, 1>, Matrix<float, -1, 1>>();
|
||||
|
||||
// RowMajor / ColMajor
|
||||
{
|
||||
TTS_CONSTEXPR_EQUAL(matrixXf::IsRowMajor, MatrixXf::IsRowMajor);
|
||||
TTS_CONSTEXPR_EQUAL((matrix<float, -1, -1, rotgen::RowMajor>::IsRowMajor),
|
||||
(Matrix<float, -1, -1, Eigen::RowMajor>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL((matrix<float, -1, 7, rotgen::RowMajor>::IsRowMajor),
|
||||
(Matrix<float, -1, 7, Eigen::RowMajor>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL((matrix<float, 7, -1, rotgen::RowMajor>::IsRowMajor),
|
||||
(Matrix<float, 7, -1, Eigen::RowMajor>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL((matrix<float, 9, 1>::IsRowMajor),
|
||||
(Matrix<float, 9, 1>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL(row_vectorXf::IsRowMajor, RowVectorXf::IsRowMajor);
|
||||
TTS_CONSTEXPR_EQUAL((matrix<float, 1, 9>::IsRowMajor),
|
||||
(Matrix<float, 1, 9>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL(vectorXf::IsRowMajor, VectorXf::IsRowMajor);
|
||||
}
|
||||
};
|
||||
|
||||
TTS_CASE("Compile-Time informations conformance w/r to Eigen - map")
|
||||
{
|
||||
using namespace rotgen;
|
||||
using namespace Eigen;
|
||||
|
||||
check_size_properties<map<matrixXf>, Map<MatrixXf>>();
|
||||
check_size_properties<map<matrix<float, -1, -1, 0, 3, 3>>,
|
||||
Map<Matrix<float, -1, -1, 0, 3, 3>>>();
|
||||
check_size_properties<map<matrix<float, -1, -1, 0, 3, 3>>,
|
||||
Map<Matrix<float, -1, -1, 0, 3, 3>>>();
|
||||
check_size_properties<map<matrix<float, 4, 9>>, Map<Matrix<float, 4, 9>>>();
|
||||
check_size_properties<map<vector4f>, Map<Vector4f>>();
|
||||
check_size_properties<map<matrix<float, 1, -1>>, Map<Matrix<float, 1, -1>>>();
|
||||
check_size_properties<map<row_vector4f>, Map<RowVector4f>>();
|
||||
check_size_properties<map<matrix<float, -1, 1>>, Map<Matrix<float, -1, 1>>>();
|
||||
|
||||
// Row/Col Major
|
||||
{
|
||||
TTS_CONSTEXPR_EQUAL((map<matrixXf>::IsRowMajor),
|
||||
(Map<MatrixXf>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL(
|
||||
(map<matrix<float, -1, -1, rotgen::RowMajor>>::IsRowMajor),
|
||||
(Map<Matrix<float, -1, -1, Eigen::RowMajor>>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL(
|
||||
(map<matrix<float, -1, -1, rotgen::ColMajor>>::IsRowMajor),
|
||||
(Map<Matrix<float, -1, -1, Eigen::ColMajor>>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL((map<vectorXf>::IsRowMajor),
|
||||
(Map<VectorXf>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL((map<row_vectorXf>::IsRowMajor),
|
||||
(Map<RowVectorXf>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL(
|
||||
(map<matrix<float, -1, 5, rotgen::RowMajor>>::IsRowMajor),
|
||||
(Map<Matrix<float, -1, 5, Eigen::RowMajor>>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL(
|
||||
(map<matrix<float, -1, 7, rotgen::ColMajor>>::IsRowMajor),
|
||||
(Map<Matrix<float, -1, 7, Eigen::ColMajor>>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL(
|
||||
(map<matrix<float, 5, -1, rotgen::RowMajor>>::IsRowMajor),
|
||||
(Map<Matrix<float, 5, -1, Eigen::RowMajor>>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL(
|
||||
(map<matrix<float, 7, -1, rotgen::ColMajor>>::IsRowMajor),
|
||||
(Map<Matrix<float, 7, -1, Eigen::ColMajor>>::IsRowMajor));
|
||||
}
|
||||
};
|
||||
|
||||
TTS_CASE("Compile-Time informations conformance w/r to Eigen - block")
|
||||
{
|
||||
using namespace rotgen;
|
||||
using namespace Eigen;
|
||||
|
||||
check_size_properties<block<matrixXf>, Block<MatrixXf>>();
|
||||
check_size_properties<block<matrix<float, 2, 4>>,
|
||||
Block<Matrix<float, 2, 4>>>();
|
||||
check_size_properties<block<matrixXf, 3, 6>, Block<MatrixXf, 3, 6>>();
|
||||
check_size_properties<block<matrix<float, 8, 8>, 3, 6>,
|
||||
Block<Matrix<float, 8, 8>, 3, 6>>();
|
||||
check_size_properties<block<matrixXf, 1, 6>, Block<MatrixXf, 1, 6>>();
|
||||
check_size_properties<block<matrix<float, 8, 8>, 1, 6>,
|
||||
Block<Matrix<float, 8, 8>, 1, 6>>();
|
||||
check_size_properties<block<matrixXf, 7, 1>, Block<MatrixXf, 7, 1>>();
|
||||
check_size_properties<block<matrix<float, 8, 8>, 7, 1>,
|
||||
Block<Matrix<float, 8, 8>, 7, 1>>();
|
||||
|
||||
check_size_properties<block<map<matrixXf>>, Block<Map<MatrixXf>>>();
|
||||
check_size_properties<block<map<matrix<float, 2, 4>>>,
|
||||
Block<Map<Matrix<float, 2, 4>>>>();
|
||||
check_size_properties<block<map<matrixXf>, 3, 6>,
|
||||
Block<Map<MatrixXf>, 3, 6>>();
|
||||
check_size_properties<block<map<matrix<float, 8, 8>>, 3, 6>,
|
||||
Block<Map<Matrix<float, 8, 8>>, 3, 6>>();
|
||||
check_size_properties<block<map<matrixXf>, 1, 6>,
|
||||
Block<Map<MatrixXf>, 1, 6>>();
|
||||
check_size_properties<block<map<matrix<float, 8, 8>>, 1, 6>,
|
||||
Block<Map<Matrix<float, 8, 8>>, 1, 6>>();
|
||||
check_size_properties<block<map<matrixXf>, 7, 1>,
|
||||
Block<Map<MatrixXf>, 7, 1>>();
|
||||
check_size_properties<block<map<matrix<float, 8, 8>>, 7, 1>,
|
||||
Block<Map<Matrix<float, 8, 8>>, 7, 1>>();
|
||||
|
||||
// Row/Col Major
|
||||
{
|
||||
TTS_CONSTEXPR_EQUAL((block<matrixXf>::IsRowMajor),
|
||||
(Block<MatrixXf>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL((block<matrixXf, 1, 8>::IsRowMajor),
|
||||
(Block<MatrixXf, 1, 8>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL((block<matrixXf, 8, 1>::IsRowMajor),
|
||||
(Block<MatrixXf, 8, 1>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL(
|
||||
(block<matrix<float, -1, -1, rotgen::RowMajor>>::IsRowMajor),
|
||||
(Block<Matrix<float, -1, -1, Eigen::RowMajor>>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL(
|
||||
(block<matrix<float, -1, -1, rotgen::ColMajor>>::IsRowMajor),
|
||||
(Block<Matrix<float, -1, -1, Eigen::ColMajor>>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL((block<vectorXf>::IsRowMajor),
|
||||
(Block<VectorXf>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL((block<row_vectorXf>::IsRowMajor),
|
||||
(Block<RowVectorXf>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL((block<vectorXf, 1, 8>::IsRowMajor),
|
||||
(Block<VectorXf, 1, 8>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL((block<row_vectorXf, 8, 1>::IsRowMajor),
|
||||
(Block<RowVectorXf, 8, 1>::IsRowMajor));
|
||||
}
|
||||
};
|
||||
|
||||
TTS_CASE("Compile-Time informations conformance w/r to Eigen - ref")
|
||||
{
|
||||
using namespace rotgen;
|
||||
using namespace Eigen;
|
||||
|
||||
check_size_properties<ref<matrixXf>, Ref<MatrixXf>>();
|
||||
check_size_properties<ref<matrix<float, -1, -1, 0, 3, 3>>,
|
||||
Ref<Matrix<float, -1, -1, 0, 3, 3>>>();
|
||||
check_size_properties<ref<matrix<float, 4, 9>>, Ref<Matrix<float, 4, 9>>>();
|
||||
check_size_properties<ref<vector4f>, Ref<Vector4f>>();
|
||||
check_size_properties<ref<matrix<float, 1, -1>>, Ref<Matrix<float, 1, -1>>>();
|
||||
check_size_properties<ref<row_vector4f>, Ref<RowVector4f>>();
|
||||
check_size_properties<ref<matrix<float, -1, 1>>, Ref<Matrix<float, -1, 1>>>();
|
||||
|
||||
// Row/Col Major
|
||||
{
|
||||
TTS_CONSTEXPR_EQUAL((ref<matrixXf>::IsRowMajor),
|
||||
(Ref<MatrixXf>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL(
|
||||
(ref<matrix<float, -1, -1, rotgen::RowMajor>>::IsRowMajor),
|
||||
(Ref<Matrix<float, -1, -1, Eigen::RowMajor>>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL(
|
||||
(ref<matrix<float, -1, -1, rotgen::ColMajor>>::IsRowMajor),
|
||||
(Ref<Matrix<float, -1, -1, Eigen::ColMajor>>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL((ref<vectorXf>::IsRowMajor),
|
||||
(Ref<VectorXf>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL((ref<row_vectorXf>::IsRowMajor),
|
||||
(Ref<RowVectorXf>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL(
|
||||
(ref<matrix<float, -1, 5, rotgen::RowMajor>>::IsRowMajor),
|
||||
(Ref<Matrix<float, -1, 5, Eigen::RowMajor>>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL(
|
||||
(ref<matrix<float, -1, 7, rotgen::ColMajor>>::IsRowMajor),
|
||||
(Ref<Matrix<float, -1, 7, Eigen::ColMajor>>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL(
|
||||
(ref<matrix<float, 5, -1, rotgen::RowMajor>>::IsRowMajor),
|
||||
(Ref<Matrix<float, 5, -1, Eigen::RowMajor>>::IsRowMajor));
|
||||
TTS_CONSTEXPR_EQUAL(
|
||||
(ref<matrix<float, 7, -1, rotgen::ColMajor>>::IsRowMajor),
|
||||
(Ref<Matrix<float, 7, -1, Eigen::ColMajor>>::IsRowMajor));
|
||||
}
|
||||
};
|
||||
193
test/unit/meta/ref.cpp
Normal file
193
test/unit/meta/ref.cpp
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
//==================================================================================================
|
||||
/*
|
||||
ROTGEN - Runtime Overlay for Eigen
|
||||
Copyright : CODE RECKONS
|
||||
SPDX-License-Identifier: BSL-1.0
|
||||
*/
|
||||
//==================================================================================================
|
||||
#include <rotgen/rotgen.hpp>
|
||||
|
||||
#include "unit/tests.hpp"
|
||||
|
||||
using row_matrixXf = rotgen::matrix<float, -1, -1, rotgen::RowMajor>;
|
||||
|
||||
template<typename Ref, typename Generator> void check_acceptance(Generator f)
|
||||
{
|
||||
auto in = f();
|
||||
rotgen::matrixXf data;
|
||||
bool verbose = ::tts::arguments()[{"--verbose"}];
|
||||
|
||||
auto acceptor = [&](rotgen::ref<Ref> v, auto ptr) {
|
||||
// Check that ref is not a copy
|
||||
TTS_EQUAL(v.data(), ptr);
|
||||
|
||||
// Setup the data correctly
|
||||
data.resize(v.rows(), v.cols());
|
||||
rotgen::setRandom(data);
|
||||
|
||||
// Assign through the ref
|
||||
v = data;
|
||||
if (verbose) std::cout << "V:\n" << v << std::endl << std::endl;
|
||||
};
|
||||
auto constant_acceptor = [&](rotgen::ref<Ref const> v) {
|
||||
return minCoeff(v);
|
||||
};
|
||||
|
||||
acceptor(in, in.data());
|
||||
data.resize(in.rows(), in.cols());
|
||||
|
||||
TTS_EQUAL(in, data);
|
||||
TTS_EQUAL(constant_acceptor(in), minCoeff(data)) << in << "\n"
|
||||
<< data << "\n";
|
||||
}
|
||||
|
||||
TTS_CASE_TPL("Assert ref construction rules - Vector cases",
|
||||
rotgen::vectorXf,
|
||||
rotgen::vector2f,
|
||||
rotgen::row_vectorXf,
|
||||
rotgen::row_vector2f)
|
||||
|
||||
<typename T>(::tts::type<T>)
|
||||
{
|
||||
TTS_WHEN("Call a function accepting a ref<" << ::tts::typename_<T> << "> ...")
|
||||
{
|
||||
rotgen::matrixXf mc(2, 1);
|
||||
rotgen::vectorXf vc(2);
|
||||
rotgen::matrixXf mr(1, 2);
|
||||
row_matrixXf mrr(1, 2);
|
||||
rotgen::row_vectorXf vr(2);
|
||||
rotgen::vector2f vcf;
|
||||
rotgen::row_vector2f vrf;
|
||||
|
||||
TTS_AND_THEN("with a vector-like matrix")
|
||||
{
|
||||
check_acceptance<T>([&]() { return mc; });
|
||||
check_acceptance<T>([&]() { return vc; });
|
||||
check_acceptance<T>([&]() { return mr; });
|
||||
check_acceptance<T>([&]() { return mrr; });
|
||||
check_acceptance<T>([&]() { return vr; });
|
||||
check_acceptance<T>([&]() { return vcf; });
|
||||
check_acceptance<T>([&]() { return vrf; });
|
||||
}
|
||||
|
||||
TTS_AND_THEN("with a vector-like block")
|
||||
{
|
||||
check_acceptance<T>([&]() { return rotgen::head(vc, 2); });
|
||||
check_acceptance<T>([&]() { return rotgen::head(vr, 2); });
|
||||
check_acceptance<T>([&]() { return rotgen::head(vcf, 2); });
|
||||
check_acceptance<T>([&]() { return rotgen::head(vrf, 2); });
|
||||
|
||||
check_acceptance<T>([&]() { return rotgen::head<2>(vc); });
|
||||
check_acceptance<T>([&]() { return rotgen::head<2>(vr); });
|
||||
check_acceptance<T>([&]() { return rotgen::head<2>(vcf); });
|
||||
check_acceptance<T>([&]() { return rotgen::head<2>(vrf); });
|
||||
}
|
||||
|
||||
TTS_AND_THEN("with a vector-like map")
|
||||
{
|
||||
rotgen::map<rotgen::matrixXf> mmc(vc.data(), 2, 1);
|
||||
rotgen::map<rotgen::matrixXf> mmr(vc.data(), 1, 2);
|
||||
rotgen::map<row_matrixXf> mmrr(vc.data(), 1, 2);
|
||||
rotgen::map<rotgen::vectorXf> mvc(vc.data(), vc.size());
|
||||
rotgen::map<rotgen::row_vectorXf> mvr(vr.data(), vr.size());
|
||||
rotgen::map<rotgen::vector2f> mvcf(vc.data());
|
||||
rotgen::map<rotgen::row_vector2f> mvrf(vr.data());
|
||||
|
||||
check_acceptance<T>([&]() { return mmc; });
|
||||
check_acceptance<T>([&]() { return mvc; });
|
||||
check_acceptance<T>([&]() { return mvr; });
|
||||
check_acceptance<T>([&]() { return mmr; });
|
||||
check_acceptance<T>([&]() { return mmrr; });
|
||||
check_acceptance<T>([&]() { return mvcf; });
|
||||
check_acceptance<T>([&]() { return mvrf; });
|
||||
}
|
||||
|
||||
TTS_AND_THEN("with a vector-like ref")
|
||||
{
|
||||
rotgen::ref<row_matrixXf> mmrr(mrr);
|
||||
rotgen::ref<rotgen::vectorXf> mvc(mc);
|
||||
rotgen::ref<rotgen::row_vectorXf> mvr(mc);
|
||||
rotgen::ref<rotgen::vector2f> mvcf(mc);
|
||||
rotgen::ref<rotgen::row_vector2f> mvrf(mc);
|
||||
|
||||
check_acceptance<T>([&]() { return mvc; });
|
||||
check_acceptance<T>([&]() { return mvr; });
|
||||
check_acceptance<T>([&]() { return mmrr; });
|
||||
check_acceptance<T>([&]() { return mvcf; });
|
||||
check_acceptance<T>([&]() { return mvrf; });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TTS_CASE("Assert ref construction rules Matrix cases")
|
||||
{
|
||||
using MatC = rotgen::matrix<float, -1, -1, rotgen::ColMajor>;
|
||||
using MatR = rotgen::matrix<float, -1, -1, rotgen::RowMajor>;
|
||||
|
||||
TTS_WHEN("Call a function accepting a ref<"
|
||||
<< ::tts::typename_<MatC> << "> ...")
|
||||
{
|
||||
rotgen::matrixXf mc(2, 1);
|
||||
rotgen::matrixXf mr(1, 2);
|
||||
rotgen::matrixXf mn(4, 2);
|
||||
row_matrixXf mnr(4, 2);
|
||||
rotgen::matrix<float, 2, 1> mcf(2, 1);
|
||||
rotgen::matrix<float, 1, 2> mrf(1, 2);
|
||||
rotgen::matrix<float, 4, 2> mnf(4, 2);
|
||||
|
||||
TTS_AND_THEN("with a matrix")
|
||||
{
|
||||
check_acceptance<MatC>([&]() { return mc; });
|
||||
check_acceptance<MatC>([&]() { return mr; });
|
||||
check_acceptance<MatC>([&]() { return mn; });
|
||||
check_acceptance<MatC>([&]() { return mcf; });
|
||||
check_acceptance<MatC>([&]() { return mrf; });
|
||||
check_acceptance<MatC>([&]() { return mnf; });
|
||||
|
||||
TTS_EXPECT_COMPILES(mnr, { rotgen::ref<MatC const>{mnr}; });
|
||||
}
|
||||
|
||||
TTS_AND_THEN("with a map")
|
||||
{
|
||||
rotgen::map<rotgen::matrixXf> mmc(mc.data(), 2, 1);
|
||||
rotgen::map<rotgen::matrixXf> mmr(mc.data(), 1, 2);
|
||||
rotgen::map<row_matrixXf> mmrr(mc.data(), 1, 2);
|
||||
rotgen::map<row_matrixXf> mmnr(mnr.data(), 4, 2);
|
||||
rotgen::map<rotgen::vectorXf> mvc(mc.data(), mc.size());
|
||||
rotgen::map<rotgen::row_vectorXf> mvr(mr.data(), mr.size());
|
||||
rotgen::map<rotgen::vector2f> mvcf(mc.data());
|
||||
rotgen::map<rotgen::row_vector2f> mvrf(mr.data());
|
||||
|
||||
check_acceptance<MatC>([&]() { return mmc; });
|
||||
check_acceptance<MatC>([&]() { return mmr; });
|
||||
check_acceptance<MatC>([&]() { return mvc; });
|
||||
check_acceptance<MatC>([&]() { return mvr; });
|
||||
check_acceptance<MatC>([&]() { return mvcf; });
|
||||
check_acceptance<MatC>([&]() { return mvrf; });
|
||||
|
||||
TTS_EXPECT_COMPILES(mmnr, { rotgen::ref<MatC const>{mmnr}; });
|
||||
TTS_EXPECT_COMPILES(mmrr, { rotgen::ref<MatC const>{mmrr}; });
|
||||
}
|
||||
}
|
||||
|
||||
TTS_WHEN("Call a function accepting a ref<"
|
||||
<< ::tts::typename_<MatR> << "> ...")
|
||||
{
|
||||
row_matrixXf mc(2, 1);
|
||||
row_matrixXf mr(1, 2);
|
||||
row_matrixXf mn(4, 2);
|
||||
rotgen::matrix<float, 2, 1> mcf(2, 1);
|
||||
rotgen::matrix<float, 1, 2> mrf(1, 2);
|
||||
rotgen::matrix<float, 4, 2, rotgen::RowMajor> mnf(4, 2);
|
||||
|
||||
TTS_AND_THEN("with a matrix")
|
||||
{
|
||||
check_acceptance<MatR>([&]() { return mc; });
|
||||
check_acceptance<MatR>([&]() { return mr; });
|
||||
check_acceptance<MatR>([&]() { return mn; });
|
||||
check_acceptance<MatR>([&]() { return mcf; });
|
||||
check_acceptance<MatR>([&]() { return mrf; });
|
||||
check_acceptance<MatR>([&]() { return mnf; });
|
||||
}
|
||||
}
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue