Compare commits

..

10 commits

Author SHA1 Message Date
Joel Falcou
8e4359d7e6 Merge branch 'fix/product-api' into 'main'
Fix product proxy internals


See merge request oss/rotgen!53
2026-01-02 22:47:55 +01:00
Joel Falcou
95524402db Fix product proxy internals
See merge request oss/rotgen!53
2026-01-02 22:47:55 +01:00
Joel Falcou
c7b7709cc1 Merge branch 'fix/oopsies' into 'main'
Small fixes that went through last review


See merge request oss/rotgen!52
2026-01-02 20:23:59 +01:00
Joel Falcou
f80f616673 Small fixes that went through last review
See merge request oss/rotgen!52
2026-01-02 20:23:59 +01:00
Joel Falcou
e861ea96ea Merge branch '18-api-2-pseudo-privatization-of-rotgen-entity-member-functions' into 'main'
Resolve "[API-#2] Pseudo-privatization of rotgen entity member functions"

Closes #18

Co-authored-by: Jules Pénuchot <jules@penuchot.com>

See merge request oss/rotgen!50
2025-12-17 20:48:00 +01:00
Jules Pénuchot
e151e136d6 Resolve "[API-#2] Pseudo-privatization of rotgen entity member functions"
Closes #18

Co-authored-by: Jules Pénuchot <jules@penuchot.com>

See merge request oss/rotgen!50
2025-12-17 20:48:00 +01:00
Jules Pénuchot
6489697c05 Merge branch 'jpenuchot/doxygen-awesome-css' into 'main'
Added Doxygen with Doxygen Awesome CSS

Co-authored-by: Jules Pénuchot <jules@penuchot.com>

See merge request oss/rotgen!49
2025-12-08 11:23:43 +01:00
Jules Pénuchot
a7e7fdce34 Added Doxygen with Doxygen Awesome CSS
Co-authored-by: Jules Pénuchot <jules@penuchot.com>

See merge request oss/rotgen!49
2025-12-08 11:23:43 +01:00
Joel Falcou
987d71cc35 Merge branch 'fix/various-manta' into 'main'
More specific fixes


See merge request oss/rotgen!47
2025-12-02 14:40:01 +01:00
Joel Falcou
8e80d1d083 More specific fixes
See merge request oss/rotgen!47
2025-12-02 14:40:01 +01:00
67 changed files with 3238 additions and 1893 deletions

10
.clangd Normal file
View file

@ -0,0 +1,10 @@
CompileFlags:
CompilationDatabase: build/debug/ # Use this to change build type for LSP
Diagnostics:
UnusedIncludes: Strict
ClangTidy:
Add:
- 'bugprone-*'
- 'readability-*'
- 'clang-analyzer-core.*'
- 'clang-analyzer-security.*'

1
.gitignore vendored
View file

@ -12,3 +12,4 @@ _deps
build/* build/*
.idea .idea
.vscode/* .vscode/*
.clangd

View file

@ -39,11 +39,11 @@ test-native-debug:
CXX: clang++ CXX: clang++
CMAKE_PRESET: debug CMAKE_PRESET: debug
test-native-debug-static: test-native-debug-fixed:
<<: *test-native <<: *test-native
variables: variables:
CXX: clang++ CXX: clang++
CMAKE_PRESET: debug-static CMAKE_PRESET: debug-fixed
test-native-debug-et: test-native-debug-et:
<<: *test-native <<: *test-native
@ -57,11 +57,11 @@ test-native-release:
CXX: clang++ CXX: clang++
CMAKE_PRESET: release CMAKE_PRESET: release
test-native-release-static: test-native-release-fixed:
<<: *test-native <<: *test-native
variables: variables:
CXX: clang++ CXX: clang++
CMAKE_PRESET: release-static CMAKE_PRESET: release-fixed
test-native-release-et: test-native-release-et:
<<: *test-native <<: *test-native
@ -78,12 +78,12 @@ test-ubuntu-clang14-debug:
CXXFLAGS: --stdlib=libc++ CXXFLAGS: --stdlib=libc++
CMAKE_PRESET: debug CMAKE_PRESET: debug
test-ubuntu-clang14-debug-static: test-ubuntu-clang14-debug-fixed:
<<: *test-ubuntu2404 <<: *test-ubuntu2404
variables: variables:
CXX: clang++-14 CXX: clang++-14
CXXFLAGS: --stdlib=libc++ CXXFLAGS: --stdlib=libc++
CMAKE_PRESET: debug-static CMAKE_PRESET: debug-fixed
test-ubuntu-clang14-debug-et: test-ubuntu-clang14-debug-et:
<<: *test-ubuntu2404 <<: *test-ubuntu2404
@ -99,12 +99,12 @@ test-ubuntu-clang14-release:
CXXFLAGS: --stdlib=libc++ CXXFLAGS: --stdlib=libc++
CMAKE_PRESET: release CMAKE_PRESET: release
test-ubuntu-clang14-release-static: test-ubuntu-clang14-release-fixed:
<<: *test-ubuntu2404 <<: *test-ubuntu2404
variables: variables:
CXX: clang++-14 CXX: clang++-14
CXXFLAGS: --stdlib=libc++ CXXFLAGS: --stdlib=libc++
CMAKE_PRESET: release-static CMAKE_PRESET: release-fixed
test-ubuntu-clang14-release-et: test-ubuntu-clang14-release-et:
<<: *test-ubuntu2404 <<: *test-ubuntu2404
@ -121,11 +121,11 @@ test-ubuntu-gcc-debug:
CXX: g++ CXX: g++
CMAKE_PRESET: debug CMAKE_PRESET: debug
test-ubuntu-gcc-debug-static: test-ubuntu-gcc-debug-fixed:
<<: *test-ubuntu2404 <<: *test-ubuntu2404
variables: variables:
CXX: g++ CXX: g++
CMAKE_PRESET: debug-static CMAKE_PRESET: debug-fixed
test-ubuntu-gcc-debug-et: test-ubuntu-gcc-debug-et:
<<: *test-ubuntu2404 <<: *test-ubuntu2404
@ -139,11 +139,11 @@ test-ubuntu-gcc-release:
CXX: g++ CXX: g++
CMAKE_PRESET: release CMAKE_PRESET: release
test-ubuntu-gcc-release-static: test-ubuntu-gcc-release-fixed:
<<: *test-ubuntu2404 <<: *test-ubuntu2404
variables: variables:
CXX: g++ CXX: g++
CMAKE_PRESET: release-static CMAKE_PRESET: release-fixed
test-ubuntu-gcc-release-et: test-ubuntu-gcc-release-et:
<<: *test-ubuntu2404 <<: *test-ubuntu2404

View file

@ -96,3 +96,8 @@ include(${ROTGEN_SOURCE_DIR}/cmake/config/rotgen-install.cmake)
## Setup the library's Tests ## Setup the library's Tests
##============================================================================== ##==============================================================================
add_subdirectory(test) add_subdirectory(test)
##==============================================================================
## Setup the library's documentation
##==============================================================================
include(${ROTGEN_SOURCE_DIR}/cmake/docs.cmake)

View file

@ -42,21 +42,21 @@
} }
}, },
{ {
"name": "release-static", "name": "release-fixed",
"displayName": "Release (Static size)", "displayName": "Release (Fixed size)",
"description": "Release (Static size) build", "description": "Release (Fixed size) build",
"generator": "Ninja", "generator": "Ninja",
"binaryDir": "${sourceDir}/build/release-static", "binaryDir": "${sourceDir}/build/release-fixed",
"cacheVariables": { "cacheVariables": {
"ROTGEN_MAX_SIZE": "16" "ROTGEN_MAX_SIZE": "16"
} }
}, },
{ {
"name": "debug-static", "name": "debug-fixed",
"displayName": "Debug (Static size)", "displayName": "Debug (Fixed size)",
"description": "Debug (Static size) build", "description": "Debug (Fixed size) build",
"generator": "Ninja", "generator": "Ninja",
"binaryDir": "${sourceDir}/build/debug-static", "binaryDir": "${sourceDir}/build/debug-fixed",
"cacheVariables": { "cacheVariables": {
"ROTGEN_MAX_SIZE": "16" "ROTGEN_MAX_SIZE": "16"
} }
@ -90,8 +90,8 @@
"configurePreset": "release" "configurePreset": "release"
}, },
{ {
"name": "release-static", "name": "release-fixed",
"configurePreset": "release-static" "configurePreset": "release-fixed"
}, },
{ {
"name": "release-et", "name": "release-et",
@ -102,8 +102,8 @@
"configurePreset": "debug" "configurePreset": "debug"
}, },
{ {
"name": "debug-static", "name": "debug-fixed",
"configurePreset": "debug-static" "configurePreset": "debug-fixed"
}, },
{ {
"name": "debug-et", "name": "debug-et",

41
cmake/docs.cmake Normal file
View file

@ -0,0 +1,41 @@
##==============================================================================
## ROTGEN - Runtime Overlay for Eigen
## Copyright : CODE RECKONS
## SPDX-License-Identifier: BSL-1.0
##==============================================================================
find_package(Doxygen COMPONENTS dot OPTIONAL_COMPONENTS mscgen dia)
if(Doxygen_FOUND)
# Documentation options
set(DOXYGEN_EXTRACT_ALL YES)
set(DOXYGEN_GENERATE_TREEVIEW YES)
set(DOXYGEN_EXCLUDE_PATTERNS */build/* */test/*)
set(DOXYGEN_USE_MDFILE_AS_MAINPAGE ${CMAKE_SOURCE_DIR}/README.md)
set(DOXYGEN_EXAMPLE_PATH ${CMAKE_SOURCE_DIR})
set(DOXYGEN_DOT_TRANSPARENT YES)
set(DOXYGEN_IMAGE_PATH ${CMAKE_SOURCE_DIR})
# ============================================================================
# Doxygen Awesome CSS
include(FetchContent)
FetchContent_Declare(
doxygen_awesome_content
GIT_REPOSITORY https://github.com/jothepro/doxygen-awesome-css.git
GIT_TAG v2.4.1
GIT_SHALLOW)
FetchContent_GetProperties(doxygen_awesome_content)
if(NOT doxygen_awesome_content_POPULATED)
FetchContent_Populate(doxygen_awesome_content)
endif()
set(DOXYGEN_HTML_EXTRA_STYLESHEET
${doxygen_awesome_content_SOURCE_DIR}/doxygen-awesome.css)
doxygen_add_docs(docs)
endif()

View file

@ -58,10 +58,10 @@ function(print_configuration_summary FORCE_DYNAMIC_VAR FORCE_CONFIG_REASON MAX_S
if(${FORCE_DYNAMIC_VAR}) if(${FORCE_DYNAMIC_VAR})
message(STATUS " Configuration mode: DYNAMIC") message(STATUS " Configuration mode: DYNAMIC")
if(${FORCE_CONFIG_REASON}) if(${FORCE_CONFIG_REASON})
message(STATUS " Reason : No static size options were provided") message(STATUS " Reason : No fixed size options were provided")
endif() endif()
else() else()
message(STATUS " Configuration mode: STATIC") message(STATUS " Configuration mode: FIXED SIZE")
message(STATUS " Expression Templates: ${ROTGEN_ENABLE_EXPRESSION_TEMPLATES}") message(STATUS " Expression Templates: ${ROTGEN_ENABLE_EXPRESSION_TEMPLATES}")
endif() endif()

View file

@ -25,20 +25,20 @@ namespace rotgen
int rank() const { return parent::rank(); } int rank() const { return parent::rank(); }
m_type U() const { return parent::U(); } m_type matrixU() const { return parent::U(); }
m_type D() const { return parent::D(); } m_type matrixD() const { return parent::D(); }
m_type V() const { return parent::V(); } m_type matrixV() const { return parent::V(); }
d_type singular_values() const { return parent::singular_values(); } d_type singularValues() const { return parent::singular_values(); }
m_type U(int r) const { return parent::U(r); } m_type matrixU(int r) const { return parent::U(r); }
m_type D(int r) const { return parent::D(r); } m_type matrixD(int r) const { return parent::D(r); }
m_type V(int r) const { return parent::V(r); } m_type matrixV(int r) const { return parent::V(r); }
m_type singular_values(int r) const { return parent::singular_values(r); } m_type singularValues(int r) const { return parent::singular_values(r); }
}; };
} }

View file

@ -31,28 +31,28 @@ namespace rotgen
int rank() const { return svd_.rank(); } int rank() const { return svd_.rank(); }
auto singular_values() const auto singularValues() const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return detail::as_concrete_t<d_type, matrix>{svd_.singularValues()}; return detail::as_concrete_t<d_type, matrix>{svd_.singularValues()};
else return svd_.singularValues(); else return svd_.singularValues();
} }
auto U() const auto matrixU() const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return detail::as_concrete_t<u_type, matrix>{svd_.matrixU()}; return detail::as_concrete_t<u_type, matrix>{svd_.matrixU()};
else return svd_.matrixU(); else return svd_.matrixU();
} }
auto V() const auto matrixV() const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return detail::as_concrete_t<v_type, matrix>{svd_.matrixV()}; return detail::as_concrete_t<v_type, matrix>{svd_.matrixV()};
else return svd_.matrixV(); else return svd_.matrixV();
} }
auto D() const auto matrixD() const
{ {
auto d = svd_.singularValues().asDiagonal(); auto d = svd_.singularValues().asDiagonal();
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
@ -61,7 +61,7 @@ namespace rotgen
else return d; else return d;
} }
auto singular_values(int r) const auto singularValues(int r) const
{ {
auto that = svd_.singularValues().head(r); auto that = svd_.singularValues().head(r);
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
@ -69,7 +69,7 @@ namespace rotgen
else return svd_.singularValues(); else return svd_.singularValues();
} }
auto U(int r) const auto matrixU(int r) const
{ {
auto that = svd_.matrixU().leftCols(r); auto that = svd_.matrixU().leftCols(r);
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
@ -77,7 +77,7 @@ namespace rotgen
else return that; else return that;
} }
auto V(int r) const auto matrixV(int r) const
{ {
auto that = svd_.matrixV().leftCols(r); auto that = svd_.matrixV().leftCols(r);
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
@ -85,7 +85,7 @@ namespace rotgen
else return that; else return that;
} }
auto D(int r) const auto matrixD(int r) const
{ {
auto d = svd_.singularValues().head(r).asDiagonal(); auto d = svd_.singularValues().head(r).asDiagonal();
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)

View file

@ -12,6 +12,26 @@
namespace rotgen::concepts namespace rotgen::concepts
{ {
//================================================================================================
//! @brief Check if a type is a Rotgen block.
//================================================================================================
template<typename T>
concept block =
requires { typename std::remove_cvref_t<T>::rotgen_block_tag; };
//================================================================================================
//! @brief Check if a type is a Rotgen matrix.
//================================================================================================
template<typename T>
concept matrix =
requires { typename std::remove_cvref_t<T>::rotgen_matrix_tag; };
//================================================================================================
//! @brief Check if a type is a Rotgen map.
//================================================================================================
template<typename T>
concept map = requires { typename std::remove_cvref_t<T>::rotgen_map_tag; };
//================================================================================================ //================================================================================================
//! @brief Check if a type is a Rotgen reference. //! @brief Check if a type is a Rotgen reference.
//================================================================================================ //================================================================================================
@ -36,10 +56,8 @@ namespace rotgen::concepts
//! @brief Check if a type is a ROTGEN type. //! @brief Check if a type is a ROTGEN type.
//================================================================================================ //================================================================================================
template<typename T> template<typename T>
concept entity = requires(T const&) { concept entity =
typename std::remove_cvref_t<T>::rotgen_tag; requires(T const&) { typename std::remove_cvref_t<T>::rotgen_tag; };
typename std::remove_cvref_t<T>::parent;
};
//================================================================================================ //================================================================================================
//! @brief Check if a type is an EIGEN type. //! @brief Check if a type is an EIGEN type.

View file

@ -7,11 +7,12 @@
//================================================================================================== //==================================================================================================
#pragma once #pragma once
#include <rotgen/detail/assert.hpp>
#include <rotgen/concepts.hpp> #include <rotgen/concepts.hpp>
#include <rotgen/container/block/dynamic/impl.hpp> #include <rotgen/container/block/dynamic/impl.hpp>
#include <rotgen/container/matrix/dynamic.hpp> #include <rotgen/container/matrix/dynamic.hpp>
#include <cassert>
#include <initializer_list> #include <initializer_list>
namespace rotgen namespace rotgen
@ -76,14 +77,37 @@ namespace rotgen
using parent::operator=; using parent::operator=;
block& operator=(concepts::entity auto const& other) template<concepts::entity Src>
block& operator=(Src const& other)
requires(!is_immutable) requires(!is_immutable)
{ {
assert(parent::rows() == other.rows() && parent::cols() == other.cols()); if constexpr (IsVectorAtCompileTime && Src::IsVectorAtCompileTime)
for (rotgen::Index r = 0; r < parent::rows(); ++r) {
for (rotgen::Index c = 0; c < parent::cols(); ++c) ROTGEN_ASSERT(parent::size() == other.size(),
(*this)(r, c) = other(r, c); "Block assignment from 1D source doesn't match size");
for (rotgen::Index i = 0; i < parent::size(); ++i)
(*this)[i] = other[i];
}
else if constexpr (IsVectorAtCompileTime && !Src::IsVectorAtCompileTime)
{
auto r = other._rows();
auto c = other._cols();
ROTGEN_ASSERT(r == 1 || c == 1, "Block assignment from dynamic sized "
"source doesn't match static size");
for (rotgen::Index i = 0; i < parent::size(); ++i)
(*this)[i] = other(r == 1 ? 0 : i, c == 1 ? 0 : i);
}
else
{
ROTGEN_ASSERT(parent::_rows() == other._rows() &&
parent::_cols() == other._cols(),
"Block assignment size mismatch");
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; return *this;
} }
@ -167,13 +191,6 @@ namespace rotgen
block(parent const& base) : parent(base) {} block(parent const& base) : parent(base) {}
bool is_contiguous_linear() const
{
if (parent::innerStride() != 1) return false;
if constexpr (IsRowMajor) return parent::outerStride() == parent::cols();
else return parent::outerStride() == parent::rows();
}
value_type& operator()(Index i, Index j) value_type& operator()(Index i, Index j)
requires(!is_immutable) requires(!is_immutable)
{ {
@ -183,7 +200,6 @@ namespace rotgen
value_type& operator()(Index i) value_type& operator()(Index i)
requires(!is_immutable && IsVectorAtCompileTime) requires(!is_immutable && IsVectorAtCompileTime)
{ {
assert(is_contiguous_linear());
return parent::operator()(i); return parent::operator()(i);
} }
@ -201,7 +217,6 @@ namespace rotgen
value_type operator()(Index i) const value_type operator()(Index i) const
requires(IsVectorAtCompileTime) requires(IsVectorAtCompileTime)
{ {
assert(is_contiguous_linear());
return parent::operator()(i); return parent::operator()(i);
} }
@ -211,66 +226,69 @@ namespace rotgen
return (*this)(i); return (*this)(i);
} }
auto evaluate() const { return *this; } concrete_type _evaluate() const { return concrete_type{*this}; }
decltype(auto) noalias() const { return *this; } decltype(auto) _noalias() const { return *this; }
decltype(auto) noalias() { return *this; } decltype(auto) _noalias() { return *this; }
concrete_type normalized() const concrete_type _normalized() const
requires(IsVectorAtCompileTime) requires(IsVectorAtCompileTime)
{ {
return concrete_type(base().normalized()); return concrete_type(base()._normalized());
} }
transposed_type transpose() const transposed_type _transpose() const
{ {
return transposed_type(base().transpose()); return transposed_type(base()._transpose());
} }
concrete_type conjugate() const concrete_type _conjugate() const
{ {
return concrete_type(base().conjugate()); return concrete_type(base()._conjugate());
} }
transposed_type adjoint() const transposed_type _adjoint() const
{ {
return transposed_type(base().adjoint()); return transposed_type(base()._adjoint());
} }
concrete_type cwiseAbs() const { return concrete_type(base().cwiseAbs()); } concrete_type _cwiseAbs() const
concrete_type cwiseAbs2() const
{ {
return concrete_type(base().cwiseAbs2()); return concrete_type(base()._cwiseAbs());
} }
concrete_type cwiseInverse() const concrete_type _cwiseAbs2() const
{ {
return concrete_type(base().cwiseInverse()); return concrete_type(base()._cwiseAbs2());
} }
concrete_type cwiseSqrt() const concrete_type _cwiseInverse() const
{ {
return concrete_type(base().cwiseSqrt()); return concrete_type(base()._cwiseInverse());
} }
void normalize() concrete_type _cwiseSqrt() const
{
return concrete_type(base()._cwiseSqrt());
}
void _normalize()
requires(!is_immutable && IsVectorAtCompileTime) requires(!is_immutable && IsVectorAtCompileTime)
{ {
parent::normalize(); parent::_normalize();
} }
void transposeInPlace() void _transposeInPlace()
requires(!is_immutable) requires(!is_immutable)
{ {
parent::transposeInPlace(); parent::_transposeInPlace();
} }
void adjointInPlace() void _adjointInPlace()
requires(!is_immutable) requires(!is_immutable)
{ {
parent::adjointInPlace(); parent::_adjointInPlace();
} }
friend bool operator==(block const& lhs, block const& rhs) friend bool operator==(block const& lhs, block const& rhs)
@ -278,17 +296,19 @@ namespace rotgen
return static_cast<parent const&>(lhs) == static_cast<parent const&>(rhs); return static_cast<parent const&>(lhs) == static_cast<parent const&>(rhs);
} }
block& operator+=(block const& rhs) template<concepts::entity E>
block& operator+=(E const& rhs)
requires(!is_immutable) requires(!is_immutable)
{ {
base() += static_cast<parent const&>(rhs); base() += rhs.base();
return *this; return *this;
} }
block& operator-=(block const& rhs) template<concepts::entity E>
block& operator-=(E const& rhs)
requires(!is_immutable) requires(!is_immutable)
{ {
base() -= static_cast<parent const&>(rhs); base() -= rhs.base();
return *this; return *this;
} }
@ -297,10 +317,11 @@ namespace rotgen
return concrete_type(static_cast<parent const&>(*this).operator-()); return concrete_type(static_cast<parent const&>(*this).operator-());
} }
block& operator*=(block const& rhs) template<concepts::entity E>
block& operator*=(E const& rhs)
requires(!is_immutable) requires(!is_immutable)
{ {
base() *= static_cast<parent const&>(rhs); base() *= rhs.base();
return *this; return *this;
} }
@ -318,154 +339,155 @@ namespace rotgen
return *this; return *this;
} }
auto minCoeff() const { return parent::minCoeff(); } auto _minCoeff() const { return parent::_minCoeff(); }
auto maxCoeff() const { return parent::maxCoeff(); } auto _maxCoeff() const { return parent::_maxCoeff(); }
template<std::integral IndexType> template<std::integral IndexType>
auto minCoeff(IndexType* row, IndexType* col) const auto _minCoeff(IndexType* row, IndexType* col) const
{ {
Index r, c; Index r, c;
auto result = parent::minCoeff(&r, &c); auto result = parent::_minCoeff(&r, &c);
*row = r; *row = r;
*col = c; *col = c;
return result; return result;
} }
template<std::integral IndexType> template<std::integral IndexType>
auto maxCoeff(IndexType* row, IndexType* col) const auto _maxCoeff(IndexType* row, IndexType* col) const
{ {
Index r, c; Index r, c;
auto result = parent::maxCoeff(&r, &c); auto result = parent::_maxCoeff(&r, &c);
*row = r; *row = r;
*col = c; *col = c;
return result; return result;
} }
static concrete_type Zero() static concrete_type _Zero()
requires(Rows != -1 && Cols != -1) requires(Rows != -1 && Cols != -1)
{ {
return parent::Zero(Rows, Cols); return parent::_Zero(Rows, Cols);
} }
static concrete_type Zero(int rows, int cols) static concrete_type _Zero(int rows, int cols)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(rows == Rows && ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size"); "Mismatched between dynamic and static row size");
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(cols == Cols && ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size"); "Mismatched between dynamic and static column size");
return parent::Zero(rows, cols); return parent::_Zero(rows, cols);
} }
static concrete_type Ones() static concrete_type _Ones()
requires(Rows != -1 && Cols != -1) requires(Rows != -1 && Cols != -1)
{ {
return parent::Ones(Rows, Cols); return parent::_Ones(Rows, Cols);
} }
static concrete_type Ones(int rows, int cols) static concrete_type _Ones(int rows, int cols)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(rows == Rows && ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size"); "Mismatched between dynamic and static row size");
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(cols == Cols && ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size"); "Mismatched between dynamic and static column size");
return parent::Ones(rows, cols); return parent::_Ones(rows, cols);
} }
static concrete_type Constant(value_type value) static concrete_type _Constant(value_type value)
requires(Rows != -1 && Cols != -1) requires(Rows != -1 && Cols != -1)
{ {
return parent::Constant(Rows, Cols, static_cast<double>(value)); return parent::_Constant(Rows, Cols, static_cast<double>(value));
} }
static concrete_type Constant(int rows, int cols, value_type value) static concrete_type _Constant(int rows, int cols, value_type value)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(rows == Rows && ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size"); "Mismatched between dynamic and static row size");
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(cols == Cols && ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size"); "Mismatched between dynamic and static column size");
return parent::Constant(rows, cols, static_cast<double>(value)); return parent::_Constant(rows, cols, static_cast<double>(value));
} }
static concrete_type Random() static concrete_type _Random()
requires(Rows != -1 && Cols != -1) requires(Rows != -1 && Cols != -1)
{ {
return parent::Random(Rows, Cols); return parent::_Random(Rows, Cols);
} }
static concrete_type Random(int rows, int cols) static concrete_type _Random(int rows, int cols)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(rows == Rows && ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size"); "Mismatched between dynamic and static row size");
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(cols == Cols && ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size"); "Mismatched between dynamic and static column size");
return parent::Random(rows, cols); return parent::_Random(rows, cols);
} }
static concrete_type Identity() static concrete_type _Identity()
requires(Rows != -1 && Cols != -1) requires(Rows != -1 && Cols != -1)
{ {
return parent::Identity(Rows, Cols); return parent::_Identity(Rows, Cols);
} }
static concrete_type Identity(int rows, int cols) static concrete_type _Identity(int rows, int cols)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(rows == Rows && ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size"); "Mismatched between dynamic and static row size");
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(cols == Cols && ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size"); "Mismatched between dynamic and static column size");
return parent::Identity(rows, cols); return parent::_Identity(rows, cols);
} }
block& setOnes() block& _setOnes()
requires(!is_immutable) requires(!is_immutable)
{ {
parent::assign(parent::Ones(parent::rows(), parent::cols())); parent::assign(parent::_Ones(parent::_rows(), parent::_cols()));
return *this; return *this;
} }
block& setZero() block& _setZero()
requires(!is_immutable) requires(!is_immutable)
{ {
parent::assign(parent::Zero(parent::rows(), parent::cols())); parent::assign(parent::_Zero(parent::_rows(), parent::_cols()));
return *this; return *this;
} }
block& setConstant(value_type value) block& _setConstant(value_type value)
requires(!is_immutable) requires(!is_immutable)
{ {
parent::assign(parent::Constant(parent::rows(), parent::cols(), value)); parent::assign(
parent::_Constant(parent::_rows(), parent::_cols(), value));
return *this; return *this;
} }
block& setRandom() block& _setRandom()
requires(!is_immutable) requires(!is_immutable)
{ {
parent::assign(parent::Random(parent::rows(), parent::cols())); parent::assign(parent::_Random(parent::_rows(), parent::_cols()));
return *this; return *this;
} }
block& setIdentity() block& _setIdentity()
requires(!is_immutable) requires(!is_immutable)
{ {
parent::assign(parent::Identity(parent::rows(), parent::cols())); parent::assign(parent::_Identity(parent::_rows(), parent::_cols()));
return *this; return *this;
} }
template<int P> value_type lpNorm() const template<int P> value_type _lpNorm() const
{ {
assert(P == 1 || P == 2 || P == Infinity); static_assert(P == 1 || P == 2 || P == Infinity);
return parent::lpNorm(P); return parent::_lpNorm(P);
} }
parent& base() { return static_cast<parent&>(*this); } parent& base() { return static_cast<parent&>(*this); }
@ -477,41 +499,41 @@ namespace rotgen
auto operator+(block<Ref, R, C, I> const& lhs, block<Ref, R, C, I> const& rhs) auto operator+(block<Ref, R, C, I> const& lhs, block<Ref, R, C, I> const& rhs)
{ {
using concrete_type = typename block<Ref, R, C, I>::concrete_type; using concrete_type = typename block<Ref, R, C, I>::concrete_type;
return concrete_type(lhs.base().add(rhs)); return concrete_type(lhs.base()._add(rhs));
} }
template<typename Ref, int R, int C, bool I> template<typename Ref, int R, int C, bool I>
auto operator-(block<Ref, R, C, I> const& lhs, block<Ref, R, C, I> const& rhs) auto operator-(block<Ref, R, C, I> const& lhs, block<Ref, R, C, I> const& rhs)
{ {
using concrete_type = typename block<Ref, R, C, I>::concrete_type; using concrete_type = typename block<Ref, R, C, I>::concrete_type;
return concrete_type(lhs.base().sub(rhs)); return concrete_type(lhs.base()._sub(rhs));
} }
template<typename Ref, int R, int C, bool I> template<typename Ref, int R, int C, bool I>
auto operator*(block<Ref, R, C, I> const& lhs, block<Ref, R, C, I> const& rhs) auto operator*(block<Ref, R, C, I> const& lhs, block<Ref, R, C, I> const& rhs)
{ {
using concrete_type = typename block<Ref, R, C, I>::concrete_type; using concrete_type = typename block<Ref, R, C, I>::concrete_type;
return concrete_type(lhs.base().mul(rhs)); return concrete_type(lhs.base()._mul(rhs));
} }
template<typename Ref, int R, int C, bool I> template<typename Ref, int R, int C, bool I>
auto operator*(block<Ref, R, C, I> const& lhs, double rhs) auto operator*(block<Ref, R, C, I> const& lhs, double rhs)
{ {
using concrete_type = typename block<Ref, R, C, I>::concrete_type; using concrete_type = typename block<Ref, R, C, I>::concrete_type;
return concrete_type(lhs.base().mul(rhs)); return concrete_type(lhs.base()._mul(rhs));
} }
template<typename Ref, int R, int C, bool I> template<typename Ref, int R, int C, bool I>
auto operator*(double lhs, block<Ref, R, C, I> const& rhs) auto operator*(double lhs, block<Ref, R, C, I> const& rhs)
{ {
using concrete_type = typename block<Ref, R, C, I>::concrete_type; using concrete_type = typename block<Ref, R, C, I>::concrete_type;
return concrete_type(rhs.base().mul(lhs)); return concrete_type(rhs.base()._mul(lhs));
} }
template<typename Ref, int R, int C, bool I> template<typename Ref, int R, int C, bool I>
auto operator/(block<Ref, R, C, I> const& lhs, double rhs) auto operator/(block<Ref, R, C, I> const& lhs, double rhs)
{ {
using concrete_type = typename block<Ref, R, C, I>::concrete_type; using concrete_type = typename block<Ref, R, C, I>::concrete_type;
return concrete_type(lhs.base().div(rhs)); return concrete_type(lhs.base()._div(rhs));
} }
} }

View file

@ -2,28 +2,36 @@
#define TYPE double #define TYPE double
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col) #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _col)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row) #define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row) #define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col) #define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
#include <rotgen/container/block/dynamic/model.hpp> #include <rotgen/container/block/dynamic/model.hpp>
#undef CLASSNAME #undef CLASSNAME
#undef CLASSCONSTNAME
#undef TRANSCLASSNAME #undef TRANSCLASSNAME
#undef TRANSNAME #undef TRANSNAME
#undef SOURCENAME #undef SOURCENAME
#undef MAPNAME #undef MAPNAME
#undef TRANSMAPNAME
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row) #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _row)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col) #define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col) #define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row) #define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
#include <rotgen/container/block/dynamic/model.hpp> #include <rotgen/container/block/dynamic/model.hpp>
#undef CLASSNAME #undef CLASSNAME
#undef CLASSCONSTNAME
#undef TRANSCLASSNAME #undef TRANSCLASSNAME
#undef TRANSNAME #undef TRANSNAME
#undef SOURCENAME #undef SOURCENAME
#undef MAPNAME #undef MAPNAME
#undef TRANSMAPNAME
#undef SIZE #undef SIZE
#undef TYPE #undef TYPE
@ -32,28 +40,36 @@
#define TYPE float #define TYPE float
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col) #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _col)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row) #define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row) #define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col) #define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
#include <rotgen/container/block/dynamic/model.hpp> #include <rotgen/container/block/dynamic/model.hpp>
#undef CLASSNAME #undef CLASSNAME
#undef CLASSCONSTNAME
#undef TRANSCLASSNAME #undef TRANSCLASSNAME
#undef TRANSNAME #undef TRANSNAME
#undef SOURCENAME #undef SOURCENAME
#undef MAPNAME #undef MAPNAME
#undef TRANSMAPNAME
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row) #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _row)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col) #define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col) #define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row) #define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
#include <rotgen/container/block/dynamic/model.hpp> #include <rotgen/container/block/dynamic/model.hpp>
#undef CLASSNAME #undef CLASSNAME
#undef CLASSCONSTNAME
#undef TRANSCLASSNAME #undef TRANSCLASSNAME
#undef TRANSNAME #undef TRANSNAME
#undef SOURCENAME #undef SOURCENAME
#undef MAPNAME #undef MAPNAME
#undef TRANSMAPNAME
#undef SIZE #undef SIZE
#undef TYPE #undef TYPE

View file

@ -23,6 +23,7 @@ public:
CLASSNAME(MAPNAME CONST& r, Index i0, Index j0, Index ni, Index nj); CLASSNAME(MAPNAME CONST& r, Index i0, Index j0, Index ni, Index nj);
CLASSNAME(CLASSNAME 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(TRANSCLASSNAME CONST& r, Index i0, Index j0, Index ni, Index nj);
CLASSNAME(TRANSMAPNAME CONST& r, Index i0, Index j0, Index ni, Index nj);
CLASSNAME(CLASSNAME const& other); CLASSNAME(CLASSNAME const& other);
CLASSNAME(CLASSNAME&&) noexcept; CLASSNAME(CLASSNAME&&) noexcept;
@ -38,51 +39,61 @@ public:
void assign(SOURCENAME const&); void assign(SOURCENAME const&);
#endif #endif
Index rows() const;
Index cols() const;
Index size() const; Index size() const;
Index innerStride() const; Index _rows() const;
Index outerStride() const; Index _cols() const;
Index startRow() const; Index _innerStride() const;
Index startCol() const; Index _outerStride() const;
SOURCENAME normalized() const; Index _startRow() const;
SOURCENAME transpose() const; Index _startCol() const;
SOURCENAME conjugate() const;
SOURCENAME adjoint() const;
SOURCENAME cwiseAbs() const; SOURCENAME _normalized() const;
SOURCENAME cwiseAbs2() const; SOURCENAME _transpose() const;
SOURCENAME cwiseInverse() const; SOURCENAME _conjugate() const;
SOURCENAME cwiseSqrt() const; SOURCENAME _adjoint() const;
SOURCENAME _cwiseAbs() const;
SOURCENAME _cwiseAbs2() const;
SOURCENAME _cwiseInverse() const;
SOURCENAME _cwiseSqrt() const;
#if !defined(USE_CONST) #if !defined(USE_CONST)
void normalize(); void _normalize();
void transposeInPlace(); void _transposeInPlace();
void adjointInPlace(); void _adjointInPlace();
#endif #endif
TYPE sum() const; TYPE _sum() const;
TYPE prod() const; TYPE _prod() const;
TYPE mean() const; TYPE _mean() const;
TYPE trace() const; TYPE _trace() const;
TYPE maxCoeff() const; TYPE _maxCoeff() const;
TYPE minCoeff() const; TYPE _minCoeff() const;
TYPE maxCoeff(Index* row, Index* col) const; TYPE _maxCoeff(Index* row, Index* col) const;
TYPE minCoeff(Index* row, Index* col) const; TYPE _minCoeff(Index* row, Index* col) const;
TYPE squaredNorm() const; TYPE _squaredNorm() const;
TYPE norm() const; TYPE _norm() const;
TYPE lpNorm(int p) const; TYPE _lpNorm(int p) const;
#if !defined(USE_CONST) #if !defined(USE_CONST)
TYPE& operator()(Index i, Index j); TYPE& operator()(Index i, Index j);
TYPE& operator()(Index index); TYPE& operator()(Index index);
CLASSNAME& operator+=(CLASSNAME const& rhs); CLASSNAME& operator+=(CLASSNAME const& rhs);
CLASSNAME& operator+=(CLASSCONSTNAME const& rhs);
CLASSNAME& operator+=(SOURCENAME const& rhs);
CLASSNAME& operator+=(TRANSNAME const& rhs);
CLASSNAME& operator-=(CLASSNAME const& rhs); CLASSNAME& operator-=(CLASSNAME const& rhs);
CLASSNAME& operator-=(CLASSCONSTNAME const& rhs);
CLASSNAME& operator-=(SOURCENAME const& rhs);
CLASSNAME& operator-=(TRANSNAME const& rhs);
CLASSNAME& operator*=(CLASSNAME const& rhs); CLASSNAME& operator*=(CLASSNAME const& rhs);
CLASSNAME& operator*=(CLASSCONSTNAME const& rhs);
CLASSNAME& operator*=(SOURCENAME const& rhs);
CLASSNAME& operator*=(TRANSNAME const& rhs);
CLASSNAME& operator*=(TYPE d); CLASSNAME& operator*=(TYPE d);
CLASSNAME& operator/=(TYPE d); CLASSNAME& operator/=(TYPE d);
#endif #endif
@ -91,11 +102,11 @@ public:
TYPE operator()(Index index) const; TYPE operator()(Index index) const;
SOURCENAME operator-() const; SOURCENAME operator-() const;
SOURCENAME add(CLASSNAME const& rhs) const; SOURCENAME _add(CLASSNAME const& rhs) const;
SOURCENAME sub(CLASSNAME const& rhs) const; SOURCENAME _sub(CLASSNAME const& rhs) const;
SOURCENAME mul(CLASSNAME const& rhs) const; SOURCENAME _mul(CLASSNAME const& rhs) const;
SOURCENAME mul(TYPE s) const; SOURCENAME _mul(TYPE s) const;
SOURCENAME div(TYPE s) const; SOURCENAME _div(TYPE s) const;
friend ROTGEN_EXPORT std::ostream& operator<<(std::ostream&, friend ROTGEN_EXPORT std::ostream& operator<<(std::ostream&,
CLASSNAME const&); CLASSNAME const&);
@ -111,23 +122,23 @@ public:
#endif #endif
const TYPE* data() const; const TYPE* data() const;
static SOURCENAME Zero(Index r, Index c) { return SOURCENAME::Zero(r, c); } static SOURCENAME _Zero(Index r, Index c) { return SOURCENAME::_Zero(r, c); }
static SOURCENAME Ones(Index r, Index c) { return SOURCENAME::Ones(r, c); } static SOURCENAME _Ones(Index r, Index c) { return SOURCENAME::_Ones(r, c); }
static SOURCENAME Constant(Index r, Index c, TYPE v) static SOURCENAME _Constant(Index r, Index c, TYPE v)
{ {
return SOURCENAME::Constant(r, c, v); return SOURCENAME::_Constant(r, c, v);
} }
static SOURCENAME Random(Index r, Index c) static SOURCENAME _Random(Index r, Index c)
{ {
return SOURCENAME::Random(r, c); return SOURCENAME::_Random(r, c);
} }
static SOURCENAME Identity(Index r, Index c) static SOURCENAME _Identity(Index r, Index c)
{ {
return SOURCENAME::Identity(r, c); return SOURCENAME::_Identity(r, c);
} }
public: public:

View file

@ -193,25 +193,21 @@ namespace rotgen
parent const& base() const { return static_cast<parent const&>(*this); } parent const& base() const { return static_cast<parent const&>(*this); }
auto evaluate() const auto _evaluate() const { return concrete_type(base().eval()); }
{
auto res = base().eval();
return as_concrete_type<decltype(res)>(res);
}
decltype(auto) noalias() const decltype(auto) _noalias() const
{ {
if constexpr (use_expression_templates) return base().noalias(); if constexpr (use_expression_templates) return base().noalias();
else return *this; else return *this;
} }
decltype(auto) noalias() decltype(auto) _noalias()
{ {
if constexpr (use_expression_templates) return base().noalias(); if constexpr (use_expression_templates) return base().noalias();
else return *this; else return *this;
} }
auto normalized() const auto _normalized() const
requires(IsVectorAtCompileTime) requires(IsVectorAtCompileTime)
{ {
if constexpr (use_expression_templates) return base().normalized(); if constexpr (use_expression_templates) return base().normalized();
@ -220,7 +216,7 @@ namespace rotgen
base().normalized()); base().normalized());
} }
auto transpose() const auto _transpose() const
{ {
if constexpr (use_expression_templates) return base().transpose(); if constexpr (use_expression_templates) return base().transpose();
else else
@ -228,14 +224,14 @@ namespace rotgen
base().transpose()); base().transpose());
} }
auto adjoint() const auto _adjoint() const
{ {
if constexpr (use_expression_templates) return base().adjoint(); if constexpr (use_expression_templates) return base().adjoint();
else else
return as_concrete_type<decltype(base().adjoint())>(base().adjoint()); return as_concrete_type<decltype(base().adjoint())>(base().adjoint());
} }
auto conjugate() const auto _conjugate() const
{ {
if constexpr (use_expression_templates) return base().conjugate(); if constexpr (use_expression_templates) return base().conjugate();
else else
@ -243,208 +239,208 @@ namespace rotgen
base().conjugate()); base().conjugate());
} }
void normalize() void _normalize()
requires(!is_immutable && IsVectorAtCompileTime) requires(!is_immutable && IsVectorAtCompileTime)
{ {
parent::normalize(); parent::normalize();
} }
void transposeInPlace() void _transposeInPlace()
requires(!is_immutable) requires(!is_immutable)
{ {
parent::transposeInPlace(); parent::transposeInPlace();
} }
void adjointInPlace() void _adjointInPlace()
requires(!is_immutable) requires(!is_immutable)
{ {
parent::adjointInPlace(); parent::adjointInPlace();
} }
auto cwiseAbs() const auto _cwiseAbs() const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseAbs()}; return concrete_type{parent::cwiseAbs()};
else return base().cwiseAbs(); else return base().cwiseAbs();
} }
auto cwiseAbs2() const auto _cwiseAbs2() const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseAbs2()}; return concrete_type{parent::cwiseAbs2()};
else return base().cwiseAbs2(); else return base().cwiseAbs2();
} }
auto cwiseInverse() const auto _cwiseInverse() const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseInverse()}; return concrete_type{parent::cwiseInverse()};
else return base().cwiseInverse(); else return base().cwiseInverse();
} }
auto cwiseSqrt() const auto _cwiseSqrt() const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseSqrt()}; return concrete_type{parent::cwiseSqrt()};
else return base().cwiseSqrt(); else return base().cwiseSqrt();
} }
static concrete_type Constant(value_type value) static concrete_type _Constant(value_type value)
requires(Rows != -1 && Cols != -1) requires(Rows != -1 && Cols != -1)
{ {
return parent::Constant(Rows, Cols, static_cast<value_type>(value)); return parent::Constant(Rows, Cols, static_cast<value_type>(value));
} }
static concrete_type Constant(int rows, int cols, value_type value) static concrete_type _Constant(int rows, int cols, value_type value)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(rows == Rows && ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size"); "Mismatched between dynamic and static row size");
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(cols == Cols && ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size"); "Mismatched between dynamic and static column size");
return parent::Constant(rows, cols, static_cast<value_type>(value)); return parent::Constant(rows, cols, static_cast<value_type>(value));
} }
static concrete_type Identity() static concrete_type _Identity()
requires(Rows != -1 && Cols != -1) requires(Rows != -1 && Cols != -1)
{ {
return parent::Identity(Rows, Cols); return parent::Identity(Rows, Cols);
} }
static concrete_type Identity(int rows, int cols) static concrete_type _Identity(int rows, int cols)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(rows == Rows && ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size"); "Mismatched between dynamic and static row size");
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(cols == Cols && ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size"); "Mismatched between dynamic and static column size");
return parent::Identity(rows, cols); return parent::Identity(rows, cols);
} }
static concrete_type Zero() static concrete_type _Zero()
requires(Rows != -1 && Cols != -1) requires(Rows != -1 && Cols != -1)
{ {
return parent::Zero(Rows, Cols); return parent::Zero(Rows, Cols);
} }
static concrete_type Zero(int rows, int cols) static concrete_type _Zero(int rows, int cols)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(rows == Rows && ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size"); "Mismatched between dynamic and static row size");
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(cols == Cols && ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size"); "Mismatched between dynamic and static column size");
return parent::Zero(rows, cols); return parent::Zero(rows, cols);
} }
static concrete_type Ones() static concrete_type _Ones()
requires(Rows != -1 && Cols != -1) requires(Rows != -1 && Cols != -1)
{ {
return parent::Ones(Rows, Cols); return parent::Ones(Rows, Cols);
} }
static concrete_type Ones(int rows, int cols) static concrete_type _Ones(int rows, int cols)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(rows == Rows && ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size"); "Mismatched between dynamic and static row size");
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(cols == Cols && ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size"); "Mismatched between dynamic and static column size");
return parent::Ones(rows, cols); return parent::Ones(rows, cols);
} }
static concrete_type Random() static concrete_type _Random()
requires(Rows != -1 && Cols != -1) requires(Rows != -1 && Cols != -1)
{ {
return parent::Random(Rows, Cols); return parent::Random(Rows, Cols);
} }
static concrete_type Random(int rows, int cols) static concrete_type _Random(int rows, int cols)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(rows == Rows && ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size"); "Mismatched between dynamic and static row size");
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(cols == Cols && ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size"); "Mismatched between dynamic and static column size");
return parent::Random(rows, cols); return parent::Random(rows, cols);
} }
block& setOnes() block& _setOnes()
requires(!is_immutable) requires(!is_immutable)
{ {
*this = parent::Ones(rows(), cols()); *this = parent::Ones(_rows(), _cols());
return *this; return *this;
} }
block& setOnes(int r, int c) block& _setOnes(int r, int c)
requires(!is_immutable) requires(!is_immutable)
{ {
*this = parent::Ones(r, c); *this = parent::Ones(r, c);
return *this; return *this;
} }
block& setZero() block& _setZero()
requires(!is_immutable) requires(!is_immutable)
{ {
*this = parent::Zero(rows(), cols()); *this = parent::Zero(_rows(), _cols());
return *this; return *this;
} }
block& setZero(int r, int c) block& _setZero(int r, int c)
requires(!is_immutable) requires(!is_immutable)
{ {
*this = parent::Zero(r, c); *this = parent::Zero(r, c);
return *this; return *this;
} }
block& setConstant(value_type value) block& _setConstant(value_type value)
requires(!is_immutable) requires(!is_immutable)
{ {
*this = parent::Constant(rows(), cols(), value); *this = parent::Constant(_rows(), _cols(), value);
return *this; return *this;
} }
block& setConstant(int r, int c, value_type value) block& _setConstant(int r, int c, value_type value)
requires(!is_immutable) requires(!is_immutable)
{ {
*this = parent::Constant(r, c, value); *this = parent::Constant(r, c, value);
return *this; return *this;
} }
block& setRandom() block& _setRandom()
requires(!is_immutable) requires(!is_immutable)
{ {
*this = parent::Random(rows(), cols()); *this = parent::Random(_rows(), _cols());
return *this; return *this;
} }
block& setRandom(int r, int c) block& _setRandom(int r, int c)
requires(!is_immutable) requires(!is_immutable)
{ {
*this = parent::Random(r, c); *this = parent::Random(r, c);
return *this; return *this;
} }
block& setIdentity() block& _setIdentity()
requires(!is_immutable) requires(!is_immutable)
{ {
*this = parent::Identity(rows(), cols()); *this = parent::Identity(_rows(), _cols());
return *this; return *this;
} }
block& setIdentity(int r, int c) block& _setIdentity(int r, int c)
requires(!is_immutable) requires(!is_immutable)
{ {
*this = parent::Identity(r, c); *this = parent::Identity(r, c);
return *this; return *this;
} }
template<int P> value_type lpNorm() const template<int P> value_type _lpNorm() const
{ {
static_assert(P == 1 || P == 2 || P == Infinity); static_assert(P == 1 || P == 2 || P == Infinity);
return parent::template lpNorm<P>(); return parent::template lpNorm<P>();
@ -482,25 +478,35 @@ namespace rotgen
return (*this)(i); return (*this)(i);
} }
using parent::cols;
using parent::data; using parent::data;
using parent::innerStride;
using parent::mean;
using parent::norm;
using parent::outerStride;
using parent::prod;
using parent::rows;
using parent::size; using parent::size;
using parent::squaredNorm;
using parent::sum;
using parent::trace;
auto minCoeff() const { return parent::minCoeff(); } Index _cols() const { return parent::cols(); }
auto maxCoeff() const { return parent::maxCoeff(); } Index _rows() const { return parent::rows(); }
value_type _mean() const { return parent::mean(); }
value_type _norm() const { return parent::norm(); }
value_type _squaredNorm() const { return parent::squaredNorm(); }
value_type _sum() const { return parent::sum(); }
value_type _prod() const { return parent::prod(); }
value_type _trace() const { return parent::trace(); }
Index _innerStride() const noexcept { return parent::innerStride(); };
Index _outerStride() const noexcept { return parent::outerStride(); };
auto _minCoeff() const { return parent::minCoeff(); }
auto _maxCoeff() const { return parent::maxCoeff(); }
template<std::integral IndexType> template<std::integral IndexType>
auto minCoeff(IndexType* row, IndexType* col) const auto _minCoeff(IndexType* row, IndexType* col) const
{ {
Index r, c; Index r, c;
auto result = parent::minCoeff(&r, &c); auto result = parent::minCoeff(&r, &c);
@ -510,7 +516,7 @@ namespace rotgen
} }
template<std::integral IndexType> template<std::integral IndexType>
auto maxCoeff(IndexType* row, IndexType* col) const auto _maxCoeff(IndexType* row, IndexType* col) const
{ {
Index r, c; Index r, c;
auto result = parent::maxCoeff(&r, &c); auto result = parent::maxCoeff(&r, &c);
@ -519,21 +525,23 @@ namespace rotgen
return result; return result;
} }
Index startRow() const { return base().startRow(); } Index _startRow() const { return base().startRow(); }
Index startCol() const { return base().startCol(); } Index _startCol() const { return base().startCol(); }
block& operator+=(block const& rhs) template<concepts::entity E>
block& operator+=(E const& rhs)
requires(!is_immutable) requires(!is_immutable)
{ {
static_cast<parent&>(*this) += static_cast<parent const&>(rhs); base() += rhs.base();
return *this; return *this;
} }
block& operator-=(block const& rhs) template<concepts::entity E>
block& operator-=(E const& rhs)
requires(!is_immutable) requires(!is_immutable)
{ {
static_cast<parent&>(*this) -= static_cast<parent const&>(rhs); base() -= rhs.base();
return *this; return *this;
} }
@ -542,10 +550,11 @@ namespace rotgen
return concrete_type(static_cast<parent const&>(*this).operator-()); return concrete_type(static_cast<parent const&>(*this).operator-());
} }
block& operator*=(block const& rhs) template<concepts::entity E>
block& operator*=(E const& rhs)
requires(!is_immutable) requires(!is_immutable)
{ {
static_cast<parent&>(*this) *= static_cast<parent const&>(rhs); base() *= rhs.base();
return *this; return *this;
} }

View file

@ -7,14 +7,14 @@
//================================================================================================== //==================================================================================================
#pragma once #pragma once
#include <rotgen/detail/assert.hpp>
#include <rotgen/detail/helpers.hpp> #include <rotgen/detail/helpers.hpp>
#include <rotgen/detail/product.hpp>
#include <rotgen/concepts.hpp> #include <rotgen/concepts.hpp>
#include <rotgen/container/map/dynamic/impl.hpp> #include <rotgen/container/map/dynamic/impl.hpp>
#include <rotgen/container/matrix.hpp> #include <rotgen/container/matrix.hpp>
#include <cassert>
namespace rotgen namespace rotgen
{ {
namespace detail namespace detail
@ -35,6 +35,7 @@ namespace rotgen
using parent = find_map<Ref>; using parent = find_map<Ref>;
using rotgen_tag = void; using rotgen_tag = void;
using rotgen_map_tag = void;
using value_type = typename std::remove_const_t<Ref>::value_type; using value_type = typename std::remove_const_t<Ref>::value_type;
using concrete_type = typename std::remove_const_t<Ref>::concrete_type; using concrete_type = typename std::remove_const_t<Ref>::concrete_type;
@ -52,6 +53,7 @@ namespace rotgen
static constexpr int ColsAtCompileTime = Ref::ColsAtCompileTime; static constexpr int ColsAtCompileTime = Ref::ColsAtCompileTime;
static constexpr int MaxRowsAtCompileTime = Ref::MaxRowsAtCompileTime; static constexpr int MaxRowsAtCompileTime = Ref::MaxRowsAtCompileTime;
static constexpr int MaxColsAtCompileTime = Ref::MaxColsAtCompileTime; static constexpr int MaxColsAtCompileTime = Ref::MaxColsAtCompileTime;
static constexpr int SizeAtCompileTime = Ref::SizeAtCompileTime;
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime; static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
static constexpr bool is_defined_static = static constexpr bool is_defined_static =
RowsAtCompileTime != -1 && ColsAtCompileTime != -1; RowsAtCompileTime != -1 && ColsAtCompileTime != -1;
@ -75,12 +77,12 @@ namespace rotgen
: parent(ptr, r, c, strides<storage_order>(s, r, c)) : parent(ptr, r, c, strides<storage_order>(s, r, c))
{ {
if constexpr (RowsAtCompileTime != -1) if constexpr (RowsAtCompileTime != -1)
assert(r == RowsAtCompileTime && ROTGEN_ASSERT(r == RowsAtCompileTime,
"Mismatched between dynamic and static row size"); "Mismatched between dynamic and static row size");
if constexpr (ColsAtCompileTime != -1) if constexpr (ColsAtCompileTime != -1)
assert(c == ColsAtCompileTime && ROTGEN_ASSERT(c == ColsAtCompileTime,
"Mismatched between dynamic and static column size"); "Mismatched between dynamic and static column size");
} }
// Used to properly delay ref dynamic construction // Used to properly delay ref dynamic construction
@ -95,8 +97,13 @@ namespace rotgen
map(ptr_type ptr, Index r, Index c) map(ptr_type ptr, Index r, Index c)
: parent(ptr, r, c, [&]() { : parent(ptr, r, c, [&]() {
if constexpr (!std::same_as<Stride, stride<0, 0>>) if constexpr (!std::same_as<Stride, stride<0, 0>>)
{
return strides<storage_order>(Stride{}, r, c); return strides<storage_order>(Stride{}, r, c);
else return strides<storage_order>(r, c); }
else
{
return strides<storage_order>(r, c);
}
}()) }())
{ {
} }
@ -125,9 +132,9 @@ namespace rotgen
template<typename R2, int O2, typename S2> template<typename R2, int O2, typename S2>
map(map<R2, O2, S2> const& other) map(map<R2, O2, S2> const& other)
: map(other.data(), : map(other.data(),
other.rows(), other._rows(),
other.cols(), other._cols(),
dynamic_stride{other.outerStride(), other.innerStride()}) dynamic_stride{other._outerStride(), other._innerStride()})
{ {
} }
@ -135,26 +142,52 @@ namespace rotgen
map(map const& other) : parent(other) {} map(map const& other) : parent(other) {}
map(map&& other) : parent(std::move(other)) {}
map& operator=(map const& other) map& operator=(map const& other)
requires(!is_immutable) requires(!is_immutable)
{ {
base() = static_cast<parent const&>(other); base() = other.base();
return *this; return *this;
} }
map& operator=(concepts::entity auto const& other) map& operator=(map&& other)
requires(!is_immutable) requires(!is_immutable)
{ {
assert(parent::rows() == other.rows() && parent::cols() == other.cols()); base() = std::move(other.base());
if constexpr (IsVectorAtCompileTime) return *this;
}
template<concepts::entity Src>
map& operator=(Src const& other)
requires(!is_immutable)
{
if constexpr (IsVectorAtCompileTime && Src::IsVectorAtCompileTime)
{ {
ROTGEN_ASSERT(parent::size() == other.size(),
"Map assignment from 1D source doesn't match size");
for (rotgen::Index i = 0; i < parent::size(); ++i) for (rotgen::Index i = 0; i < parent::size(); ++i)
(*this)(i) = other(i); (*this)[i] = other[i];
}
else if constexpr (IsVectorAtCompileTime && !Src::IsVectorAtCompileTime)
{
auto r = other._rows();
auto c = other._cols();
ROTGEN_ASSERT(
r == 1 || c == 1,
"Map assignment from dynamic sized source doesn't match static size");
for (rotgen::Index i = 0; i < parent::size(); ++i)
(*this)[i] = other(r == 1 ? 0 : i, c == 1 ? 0 : i);
} }
else else
{ {
for (rotgen::Index r = 0; r < parent::rows(); ++r) ROTGEN_ASSERT(parent::_rows() == other._rows() &&
for (rotgen::Index c = 0; c < parent::cols(); ++c) parent::_cols() == other._cols(),
"Map assignment size mismatch");
for (rotgen::Index r = 0; r < parent::_rows(); ++r)
for (rotgen::Index c = 0; c < parent::_cols(); ++c)
(*this)(r, c) = other(r, c); (*this)(r, c) = other(r, c);
} }
@ -196,86 +229,89 @@ namespace rotgen
return (*this)(i); return (*this)(i);
} }
auto evaluate() const { return *this; } concrete_type _evaluate() const { return concrete_type{*this}; }
decltype(auto) noalias() const { return *this; } decltype(auto) _noalias() const { return *this; }
decltype(auto) noalias() { return *this; } decltype(auto) _noalias() { return *this; }
concrete_type normalized() const concrete_type _normalized() const
requires(IsVectorAtCompileTime) requires(IsVectorAtCompileTime)
{ {
return concrete_type(base().normalized()); return concrete_type(base()._normalized());
} }
transposed_type transpose() const transposed_type _transpose() const
{ {
return transposed_type(base().transpose()); return transposed_type(base()._transpose());
} }
concrete_type conjugate() const concrete_type _conjugate() const
{ {
return concrete_type(base().conjugate()); return concrete_type(base()._conjugate());
} }
transposed_type adjoint() const transposed_type _adjoint() const
{ {
return transposed_type(base().adjoint()); return transposed_type(base()._adjoint());
} }
concrete_type cwiseAbs() const { return concrete_type(base().cwiseAbs()); } concrete_type _cwiseAbs() const
concrete_type cwiseAbs2() const
{ {
return concrete_type(base().cwiseAbs2()); return concrete_type(base()._cwiseAbs());
} }
concrete_type cwiseInverse() const concrete_type _cwiseAbs2() const
{ {
return concrete_type(base().cwiseInverse()); return concrete_type(base()._cwiseAbs2());
} }
concrete_type cwiseSqrt() const concrete_type _cwiseInverse() const
{ {
return concrete_type(base().cwiseSqrt()); return concrete_type(base()._cwiseInverse());
} }
concrete_type cwiseMin(map const& rhs) const concrete_type _cwiseSqrt() const
{ {
return concrete_type(base().cwiseMin(rhs.base())); return concrete_type(base()._cwiseSqrt());
} }
concrete_type cwiseMax(map const& rhs) const concrete_type _cwiseMin(map const& rhs) const
{ {
return concrete_type(base().cwiseMax(rhs.base())); return concrete_type(base()._cwiseMin(rhs.base()));
} }
concrete_type cwiseQuotient(map const& rhs) const concrete_type _cwiseMax(map const& rhs) const
{ {
return concrete_type(base().cwiseQuotient(rhs.base())); return concrete_type(base()._cwiseMax(rhs.base()));
} }
concrete_type cwiseProduct(map const& rhs) const concrete_type _cwiseQuotient(map const& rhs) const
{ {
return concrete_type(base().cwiseProduct(rhs.base())); return concrete_type(base()._cwiseQuotient(rhs.base()));
} }
concrete_type cwiseMin(value_type s) const concrete_type _cwiseProduct(map const& rhs) const
{ {
return concrete_type(base().cwiseMin(s)); return concrete_type(base()._cwiseProduct(rhs.base()));
} }
concrete_type cwiseMax(value_type s) const concrete_type _cwiseMin(value_type s) const
{ {
return concrete_type(base().cwiseMax(s)); return concrete_type(base()._cwiseMin(s));
} }
concrete_type inverse() const { return concrete_type(base().inverse()); } concrete_type _cwiseMax(value_type s) const
{
return concrete_type(base()._cwiseMax(s));
}
concrete_type cross(map const& other) const concrete_type _inverse() const { return concrete_type(base()._inverse()); }
concrete_type _cross(map const& other) const
{ {
concrete_type that; concrete_type that;
if constexpr (RowsAtCompileTime == -1) if constexpr (ColsAtCompileTime == 1)
{ {
that(0, 0) = (*this)(1, 0) * other(2, 0) - (*this)(2, 0) * other(1, 0); that(0, 0) = (*this)(1, 0) * other(2, 0) - (*this)(2, 0) * other(1, 0);
that(1, 0) = (*this)(2, 0) * other(0, 0) - (*this)(0, 0) * other(2, 0); that(1, 0) = (*this)(2, 0) * other(0, 0) - (*this)(0, 0) * other(2, 0);
@ -290,28 +326,29 @@ namespace rotgen
return that; return that;
} }
void normalize() void _normalize()
requires(!is_immutable && IsVectorAtCompileTime) requires(!is_immutable && IsVectorAtCompileTime)
{ {
parent::normalize(); parent::_normalize();
} }
void transposeInPlace() void _transposeInPlace()
requires(!is_immutable) requires(!is_immutable)
{ {
parent::transposeInPlace(); parent::_transposeInPlace();
} }
void adjointInPlace() void _adjointInPlace()
requires(!is_immutable) requires(!is_immutable)
{ {
parent::adjointInPlace(); parent::_adjointInPlace();
} }
template<typename R2, int O2, typename S2> template<typename R2, int O2, typename S2>
map& operator+=(map<R2, O2, S2> const& rhs) map& operator+=(map<R2, O2, S2> const& rhs)
requires(!is_immutable) requires(!is_immutable)
{ {
validate_compound_operator(rhs);
base() += rhs.base(); base() += rhs.base();
return *this; return *this;
} }
@ -320,6 +357,7 @@ namespace rotgen
map& operator-=(map<R2, O2, S2> const& rhs) map& operator-=(map<R2, O2, S2> const& rhs)
requires(!is_immutable) requires(!is_immutable)
{ {
validate_compound_operator(rhs);
base() -= rhs.base(); base() -= rhs.base();
return *this; return *this;
} }
@ -333,6 +371,9 @@ namespace rotgen
map& operator*=(map<R2, O2, S2> const& rhs) map& operator*=(map<R2, O2, S2> const& rhs)
requires(!is_immutable) requires(!is_immutable)
{ {
ROTGEN_ASSERT(parent::_cols() == rhs._rows() &&
parent::_cols() == rhs._cols(),
"Incompatible dimensions for compound matrix-product");
base() *= rhs.base(); base() *= rhs.base();
return *this; return *this;
} }
@ -351,121 +392,121 @@ namespace rotgen
return *this; return *this;
} }
auto minCoeff() const { return parent::minCoeff(); } auto _minCoeff() const { return parent::_minCoeff(); }
auto maxCoeff() const { return parent::maxCoeff(); } auto _maxCoeff() const { return parent::_maxCoeff(); }
template<std::integral IndexType> template<std::integral IndexType>
auto minCoeff(IndexType* row, IndexType* col) const auto _minCoeff(IndexType* row, IndexType* col) const
{ {
Index r, c; Index r, c;
auto result = parent::minCoeff(&r, &c); auto result = parent::_minCoeff(&r, &c);
*row = r; *row = r;
*col = c; *col = c;
return result; return result;
} }
template<std::integral IndexType> template<std::integral IndexType>
auto maxCoeff(IndexType* row, IndexType* col) const auto _maxCoeff(IndexType* row, IndexType* col) const
{ {
Index r, c; Index r, c;
auto result = parent::maxCoeff(&r, &c); auto result = parent::_maxCoeff(&r, &c);
*row = r; *row = r;
*col = c; *col = c;
return result; return result;
} }
static auto Zero() static auto _Zero()
requires(requires { Ref::Zero(); }) requires(requires { Ref::_Zero(); })
{ {
return Ref::Zero(); return Ref::_Zero();
} }
static auto Ones() static auto _Ones()
requires(requires { Ref::Ones(); }) requires(requires { Ref::_Ones(); })
{ {
return Ref::Ones(); return Ref::_Ones();
} }
static auto Zero(int rows, int cols) { return Ref::Zero(rows, cols); } 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 _Ones(int rows, int cols) { return Ref::_Ones(rows, cols); }
static auto Constant(value_type value) static auto _Constant(value_type value)
requires(requires { Ref::Constant(value); }) requires(requires { Ref::_Constant(value); })
{ {
return Ref::Constant(value); return Ref::_Constant(value);
} }
static auto Constant(int rows, int cols, value_type value) static auto _Constant(int rows, int cols, value_type value)
{ {
return Ref::Constant(rows, cols, value); return Ref::_Constant(rows, cols, value);
} }
static auto Random() static auto _Random()
requires(requires { Ref::Random(); }) requires(requires { Ref::_Random(); })
{ {
return Ref::Random(); return Ref::_Random();
} }
static auto Random(int rows, int cols) { return Ref::Random(rows, cols); } static auto _Random(int rows, int cols) { return Ref::_Random(rows, cols); }
static auto Identity() static auto _Identity()
requires(requires { Ref::Identity(); }) requires(requires { Ref::_Identity(); })
{ {
return Ref::Identity(); return Ref::_Identity();
} }
static auto Identity(int rows, int cols) static auto _Identity(int rows, int cols)
{ {
return Ref::Identity(rows, cols); return Ref::_Identity(rows, cols);
} }
map& setZero() map& _setZero()
requires(!is_immutable) requires(!is_immutable)
{ {
parent::setZero(); parent::_setZero();
return *this; return *this;
} }
map& setOnes() map& _setOnes()
requires(!is_immutable) requires(!is_immutable)
{ {
parent::setOnes(); parent::_setOnes();
return *this; return *this;
} }
map& setIdentity() map& _setIdentity()
requires(!is_immutable) requires(!is_immutable)
{ {
parent::setIdentity(); parent::_setIdentity();
return *this; return *this;
} }
map& setRandom() map& _setRandom()
requires(!is_immutable) requires(!is_immutable)
{ {
parent::setRandom(); parent::_setRandom();
return *this; return *this;
} }
map& setConstant(value_type s) map& _setConstant(value_type scalar)
requires(!is_immutable) requires(!is_immutable)
{ {
parent::setConstant(s); parent::_setConstant(scalar);
return *this; return *this;
} }
template<typename R2, int O2, typename S2> template<typename R2, int O2, typename S2>
value_type dot(map<R2, O2, S2> const& rhs) const value_type _dot(map<R2, O2, S2> const& rhs) const
{ {
return base().dot(rhs.base()); return base()._dot(rhs.base());
} }
template<int P> value_type lpNorm() const template<int P> value_type _lpNorm() const
{ {
assert(P == 1 || P == 2 || P == Infinity); static_assert(P == 1 || P == 2 || P == Infinity);
return parent::lpNorm(P); return parent::_lpNorm(P);
} }
parent& base() { return static_cast<parent&>(*this); } parent& base() { return static_cast<parent&>(*this); }
@ -476,6 +517,32 @@ namespace rotgen
{ {
return concrete_type(base().qr_solve(rhs.base())); return concrete_type(base().qr_solve(rhs.base()));
}; };
template<typename R2, int O2, typename S2>
void validate_compound_operator(map<R2, O2, S2> const& rhs)
{
if constexpr (IsVectorAtCompileTime && R2::IsVectorAtCompileTime)
{
if constexpr (is_defined_static && R2::is_defined_static)
{
static_assert(
SizeAtCompileTime == R2::SizeAtCompileTime,
"Compile-time size mismatch in compound assignment operator");
}
else
{
ROTGEN_ASSERT(parent::size() == rhs.size(),
"Size mismatch in compound assignment operator");
}
}
else
{
ROTGEN_ASSERT(parent::_rows() == rhs._rows(),
"Mismatched rows count in compound assignment operator");
ROTGEN_ASSERT(parent::_cols() == rhs._cols(),
"Mismatched cols count in compound assignment operator");
}
}
}; };
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2> template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
@ -485,7 +552,7 @@ namespace rotgen
using map1_type = map<R1 const, O1, S1>; using map1_type = map<R1 const, O1, S1>;
using map2_type = map<R2 const, O2, S2>; using map2_type = map<R2 const, O2, S2>;
using concrete_type = detail::composite_type<R1, R2, matrix>; using concrete_type = detail::composite_type<R1, R2, matrix>;
return concrete_type(map1_type(lhs).base().add(map2_type(rhs))); return concrete_type(map1_type(lhs).base()._add(map2_type(rhs)));
} }
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2> template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
@ -495,22 +562,34 @@ namespace rotgen
using map1_type = map<R1 const, O1, S1>; using map1_type = map<R1 const, O1, S1>;
using map2_type = map<R2 const, O2, S2>; using map2_type = map<R2 const, O2, S2>;
using concrete_type = detail::composite_type<R1, R2, matrix>; using concrete_type = detail::composite_type<R1, R2, matrix>;
return concrete_type(map1_type(lhs).base().sub(map2_type(rhs))); return concrete_type(map1_type(lhs).base()._sub(map2_type(rhs)));
} }
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2> template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
matrix<typename R1::value_type, auto operator*(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
R1::RowsAtCompileTime,
R2::ColsAtCompileTime,
R1::storage_order>
operator*(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
{ {
using map1_type = map<R1 const, O1, S1>; using map1_type = map<R1 const, O1, S1>;
using map2_type = map<R2 const, O2, S2>; using map2_type = map<R2 const, O2, S2>;
using concrete_type = matrix<typename R1::value_type, R1::RowsAtCompileTime, using concrete_type = matrix<typename R1::value_type, R1::RowsAtCompileTime,
R2::ColsAtCompileTime, R1::storage_order>; R2::ColsAtCompileTime, R1::storage_order>;
return concrete_type(map1_type(lhs).base().mul(map2_type(rhs).base())); if constexpr (concrete_type::SizeAtCompileTime == 0)
{
return concrete_type{};
}
else
{
auto product_result =
concrete_type(map1_type(lhs).base()._mul(map2_type(rhs).base()));
if constexpr (concrete_type::SizeAtCompileTime == 1)
{
return product{product_result};
}
else
{
return product_result;
}
}
} }
template<typename R, int O, typename S> template<typename R, int O, typename S>
@ -518,7 +597,7 @@ namespace rotgen
map<R, O, S> const& lhs, std::convertible_to<typename R::value_type> auto s) map<R, O, S> const& lhs, std::convertible_to<typename R::value_type> auto s)
{ {
using concrete_type = typename map<R, O, S>::concrete_type; using concrete_type = typename map<R, O, S>::concrete_type;
return concrete_type(lhs.base().mul(s)); return concrete_type(lhs.base()._mul(s));
} }
template<typename R, int O, typename S> template<typename R, int O, typename S>
@ -526,7 +605,7 @@ namespace rotgen
std::convertible_to<typename R::value_type> auto s, map<R, O, S> const& rhs) std::convertible_to<typename R::value_type> auto s, map<R, O, S> const& rhs)
{ {
using concrete_type = typename map<R, O, S>::concrete_type; using concrete_type = typename map<R, O, S>::concrete_type;
return concrete_type(rhs.base().mul(s)); return concrete_type(rhs.base()._mul(s));
} }
template<typename R, int O, typename S> template<typename R, int O, typename S>
@ -534,7 +613,7 @@ namespace rotgen
map<R, O, S> const& lhs, std::convertible_to<typename R::value_type> auto s) map<R, O, S> const& lhs, std::convertible_to<typename R::value_type> auto s)
{ {
using concrete_type = typename map<R, O, S>::concrete_type; using concrete_type = typename map<R, O, S>::concrete_type;
return concrete_type(lhs.base().div(s)); return concrete_type(lhs.base()._div(s));
} }
template<typename R1, int O1, typename S1, typename R2, int O2, typename S2> template<typename R1, int O1, typename S1, typename R2, int O2, typename S2>

View file

@ -3,27 +3,39 @@
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col) #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row) #define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col) #define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row) #define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#include <rotgen/container/map/dynamic/model.hpp> #include <rotgen/container/map/dynamic/model.hpp>
#undef CLASSNAME #undef CLASSNAME
#undef TRANSCLASSNAME #undef TRANSCLASSNAME
#undef TRANSCLASSCONSTNAME
#undef TRANSCLASSNONCONSTNAME
#undef TRANSSOURCENAME #undef TRANSSOURCENAME
#undef SOURCENAME #undef SOURCENAME
#undef CLASSCONSTNAME #undef CLASSCONSTNAME
#undef CLASSNONCONSTNAME
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row) #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col) #define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row) #define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col) #define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#include <rotgen/container/map/dynamic/model.hpp> #include <rotgen/container/map/dynamic/model.hpp>
#undef CLASSNAME #undef CLASSNAME
#undef TRANSCLASSNAME #undef TRANSCLASSNAME
#undef TRANSCLASSCONSTNAME
#undef TRANSCLASSNONCONSTNAME
#undef TRANSSOURCENAME #undef TRANSSOURCENAME
#undef SOURCENAME #undef SOURCENAME
#undef CLASSCONSTNAME #undef CLASSCONSTNAME
#undef CLASSNONCONSTNAME
#undef SIZE #undef SIZE
#undef TYPE #undef TYPE
@ -33,27 +45,39 @@
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col) #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row) #define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col) #define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row) #define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#include <rotgen/container/map/dynamic/model.hpp> #include <rotgen/container/map/dynamic/model.hpp>
#undef CLASSNAME #undef CLASSNAME
#undef TRANSCLASSNAME #undef TRANSCLASSNAME
#undef TRANSCLASSCONSTNAME
#undef TRANSCLASSNONCONSTNAME
#undef TRANSSOURCENAME #undef TRANSSOURCENAME
#undef SOURCENAME #undef SOURCENAME
#undef CLASSCONSTNAME #undef CLASSCONSTNAME
#undef CLASSNONCONSTNAME
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row) #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col) #define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row) #define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col) #define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#include <rotgen/container/map/dynamic/model.hpp> #include <rotgen/container/map/dynamic/model.hpp>
#undef CLASSNAME #undef CLASSNAME
#undef TRANSCLASSNAME #undef TRANSCLASSNAME
#undef TRANSCLASSCONSTNAME
#undef TRANSCLASSNONCONSTNAME
#undef TRANSSOURCENAME #undef TRANSSOURCENAME
#undef SOURCENAME #undef SOURCENAME
#undef CLASSCONSTNAME #undef CLASSCONSTNAME
#undef CLASSNONCONSTNAME
#undef SIZE #undef SIZE
#undef TYPE #undef TYPE

View file

@ -28,50 +28,53 @@ public:
~CLASSNAME(); ~CLASSNAME();
Index rows() const;
Index cols() const;
Index size() const; Index size() const;
Index innerStride() const; Index _rows() const;
Index outerStride() const; Index _cols() const;
SOURCENAME normalized() const; Index _innerStride() const;
SOURCENAME transpose() const; Index _outerStride() const;
SOURCENAME conjugate() const;
SOURCENAME adjoint() const;
SOURCENAME cwiseAbs() const; SOURCENAME _normalized() const;
SOURCENAME cwiseAbs2() const; SOURCENAME _transpose() const;
SOURCENAME cwiseInverse() const; SOURCENAME _conjugate() const;
SOURCENAME cwiseSqrt() const; SOURCENAME _adjoint() const;
SOURCENAME cwiseMax(CLASSNAME const&) const; SOURCENAME _cwiseAbs() const;
SOURCENAME cwiseMin(CLASSNAME const&) const; SOURCENAME _cwiseAbs2() const;
SOURCENAME cwiseProduct(CLASSNAME const&) const; SOURCENAME _cwiseInverse() const;
SOURCENAME cwiseQuotient(CLASSNAME const&) const; SOURCENAME _cwiseSqrt() const;
SOURCENAME cwiseMax(TYPE) const;
SOURCENAME cwiseMin(TYPE) const; SOURCENAME _cwiseMax(CLASSNAME const&) const;
SOURCENAME _cwiseMin(CLASSNAME const&) const;
SOURCENAME _cwiseProduct(CLASSNAME const&) const;
SOURCENAME _cwiseQuotient(CLASSNAME const&) const;
SOURCENAME _cwiseMax(TYPE) const;
SOURCENAME _cwiseMin(TYPE) const;
#if !defined(USE_CONST) #if !defined(USE_CONST)
void normalize(); void _normalize();
void transposeInPlace(); void _transposeInPlace();
void adjointInPlace(); void _adjointInPlace();
#endif #endif
TYPE sum() const; TYPE _sum() const;
TYPE prod() const; TYPE _prod() const;
TYPE mean() const; TYPE _mean() const;
TYPE trace() const; TYPE _trace() const;
TYPE maxCoeff() const; TYPE _maxCoeff() const;
TYPE minCoeff() const; TYPE _minCoeff() const;
TYPE maxCoeff(Index*, Index*) const; TYPE _maxCoeff(Index*, Index*) const;
TYPE minCoeff(Index*, Index*) const; TYPE _minCoeff(Index*, Index*) const;
TYPE dot(CLASSNAME const&) const; TYPE _dot(CLASSNONCONSTNAME const&) const;
TYPE dot(TRANSCLASSNAME const&) const; TYPE _dot(CLASSCONSTNAME const&) const;
TYPE _dot(TRANSCLASSCONSTNAME const&) const;
TYPE _dot(TRANSCLASSNONCONSTNAME const&) const;
TYPE squaredNorm() const; TYPE _squaredNorm() const;
TYPE norm() const; TYPE _norm() const;
TYPE lpNorm(int p) const; TYPE _lpNorm(int p) const;
SOURCENAME qr_solve(CLASSNAME const& rhs) const; SOURCENAME qr_solve(CLASSNAME const& rhs) const;
@ -86,25 +89,31 @@ public:
#if !defined(USE_CONST) #if !defined(USE_CONST)
CLASSNAME& operator+=(CLASSNAME const& rhs); CLASSNAME& operator+=(CLASSNAME const& rhs);
CLASSNAME& operator+=(CLASSCONSTNAME const& rhs); CLASSNAME& operator+=(CLASSCONSTNAME const& rhs);
CLASSNAME& operator+=(TRANSCLASSCONSTNAME const& rhs);
CLASSNAME& operator+=(TRANSCLASSNONCONSTNAME const& rhs);
CLASSNAME& operator-=(CLASSNAME const& rhs); CLASSNAME& operator-=(CLASSNAME const& rhs);
CLASSNAME& operator-=(CLASSCONSTNAME const& rhs); CLASSNAME& operator-=(CLASSCONSTNAME const& rhs);
CLASSNAME& operator-=(TRANSCLASSCONSTNAME const& rhs);
CLASSNAME& operator-=(TRANSCLASSNONCONSTNAME const& rhs);
CLASSNAME& operator*=(CLASSNAME const& rhs); CLASSNAME& operator*=(CLASSNAME const& rhs);
CLASSNAME& operator*=(CLASSCONSTNAME const& rhs); CLASSNAME& operator*=(CLASSCONSTNAME const& rhs);
CLASSNAME& operator*=(TRANSCLASSCONSTNAME const& rhs);
CLASSNAME& operator*=(TRANSCLASSNONCONSTNAME const& rhs);
CLASSNAME& operator*=(TYPE d); CLASSNAME& operator*=(TYPE d);
CLASSNAME& operator/=(TYPE d); CLASSNAME& operator/=(TYPE d);
#endif #endif
SOURCENAME operator-() const; SOURCENAME operator-() const;
SOURCENAME add(CLASSNAME const& rhs) const; SOURCENAME _add(CLASSNAME const& rhs) const;
SOURCENAME add(TRANSCLASSNAME const& rhs) const; SOURCENAME _add(TRANSCLASSNAME const& rhs) const;
SOURCENAME sub(CLASSNAME const& rhs) const; SOURCENAME _sub(CLASSNAME const& rhs) const;
SOURCENAME sub(TRANSCLASSNAME const& rhs) const; SOURCENAME _sub(TRANSCLASSNAME const& rhs) const;
SOURCENAME mul(CLASSNAME const& rhs) const; SOURCENAME _mul(CLASSNAME const& rhs) const;
SOURCENAME mul(TRANSCLASSNAME const& rhs) const; SOURCENAME _mul(TRANSCLASSNAME const& rhs) const;
SOURCENAME mul(TYPE s) const; SOURCENAME _mul(TYPE s) const;
SOURCENAME div(TYPE s) const; SOURCENAME _div(TYPE s) const;
SOURCENAME inverse() const; SOURCENAME _inverse() const;
friend ROTGEN_EXPORT std::ostream& operator<<(std::ostream&, friend ROTGEN_EXPORT std::ostream& operator<<(std::ostream&,
CLASSNAME const&); CLASSNAME const&);
@ -114,11 +123,11 @@ public:
#if !defined(USE_CONST) #if !defined(USE_CONST)
TYPE* data(); TYPE* data();
void setZero(); void _setZero();
void setOnes(); void _setOnes();
void setRandom(); void _setRandom();
void setIdentity(); void _setIdentity();
void setConstant(TYPE); void _setConstant(TYPE);
#endif #endif
friend ROTGEN_EXPORT bool operator==(CLASSNAME const& lhs, friend ROTGEN_EXPORT bool operator==(CLASSNAME const& lhs,

View file

@ -7,6 +7,8 @@
//================================================================================================== //==================================================================================================
#pragma once #pragma once
#include <rotgen/detail/product.hpp>
#include <Eigen/Dense> #include <Eigen/Dense>
#include <iostream> #include <iostream>
@ -41,6 +43,7 @@ namespace rotgen
{ {
public: public:
using rotgen_tag = void; using rotgen_tag = void;
using rotgen_map_tag = void;
using parent = detail:: using parent = detail::
map_type<std::remove_const_t<Ref>, Options, std::is_const_v<Ref>, Stride>; 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 value_type = typename std::remove_const_t<Ref>::value_type;
@ -50,6 +53,7 @@ namespace rotgen
static constexpr int ColsAtCompileTime = Ref::ColsAtCompileTime; static constexpr int ColsAtCompileTime = Ref::ColsAtCompileTime;
static constexpr int MaxRowsAtCompileTime = Ref::MaxRowsAtCompileTime; static constexpr int MaxRowsAtCompileTime = Ref::MaxRowsAtCompileTime;
static constexpr int MaxColsAtCompileTime = Ref::MaxColsAtCompileTime; static constexpr int MaxColsAtCompileTime = Ref::MaxColsAtCompileTime;
static constexpr int SizeAtCompileTime = Ref::SizeAtCompileTime;
static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime; static constexpr bool IsVectorAtCompileTime = Ref::IsVectorAtCompileTime;
static constexpr bool has_static_storage = Ref::has_static_storage; static constexpr bool has_static_storage = Ref::has_static_storage;
static constexpr bool IsRowMajor = Ref::IsRowMajor; static constexpr bool IsRowMajor = Ref::IsRowMajor;
@ -112,29 +116,33 @@ namespace rotgen
return *this; return *this;
} }
template<typename OtherDerived>
map& operator=(Eigen::MatrixBase<OtherDerived> const& other)
{
parent::operator=(other);
return *this;
}
template<typename OtherDerived>
map& operator=(Eigen::EigenBase<OtherDerived> const& other)
{
parent::operator=(other);
return *this;
}
parent& base() { return static_cast<parent&>(*this); } parent& base() { return static_cast<parent&>(*this); }
parent const& base() const { return static_cast<parent const&>(*this); } parent const& base() const { return static_cast<parent const&>(*this); }
auto evaluate() const auto _evaluate() const { return concrete_type(base().eval()); }
{
auto res = static_cast<parent const&>(*this).eval();
return as_concrete_type<decltype(res)>(res);
}
auto evaluate() decltype(auto) _noalias() const
{
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(); if constexpr (use_expression_templates) return base().noalias();
else return *this; else return *this;
} }
decltype(auto) noalias() decltype(auto) _noalias()
{ {
if constexpr (use_expression_templates) return base().noalias(); if constexpr (use_expression_templates) return base().noalias();
else return *this; else return *this;
@ -176,6 +184,7 @@ namespace rotgen
map& operator+=(map<R2, O2, S2> const& rhs) map& operator+=(map<R2, O2, S2> const& rhs)
requires(!is_immutable) requires(!is_immutable)
{ {
validate_compound_operator(rhs);
base() += rhs.base(); base() += rhs.base();
return *this; return *this;
} }
@ -184,6 +193,7 @@ namespace rotgen
map& operator-=(map<R2, O2, S2> const& rhs) map& operator-=(map<R2, O2, S2> const& rhs)
requires(!is_immutable) requires(!is_immutable)
{ {
validate_compound_operator(rhs);
base() -= rhs.base(); base() -= rhs.base();
return *this; return *this;
} }
@ -192,6 +202,9 @@ namespace rotgen
map& operator*=(map<R2, O2, S2> const& rhs) map& operator*=(map<R2, O2, S2> const& rhs)
requires(!is_immutable) requires(!is_immutable)
{ {
ROTGEN_ASSERT(parent::cols() == rhs.rows() &&
parent::cols() == rhs.cols(),
"Incompatible dimensions for compound matrix-product");
base() *= rhs.base(); base() *= rhs.base();
return *this; return *this;
} }
@ -208,91 +221,91 @@ namespace rotgen
return *this; return *this;
} }
auto cwiseMin(map const& rhs) const auto _cwiseMin(map const& rhs) const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseMin(rhs.base())}; return concrete_type{parent::cwiseMin(rhs.base())};
else return base().cwiseMin(rhs.base()); else return base().cwiseMin(rhs.base());
} }
auto cwiseMin(value_type rhs) const auto _cwiseMin(value_type rhs) const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseMin(rhs)}; return concrete_type{parent::cwiseMin(rhs)};
else return base().cwiseMin(rhs); else return base().cwiseMin(rhs);
} }
auto cwiseMax(map const& rhs) const auto _cwiseMax(map const& rhs) const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseMax(rhs.base())}; return concrete_type{parent::cwiseMax(rhs.base())};
else return base().cwiseMax(rhs.base()); else return base().cwiseMax(rhs.base());
} }
auto cwiseMax(value_type rhs) const auto _cwiseMax(value_type rhs) const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseMax(rhs)}; return concrete_type{parent::cwiseMax(rhs)};
else return base().cwiseMax(rhs); else return base().cwiseMax(rhs);
} }
auto cwiseProduct(map const& rhs) const auto _cwiseProduct(map const& rhs) const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseProduct(rhs.base())}; return concrete_type{parent::cwiseProduct(rhs.base())};
else return base().cwiseProduct(rhs.base()); else return base().cwiseProduct(rhs.base());
} }
auto cwiseQuotient(map const& rhs) const auto _cwiseQuotient(map const& rhs) const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseQuotient(rhs.base())}; return concrete_type{parent::cwiseQuotient(rhs.base())};
else return base().cwiseQuotient(rhs.base()); else return base().cwiseQuotient(rhs.base());
} }
auto cwiseAbs() const auto _cwiseAbs() const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseAbs()}; return concrete_type{parent::cwiseAbs()};
else return base().cwiseAbs(); else return base().cwiseAbs();
} }
auto cwiseAbs2() const auto _cwiseAbs2() const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseAbs2()}; return concrete_type{parent::cwiseAbs2()};
else return base().cwiseAbs2(); else return base().cwiseAbs2();
} }
auto cwiseInverse() const auto _cwiseInverse() const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseInverse()}; return concrete_type{parent::cwiseInverse()};
else return base().cwiseInverse(); else return base().cwiseInverse();
} }
auto cwiseSqrt() const auto _cwiseSqrt() const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return concrete_type{parent::cwiseSqrt()}; return concrete_type{parent::cwiseSqrt()};
else return base().cwiseSqrt(); else return base().cwiseSqrt();
} }
auto cross(map const& rhs) const auto _cross(map const& rhs) const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
return concrete_type{parent::cross(rhs.base())}; return concrete_type{parent::cross(rhs.base())};
else return base().cross(rhs.base()); else return base().cross(rhs.base());
} }
auto inverse() const auto _inverse() const
{ {
if constexpr (use_expression_templates) return base().inverse(); if constexpr (use_expression_templates) return base().inverse();
else else
return as_concrete_type<decltype(base().inverse())>(base().inverse()); return as_concrete_type<decltype(base().inverse())>(base().inverse());
} }
auto normalized() const auto _normalized() const
requires(IsVectorAtCompileTime) requires(IsVectorAtCompileTime)
{ {
if constexpr (use_expression_templates) return base().normalized(); if constexpr (use_expression_templates) return base().normalized();
@ -301,7 +314,7 @@ namespace rotgen
base().normalized()); base().normalized());
} }
auto transpose() const auto _transpose() const
{ {
if constexpr (use_expression_templates) return base().transpose(); if constexpr (use_expression_templates) return base().transpose();
else else
@ -309,14 +322,14 @@ namespace rotgen
base().transpose()); base().transpose());
} }
auto adjoint() const auto _adjoint() const
{ {
if constexpr (use_expression_templates) return base().adjoint(); if constexpr (use_expression_templates) return base().adjoint();
else else
return as_concrete_type<decltype(base().adjoint())>(base().adjoint()); return as_concrete_type<decltype(base().adjoint())>(base().adjoint());
} }
auto conjugate() const auto _conjugate() const
{ {
if constexpr (use_expression_templates) return base().conjugate(); if constexpr (use_expression_templates) return base().conjugate();
else else
@ -324,116 +337,126 @@ namespace rotgen
base().conjugate()); base().conjugate());
} }
void normalize() void _normalize()
requires(IsVectorAtCompileTime) requires(IsVectorAtCompileTime)
{ {
base().normalize(); base().normalize();
} }
void transposeInPlace() { base().transposeInPlace(); } void _transposeInPlace() { base().transposeInPlace(); }
void adjointInPlace() { base().adjointInPlace(); } void _adjointInPlace() { base().adjointInPlace(); }
auto qr_solve(auto const& rhs) const auto qr_solve(auto const& rhs) const
{ {
return concrete_type(base().colPivHouseholderQr().solve(rhs.base())); return concrete_type(base().colPivHouseholderQr().solve(rhs.base()));
}; };
static auto Zero() static auto _Zero()
requires(requires { Ref::Zero(); }) requires(requires { Ref::Zero(); })
{ {
return Ref::Zero(); return Ref::Zero();
} }
static auto Zero(int rows, int cols) { return Ref::Zero(rows, cols); } static auto _Zero(int rows, int cols) { return Ref::Zero(rows, cols); }
static auto Ones() static auto _Ones()
requires(requires { Ref::Ones(); }) requires(requires { Ref::Ones(); })
{ {
return Ref::Ones(); return Ref::Ones();
} }
static auto Ones(int rows, int cols) { return Ref::Ones(rows, cols); } static auto _Ones(int rows, int cols) { return Ref::Ones(rows, cols); }
static auto Constant(value_type value) static auto _Constant(value_type value)
requires(requires { Ref::Constant(value); }) requires(requires { Ref::Constant(value); })
{ {
return Ref::Constant(value); return Ref::Constant(value);
} }
static auto Constant(int rows, int cols, value_type value) static auto _Constant(int rows, int cols, value_type value)
{ {
return Ref::Constant(rows, cols, value); return Ref::Constant(rows, cols, value);
} }
static auto Random() static auto _Random()
requires(requires { Ref::Random(); }) requires(requires { Ref::Random(); })
{ {
return Ref::Random(); return Ref::Random();
} }
static auto Random(int rows, int cols) { return Ref::Random(rows, cols); } static auto _Random(int rows, int cols) { return Ref::Random(rows, cols); }
static auto Identity() static auto _Identity()
requires(requires { Ref::Identity(); }) requires(requires { Ref::Identity(); })
{ {
return Ref::Identity(); return Ref::Identity();
} }
static auto Identity(int rows, int cols) static auto _Identity(int rows, int cols)
{ {
return Ref::Identity(rows, cols); return Ref::Identity(rows, cols);
} }
map& setOnes() map& _setOnes()
{ {
base() = parent::Ones(base().rows(), base().cols()); base() = parent::Ones(base().rows(), base().cols());
return *this; return *this;
} }
map& setZero() map& _setZero()
{ {
base() = parent::Zero(base().rows(), base().cols()); base() = parent::Zero(base().rows(), base().cols());
return *this; return *this;
} }
map& setConstant(value_type value) map& _setConstant(value_type value)
{ {
base() = parent::Constant(base().rows(), base().cols(), value); base() = parent::Constant(base().rows(), base().cols(), value);
return *this; return *this;
} }
map& setRandom() map& _setRandom()
{ {
base() = parent::Random(base().rows(), base().cols()); base() = parent::Random(base().rows(), base().cols());
return *this; return *this;
} }
map& setIdentity() map& _setIdentity()
{ {
base() = parent::Identity(base().rows(), base().cols()); base() = parent::Identity(base().rows(), base().cols());
return *this; return *this;
} }
using parent::cols;
using parent::data; using parent::data;
using parent::innerStride;
using parent::mean;
using parent::norm;
using parent::outerStride;
using parent::prod;
using parent::rows;
using parent::size; using parent::size;
using parent::squaredNorm;
using parent::sum;
using parent::trace;
auto minCoeff() const { return parent::minCoeff(); } Index _cols() const { return parent::cols(); }
auto maxCoeff() const { return parent::maxCoeff(); } Index _rows() const { return parent::rows(); }
value_type _mean() const { return parent::mean(); }
value_type _norm() const { return parent::norm(); }
value_type _squaredNorm() const { return parent::squaredNorm(); }
value_type _sum() const { return parent::sum(); }
value_type _prod() const { return parent::prod(); }
value_type _trace() const { return parent::trace(); }
Index _innerStride() const noexcept { return parent::innerStride(); };
Index _outerStride() const noexcept { return parent::outerStride(); };
auto _minCoeff() const { return parent::minCoeff(); }
auto _maxCoeff() const { return parent::maxCoeff(); }
template<std::integral IndexType> template<std::integral IndexType>
auto minCoeff(IndexType* row, IndexType* col) const auto _minCoeff(IndexType* row, IndexType* col) const
{ {
Index r, c; Index r, c;
auto result = parent::minCoeff(&r, &c); auto result = parent::minCoeff(&r, &c);
@ -443,7 +466,7 @@ namespace rotgen
} }
template<std::integral IndexType> template<std::integral IndexType>
auto maxCoeff(IndexType* row, IndexType* col) const auto _maxCoeff(IndexType* row, IndexType* col) const
{ {
Index r, c; Index r, c;
auto result = parent::maxCoeff(&r, &c); auto result = parent::maxCoeff(&r, &c);
@ -453,16 +476,42 @@ namespace rotgen
} }
template<typename R2, int O2, typename S2> template<typename R2, int O2, typename S2>
value_type dot(map<R2, O2, S2> const& rhs) const value_type _dot(map<R2, O2, S2> const& rhs) const
{ {
return base().dot(rhs.base()); return base().dot(rhs.base());
} }
template<int P> value_type lpNorm() const template<int P> value_type _lpNorm() const
{ {
static_assert(P == 1 || P == 2 || P == Infinity); static_assert(P == 1 || P == 2 || P == Infinity);
return parent::template lpNorm<P>(); return parent::template lpNorm<P>();
} }
template<typename R2, int O2, typename S2>
void validate_compound_operator(map<R2, O2, S2> const& rhs)
{
if constexpr (IsVectorAtCompileTime && R2::IsVectorAtCompileTime)
{
if constexpr (is_defined_static && R2::is_defined_static)
{
static_assert(
SizeAtCompileTime == R2::SizeAtCompileTime,
"Compile-time size mismatch in compound assignment operator");
}
else
{
ROTGEN_ASSERT(parent::size() == rhs.size(),
"Size mismatch in compound assignment operator");
}
}
else
{
ROTGEN_ASSERT(parent::rows() == rhs.rows(),
"Mismatched rows count in compound assignment operator");
ROTGEN_ASSERT(parent::cols() == rhs.cols(),
"Mismatched cols count in compound assignment operator");
}
}
}; };
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2> template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
@ -534,13 +583,14 @@ namespace rotgen
} }
template<typename R1, typename R2, int O1, typename S1, int O2, typename S2> template<typename R1, typename R2, int O1, typename S1, int O2, typename S2>
matrix<typename R1::value_type, R1::RowsAtCompileTime, R2::ColsAtCompileTime> auto operator*(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
operator*(map<R1, O1, S1> const& lhs, map<R2, O2, S2> const& rhs)
{ {
using concrete_type = matrix<typename R1::value_type, R1::RowsAtCompileTime, auto p = lhs.base() * rhs.base();
R2::ColsAtCompileTime>; using concrete_type = detail::as_concrete_t<decltype(p), matrix>;
return concrete_type(lhs.base() * rhs.base()); if constexpr (concrete_type::SizeAtCompileTime == 1)
return product{concrete_type{p}};
else return concrete_type{p};
} }
template<typename R, int O, typename S> template<typename R, int O, typename S>

View file

@ -7,11 +7,12 @@
//================================================================================================== //==================================================================================================
#pragma once #pragma once
#include <rotgen/detail/assert.hpp>
#include <rotgen/detail/helpers.hpp> #include <rotgen/detail/helpers.hpp>
#include <rotgen/concepts.hpp> #include <rotgen/concepts.hpp>
#include <rotgen/container/matrix/dynamic/impl.hpp> #include <rotgen/container/matrix/dynamic/impl.hpp>
#include <cassert>
#include <initializer_list> #include <initializer_list>
namespace rotgen namespace rotgen
@ -27,6 +28,7 @@ namespace rotgen
public: public:
using parent = find_matrix<Scalar, Opts>; using parent = find_matrix<Scalar, Opts>;
using rotgen_tag = void; using rotgen_tag = void;
using rotgen_matrix_tag = void;
using concrete_type = matrix; using concrete_type = matrix;
using value_type = Scalar; using value_type = Scalar;
@ -48,29 +50,40 @@ namespace rotgen
static constexpr bool has_static_storage = false; static constexpr bool has_static_storage = false;
static constexpr bool is_immutable = false; static constexpr bool is_immutable = false;
static constexpr int InnerStrideAtCompileTime = 1; static constexpr int InnerStrideAtCompileTime = 1;
static constexpr int OuterStrideAtCompileTime = static constexpr int OuterStrideAtCompileTime = IsRowMajor ? Cols : Rows;
IsRowMajor ? ColsAtCompileTime : RowsAtCompileTime;
using transposed_type = matrix<value_type, Cols, Rows, storage_order>; using transposed_type = matrix<value_type, Cols, Rows, storage_order>;
matrix() : parent(Rows == -1 ? 0 : Rows, Cols == -1 ? 0 : Cols) {} static constexpr int AllocatedRows =
Rows == -1 ? (MaxRows == -1 ? 0 : MaxRows) : Rows;
static constexpr int AllocatedCols =
Cols == -1 ? (MaxCols == -1 ? 0 : MaxCols) : Cols;
matrix() : parent(AllocatedRows, AllocatedCols) {}
matrix(Index r, Index c) : parent(r, c) matrix(Index r, Index c) : parent(r, c)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(r == Rows && "Mismatched between dynamic and static row size"); ROTGEN_ASSERT(r == Rows,
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(c == Cols && ROTGEN_ASSERT(c == Cols,
"Mismatched between dynamic and static column size"); "Mismatched between dynamic and static column size");
} }
matrix(Index n) matrix(Index n)
requires(IsVectorAtCompileTime && (Rows != 1 || Cols != 1)) requires(IsVectorAtCompileTime && (Rows != 1 || Cols != 1))
: parent(Rows != -1 ? 1 : n, Cols != -1 ? 1 : n) : parent(Rows != 1 ? n : 1, Cols != 1 ? n : 1)
{ {
if constexpr (Rows == 1 && Cols != -1)
ROTGEN_ASSERT(Cols == n,
"Mismatched between dynamic and static col size");
if constexpr (Cols == 1 && Rows != -1)
ROTGEN_ASSERT(Rows == n,
"Mismatched between dynamic and static row size");
} }
matrix(Scalar v) explicit matrix(Scalar v)
requires(Rows == 1 && Cols == 1) requires(Rows == 1 && Cols == 1)
: parent(1, 1, {v}) : parent(1, 1, {v})
{ {
@ -89,14 +102,14 @@ namespace rotgen
: parent(init) : parent(init)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(init.size() == Rows && ROTGEN_ASSERT(init.size() == Rows,
"Mismatched between dynamic and static row size"); "Mismatched between dynamic and static row size");
if constexpr (Cols != -1) if constexpr (Cols != -1)
{ {
[[maybe_unused]] Index c = 0; [[maybe_unused]] Index c = 0;
if (init.size()) c = init.begin()->size(); if (init.size()) c = init.begin()->size();
assert(c == Cols && ROTGEN_ASSERT(c == Cols,
"Mismatched between dynamic and static column size"); "Mismatched between dynamic and static column size");
} }
} }
@ -106,31 +119,28 @@ namespace rotgen
{ {
} }
matrix(concepts::entity auto const& e) : parent(e.rows(), e.cols()) template<concepts::entity Src> matrix(Src const& other) : parent()
{ {
if constexpr (Rows != -1) if constexpr (IsVectorAtCompileTime && Src::IsVectorAtCompileTime)
assert(e.rows() == Rows && {
"Mismatched between dynamic and static row size"); resize(other.size());
if constexpr (Cols != -1) for (rotgen::Index i = 0; i < parent::size(); ++i)
assert(e.cols() == Cols && (*this)[i] = other[i];
"Mismatched between dynamic and static col size"); }
for (rotgen::Index r = 0; r < e.rows(); ++r) else
for (rotgen::Index c = 0; c < e.cols(); ++c) (*this)(r, c) = e(r, c); {
resize(other._rows(), 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);
}
} }
matrix& operator=(concepts::entity auto const& e) matrix& operator=(concepts::entity auto const& other)
{ {
if constexpr (Rows != -1) matrix local(other);
assert(e.rows() == Rows && swap(local);
"Mismatched between dynamic and static row size");
if constexpr (Cols != -1)
assert(e.cols() == Cols &&
"Mismatched between dynamic and static col size");
resize(e.rows(), e.cols());
for (rotgen::Index r = 0; r < e.rows(); ++r)
for (rotgen::Index c = 0; c < e.cols(); ++c) (*this)(r, c) = e(r, c);
return *this; return *this;
} }
@ -146,27 +156,39 @@ namespace rotgen
return (*this)(i); return (*this)(i);
} }
auto evaluate() const { return *this; } void swap(matrix& other)
decltype(auto) noalias() const { return *this; }
decltype(auto) noalias() { return *this; }
Index innerStride() const noexcept { return 1; }
Index outerStride() const noexcept
{ {
return IsVectorAtCompileTime ? this->size() // TODO: Swap elements per elements if statically defined to preserve
: IsRowMajor ? this->cols() // data location in memory as with actual statically defines matrix
: this->rows(); base().swap(other.base());
}
auto _evaluate() const { return *this; }
decltype(auto) _noalias() const { return *this; }
decltype(auto) _noalias() { return *this; }
Index _innerStride() const noexcept { return 1; }
Index _outerStride() const noexcept
{
if constexpr (IsVectorAtCompileTime) return this->size();
else
{
if constexpr (IsRowMajor) return this->_cols();
else return this->_rows();
}
} }
void resize(int r, int c) void resize(int r, int c)
{ {
if constexpr (Rows == 1) if constexpr (Cols != -1)
assert(c == Cols && "Mismatched between dynamic and static col size"); ROTGEN_ASSERT(c == Cols,
if constexpr (Cols == 1) "Mismatched between dynamic and static col size");
assert(r == Rows && "Mismatched between dynamic and static row size"); if constexpr (Rows != -1)
ROTGEN_ASSERT(r == Rows,
"Mismatched between dynamic and static row size");
parent::resize(r, c); parent::resize(r, c);
} }
@ -177,80 +199,82 @@ namespace rotgen
else parent::resize(s, 1); else parent::resize(s, 1);
} }
void conservativeResize(int r, int c) void _conservativeResize(int r, int c)
{ {
if constexpr (Rows == 1) if constexpr (Cols != -1)
assert(c == Cols && "Mismatched between dynamic and static col size"); ROTGEN_ASSERT(c == Cols,
if constexpr (Cols == 1) "Mismatched between dynamic and static col size");
assert(r == Rows && "Mismatched between dynamic and static row size"); if constexpr (Rows != -1)
parent::conservativeResize(r, c); ROTGEN_ASSERT(r == Rows,
"Mismatched between dynamic and static row size");
parent::_conservativeResize(r, c);
} }
void conservativeResize(int s) void _conservativeResize(int s)
requires(IsVectorAtCompileTime) requires(IsVectorAtCompileTime)
{ {
if constexpr (Rows == 1) parent::conservativeResize(1, s); if constexpr (Rows == 1) parent::_conservativeResize(1, s);
else parent::conservativeResize(s, 1); else parent::_conservativeResize(s, 1);
} }
matrix normalized() const matrix _normalized() const
requires(IsVectorAtCompileTime) requires(IsVectorAtCompileTime)
{ {
return matrix(base().normalized()); return matrix(base()._normalized());
} }
transposed_type transpose() const transposed_type _transpose() const
{ {
return transposed_type(base().transpose()); return transposed_type(base()._transpose());
} }
matrix conjugate() const { return matrix(base().conjugate()); } matrix _conjugate() const { return matrix(base()._conjugate()); }
transposed_type adjoint() const transposed_type _adjoint() const
{ {
return transposed_type(base().adjoint()); return transposed_type(base()._adjoint());
} }
void normalize() void _normalize()
requires(IsVectorAtCompileTime) requires(IsVectorAtCompileTime)
{ {
parent::normalize(); parent::_normalize();
} }
void transposeInPlace() { parent::transposeInPlace(); } void _transposeInPlace() { parent::_transposeInPlace(); }
void adjointInPlace() { parent::adjointInPlace(); } void _adjointInPlace() { parent::_adjointInPlace(); }
matrix cwiseAbs() const { return matrix(base().cwiseAbs()); } matrix _cwiseAbs() const { return matrix(base()._cwiseAbs()); }
matrix cwiseAbs2() const { return matrix(base().cwiseAbs2()); } matrix _cwiseAbs2() const { return matrix(base()._cwiseAbs2()); }
matrix cwiseInverse() const { return matrix(base().cwiseInverse()); } matrix _cwiseInverse() const { return matrix(base()._cwiseInverse()); }
matrix cwiseSqrt() const { return matrix(base().cwiseSqrt()); } matrix _cwiseSqrt() const { return matrix(base()._cwiseSqrt()); }
friend bool operator==(matrix const& lhs, matrix const& rhs) friend bool operator==(matrix const& lhs, matrix const& rhs)
{ {
return static_cast<parent const&>(lhs) == static_cast<parent const&>(rhs); return lhs.base() == rhs.base();
} }
matrix& operator+=(matrix const& rhs) matrix& operator+=(matrix const& rhs)
{ {
base() += static_cast<parent const&>(rhs); base() += rhs.base();
return *this; return *this;
} }
matrix& operator-=(matrix const& rhs) matrix& operator-=(matrix const& rhs)
{ {
base() -= static_cast<parent const&>(rhs); base() -= rhs.base();
return *this; return *this;
} }
matrix operator-() const { return matrix(base().operator-()); } matrix operator-() const { return -base(); }
matrix& operator*=(matrix const& rhs) matrix& operator*=(matrix const& rhs)
{ {
base() *= static_cast<parent const&>(rhs); base() *= rhs.base();
return *this; return *this;
} }
@ -266,231 +290,184 @@ namespace rotgen
return *this; return *this;
} }
auto minCoeff() const { return parent::minCoeff(); } auto _minCoeff() const { return parent::_minCoeff(); }
auto maxCoeff() const { return parent::maxCoeff(); } auto _maxCoeff() const { return parent::_maxCoeff(); }
template<std::integral IndexType> template<std::integral IndexType>
auto minCoeff(IndexType* row, IndexType* col) const auto _minCoeff(IndexType* row, IndexType* col) const
{ {
Index r, c; Index r, c;
auto result = parent::minCoeff(&r, &c); auto result = parent::_minCoeff(&r, &c);
*row = r; *row = r;
*col = c; *col = c;
return result; return result;
} }
template<std::integral IndexType> template<std::integral IndexType>
auto maxCoeff(IndexType* row, IndexType* col) const auto _maxCoeff(IndexType* row, IndexType* col) const
{ {
Index r, c; Index r, c;
auto result = parent::maxCoeff(&r, &c); auto result = parent::_maxCoeff(&r, &c);
*row = r; *row = r;
*col = c; *col = c;
return result; return result;
} }
static matrix Ones() static matrix _Ones()
requires(Rows != -1 && Cols != -1) requires(Rows != -1 && Cols != -1)
{ {
return parent::Ones(Rows, Cols); return parent::_Ones(Rows, Cols);
} }
static matrix Ones(int rows, int cols) static matrix _Ones(int rows, int cols)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(rows == Rows && ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size"); "Mismatched between dynamic and static row size");
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(cols == Cols && ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size"); "Mismatched between dynamic and static column size");
return parent::Ones(rows, cols); return parent::_Ones(rows, cols);
} }
static matrix Zero() static matrix _Zero()
requires(Rows != -1 && Cols != -1) requires(Rows != -1 && Cols != -1)
{ {
return parent::Zero(Rows, Cols); return parent::_Zero(Rows, Cols);
} }
static matrix Zero(int rows, int cols) static matrix _Zero(int rows, int cols)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(rows == Rows && ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size"); "Mismatched between dynamic and static row size");
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(cols == Cols && ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size"); "Mismatched between dynamic and static column size");
return parent::Zero(rows, cols); return parent::_Zero(rows, cols);
} }
static matrix Constant(Scalar value) static matrix _Constant(Scalar value)
requires(Rows != -1 && Cols != -1) requires(Rows != -1 && Cols != -1)
{ {
return parent::Constant(Rows, Cols, static_cast<Scalar>(value)); return parent::_Constant(Rows, Cols, static_cast<Scalar>(value));
} }
static matrix Constant(int rows, int cols, Scalar value) static matrix _Constant(int rows, int cols, Scalar value)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(rows == Rows && ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size"); "Mismatched between dynamic and static row size");
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(cols == Cols && ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size"); "Mismatched between dynamic and static column size");
return parent::Constant(rows, cols, static_cast<Scalar>(value)); return parent::_Constant(rows, cols, static_cast<Scalar>(value));
} }
static matrix Random() static matrix _Random()
requires(Rows != -1 && Cols != -1) requires(Rows != -1 && Cols != -1)
{ {
return parent::Random(Rows, Cols); return parent::_Random(Rows, Cols);
} }
static matrix Random(int rows, int cols) static matrix _Random(int rows, int cols)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(rows == Rows && ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size"); "Mismatched between dynamic and static row size");
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(cols == Cols && ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size"); "Mismatched between dynamic and static column size");
return parent::Random(rows, cols); return parent::_Random(rows, cols);
} }
static matrix Identity() static matrix _Identity()
requires(Rows != -1 && Cols != -1) requires(Rows != -1 && Cols != -1)
{ {
return parent::Identity(Rows, Cols); return parent::_Identity(Rows, Cols);
} }
static matrix Identity(int rows, int cols) static matrix _Identity(int rows, int cols)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(rows == Rows && ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size"); "Mismatched between dynamic and static row size");
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(cols == Cols && ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size"); "Mismatched between dynamic and static column size");
return parent::Identity(rows, cols); return parent::_Identity(rows, cols);
} }
matrix& setOnes() matrix& _setOnes()
{ {
parent::setOnes(parent::rows(), parent::cols()); parent::_setOnes(parent::_rows(), parent::_cols());
return *this; return *this;
} }
matrix& setOnes(int rows, int cols) matrix& _setOnes(int rows, int cols)
{ {
parent::setOnes(rows, cols); parent::_setOnes(rows, cols);
return *this; return *this;
} }
matrix& setZero() matrix& _setZero()
{ {
parent::setZero(parent::rows(), parent::cols()); parent::_setZero(parent::_rows(), parent::_cols());
return *this; return *this;
} }
matrix& setZero(int rows, int cols) matrix& _setZero(int rows, int cols)
{ {
parent::setZero(rows, cols); parent::_setZero(rows, cols);
return *this; return *this;
} }
matrix& setConstant(Scalar v) matrix& _setConstant(Scalar v)
{ {
parent::setConstant(parent::rows(), parent::cols(), parent::_setConstant(parent::_rows(), parent::_cols(),
static_cast<Scalar>(v)); static_cast<Scalar>(v));
return *this; return *this;
} }
matrix& setConstant(int rows, int cols, Scalar v) matrix& _setConstant(int rows, int cols, Scalar v)
{ {
parent::setConstant(rows, cols, static_cast<Scalar>(v)); parent::_setConstant(rows, cols, static_cast<Scalar>(v));
return *this; return *this;
} }
matrix& setRandom() matrix& _setRandom()
{ {
parent::setRandom(parent::rows(), parent::cols()); parent::_setRandom(parent::_rows(), parent::_cols());
return *this; return *this;
} }
matrix& setRandom(int rows, int cols) matrix& _setRandom(int rows, int cols)
{ {
parent::setRandom(rows, cols); parent::_setRandom(rows, cols);
return *this; return *this;
} }
matrix& setIdentity() matrix& _setIdentity()
{ {
parent::setIdentity(parent::rows(), parent::cols()); parent::_setIdentity(parent::_rows(), parent::_cols());
return *this; return *this;
} }
matrix& setIdentity(int rows, int cols) matrix& _setIdentity(int rows, int cols)
{ {
parent::setIdentity(rows, cols); parent::_setIdentity(rows, cols);
return *this; return *this;
} }
template<int P> Scalar lpNorm() const template<int P> Scalar _lpNorm() const
{ {
static_assert(P == 1 || P == 2 || P == Infinity); static_assert(P == 1 || P == 2 || P == Infinity);
return parent::lp_norm(P); return parent::_lp_norm(P);
} }
parent& base() { return static_cast<parent&>(*this); } parent& base() { return static_cast<parent&>(*this); }
parent const& base() const { return static_cast<parent const&>(*this); } parent const& base() const { return static_cast<parent const&>(*this); }
}; };
template<typename S, int R, int C, int O, int MR, int MC>
matrix<S, R, C, O, MR, MC> operator+(matrix<S, R, C, O, MR, MC> const& lhs,
matrix<S, R, C, O, MR, MC> const& rhs)
{
matrix<S, R, C, O, MR, MC> that(lhs);
return that += rhs;
}
template<typename S, int R, int C, int O, int MR, int MC>
matrix<S, R, C, O, MR, MC> operator-(matrix<S, R, C, O, MR, MC> const& lhs,
matrix<S, R, C, O, MR, MC> const& rhs)
{
matrix<S, R, C, O, MR, MC> that(lhs);
return that -= rhs;
}
template<typename S, int R, int C, int O, int MR, int MC>
matrix<S, R, C, O, MR, MC> operator*(matrix<S, R, C, O, MR, MC> const& lhs,
matrix<S, R, C, O, MR, MC> const& rhs)
{
matrix<S, R, C, O, MR, MC> that(lhs);
return that *= rhs;
}
template<typename S, int R, int C, int O, int MR, int MC>
matrix<S, R, C, O, MR, MC> operator*(matrix<S, R, C, O, MR, MC> const& lhs,
double rhs)
{
matrix<S, R, C, O, MR, MC> that(lhs);
return that *= rhs;
}
template<typename S, int R, int C, int O, int MR, int MC>
matrix<S, R, C, O, MR, MC> operator*(double lhs,
matrix<S, R, C, O, MR, MC> const& rhs)
{
return rhs * lhs;
}
template<typename S, int R, int C, int O, int MR, int MC>
matrix<S, R, C, O, MR, MC> operator/(matrix<S, R, C, O, MR, MC> const& lhs,
double rhs)
{
matrix<S, R, C, O, MR, MC> that(lhs);
return that /= rhs;
}
} }

View file

@ -28,39 +28,40 @@ public:
~CLASSNAME(); ~CLASSNAME();
Index rows() const;
Index cols() const;
Index size() const; Index size() const;
Index _rows() const;
Index _cols() const;
void resize(Index new_rows, Index new_cols); void resize(Index new_rows, Index new_cols);
void conservativeResize(Index new_rows, Index new_cols); void _conservativeResize(Index new_rows, Index new_cols);
CLASSNAME normalized() const; CLASSNAME _normalized() const;
CLASSNAME transpose() const; CLASSNAME _transpose() const;
CLASSNAME conjugate() const; CLASSNAME _conjugate() const;
CLASSNAME adjoint() const; CLASSNAME _adjoint() const;
CLASSNAME cwiseAbs() const; CLASSNAME _cwiseAbs() const;
CLASSNAME cwiseAbs2() const; CLASSNAME _cwiseAbs2() const;
CLASSNAME cwiseInverse() const; CLASSNAME _cwiseInverse() const;
CLASSNAME cwiseSqrt() const; CLASSNAME _cwiseSqrt() const;
void normalize(); void _normalize();
void transposeInPlace(); void _transposeInPlace();
void adjointInPlace(); void _adjointInPlace();
TYPE sum() const; TYPE _sum() const;
TYPE prod() const; TYPE _prod() const;
TYPE mean() const; TYPE _mean() const;
TYPE trace() const; TYPE _trace() const;
TYPE maxCoeff() const; TYPE _maxCoeff() const;
TYPE minCoeff() const; TYPE _minCoeff() const;
TYPE maxCoeff(Index* row, Index* col) const; TYPE _maxCoeff(Index* row, Index* col) const;
TYPE minCoeff(Index* row, Index* col) const; TYPE _minCoeff(Index* row, Index* col) const;
TYPE squaredNorm() const; TYPE _squaredNorm() const;
TYPE norm() const; TYPE _norm() const;
TYPE lp_norm(int p) const; TYPE _lp_norm(int p) const;
TYPE& operator()(Index i, Index j); TYPE& operator()(Index i, Index j);
TYPE const& operator()(Index i, Index j) const; TYPE const& operator()(Index i, Index j) const;
@ -87,17 +88,19 @@ public:
const TYPE* data() const; const TYPE* data() const;
TYPE* data(); TYPE* data();
static CLASSNAME Zero(Index rows, Index cols); static CLASSNAME _Zero(Index rows, Index cols);
static CLASSNAME Ones(Index rows, Index cols); static CLASSNAME _Ones(Index rows, Index cols);
static CLASSNAME Constant(Index rows, Index cols, TYPE value); static CLASSNAME _Constant(Index rows, Index cols, TYPE value);
static CLASSNAME Random(Index rows, Index cols); static CLASSNAME _Random(Index rows, Index cols);
static CLASSNAME Identity(Index rows, Index cols); static CLASSNAME _Identity(Index rows, Index cols);
void setOnes(Index rows, Index cols); void _setOnes(Index rows, Index cols);
void setZero(Index rows, Index cols); void _setZero(Index rows, Index cols);
void setConstant(Index rows, Index cols, TYPE value); void _setConstant(Index rows, Index cols, TYPE value);
void setRandom(Index rows, Index cols); void _setRandom(Index rows, Index cols);
void setIdentity(Index rows, Index cols); void _setIdentity(Index rows, Index cols);
void swap(CLASSNAME& other) { storage_.swap(other.storage_); }
private: private:
struct payload; struct payload;

View file

@ -7,6 +7,7 @@
//================================================================================================== //==================================================================================================
#pragma once #pragma once
#include <rotgen/detail/assert.hpp>
#include <rotgen/detail/helpers.hpp> #include <rotgen/detail/helpers.hpp>
#include <rotgen/concepts.hpp> #include <rotgen/concepts.hpp>
@ -40,6 +41,7 @@ namespace rotgen
{ {
public: public:
using rotgen_tag = void; using rotgen_tag = void;
using rotgen_matrix_tag = void;
using parent = using parent =
detail::storage_type<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>; detail::storage_type<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>;
using value_type = Scalar; using value_type = Scalar;
@ -49,6 +51,9 @@ namespace rotgen
using concrete_type = matrix; using concrete_type = matrix;
using concrete_dynamic_type = matrix<value_type>; using concrete_dynamic_type = matrix<value_type>;
using exact_base =
Eigen::Matrix<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>;
static constexpr int RowsAtCompileTime = Rows; static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols; static constexpr int ColsAtCompileTime = Cols;
static constexpr int SizeAtCompileTime = detail::static_size<matrix>(); static constexpr int SizeAtCompileTime = detail::static_size<matrix>();
@ -75,6 +80,11 @@ namespace rotgen
static constexpr bool has_static_storage = static constexpr bool has_static_storage =
storage_status<Rows, Cols, MaxRows, MaxCols>; storage_status<Rows, Cols, MaxRows, MaxCols>;
static constexpr int AllocatedRows =
Rows == -1 ? (MaxRows == -1 ? 0 : MaxRows) : Rows;
static constexpr int AllocatedCols =
Cols == -1 ? (MaxCols == -1 ? 0 : MaxCols) : Cols;
public: public:
matrix() matrix()
requires(has_static_storage) requires(has_static_storage)
@ -83,19 +93,23 @@ namespace rotgen
matrix() matrix()
requires(!has_static_storage) requires(!has_static_storage)
: parent(Rows > 0 ? Rows : 0, Cols > 0 ? Cols : 0) : parent(AllocatedRows, AllocatedCols)
{ {
} }
matrix(Index r, Index c) : parent(r, c) matrix(Index r, Index c) : parent(r, c)
{ {
if constexpr (RowsAtCompileTime != -1) if constexpr (RowsAtCompileTime != -1)
assert(r == RowsAtCompileTime && {
"Mismatched between dynamic and static row size"); ROTGEN_ASSERT(r == RowsAtCompileTime,
"Mismatched between dynamic and static row size");
}
if constexpr (ColsAtCompileTime != -1) if constexpr (ColsAtCompileTime != -1)
assert(c == ColsAtCompileTime && {
"Mismatched between dynamic and static column size"); ROTGEN_ASSERT(c == ColsAtCompileTime,
"Mismatched between dynamic and static column size");
}
} }
matrix(matrix const& other) = default; matrix(matrix const& other) = default;
@ -117,8 +131,11 @@ namespace rotgen
explicit matrix(Scalar v) explicit matrix(Scalar v)
requires(Rows == 1 && Cols == 1) requires(Rows == 1 && Cols == 1)
: parent([&]() { : parent([&]() {
if constexpr (has_static_storage) return parent(v); if constexpr (has_static_storage) { return parent(v); }
else return parent{1, 1}; else
{
return parent{1, 1};
}
}()) }())
{ {
if constexpr (!has_static_storage) (*this)(0) = v; if constexpr (!has_static_storage) (*this)(0) = v;
@ -127,12 +144,18 @@ namespace rotgen
matrix(std::initializer_list<Scalar> init) matrix(std::initializer_list<Scalar> init)
requires(IsVectorAtCompileTime) requires(IsVectorAtCompileTime)
: parent([&]() { : parent([&]() {
if constexpr (has_static_storage) return parent{}; if constexpr (has_static_storage) { return parent{}; }
else return parent{Rows, Cols}; else
{
return parent{Rows, Cols};
}
}()) }())
{ {
auto first = init.begin(); auto first = init.begin();
for (rotgen::Index i = 0; i < parent::size(); i++) (*this)(i) = first[i]; for (rotgen::Index i = 0; i < parent::size(); i++)
{
(*this)(i) = first[i];
}
} }
matrix(Scalar v0, Scalar v1, auto... vs) matrix(Scalar v0, Scalar v1, auto... vs)
@ -174,35 +197,34 @@ namespace rotgen
return *this; return *this;
} }
using parent::innerStride;
using parent::outerStride;
parent& base() { return static_cast<parent&>(*this); } parent& base() { return static_cast<parent&>(*this); }
parent const& base() const { return static_cast<parent const&>(*this); } parent const& base() const { return static_cast<parent const&>(*this); }
auto evaluate() const auto _evaluate() const { return *this; }
decltype(auto) _noalias() const
{ {
auto res = base().eval(); if constexpr (use_expression_templates) { return base().noalias(); }
return as_concrete_type<decltype(res)>(res); else
{
return *this;
}
} }
decltype(auto) noalias() const decltype(auto) _noalias()
{ {
if constexpr (use_expression_templates) return base().noalias(); if constexpr (use_expression_templates) { return base().noalias(); }
else return *this; else
{
return *this;
}
} }
decltype(auto) noalias() auto _normalized() const
{
if constexpr (use_expression_templates) return base().noalias();
else return *this;
}
auto normalized() const
requires(IsVectorAtCompileTime) requires(IsVectorAtCompileTime)
{ {
if constexpr (use_expression_templates) return base().normalized(); if constexpr (use_expression_templates) { return base().normalized(); }
else else
{ {
auto res = base().normalized(); auto res = base().normalized();
@ -210,9 +232,9 @@ namespace rotgen
} }
} }
auto transpose() const auto _transpose() const
{ {
if constexpr (use_expression_templates) return base().transpose(); if constexpr (use_expression_templates) { return base().transpose(); }
else else
{ {
auto res = base().transpose(); auto res = base().transpose();
@ -220,180 +242,232 @@ namespace rotgen
} }
} }
auto conjugate() const auto _conjugate() const
{ {
auto res = base().conjugate(); auto res = base().conjugate();
return as_concrete_type<decltype(res)>(res); return as_concrete_type<decltype(res)>(res);
} }
auto adjoint() const auto _adjoint() const
{ {
auto res = base().adjoint(); auto res = base().adjoint();
return as_concrete_type<decltype(res)>(res); return as_concrete_type<decltype(res)>(res);
} }
void normalize() void _normalize()
requires(IsVectorAtCompileTime) requires(IsVectorAtCompileTime)
{ {
parent::normalize(); parent::normalize();
} }
void transposeInPlace() { parent::transposeInPlace(); } void _transposeInPlace() { parent::transposeInPlace(); }
void adjointInPlace() { parent::adjointInPlace(); } void _adjointInPlace() { parent::adjointInPlace(); }
auto cwiseAbs() const auto _cwiseAbs() const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
{
return matrix{parent::cwiseAbs()}; return matrix{parent::cwiseAbs()};
else return base().cwiseAbs(); }
else
{
return base().cwiseAbs();
}
} }
auto cwiseAbs2() const auto _cwiseAbs2() const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
{
return matrix{parent::cwiseAbs2()}; return matrix{parent::cwiseAbs2()};
else return base().cwiseAbs2(); }
else
{
return base().cwiseAbs2();
}
} }
auto cwiseInverse() const auto _cwiseInverse() const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
{
return matrix{parent::cwiseInverse()}; return matrix{parent::cwiseInverse()};
else return base().cwiseInverse(); }
else
{
return base().cwiseInverse();
}
} }
auto cwiseSqrt() const auto _cwiseSqrt() const
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
{
return matrix{parent::cwiseSqrt()}; return matrix{parent::cwiseSqrt()};
else return base().cwiseSqrt(); }
else
{
return base().cwiseSqrt();
}
} }
void resize(int s) void resize(int new_size)
requires(IsVectorAtCompileTime) requires(IsVectorAtCompileTime)
{ {
if constexpr (Rows == 1) if constexpr (Rows == 1) { parent::resize(1, new_size); }
assert(s == Cols && "Mismatched between dynamic and static col size"); else
if constexpr (Cols == 1) {
assert(s == Rows && "Mismatched between dynamic and static row size"); parent::resize(new_size, 1);
parent::resize(s); }
} }
void resize(int r, int c) void resize(int new_row_count, int new_col_count)
{ {
if constexpr (Rows == 1) if constexpr (Cols != -1)
assert(c == Cols && "Mismatched between dynamic and static col size"); {
if constexpr (Cols == 1) ROTGEN_ASSERT(new_col_count == Cols,
assert(r == Rows && "Mismatched between dynamic and static row size"); "Mismatched between dynamic and static col size");
parent::resize(r, c); }
if constexpr (Rows != -1)
{
ROTGEN_ASSERT(new_row_count == Rows,
"Mismatched between dynamic and static row size");
}
parent::resize(new_row_count, new_col_count);
} }
void conservativeResize(int s) void _conservativeResize(int new_size)
requires(IsVectorAtCompileTime) requires(IsVectorAtCompileTime)
{ {
if constexpr (Rows == 1) if constexpr (Rows == 1) { parent::conservativeResize(1, new_size); }
assert(s == Cols && "Mismatched between dynamic and static col size"); else
if constexpr (Cols == 1) {
assert(s == Rows && "Mismatched between dynamic and static row size"); parent::conservativeResize(new_size, 1);
parent::conservativeResize(s); }
} }
void conservativeResize(int r, int c) void _conservativeResize(int new_row_count, int new_col_count)
{ {
if constexpr (Rows == 1) if constexpr (Cols != -1)
assert(c == Cols && "Mismatched between dynamic and static col size"); {
if constexpr (Cols == 1) ROTGEN_ASSERT(new_col_count == Cols,
assert(r == Rows && "Mismatched between dynamic and static row size"); "Mismatched between dynamic and static col size");
parent::conservativeResize(r, c); }
if constexpr (Rows != -1)
{
ROTGEN_ASSERT(new_row_count == Rows,
"Mismatched between dynamic and static row size");
}
parent::conservativeResize(new_row_count, new_col_count);
} }
static matrix Constant(Scalar value) static matrix _Constant(Scalar value)
requires(Rows != -1 && Cols != -1) requires(Rows != -1 && Cols != -1)
{ {
return parent::Constant(Rows, Cols, static_cast<Scalar>(value)); return parent::Constant(Rows, Cols, value);
} }
static matrix Constant(int rows, int cols, Scalar value) static matrix _Constant(int rows, int cols, Scalar value)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(rows == Rows && {
"Mismatched between dynamic and static row size"); ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
}
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(cols == Cols && {
"Mismatched between dynamic and static column size"); ROTGEN_ASSERT(cols == Cols,
return parent::Constant(rows, cols, static_cast<Scalar>(value)); "Mismatched between dynamic and static column size");
}
return parent::Constant(rows, cols, value);
} }
static matrix Identity() static matrix _Identity()
requires(Rows != -1 && Cols != -1) requires(Rows != -1 && Cols != -1)
{ {
return parent::Identity(Rows, Cols); return parent::Identity(Rows, Cols);
} }
static matrix Identity(int rows, int cols) static matrix _Identity(int rows, int cols)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(rows == Rows && {
"Mismatched between dynamic and static row size"); ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
}
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(cols == Cols && {
"Mismatched between dynamic and static column size"); ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
}
return parent::Identity(rows, cols); return parent::Identity(rows, cols);
} }
static matrix Ones() static matrix _Ones()
requires(Rows != -1 && Cols != -1) requires(Rows != -1 && Cols != -1)
{ {
return parent::Ones(Rows, Cols); return parent::Ones(Rows, Cols);
} }
static matrix Ones(int rows, int cols) static matrix _Ones(int rows, int cols)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(rows == Rows && {
"Mismatched between dynamic and static row size"); ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
}
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(cols == Cols && {
"Mismatched between dynamic and static column size"); ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
}
return parent::Ones(rows, cols); return parent::Ones(rows, cols);
} }
static matrix Zero() static matrix _Zero()
requires(Rows != -1 && Cols != -1) requires(Rows != -1 && Cols != -1)
{ {
return parent::Zero(Rows, Cols); return parent::Zero(Rows, Cols);
} }
static matrix Zero(int rows, int cols) static matrix _Zero(int rows, int cols)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(rows == Rows && {
"Mismatched between dynamic and static row size"); ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
}
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(cols == Cols && {
"Mismatched between dynamic and static column size"); ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
}
return parent::Zero(rows, cols); return parent::Zero(rows, cols);
} }
static matrix Random() static matrix _Random()
requires(Rows != -1 && Cols != -1) requires(Rows != -1 && Cols != -1)
{ {
return parent::Random(Rows, Cols); return parent::Random(Rows, Cols);
} }
static matrix Random(int rows, int cols) static matrix _Random(int rows, int cols)
{ {
if constexpr (Rows != -1) if constexpr (Rows != -1)
assert(rows == Rows && {
"Mismatched between dynamic and static row size"); ROTGEN_ASSERT(rows == Rows,
"Mismatched between dynamic and static row size");
}
if constexpr (Cols != -1) if constexpr (Cols != -1)
assert(cols == Cols && {
"Mismatched between dynamic and static column size"); ROTGEN_ASSERT(cols == Cols,
"Mismatched between dynamic and static column size");
}
return parent::Random(rows, cols); return parent::Random(rows, cols);
} }
template<int P> value_type lpNorm() const template<int P> value_type _lpNorm() const
{ {
static_assert(P == 1 || P == 2 || P == Infinity); static_assert(P == 1 || P == 2 || P == Infinity);
return parent::template lpNorm<P>(); return parent::template lpNorm<P>();
@ -412,96 +486,111 @@ namespace rotgen
} }
using parent::operator(); using parent::operator();
using parent::cols;
using parent::data; using parent::data;
using parent::mean;
using parent::norm;
using parent::prod;
using parent::rows;
using parent::size; using parent::size;
using parent::squaredNorm;
using parent::sum;
using parent::trace;
auto minCoeff() const { return parent::minCoeff(); } Index _cols() const { return parent::cols(); }
auto maxCoeff() const { return parent::maxCoeff(); } Index _rows() const { return parent::rows(); }
// Reductions
value_type _mean() const { return parent::mean(); }
value_type _norm() const { return parent::norm(); }
value_type _squaredNorm() const { return parent::squaredNorm(); }
value_type _sum() const { return parent::sum(); }
value_type _prod() const { return parent::prod(); }
value_type _trace() const { return parent::trace(); }
Index _innerStride() const noexcept { return parent::innerStride(); };
Index _outerStride() const noexcept { return parent::outerStride(); };
auto _minCoeff() const { return parent::minCoeff(); }
auto _maxCoeff() const { return parent::maxCoeff(); }
template<std::integral IndexType> template<std::integral IndexType>
auto minCoeff(IndexType* row, IndexType* col) const auto _minCoeff(IndexType* row, IndexType* col) const
{ {
Index r, c; Index result_row, result_col;
auto result = parent::minCoeff(&r, &c); auto result = parent::minCoeff(&result_row, &result_col);
*row = r; *row = result_row;
*col = c; *col = result_col;
return result; return result;
} }
template<std::integral IndexType> template<std::integral IndexType>
auto maxCoeff(IndexType* row, IndexType* col) const auto _maxCoeff(IndexType* row, IndexType* col) const
{ {
Index r, c; Index result_row, result_col;
auto result = parent::maxCoeff(&r, &c); auto result = parent::maxCoeff(&result_row, &result_col);
*row = r; *row = result_row;
*col = c; *col = result_col;
return result; return result;
} }
matrix& setOnes() matrix& _setOnes()
{ {
*this = parent::Ones(rows(), cols()); *this = parent::Ones(_rows(), _cols());
return *this; return *this;
} }
matrix& setOnes(int r, int c) matrix& _setOnes(int r, int c)
{ {
*this = parent::Ones(r, c); *this = parent::Ones(r, c);
return *this; return *this;
} }
matrix& setZero() matrix& _setZero()
{ {
*this = parent::Zero(rows(), cols()); *this = parent::Zero(_rows(), _cols());
return *this; return *this;
} }
matrix& setZero(int r, int c) matrix& _setZero(int r, int c)
{ {
*this = parent::Zero(r, c); *this = parent::Zero(r, c);
return *this; return *this;
} }
matrix& setConstant(Scalar value) matrix& _setConstant(Scalar value)
{ {
*this = parent::Constant(rows(), cols(), static_cast<Scalar>(value)); *this = parent::Constant(_rows(), _cols(), value);
return *this; return *this;
} }
matrix& setConstant(int r, int c, Scalar value) matrix& _setConstant(int r, int c, Scalar value)
{ {
*this = parent::Constant(r, c, static_cast<Scalar>(value)); *this = parent::Constant(r, c, value);
return *this; return *this;
} }
matrix& setRandom() matrix& _setRandom()
{ {
*this = parent::Random(rows(), cols()); *this = parent::Random(_rows(), _cols());
return *this; return *this;
} }
matrix& setRandom(int r, int c) matrix& _setRandom(int r, int c)
{ {
*this = parent::Random(r, c); *this = parent::Random(r, c);
return *this; return *this;
} }
matrix& setIdentity() matrix& _setIdentity()
{ {
*this = parent::Identity(rows(), cols()); *this = parent::Identity(_rows(), _cols());
return *this; return *this;
} }
matrix& setIdentity(int r, int c) matrix& _setIdentity(int r, int c)
{ {
*this = parent::Identity(r, c); *this = parent::Identity(r, c);
return *this; return *this;
@ -519,7 +608,7 @@ namespace rotgen
return *this; return *this;
} }
matrix operator-() const { return matrix(base()(*this).operator-()); } matrix operator-() const { return -base(); }
matrix& operator*=(matrix const& rhs) matrix& operator*=(matrix const& rhs)
{ {

View file

@ -7,12 +7,13 @@
//================================================================================================== //==================================================================================================
#pragma once #pragma once
#include <rotgen/detail/assert.hpp>
#include <rotgen/config.hpp> #include <rotgen/config.hpp>
#include <rotgen/container/block.hpp> #include <rotgen/container/block.hpp>
#include <rotgen/container/map.hpp> #include <rotgen/container/map.hpp>
#include <rotgen/format.hpp> #include <rotgen/format.hpp>
#include <cassert>
#include <iostream> #include <iostream>
#include <type_traits> #include <type_traits>

View file

@ -7,7 +7,8 @@
//================================================================================================== //==================================================================================================
#pragma once #pragma once
#include <cassert> #include <rotgen/detail/assert.hpp>
#include <type_traits> #include <type_traits>
#if !defined(ROTGEN_FORCE_DYNAMIC) #if !defined(ROTGEN_FORCE_DYNAMIC)
@ -15,6 +16,7 @@
#endif #endif
#include <rotgen/detail/accept_as_ref.hpp> #include <rotgen/detail/accept_as_ref.hpp>
#include <rotgen/detail/product.hpp>
namespace rotgen namespace rotgen
{ {
@ -58,33 +60,33 @@ namespace rotgen
using parent::operator[]; using parent::operator[];
// Size related functions // Size related functions
using parent::cols;
using parent::data; using parent::data;
using parent::innerStride;
using parent::outerStride;
using parent::rows;
using parent::size; using parent::size;
using parent::_cols;
using parent::_innerStride;
using parent::_outerStride;
using parent::_rows;
// Aliasing handling // Aliasing handling
using parent::evaluate; using parent::_evaluate;
using parent::noalias; using parent::_noalias;
// Reductions // Reductions
using parent::lpNorm; using parent::_lpNorm;
using parent::maxCoeff; using parent::_maxCoeff;
using parent::mean; using parent::_mean;
using parent::minCoeff; using parent::_minCoeff;
using parent::norm; using parent::_norm;
using parent::prod; using parent::_prod;
using parent::squaredNorm; using parent::_squaredNorm;
using parent::sum; using parent::_sum;
using parent::trace; using parent::_trace;
// Arithmetic // Arithmetic
using parent::cwiseAbs; using parent::_cwiseAbs;
using parent::cwiseAbs2; using parent::_cwiseAbs2;
using parent::cwiseInverse; using parent::_cwiseInverse;
using parent::cwiseSqrt; using parent::_cwiseSqrt;
// Compound Operators // Compound Operators
template<typename A, int O, typename S> template<typename A, int O, typename S>
@ -126,29 +128,30 @@ namespace rotgen
} }
// Shape modifications // Shape modifications
using parent::adjoint; using parent::_adjoint;
using parent::conjugate; using parent::_conjugate;
using parent::normalized; using parent::_normalized;
using parent::transpose; using parent::_transpose;
// In-place Shape modifications // In-place Shape modifications
using parent::adjointInPlace; using parent::_adjointInPlace;
using parent::normalize; using parent::_normalize;
using parent::transposeInPlace; using parent::_transposeInPlace;
// Generators // Generators
using parent::Constant; using parent::_Constant;
using parent::Identity; using parent::_Identity;
using parent::Ones; using parent::_Ones;
using parent::Random; using parent::_Random;
using parent::setConstant; using parent::_setConstant;
using parent::setIdentity; using parent::_setIdentity;
using parent::setOnes; using parent::_setOnes;
using parent::setRandom; using parent::_setRandom;
using parent::setZero; using parent::_setZero;
using parent::Zero; using parent::_Zero;
using parent::operator=; using parent::operator=;
using parent::operator-;
template<typename RO, int OO, typename SO> template<typename RO, int OO, typename SO>
auto qr_solve(ref<RO, OO, SO> rhs) const auto qr_solve(ref<RO, OO, SO> rhs) const
@ -166,12 +169,18 @@ namespace rotgen
parent& as_map() { return base(); } parent& as_map() { return base(); }
template<typename M>
requires(is_immutable)
ref(product<M> const& m) : ref(m.storage_)
{
}
template<typename S, int R, int C, int O, int MR, int MC> 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>>) 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{}) ref(matrix<S, R, C, O, MR, MC>& m) : parent(detail::postpone{})
{ {
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, m); [[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, m);
assert(correct_ref_setup); ROTGEN_ASSERT(correct_ref_setup, "Invalid reference binding");
} }
template<typename S, int R, int C, int O, int MR, int MC> template<typename S, int R, int C, int O, int MR, int MC>
@ -202,7 +211,7 @@ namespace rotgen
ref(block<Ref, R, C, I>&& b) : parent(detail::postpone{}) ref(block<Ref, R, C, I>&& b) : parent(detail::postpone{})
{ {
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b); [[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
assert(correct_ref_setup); ROTGEN_ASSERT(correct_ref_setup, "Invalid reference binding");
} }
template<typename Ref, int R, int C, bool I> template<typename Ref, int R, int C, bool I>
@ -210,7 +219,7 @@ namespace rotgen
ref(block<Ref, R, C, I>& b) : parent(detail::postpone{}) ref(block<Ref, R, C, I>& b) : parent(detail::postpone{})
{ {
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b); [[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
assert(correct_ref_setup); ROTGEN_ASSERT(correct_ref_setup, "Invalid reference binding");
} }
template<typename Ref, int R, int C, bool I> template<typename Ref, int R, int C, bool I>
@ -229,7 +238,7 @@ namespace rotgen
ref(map<Ref, O, S>& b) : parent(detail::postpone{}) ref(map<Ref, O, S>& b) : parent(detail::postpone{})
{ {
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b); [[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
assert(correct_ref_setup); ROTGEN_ASSERT(correct_ref_setup, "Invalid reference binding");
} }
template<typename Ref, int O, typename S> template<typename Ref, int O, typename S>
@ -259,15 +268,15 @@ namespace rotgen
ref(ref<TT, OO, SS>& b) : parent(detail::postpone{}) ref(ref<TT, OO, SS>& b) : parent(detail::postpone{})
{ {
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b); [[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
assert(correct_ref_setup); ROTGEN_ASSERT(correct_ref_setup, "Invalid reference binding");
} }
template<typename TT, int OO, typename SS> template<typename TT, int OO, typename SS>
requires(detail::same_scalar<ref, ref<TT, OO, SS>>) requires(detail::accept_as_ref<ref, ref<TT, OO, SS>>)
ref(ref<TT, OO, SS> const& b) : parent(detail::postpone{}) ref(ref<TT, OO, SS> const& b) : parent(detail::postpone{})
{ {
[[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b); [[maybe_unused]] bool correct_ref_setup = detail::validate_ref(*this, b);
assert(correct_ref_setup); ROTGEN_ASSERT(correct_ref_setup, "Invalid reference binding");
} }
ref(parent& m) : parent(m.data(), m.rows(), m.cols()) {} ref(parent& m) : parent(m.data(), m.rows(), m.cols()) {}
@ -339,70 +348,70 @@ namespace rotgen
template<typename A, int O, typename S, typename B, int P, typename T> 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) auto min(ref<A, O, S> lhs, ref<B, P, T> rhs)
-> decltype(lhs.base().cwiseMin(rhs.base())) -> decltype(lhs.base()._cwiseMin(rhs.base()))
{ {
return lhs.base().cwiseMin(rhs.base()); return lhs.base()._cwiseMin(rhs.base());
} }
template<typename A, int O, typename S> template<typename A, int O, typename S>
auto min(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s) auto min(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
-> decltype(lhs.base().cwiseMin(s)) -> decltype(lhs.base()._cwiseMin(s))
{ {
return lhs.base().cwiseMin(s); return lhs.base()._cwiseMin(s);
} }
template<typename A, int O, typename S> template<typename A, int O, typename S>
auto min(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs) auto min(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs)
-> decltype(rhs.base().cwiseMin(s)) -> decltype(rhs.base()._cwiseMin(s))
{ {
return rhs.base().cwiseMin(s); return rhs.base()._cwiseMin(s);
} }
template<typename A, int O, typename S, typename B, int P, typename T> 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) auto max(ref<A, O, S> lhs, ref<B, P, T> rhs)
-> decltype(lhs.base().cwiseMax(rhs.base())) -> decltype(lhs.base()._cwiseMax(rhs.base()))
{ {
return lhs.base().cwiseMax(rhs.base()); return lhs.base()._cwiseMax(rhs.base());
} }
template<typename A, int O, typename S> template<typename A, int O, typename S>
auto max(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s) auto max(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s)
-> decltype(lhs.base().cwiseMax(s)) -> decltype(lhs.base()._cwiseMax(s))
{ {
return lhs.base().cwiseMax(s); return lhs.base()._cwiseMax(s);
} }
template<typename A, int O, typename S> template<typename A, int O, typename S>
auto max(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs) auto max(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs)
-> decltype(rhs.base().cwiseMax(s)) -> decltype(rhs.base()._cwiseMax(s))
{ {
return rhs.base().cwiseMax(s); return rhs.base()._cwiseMax(s);
} }
template<typename A, int O, typename S, typename B, int P, typename T> 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) auto mul(ref<A, O, S> lhs, ref<B, P, T> rhs)
-> decltype(lhs.base().cwiseProduct(rhs.base())) -> decltype(lhs.base()._cwiseProduct(rhs.base()))
{ {
return lhs.base().cwiseProduct(rhs.base()); return lhs.base()._cwiseProduct(rhs.base());
} }
template<typename A, int O, typename S, typename B, int P, typename T> 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) auto div(ref<A, O, S> lhs, ref<B, P, T> rhs)
-> decltype(lhs.base().cwiseQuotient(rhs.base())) -> decltype(lhs.base()._cwiseQuotient(rhs.base()))
{ {
return lhs.base().cwiseQuotient(rhs.base()); return lhs.base()._cwiseQuotient(rhs.base());
} }
template<typename A, int O, typename S> template<typename A, int O, typename S>
auto inverse(ref<A, O, S> lhs) -> decltype(lhs.base().inverse()) auto inverse(ref<A, O, S> lhs) -> decltype(lhs.base()._inverse())
{ {
return lhs.base().inverse(); return lhs.base()._inverse();
} }
template<typename A, int O, typename S, typename B, int P, typename T> 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) auto cross(ref<A, O, S> lhs, ref<B, P, T> rhs)
-> decltype(lhs.base().cross(rhs.base())) -> decltype(lhs.base()._cross(rhs.base()))
{ {
return lhs.base().cross(rhs.base()); return lhs.base()._cross(rhs.base());
} }
} }

View file

@ -8,6 +8,7 @@
#pragma once #pragma once
#include <rotgen/detail/helpers.hpp> #include <rotgen/detail/helpers.hpp>
#include <rotgen/detail/product.hpp>
#include <Eigen/Dense> #include <Eigen/Dense>
#include <type_traits> #include <type_traits>
@ -52,6 +53,9 @@ namespace rotgen
template<typename T, int Options, typename Stride> template<typename T, int Options, typename Stride>
using compile_ref_t = typename compile_ref<T, Options, Stride>::type; using compile_ref_t = typename compile_ref<T, Options, Stride>::type;
template<typename T, int Options, typename Stride>
using compile_base_t = typename compile_ref<T, Options, Stride>::base;
} }
template<typename T, int Options, typename Stride> template<typename T, int Options, typename Stride>
@ -59,6 +63,7 @@ namespace rotgen
{ {
public: public:
using parent = detail::compile_ref_t<T, Options, Stride>; using parent = detail::compile_ref_t<T, Options, Stride>;
using exact_base = detail::compile_base_t<T, Options, Stride>;
using referee = std::remove_const_t<T>; using referee = std::remove_const_t<T>;
using value_type = typename referee::value_type; using value_type = typename referee::value_type;
using rotgen_tag = void; using rotgen_tag = void;
@ -81,56 +86,99 @@ namespace rotgen
// Access to values // Access to values
using parent::operator(); using parent::operator();
using parent::operator[]; using parent::operator[];
// Size related functions
using parent::cols;
using parent::data; using parent::data;
using parent::innerStride;
using parent::outerStride;
using parent::rows;
using parent::size; using parent::size;
// Size related functions
Index _cols() const { return parent::cols(); }
Index _rows() const { return parent::rows(); }
Index _innerStride() const noexcept { return parent::innerStride(); };
Index _outerStride() const noexcept { return parent::outerStride(); };
// Aliasing handling // Aliasing handling
auto evaluate() const
{
auto res = static_cast<parent const&>(*this).eval();
return as_concrete_type<decltype(res)>(res);
}
auto evaluate() auto _evaluate() const { return T(base().eval()); }
{
auto res = static_cast<parent&>(*this).eval();
return as_concrete_type<decltype(res)>(res);
}
decltype(auto) noalias() const decltype(auto) _noalias() const
{ {
if constexpr (use_expression_templates) return base().noalias(); if constexpr (use_expression_templates) return base().noalias();
else return *this; else return *this;
} }
decltype(auto) noalias() decltype(auto) _noalias()
{ {
if constexpr (use_expression_templates) return base().noalias(); if constexpr (use_expression_templates) return base().noalias();
else return *this; else return *this;
} }
// Numeric functions // Numeric functions
using parent::cwiseAbs; auto operator-() const { return detail::concretize<matrix>(-base()); }
using parent::cwiseAbs2;
using parent::cwiseInverse; auto _cwiseAbs() const
using parent::cwiseSqrt; {
return detail::concretize<matrix>(base().cwiseAbs());
}
auto _cwiseAbs2() const
{
return detail::concretize<matrix>(base().cwiseAbs2());
}
auto _cwiseInverse() const
{
return detail::concretize<matrix>(base().cwiseInverse());
}
auto _cwiseSqrt() const
{
return detail::concretize<matrix>(base().cwiseSqrt());
}
// Reductions // Reductions
using parent::lpNorm; value_type _mean() const { return parent::mean(); }
using parent::maxCoeff;
using parent::mean; value_type _norm() const { return parent::norm(); }
using parent::minCoeff;
using parent::norm; template<int P> value_type _lpNorm() const
using parent::prod; {
using parent::squaredNorm; return parent::template lpNorm<P>();
using parent::sum; }
using parent::trace;
value_type _squaredNorm() const { return parent::squaredNorm(); }
value_type _sum() const { return parent::sum(); }
value_type _prod() const { return parent::prod(); }
value_type _trace() const { return parent::trace(); }
auto _minCoeff() const { return parent::minCoeff(); }
auto _maxCoeff() const { return parent::maxCoeff(); }
template<std::integral IndexType>
auto _minCoeff(IndexType* row, IndexType* col) const
{
Index result_row, result_col;
auto result = parent::minCoeff(&result_row, &result_col);
*row = result_row;
*col = result_col;
return result;
}
template<std::integral IndexType>
auto _maxCoeff(IndexType* row, IndexType* col) const
{
Index result_row, result_col;
auto result = parent::maxCoeff(&result_row, &result_col);
*row = result_row;
*col = result_col;
return result;
}
// Compound Operators // Compound Operators
template<typename A, int O, typename S> template<typename A, int O, typename S>
@ -172,27 +220,113 @@ namespace rotgen
} }
// Shape modifications // Shape modifications
using parent::adjoint; auto _normalized() const
using parent::conjugate; requires(IsVectorAtCompileTime)
using parent::normalized; {
using parent::transpose; return detail::concretize<matrix>(base().normalized());
}
auto _transpose() const
{
return detail::concretize<matrix>(base().transpose());
}
auto _adjoint() const
{
return detail::concretize<matrix>(base().adjoint());
}
auto _conjugate() const
{
return detail::concretize<matrix>(base().conjugate());
}
// In-place Shape modifications // In-place Shape modifications
using parent::adjointInPlace;
using parent::normalize; void _adjointInPlace() { parent::adjointInPlace(); }
using parent::transposeInPlace;
void _normalize()
requires(IsVectorAtCompileTime)
{
parent::normalize();
}
void _transposeInPlace() { parent::transposeInPlace(); }
// Generators // Generators
using parent::Constant; static auto _Zero() { return detail::concretize<matrix>(parent::Zero()); }
using parent::Identity;
using parent::Ones; static auto _Zero(int rows, int cols)
using parent::Random; {
using parent::setConstant; return detail::concretize<matrix>(parent::Zero(rows, cols));
using parent::setIdentity; }
using parent::setOnes;
using parent::setRandom; static auto _Ones() { return detail::concretize<matrix>(parent::Ones()); }
using parent::setZero;
using parent::Zero; static auto _Ones(int rows, int cols)
{
return detail::concretize<matrix>(parent::Ones(rows, cols));
}
static auto _Constant(value_type value)
{
return detail::concretize<matrix>(parent::Constant(value));
}
static auto _Constant(int rows, int cols, value_type value)
{
return detail::concretize<matrix>(parent::Constant(rows, cols, value));
}
static auto _Random()
{
return detail::concretize<matrix>(parent::Random());
}
static auto _Random(int rows, int cols)
{
return detail::concretize<matrix>(parent::Random(rows, cols));
}
static auto _Identity()
{
return detail::concretize<matrix>(parent::Identity());
}
static auto _Identity(int rows, int cols)
{
return detail::concretize<matrix>(parent::Identity(rows, cols));
}
ref& _setOnes()
{
base() = parent::Ones(base().rows(), base().cols());
return *this;
}
ref& _setZero()
{
base() = parent::Zero(base().rows(), base().cols());
return *this;
}
ref& _setConstant(value_type value)
{
base() = parent::Constant(base().rows(), base().cols(), value);
return *this;
}
ref& _setRandom()
{
base() = parent::Random(base().rows(), base().cols());
return *this;
}
ref& _setIdentity()
{
base() = parent::Identity(base().rows(), base().cols());
return *this;
}
auto qr_solve(auto const& rhs) const auto qr_solve(auto const& rhs) const
{ {
@ -212,6 +346,12 @@ namespace rotgen
parent& base() { return static_cast<parent&>(*this); } parent& base() { return static_cast<parent&>(*this); }
template<typename M>
requires(is_immutable)
ref(product<M> const& m) : ref(m.storage_)
{
}
template<typename S, int R, int C, int O, int MR, int MC> template<typename S, int R, int C, int O, int MR, int MC>
ref(matrix<S, R, C, O, MR, MC>& m) ref(matrix<S, R, C, O, MR, MC>& m)
requires(requires { parent(m.base()); }) requires(requires { parent(m.base()); })
@ -307,13 +447,14 @@ namespace rotgen
// Deduction Guides // Deduction Guides
//============================================================================ //============================================================================
template<typename S, int R, int C, int O, int MR, int MC> template<typename S, int R, int C, int O, int MR, int MC>
ref(matrix<S, R, C, O, MR, MC>&) -> ref<matrix<S>>; ref(matrix<S, R, C, O, MR, MC>&) -> ref<matrix<S, R, C, O, MR, MC>>;
template<typename Ref, int R, int C, bool I> template<typename Ref, int R, int C, bool I>
ref(block<Ref, R, C, I>& b) -> ref<Ref>; ref(block<Ref, R, C, I>& b) -> ref<Ref>;
template<typename S, int R, int C, int O, int MR, int MC> 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>; ref(matrix<S, R, C, O, MR, MC> const&)
-> ref<matrix<S, R, C, O, MR, MC> const>;
template<typename Ref, int R, int C, bool I> template<typename Ref, int R, int C, bool I>
ref(block<Ref, R, C, I> const& b) -> ref<Ref const>; ref(block<Ref, R, C, I> const& b) -> ref<Ref const>;
@ -336,7 +477,14 @@ namespace rotgen
template<typename A, int O, typename S, typename B, int P, typename T> 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) auto operator*(ref<A, O, S> lhs, ref<B, P, T> rhs)
{ {
return detail::concretize<matrix>(lhs.base() * rhs.base()); auto p = lhs.base() * rhs.base();
using concrete_type = detail::as_concrete_t<decltype(p), matrix>;
if constexpr (concrete_type::SizeAtCompileTime == 1)
return product{concrete_type{p}};
else if constexpr (concrete_type::SizeAtCompileTime == 0)
return concrete_type{};
else return concrete_type{p};
} }
template<typename A, int O, typename S> template<typename A, int O, typename S>
@ -411,7 +559,6 @@ namespace rotgen
template<typename A, int O, typename S, typename B, int P, typename T> 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) 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())); return detail::concretize<matrix>(lhs.base().cross(rhs.base()));
} }
@ -432,13 +579,8 @@ namespace rotgen
using type = std::conditional_t<is_const, ref<base const>, ref<base>>; using type = std::conditional_t<is_const, ref<base const>, ref<base>>;
}; };
template<concepts::eigen_compatible T> auto const& base_of(T const& a) template<concepts::eigen_compatible T> decltype(auto) base_of(T&& a)
{ {
return a; return ROTGEN_FWD(a);
}
template<concepts::eigen_compatible T> auto& base_of(T& a)
{
return a;
} }
} }

View file

@ -7,51 +7,67 @@
//================================================================================================== //==================================================================================================
#pragma once #pragma once
#include <rotgen/detail/helpers.hpp>
#include <type_traits> #include <type_traits>
namespace rotgen namespace rotgen
{ {
template<typename A, int O, typename S, typename B, int P, typename T> 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) bool operator==(ref<A, O, S> const& lhs, ref<B, P, T> const& rhs)
{ {
return lhs.base() == rhs.base(); return lhs.base() == rhs.base();
} }
template<typename A, int O, typename S, typename B, int P, typename T> 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) bool operator!=(ref<A, O, S> const& lhs, ref<B, P, T> const& rhs)
{ {
return lhs.base() != rhs.base(); return lhs.base() != rhs.base();
} }
template<typename A, int O, typename S> template<typename A, int O, typename S>
auto operator*(std::convertible_to<typename A::value_type> auto s, auto operator*(std::convertible_to<typename A::value_type> auto s,
ref<A, O, S> rhs) ref<A, O, S> const& rhs)
{ {
// void* _ = rhs;
return rhs * s; return rhs * s;
} }
template<typename A, int O, typename S, typename B, int P, typename T> 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) auto dot(ref<A, O, S> const& lhs, ref<B, P, T> const& rhs)
{ {
return lhs.base().dot(rhs.base()); if constexpr (requires { lhs.base().dot(rhs.base()); })
{
return lhs.base().dot(rhs.base());
}
else if constexpr (requires { lhs.base()._dot(rhs.base()); })
{
return lhs.base()._dot(rhs.base());
}
else
{
return detail::unsupported_parameters<T>();
}
} }
template<typename A, int O, typename S> template<typename A, int O, typename S>
auto mul(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s) auto mul(ref<A, O, S> const& lhs,
std::convertible_to<typename A::value_type> auto s)
-> decltype(lhs * s) -> decltype(lhs * s)
{ {
return lhs * s; return lhs * s;
} }
template<typename A, int O, typename S> template<typename A, int O, typename S>
auto mul(std::convertible_to<typename A::value_type> auto s, ref<A, O, S> rhs) auto mul(std::convertible_to<typename A::value_type> auto s,
-> decltype(s * rhs) ref<A, O, S> const& rhs) -> decltype(s * rhs)
{ {
return s * rhs; return s * rhs;
} }
template<typename A, int O, typename S> template<typename A, int O, typename S>
auto div(ref<A, O, S> lhs, std::convertible_to<typename A::value_type> auto s) auto div(ref<A, O, S> const& lhs,
std::convertible_to<typename A::value_type> auto s)
-> decltype(lhs / s) -> decltype(lhs / s)
{ {
return lhs / s; return lhs / s;

View file

@ -1,13 +1,16 @@
//================================================================================================== //==============================================================================
/* /*
ROTGEN - Runtime Overlay for Eigen ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0 SPDX-License-Identifier: BSL-1.0
*/ */
//================================================================================================== //==============================================================================
#pragma once #pragma once
#include <rotgen/concepts.hpp>
#include <rotgen/config.hpp> #include <rotgen/config.hpp>
#include <rotgen/container/matrix.hpp>
#include <rotgen/container/ref.hpp>
#include <type_traits> #include <type_traits>
@ -15,7 +18,7 @@ namespace rotgen
{ {
template<typename Scalar, int Options = AutoAlign> class quaternion; template<typename Scalar, int Options = AutoAlign> class quaternion;
//------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Convert entity/eigen types to a proper ref so we can write less function // Convert entity/eigen types to a proper ref so we can write less function
// overloads // overloads
@ -32,11 +35,12 @@ namespace rotgen
template<concepts::entity T> struct generalize<T> template<concepts::entity T> struct generalize<T>
{ {
static constexpr bool is_const = std::is_const_v<T>; static constexpr bool is_const =
using base = matrix<typename T::value_type, std::is_const_v<std::remove_reference_t<T>>;
T::RowsAtCompileTime, using base = matrix<typename std::remove_cvref_t<T>::value_type,
T::ColsAtCompileTime, std::remove_cvref_t<T>::RowsAtCompileTime,
T::storage_order>; std::remove_cvref_t<T>::ColsAtCompileTime,
std::remove_cvref_t<T>::storage_order>;
using type = std::conditional_t<is_const, ref<base const>, ref<base>>; using type = std::conditional_t<is_const, ref<base const>, ref<base>>;
}; };

View file

@ -7,7 +7,10 @@
//================================================================================================== //==================================================================================================
#pragma once #pragma once
#include <cassert> #include <rotgen/detail/assert.hpp>
#include <rotgen/functions/functions.hpp>
#include <concepts> #include <concepts>
namespace rotgen::detail namespace rotgen::detail
@ -72,30 +75,34 @@ namespace rotgen::detail
using parent = typename Ref::parent; using parent = typename Ref::parent;
using map_base = typename parent::parent; using map_base = typename parent::parent;
auto rows = in.rows(); auto r = rows(in);
auto cols = in.cols(); auto c = cols(in);
if (Ref::RowsAtCompileTime == 1) if (Ref::RowsAtCompileTime == 1)
{ {
assert(in.rows() == 1 || in.cols() == 1); ROTGEN_ASSERT(rows(in) == 1 || cols(in) == 1,
rows = 1; "Incompatible rows/cols in ref binding");
cols = in.size(); r = 1;
c = in.size();
} }
else if (Ref::ColsAtCompileTime == 1) else if (Ref::ColsAtCompileTime == 1)
{ {
assert(in.rows() == 1 || in.cols() == 1); ROTGEN_ASSERT(rows(in) == 1 || cols(in) == 1,
rows = in.size(); "Incompatible rows/cols in ref binding");
cols = 1; r = in.size();
c = 1;
} }
// Verify that the sizes are valid. // Verify that the sizes are valid.
assert((Ref::RowsAtCompileTime == Dynamic) || ROTGEN_ASSERT((Ref::RowsAtCompileTime == Dynamic) ||
(Ref::RowsAtCompileTime == rows)); (Ref::RowsAtCompileTime == r),
assert((Ref::ColsAtCompileTime == Dynamic) || "Incompatible static rows/cols in ref binding");
(Ref::ColsAtCompileTime == cols)); ROTGEN_ASSERT((Ref::ColsAtCompileTime == Dynamic) ||
(Ref::ColsAtCompileTime == c),
"Incompatible static rows/cols in ref binding");
// Swap stride if we are a vector and we changed rows as such // Swap stride if we are a vector and we changed rows as such
bool transpose = Ref::IsVectorAtCompileTime && (rows != in.rows()); bool transpose = Ref::IsVectorAtCompileTime && (r != rows(in));
// Swap stride if storage ordder doesn't match // Swap stride if storage ordder doesn't match
constexpr bool row_major = Ref::IsRowMajor; constexpr bool row_major = Ref::IsRowMajor;
@ -105,13 +112,13 @@ namespace rotgen::detail
bool swap_stride = (transpose != storage_differs); bool swap_stride = (transpose != storage_differs);
// Determine expr's actual strides, resolving any defaults if zero. // Determine expr's actual strides, resolving any defaults if zero.
Index inner_actual = proper_inner_stride(in.innerStride()); Index inner_actual = proper_inner_stride(innerStride(in));
Index outer_actual = Index outer_actual =
proper_outer_stride(inner_actual, in.outerStride(), in.rows(), in.cols(), proper_outer_stride(inner_actual, outerStride(in), rows(in), cols(in),
Input::IsVectorAtCompileTime, input_row_major); Input::IsVectorAtCompileTime, input_row_major);
bool row_vector = (rows == 1); bool row_vector = (r == 1);
bool col_vector = (cols == 1); bool col_vector = (c == 1);
// Adapt inner stride based on row/col vector status // Adapt inner stride based on row/col vector status
Index inner_stride = Index inner_stride =
@ -127,7 +134,7 @@ namespace rotgen::detail
((!row_major && col_vector) || (row_major && row_vector)) ((!row_major && col_vector) || (row_major && row_vector))
? (stride_type::OuterStrideAtCompileTime > 0 ? (stride_type::OuterStrideAtCompileTime > 0
? stride_type::OuterStrideAtCompileTime ? stride_type::OuterStrideAtCompileTime
: rows * cols * inner_stride) : r * c * inner_stride)
: swap_stride ? inner_actual : swap_stride ? inner_actual
: outer_actual; : outer_actual;
@ -142,7 +149,7 @@ namespace rotgen::detail
bool outer_valid = bool outer_valid =
(stride_type::OuterStrideAtCompileTime == Dynamic) || (stride_type::OuterStrideAtCompileTime == Dynamic) ||
(proper_outer_stride( (proper_outer_stride(
inner_stride, Index(stride_type::OuterStrideAtCompileTime), rows, cols, inner_stride, Index(stride_type::OuterStrideAtCompileTime), r, c,
Ref::IsVectorAtCompileTime != 0, row_major) == outer_stride); Ref::IsVectorAtCompileTime != 0, row_major) == outer_stride);
if (!outer_valid) return false; if (!outer_valid) return false;
@ -151,7 +158,7 @@ namespace rotgen::detail
stride_type::OuterStrideAtCompileTime == 0 ? 1 : outer_stride, stride_type::OuterStrideAtCompileTime == 0 ? 1 : outer_stride,
stride_type::InnerStrideAtCompileTime == 0 ? 1 : inner_stride); stride_type::InnerStrideAtCompileTime == 0 ? 1 : inner_stride);
auto actual = map_base(in.data(), rows, cols, proper_stride); auto actual = map_base(in.data(), r, c, proper_stride);
ref.base().base().storage().swap(actual.storage()); ref.base().base().storage().swap(actual.storage());

View file

@ -0,0 +1,22 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once
#if defined(ROTGEN_USE_LIBASSERT)
#include <libassert/assert.hpp>
#define ROTGEN_ASSERT(COND, ...) DEBUG_ASSERT(COND, __VA_ARGS__)
#else
#include <cassert>
#if !defined(NDEBUG)
#define ROTGEN_ASSERT(COND, MSG, ...) assert((COND) && (MSG))
#else
#define ROTGEN_ASSERT(COND, ...) (void)(COND)
#endif
#endif

View file

@ -1,10 +1,10 @@
//================================================================================================== //==============================================================================
/* /*
ROTGEN - Runtime Overlay for Eigen ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0 SPDX-License-Identifier: BSL-1.0
*/ */
//================================================================================================== //==============================================================================
#pragma once #pragma once
#include <rotgen/config.hpp> #include <rotgen/config.hpp>
@ -15,6 +15,15 @@
namespace rotgen::detail namespace rotgen::detail
{ {
/// Returned when a function is called with unsupported parameters,
/// effectively triggering a compile error to avoid undefined behaviors in
/// cases where return directives are missing.
template<typename T> auto unsupported_parameters()
{
static_assert(sizeof(T) == 0,
"Function was called with unsupported parameters.");
};
template<typename T> constexpr int static_size() template<typename T> constexpr int static_size()
{ {
auto rows = T::RowsAtCompileTime; auto rows = T::RowsAtCompileTime;
@ -31,7 +40,7 @@ namespace rotgen::detail
using type = Wrapper<typename EigenType::value_type, using type = Wrapper<typename EigenType::value_type,
EigenType::RowsAtCompileTime, EigenType::RowsAtCompileTime,
EigenType::ColsAtCompileTime, EigenType::ColsAtCompileTime,
EigenType::Flags & 1, EigenType::IsRowMajor ? RowMajor : ColMajor,
EigenType::MaxRowsAtCompileTime, EigenType::MaxRowsAtCompileTime,
EigenType::MaxColsAtCompileTime>; EigenType::MaxColsAtCompileTime>;
}; };

View file

@ -0,0 +1,57 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once
#include <rotgen/detail/helpers.hpp>
#include <rotgen/container/matrix.hpp>
namespace rotgen
{
// Emulate EIGEN 1x1 pseudo product type
template<typename M> struct product
{
using rotgen_tag = void;
using value_type = typename M::value_type;
using concrete_type = matrix<value_type, 1, 1>;
static constexpr auto storage_order = concrete_type::storage_order;
static constexpr int RowsAtCompileTime = 1;
static constexpr int ColsAtCompileTime = 1;
static constexpr int SizeAtCompileTime = 1;
static constexpr int MaxRowsAtCompileTime = 1;
static constexpr int MaxColsAtCompileTime = 1;
static constexpr bool IsVectorAtCompileTime =
concrete_type::IsVectorAtCompileTime;
product(M const& m) : storage_(m) {}
auto size() const { return storage_.size(); }
auto _rows() const { return storage_._rows(); }
auto _cols() const { return storage_._cols(); }
auto operator()(int i) const { return storage_(i); }
auto operator[](int i) const { return storage_(i); }
auto operator()(int r, int c) const { return storage_(r, c); }
auto _sum() const { return storage_._sum(); }
auto const& base() const { return storage_.base(); }
operator value_type const() const { return storage_(0); }
operator concrete_type() const { return storage_; }
concrete_type storage_;
};
}

View file

@ -1,13 +1,17 @@
//================================================================================================== //==============================================================================
/* /*
ROTGEN - Runtime Overlay for Eigen ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0 SPDX-License-Identifier: BSL-1.0
*/ */
//================================================================================================== //==============================================================================
#pragma once #pragma once
#include <rotgen/detail/assert.hpp>
#include <rotgen/detail/helpers.hpp> #include <rotgen/detail/helpers.hpp>
#include <rotgen/concepts.hpp>
#include <type_traits> #include <type_traits>
namespace rotgen namespace rotgen
@ -21,10 +25,12 @@ namespace rotgen
[[maybe_unused]] Index ni, [[maybe_unused]] Index ni,
[[maybe_unused]] Index nj) [[maybe_unused]] Index nj)
{ {
assert(i0 >= 0 && "block extraction uses negative row index."); ROTGEN_ASSERT(i0 >= 0, "block extraction uses negative row index.");
assert(j0 >= 0 && "block extraction uses negative col index."); ROTGEN_ASSERT(j0 >= 0, "block extraction uses negative col index.");
assert(i0 + ni <= e.rows() && "block extraction rows is out of range."); ROTGEN_ASSERT(i0 + ni <= rows(e),
assert(j0 + nj <= e.cols() && "block extraction cols is out of range."); "block extraction rows is out of range.");
ROTGEN_ASSERT(j0 + nj <= cols(e),
"block extraction cols is out of range.");
} }
} }
@ -81,55 +87,55 @@ namespace rotgen
template<concepts::entity Entity> template<concepts::entity Entity>
auto topRightCorner(Entity&& e, Index ni, Index nj) auto topRightCorner(Entity&& e, Index ni, Index nj)
{ {
return extract(ROTGEN_FWD(e), 0, e.cols() - nj, ni, nj); return extract(ROTGEN_FWD(e), 0, cols(e) - nj, ni, nj);
} }
template<Index NI, Index NJ, concepts::entity Entity> template<Index NI, Index NJ, concepts::entity Entity>
auto topRightCorner(Entity&& e) auto topRightCorner(Entity&& e)
{ {
return extract<NI, NJ>(ROTGEN_FWD(e), 0, e.cols() - NJ); return extract<NI, NJ>(ROTGEN_FWD(e), 0, cols(e) - NJ);
} }
//======================== BOTTOM LEFT CORNER ======================== //======================== BOTTOM LEFT CORNER ========================
template<concepts::entity Entity> template<concepts::entity Entity>
auto bottomLeftCorner(Entity&& e, Index ni, Index nj) auto bottomLeftCorner(Entity&& e, Index ni, Index nj)
{ {
return extract(ROTGEN_FWD(e), e.rows() - ni, 0, ni, nj); return extract(ROTGEN_FWD(e), rows(e) - ni, 0, ni, nj);
} }
template<Index NI, Index NJ, concepts::entity Entity> template<Index NI, Index NJ, concepts::entity Entity>
auto bottomLeftCorner(Entity&& e) auto bottomLeftCorner(Entity&& e)
{ {
return extract<NI, NJ>(ROTGEN_FWD(e), e.rows() - NI, 0); return extract<NI, NJ>(ROTGEN_FWD(e), rows(e) - NI, 0);
} }
//======================== BOTTOM RIGHT CORNER ======================== //======================== BOTTOM RIGHT CORNER ========================
template<concepts::entity Entity> template<concepts::entity Entity>
auto bottomRightCorner(Entity&& e, Index ni, Index nj) auto bottomRightCorner(Entity&& e, Index ni, Index nj)
{ {
return extract(ROTGEN_FWD(e), e.rows() - ni, e.cols() - nj, ni, nj); return extract(ROTGEN_FWD(e), rows(e) - ni, cols(e) - nj, ni, nj);
} }
template<Index NI, Index NJ, concepts::entity Entity> template<Index NI, Index NJ, concepts::entity Entity>
auto bottomRightCorner(Entity&& e) auto bottomRightCorner(Entity&& e)
{ {
return extract<NI, NJ>(ROTGEN_FWD(e), e.rows() - NI, e.cols() - NJ); return extract<NI, NJ>(ROTGEN_FWD(e), rows(e) - NI, cols(e) - NJ);
} }
//======================== TOP ROWS ======================== //======================== TOP ROWS ========================
template<concepts::entity Entity> auto topRows(Entity&& e, Index ni) template<concepts::entity Entity> auto topRows(Entity&& e, Index ni)
{ {
if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1) if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1)
return extract(ROTGEN_FWD(e), 0, 0, ni, e.cols()); return extract(ROTGEN_FWD(e), 0, 0, ni, cols(e));
else else
return extract<-1, std::remove_cvref_t<Entity>::ColsAtCompileTime>( return extract<-1, std::remove_cvref_t<Entity>::ColsAtCompileTime>(
ROTGEN_FWD(e), 0, 0, ni, e.cols()); ROTGEN_FWD(e), 0, 0, ni, cols(e));
} }
template<Index NI, concepts::entity Entity> auto topRows(Entity&& e) template<Index NI, concepts::entity Entity> auto topRows(Entity&& e)
{ {
if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1) if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1)
return extract<NI, -1>(ROTGEN_FWD(e), 0, 0, NI, e.cols()); return extract<NI, -1>(ROTGEN_FWD(e), 0, 0, NI, cols(e));
else else
return extract<NI, std::remove_cvref_t<Entity>::ColsAtCompileTime>( return extract<NI, std::remove_cvref_t<Entity>::ColsAtCompileTime>(
ROTGEN_FWD(e), 0, 0); ROTGEN_FWD(e), 0, 0);
@ -140,17 +146,17 @@ namespace rotgen
auto middleRows(Entity&& e, Index i0, Index ni) auto middleRows(Entity&& e, Index i0, Index ni)
{ {
if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1) if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1)
return extract(ROTGEN_FWD(e), i0, 0, ni, e.cols()); return extract(ROTGEN_FWD(e), i0, 0, ni, cols(e));
else else
return extract<-1, std::remove_cvref_t<Entity>::ColsAtCompileTime>( return extract<-1, std::remove_cvref_t<Entity>::ColsAtCompileTime>(
ROTGEN_FWD(e), i0, 0, ni, e.cols()); ROTGEN_FWD(e), i0, 0, ni, cols(e));
} }
template<Index NI, concepts::entity Entity> template<Index NI, concepts::entity Entity>
auto middleRows(Entity&& e, Index i0) auto middleRows(Entity&& e, Index i0)
{ {
if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1) if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1)
return extract<NI, -1>(ROTGEN_FWD(e), i0, 0, NI, e.cols()); return extract<NI, -1>(ROTGEN_FWD(e), i0, 0, NI, cols(e));
else else
return extract<NI, std::remove_cvref_t<Entity>::ColsAtCompileTime>( return extract<NI, std::remove_cvref_t<Entity>::ColsAtCompileTime>(
ROTGEN_FWD(e), i0, 0); ROTGEN_FWD(e), i0, 0);
@ -160,35 +166,35 @@ namespace rotgen
template<concepts::entity Entity> auto bottomRows(Entity&& e, Index ni) template<concepts::entity Entity> auto bottomRows(Entity&& e, Index ni)
{ {
if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1) if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1)
return extract(ROTGEN_FWD(e), e.rows() - ni, 0, ni, e.cols()); return extract(ROTGEN_FWD(e), rows(e) - ni, 0, ni, cols(e));
else else
return extract<-1, std::remove_cvref_t<Entity>::ColsAtCompileTime>( return extract<-1, std::remove_cvref_t<Entity>::ColsAtCompileTime>(
ROTGEN_FWD(e), e.rows() - ni, 0, ni, e.cols()); ROTGEN_FWD(e), rows(e) - ni, 0, ni, cols(e));
} }
template<Index NI, concepts::entity Entity> auto bottomRows(Entity&& e) template<Index NI, concepts::entity Entity> auto bottomRows(Entity&& e)
{ {
if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1) if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1)
return extract<NI, -1>(ROTGEN_FWD(e), e.rows() - NI, 0, NI, e.cols()); return extract<NI, -1>(ROTGEN_FWD(e), rows(e) - NI, 0, NI, cols(e));
else else
return extract<NI, std::remove_cvref_t<Entity>::ColsAtCompileTime>( return extract<NI, std::remove_cvref_t<Entity>::ColsAtCompileTime>(
ROTGEN_FWD(e), e.rows() - NI, 0); ROTGEN_FWD(e), rows(e) - NI, 0);
} }
//======================== LEFT COLS ======================== //======================== LEFT COLS ========================
template<concepts::entity Entity> auto leftCols(Entity&& e, Index nj) template<concepts::entity Entity> auto leftCols(Entity&& e, Index nj)
{ {
if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1) if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1)
return extract(ROTGEN_FWD(e), 0, 0, e.rows(), nj); return extract(ROTGEN_FWD(e), 0, 0, rows(e), nj);
else else
return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, -1>( return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, -1>(
ROTGEN_FWD(e), 0, 0, e.rows(), nj); ROTGEN_FWD(e), 0, 0, rows(e), nj);
} }
template<Index NJ, concepts::entity Entity> auto leftCols(Entity&& e) template<Index NJ, concepts::entity Entity> auto leftCols(Entity&& e)
{ {
if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1) if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1)
return extract<-1, NJ>(ROTGEN_FWD(e), 0, 0, e.rows(), NJ); return extract<-1, NJ>(ROTGEN_FWD(e), 0, 0, rows(e), NJ);
else else
return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, NJ>( return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, NJ>(
ROTGEN_FWD(e), 0, 0); ROTGEN_FWD(e), 0, 0);
@ -199,17 +205,17 @@ namespace rotgen
auto middleCols(Entity&& e, Index j0, Index nj) auto middleCols(Entity&& e, Index j0, Index nj)
{ {
if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1) if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1)
return extract(ROTGEN_FWD(e), 0, j0, e.rows(), nj); return extract(ROTGEN_FWD(e), 0, j0, rows(e), nj);
else else
return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, -1>( return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, -1>(
ROTGEN_FWD(e), 0, j0, e.rows(), nj); ROTGEN_FWD(e), 0, j0, rows(e), nj);
} }
template<Index NJ, concepts::entity Entity> template<Index NJ, concepts::entity Entity>
auto middleCols(Entity&& e, Index j0) auto middleCols(Entity&& e, Index j0)
{ {
if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1) if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1)
return extract<-1, NJ>(ROTGEN_FWD(e), 0, j0, e.rows(), NJ); return extract<-1, NJ>(ROTGEN_FWD(e), 0, j0, rows(e), NJ);
else else
return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, NJ>( return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, NJ>(
ROTGEN_FWD(e), 0, j0); ROTGEN_FWD(e), 0, j0);
@ -219,27 +225,27 @@ namespace rotgen
template<concepts::entity Entity> auto rightCols(Entity&& e, Index nj) template<concepts::entity Entity> auto rightCols(Entity&& e, Index nj)
{ {
if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1) if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1)
return extract(ROTGEN_FWD(e), 0, e.cols() - nj, e.rows(), nj); return extract(ROTGEN_FWD(e), 0, cols(e) - nj, rows(e), nj);
else else
return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, -1>( return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, -1>(
ROTGEN_FWD(e), 0, e.cols() - nj, e.rows(), nj); ROTGEN_FWD(e), 0, cols(e) - nj, rows(e), nj);
; ;
} }
template<Index NJ, concepts::entity Entity> auto rightCols(Entity&& e) template<Index NJ, concepts::entity Entity> auto rightCols(Entity&& e)
{ {
if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1) if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1)
return extract<-1, NJ>(ROTGEN_FWD(e), 0, e.cols() - NJ, e.rows(), NJ); return extract<-1, NJ>(ROTGEN_FWD(e), 0, cols(e) - NJ, rows(e), NJ);
else else
return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, NJ>( return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, NJ>(
ROTGEN_FWD(e), 0, e.cols() - NJ); ROTGEN_FWD(e), 0, cols(e) - NJ);
} }
//======================== ROW ======================== //======================== ROW ========================
template<concepts::entity Entity> auto row(Entity&& e, Index i0) template<concepts::entity Entity> auto row(Entity&& e, Index i0)
{ {
if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1) if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == -1)
return extract<1, -1>(ROTGEN_FWD(e), i0, 0, 1, e.cols()); return extract<1, -1>(ROTGEN_FWD(e), i0, 0, 1, cols(e));
else else
return extract<1, std::remove_cvref_t<Entity>::ColsAtCompileTime>( return extract<1, std::remove_cvref_t<Entity>::ColsAtCompileTime>(
ROTGEN_FWD(e), i0, 0); ROTGEN_FWD(e), i0, 0);
@ -249,7 +255,7 @@ namespace rotgen
template<concepts::entity Entity> auto col(Entity&& e, Index j0) template<concepts::entity Entity> auto col(Entity&& e, Index j0)
{ {
if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1) if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == -1)
return extract<-1, 1>(ROTGEN_FWD(e), 0, j0, e.rows(), 1); return extract<-1, 1>(ROTGEN_FWD(e), 0, j0, rows(e), 1);
else else
return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, 1>( return extract<std::remove_cvref_t<Entity>::RowsAtCompileTime, 1>(
ROTGEN_FWD(e), 0, j0); ROTGEN_FWD(e), 0, j0);
@ -285,9 +291,9 @@ namespace rotgen
std::remove_cvref_t<Entity>::ColsAtCompileTime == 1) std::remove_cvref_t<Entity>::ColsAtCompileTime == 1)
{ {
if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == 1) if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == 1)
return extract<1, Dynamic>(ROTGEN_FWD(e), 0, e.cols() - n, 1, n); return extract<1, Dynamic>(ROTGEN_FWD(e), 0, cols(e) - n, 1, n);
else if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == 1) else if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == 1)
return extract<Dynamic, 1>(ROTGEN_FWD(e), e.rows() - n, 0, n, 1); return extract<Dynamic, 1>(ROTGEN_FWD(e), rows(e) - n, 0, n, 1);
} }
template<Index N, concepts::entity Entity> template<Index N, concepts::entity Entity>
@ -296,9 +302,9 @@ namespace rotgen
std::remove_cvref_t<Entity>::ColsAtCompileTime == 1) std::remove_cvref_t<Entity>::ColsAtCompileTime == 1)
{ {
if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == 1) if constexpr (std::remove_cvref_t<Entity>::RowsAtCompileTime == 1)
return extract<1, N>(ROTGEN_FWD(e), 0, e.cols() - N); return extract<1, N>(ROTGEN_FWD(e), 0, cols(e) - N);
else if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == 1) else if constexpr (std::remove_cvref_t<Entity>::ColsAtCompileTime == 1)
return extract<N, 1>(ROTGEN_FWD(e), e.rows() - N, 0); return extract<N, 1>(ROTGEN_FWD(e), rows(e) - N, 0);
} }
//======================== VECTOR SEGMENT ======================== //======================== VECTOR SEGMENT ========================

View file

@ -1,187 +1,308 @@
//================================================================================================== //==============================================================================
/* /*
ROTGEN - Runtime Overlay for Eigen ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0 SPDX-License-Identifier: BSL-1.0
*/ */
//================================================================================================== //==============================================================================
#pragma once #pragma once
#include <rotgen/detail/helpers.hpp> #include <rotgen/detail/helpers.hpp>
#include <rotgen/concepts.hpp>
#include <rotgen/container/ref/generalize.hpp>
namespace rotgen namespace rotgen
{ {
//----------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Infos & Shape // Infos & Shape
//----------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------
/// Returns the row count of a matrix.
Index rows(auto const& m) Index rows(auto const& m)
requires(requires { m.rows(); })
{ {
return m.rows(); if constexpr (requires { m.rows(); }) { return m.rows(); }
else if constexpr (requires { m._rows(); }) { return m._rows(); }
else { return detail::unsupported_parameters<decltype(m)>(); }
} }
/// Returns the column count of a matrix.
Index cols(auto const& m) Index cols(auto const& m)
requires(requires { m.cols(); })
{ {
return m.cols();
if constexpr (requires { m.cols(); }) { return m.cols(); }
else if constexpr (requires { m._cols(); }) { return m._cols(); }
else { return detail::unsupported_parameters<decltype(m)>(); }
} }
Index startRow(auto const& m)
{
if constexpr (requires { m.startRow(); }) { return m.startRow(); }
else if constexpr (requires { m._startRow(); }) { return m._startRow(); }
else { return detail::unsupported_parameters<decltype(m)>(); }
}
Index startCol(auto const& m)
{
if constexpr (requires { m.startCol(); }) { return m.startCol(); }
else if constexpr (requires { m._startCol(); }) { return m._startCol(); }
else { return detail::unsupported_parameters<decltype(m)>(); }
}
/// Returns the size of a matrix.
Index size(auto const& m) Index size(auto const& m)
requires(requires { m.size(); }) requires(requires { m.size(); })
{ {
return m.size(); return m.size();
} }
void resize(auto& a, int s) /// Resizes a matrix into a vector of size s.
requires requires { a.resize(s); } void resize(auto& m, int s)
requires requires { m.resize(s); }
{ {
a.resize(s); m.resize(s);
} }
void resize(auto& a, int r, int c) /// Resizes a matrix into with a given number of rows and columns.
requires requires { a.resize(r, c); } void resize(auto& m, int r, int c)
requires requires { m.resize(r, c); }
{ {
a.resize(r, c); m.resize(r, c);
} }
void conservativeResize(auto& a, int s) void conservativeResize(auto& a, int s)
requires requires { a.conservativeResize(s); }
{ {
a.conservativeResize(s); if constexpr (requires { a.conservativeResize(s); })
{
a.conservativeResize(s);
}
else if constexpr (requires { a._conservativeResize(s); })
{
a._conservativeResize(s);
}
else { return detail::unsupported_parameters<decltype(a)>(); }
} }
void conservativeResize(auto& a, int r, int c) void conservativeResize(auto& a, int r, int c)
requires requires { a.conservativeResize(r, c); }
{ {
a.conservativeResize(r, c); if constexpr (requires { a.conservativeResize(r, c); })
{
a.conservativeResize(r, c);
}
else if constexpr (requires { a._conservativeResize(r, c); })
{
a._conservativeResize(r, c);
}
else { return detail::unsupported_parameters<decltype(a)>(); }
} }
//----------------------------------------------------------------------------------------------- Index innerStride(auto const& m)
// Global operations
//-----------------------------------------------------------------------------------------------
decltype(auto) normalized(auto const& m)
requires(requires { m.normalized(); })
{ {
return m.normalized(); if constexpr (requires { m.innerStride(); }) { return m.innerStride(); }
else if constexpr (requires { m._innerStride(); })
{
return m._innerStride();
}
else { return detail::unsupported_parameters<decltype(m)>(); }
}
Index outerStride(auto const& m)
{
if constexpr (requires { m.outerStride(); }) { return m.outerStride(); }
else if constexpr (requires { m._outerStride(); })
{
return m._outerStride();
}
else { return detail::unsupported_parameters<decltype(m)>(); }
}
//----------------------------------------------------------------------------
// Global operations
//----------------------------------------------------------------------------
decltype(auto) normalized(auto const& m)
{
if constexpr (requires { m.normalized(); }) { return m.normalized(); }
else if constexpr (requires { m._normalized(); })
{
return m._normalized();
}
else { return detail::unsupported_parameters<decltype(m)>(); }
} }
decltype(auto) transpose(auto const& m) decltype(auto) transpose(auto const& m)
requires(requires { m.transpose(); })
{ {
return m.transpose(); if constexpr (requires { m.transpose(); }) { return m.transpose(); }
else if constexpr (requires { m._transpose(); }) { return m._transpose(); }
else { return detail::unsupported_parameters<decltype(m)>(); }
} }
decltype(auto) conjugate(auto const& m) decltype(auto) conjugate(auto const& m)
requires(requires { m.conjugate(); })
{ {
return m.conjugate(); if constexpr (requires { m.conjugate(); }) { return m.conjugate(); }
else if constexpr (requires { m._conjugate(); }) { return m._conjugate(); }
} }
decltype(auto) adjoint(auto const& m) decltype(auto) adjoint(auto const& m)
requires(requires { m.adjoint(); })
{ {
return m.adjoint(); if constexpr (requires { m.adjoint(); }) { return m.adjoint(); }
else if constexpr (requires { m._adjoint(); }) { return m._adjoint(); }
else { return detail::unsupported_parameters<decltype(m)>(); }
} }
void normalize(auto& a) template<typename C> void normalize(C&& a)
requires(requires { a.normalize(); })
{ {
a.normalize(); if constexpr (requires { std::forward<C>(a).normalize(); })
{
std::forward<C>(a).normalize();
}
else if constexpr (requires { std::forward<C>(a)._normalize(); })
{
std::forward<C>(a)._normalize();
}
else { return detail::unsupported_parameters<decltype(a)>(); }
} }
void transposeInPlace(auto& a) template<typename C> void transposeInPlace(C&& a)
requires(requires { a.transposeInPlace(); })
{ {
a.transposeInPlace(); if constexpr (requires { std::forward<C>(a).transposeInPlace(); })
{
std::forward<C>(a).transposeInPlace();
}
else if constexpr (requires { std::forward<C>(a)._transposeInPlace(); })
{
std::forward<C>(a)._transposeInPlace();
}
else { return detail::unsupported_parameters<decltype(a)>(); }
} }
void adjointInPlace(auto& a) template<typename C> void adjointInPlace(C&& a)
requires(requires { a.adjointInPlace(); })
{ {
a.adjointInPlace(); if constexpr (requires { std::forward<C>(a).adjointInPlace(); })
{
std::forward<C>(a).adjointInPlace();
}
else if constexpr (requires { std::forward<C>(a)._adjointInPlace(); })
{
std::forward<C>(a)._adjointInPlace();
}
else { return detail::unsupported_parameters<decltype(a)>(); }
} }
//----------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Component-wise functions // Component-wise functions
//----------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------
auto abs(auto const& arg) auto abs(auto const& arg)
requires(requires { arg.cwiseAbs(); })
{ {
return arg.cwiseAbs(); if constexpr (requires { arg.cwiseAbs(); }) { return arg.cwiseAbs(); }
else if constexpr (requires { arg._cwiseAbs(); })
{
return arg._cwiseAbs();
}
else { return detail::unsupported_parameters<decltype(arg)>(); }
} }
auto abs2(auto const& arg) auto abs2(auto const& arg)
requires(requires { arg.cwiseAbs2(); })
{ {
return arg.cwiseAbs2(); if constexpr (requires { arg.cwiseAbs2(); }) { return arg.cwiseAbs2(); }
else if constexpr (requires { arg._cwiseAbs2(); })
{
return arg._cwiseAbs2();
}
else { return detail::unsupported_parameters<decltype(arg)>(); }
} }
auto rec(auto const& arg) auto rec(auto const& arg)
requires(requires { arg.cwiseInverse(); })
{ {
return arg.cwiseInverse(); if constexpr (requires { arg.cwiseInverse(); })
{
return arg.cwiseInverse();
}
else if constexpr (requires { arg._cwiseInverse(); })
{
return arg._cwiseInverse();
}
else { return detail::unsupported_parameters<decltype(arg)>(); }
} }
auto sqrt(auto const& arg) auto sqrt(auto const& arg)
requires(requires { arg.cwiseSqrt(); })
{ {
return arg.cwiseSqrt(); if constexpr (requires { arg.cwiseSqrt(); }) { return arg.cwiseSqrt(); }
else if constexpr (requires { arg._cwiseSqrt(); })
{
return arg._cwiseSqrt();
}
} }
template<concepts::entity A, concepts::entity B> template<concepts::entity A, concepts::entity B>
auto min(A const& a, B const& b) auto min(A const& a, B const& b)
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
{
return min(generalize_t<A const>(a), generalize_t<B const>(b)); return min(generalize_t<A const>(a), generalize_t<B const>(b));
else return base_of(a).cwiseMin(base_of(b)); }
else { return base_of(a).cwiseMin(base_of(b)); }
} }
template<concepts::entity A> template<concepts::entity A>
auto min(A const& a, std::convertible_to<typename A::value_type> auto b) auto min(A const& a, std::convertible_to<typename A::value_type> auto b)
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
{
return min(generalize_t<A const>(a), b); return min(generalize_t<A const>(a), b);
else return base_of(a).cwiseMin(b); }
else { return base_of(a).cwiseMin(b); }
} }
template<concepts::entity B> template<concepts::entity B>
auto min(std::convertible_to<typename B::value_type> auto a, B const& b) auto min(std::convertible_to<typename B::value_type> auto a, B const& b)
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
{
return min(a, generalize_t<B const>(b)); return min(a, generalize_t<B const>(b));
else return base_of(b).cwiseMin(a); }
else { return base_of(b).cwiseMin(a); }
} }
template<concepts::entity A, concepts::entity B> template<concepts::entity A, concepts::entity B>
auto max(A const& a, B const& b) auto max(A const& a, B const& b)
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
{
return max(generalize_t<A const>(a), generalize_t<B const>(b)); return max(generalize_t<A const>(a), generalize_t<B const>(b));
else return base_of(a).cwiseMax(base_of(b)); }
else { return base_of(a).cwiseMax(base_of(b)); }
} }
template<concepts::entity A> template<concepts::entity A>
auto max(A const& a, std::convertible_to<typename A::value_type> auto b) auto max(A const& a, std::convertible_to<typename A::value_type> auto b)
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
{
return max(generalize_t<A const>(a), b); return max(generalize_t<A const>(a), b);
else return base_of(a).cwiseMax(b); }
else { return base_of(a).cwiseMax(b); }
} }
template<concepts::entity B> template<concepts::entity B>
auto max(std::convertible_to<typename B::value_type> auto a, B const& b) auto max(std::convertible_to<typename B::value_type> auto a, B const& b)
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
{
return max(a, generalize_t<B const>(b)); return max(a, generalize_t<B const>(b));
else return base_of(b).cwiseMax(a); }
else { return base_of(b).cwiseMax(a); }
} }
template<concepts::entity A, concepts::entity B> template<concepts::entity A, concepts::entity B>
auto mul(A const& a, B const& b) auto mul(A const& a, B const& b)
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
{
return mul(generalize_t<A const>(a), generalize_t<B const>(b)); return mul(generalize_t<A const>(a), generalize_t<B const>(b));
else return base_of(a).cwiseProduct(base_of(b)); }
else { return base_of(a).cwiseProduct(base_of(b)); }
} }
template<concepts::entity A> template<concepts::entity A>
@ -200,8 +321,10 @@ namespace rotgen
auto div(A const& a, B const& b) auto div(A const& a, B const& b)
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
{
return div(generalize_t<A const>(a), generalize_t<B const>(b)); return div(generalize_t<A const>(a), generalize_t<B const>(b));
else return base_of(a).array() / base_of(b).array(); }
else { return base_of(a).array() / base_of(b).array(); }
} }
template<concepts::entity A> template<concepts::entity A>
@ -215,43 +338,54 @@ namespace rotgen
return mul(a, a); return mul(a, a);
} }
//----------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Reductions // Reductions
//----------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------
auto trace(auto const& arg) auto trace(auto const& arg)
requires requires { arg.trace(); }
{ {
return arg.trace(); if constexpr (requires { arg.trace(); }) { return arg.trace(); }
else if constexpr (requires { arg._trace(); }) { return arg._trace(); }
else { return detail::unsupported_parameters<decltype(arg)>(); }
} }
auto squaredNorm(auto const& arg) auto squaredNorm(auto const& arg)
requires requires { arg.squaredNorm(); }
{ {
return arg.squaredNorm(); if constexpr (requires { arg.squaredNorm(); }) { return arg.squaredNorm(); }
else if constexpr (requires { arg._squaredNorm(); })
{
return arg._squaredNorm();
}
else { return detail::unsupported_parameters<decltype(arg)>(); }
} }
auto norm(auto const& arg) auto norm(auto const& arg)
requires requires { arg.norm(); }
{ {
return arg.norm(); if constexpr (requires { arg.norm(); }) { return arg.norm(); }
else if constexpr (requires { arg._norm(); }) { return arg._norm(); }
else { return detail::unsupported_parameters<decltype(arg)>(); }
} }
auto sum(auto const& arg) auto sum(auto const& arg)
requires requires { arg.sum(); } requires(requires { arg.sum(); } || requires { arg._sum(); })
{ {
return arg.sum(); if constexpr (requires { arg.sum(); }) { return arg.sum(); }
else if constexpr (requires { arg._sum(); }) { return arg._sum(); }
else { return detail::unsupported_parameters<decltype(arg)>(); }
} }
auto prod(auto const& arg) auto prod(auto const& arg)
requires requires { arg.prod(); }
{ {
return arg.prod(); if constexpr (requires { arg.prod(); }) { return arg.prod(); }
else if constexpr (requires { arg._prod(); }) { return arg._prod(); }
else { return detail::unsupported_parameters<decltype(arg)>(); }
} }
auto mean(auto const& arg) auto mean(auto const& arg)
requires requires { arg.mean(); }
{ {
return arg.mean(); if constexpr (requires { arg.mean(); }) { return arg.mean(); }
else if constexpr (requires { arg._mean(); }) { return arg._mean(); }
else { return detail::unsupported_parameters<decltype(arg)>(); }
} }
template<concepts::entity A, concepts::entity B> template<concepts::entity A, concepts::entity B>
@ -260,89 +394,135 @@ namespace rotgen
std::same_as<typename A::value_type, typename B::value_type>) std::same_as<typename A::value_type, typename B::value_type>)
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
{
return dot(generalize_t<A const>(a), generalize_t<B const>(b)); return dot(generalize_t<A const>(a), generalize_t<B const>(b));
else return base_of(a).dot(base_of(b)); }
else { return base_of(a).dot(base_of(b)); }
} }
auto maxCoeff(auto const& arg) auto maxCoeff(auto const& arg)
requires(requires { arg.maxCoeff(); })
{ {
return arg.maxCoeff(); if constexpr (requires { arg.maxCoeff(); }) { return arg.maxCoeff(); }
else if constexpr (requires { arg._maxCoeff(); })
{
return arg._maxCoeff();
}
else { return detail::unsupported_parameters<decltype(arg)>(); }
} }
auto minCoeff(auto const& arg) auto minCoeff(auto const& arg)
requires(requires { arg.minCoeff(); })
{ {
return arg.minCoeff(); if constexpr (requires { arg.minCoeff(); }) { return arg.minCoeff(); }
else if constexpr (requires { arg._minCoeff(); })
{
return arg._minCoeff();
}
else { return detail::unsupported_parameters<decltype(arg)>(); }
} }
template<std::integral IndexType> template<std::integral IndexType>
auto maxCoeff(auto const& arg, IndexType* row, IndexType* col) auto maxCoeff(auto const& arg, IndexType* row, IndexType* col)
requires(requires { arg.maxCoeff(row, col); })
{ {
return arg.maxCoeff(row, col); if constexpr (requires { arg.maxCoeff(row, col); })
{
return arg.maxCoeff(row, col);
}
else if constexpr (requires { arg._maxCoeff(row, col); })
{
return arg._maxCoeff(row, col);
}
else { return detail::unsupported_parameters<decltype(arg)>(); }
} }
template<std::integral IndexType> template<std::integral IndexType>
auto minCoeff(auto const& arg, IndexType* row, IndexType* col) auto minCoeff(auto const& arg, IndexType* row, IndexType* col)
requires(requires { arg.minCoeff(row, col); })
{ {
return arg.minCoeff(row, col); if constexpr (requires { arg.minCoeff(row, col); })
{
return arg.minCoeff(row, col);
}
else if constexpr (requires { arg._minCoeff(row, col); })
{
return arg._minCoeff(row, col);
}
else { return detail::unsupported_parameters<decltype(arg)>(); }
} }
template<int P, typename T> template<int P, typename T> auto lpNorm(T const& arg)
auto lpNorm(T const& arg)
requires(requires { arg.template lpNorm<P>(); })
{ {
static_assert(P == 1 || P == 2 || P == Infinity); if constexpr (requires { arg.template lpNorm<P>(); })
return arg.template lpNorm<P>(); {
static_assert(P == 1 || P == 2 || P == Infinity);
return arg.template lpNorm<P>();
}
else if constexpr (requires { arg.template _lpNorm<P>(); })
{
static_assert(P == 1 || P == 2 || P == Infinity);
return arg.template _lpNorm<P>();
}
else { return detail::unsupported_parameters<decltype(arg)>(); }
} }
//----------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Expression handling // Expression handling
//----------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------
template<typename T> template<typename T> decltype(auto) noalias(T&& t)
decltype(auto) noalias(T&& t)
requires(requires { std::forward<T>(t).noalias(); })
{ {
return std::forward<T>(t).noalias(); if constexpr (requires { std::forward<T>(t).noalias(); })
{
return std::forward<T>(t).noalias();
}
else if constexpr (requires { std::forward<T>(t)._noalias(); })
{
return std::forward<T>(t)._noalias();
}
else { return detail::unsupported_parameters<decltype(t)>(); }
} }
template<typename T> template<typename T> auto evaluate(T&& t)
auto evaluate(T&& t)
requires(requires { std::forward<T>(t).evaluate(); })
{ {
return std::forward<T>(t).evaluate(); if constexpr (requires { std::forward<T>(t).evaluate(); })
{
return std::forward<T>(t).evaluate();
}
else if constexpr (requires { std::forward<T>(t)._evaluate(); })
{
return std::forward<T>(t)._evaluate();
}
else if constexpr (requires { std::forward<T>(t).eval(); })
{
return std::forward<T>(t).eval();
}
else { return detail::unsupported_parameters<decltype(t)>(); }
} }
template<typename T> //----------------------------------------------------------------------------
auto evaluate(T&& t)
requires(requires { std::forward<T>(t).eval(); })
{
return std::forward<T>(t).eval();
}
//-----------------------------------------------------------------------------------------------
// Others // Others
// TODO: Adapt other functions ot behave as inverse and limit code in // TODO: Adapt other functions ot behave as inverse and limit code in
// non-ref/non-map containers // non-ref/non-map containers
//----------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------
template<typename A> auto inverse(A const& a) template<typename A> auto inverse(A const& a)
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
{
return inverse(generalize_t<A const>(a)); return inverse(generalize_t<A const>(a));
else return base_of(a).inverse(); }
else { return base_of(a).inverse(); }
} }
template<concepts::vectorND<3> L, concepts::vectorND<3> R> template<concepts::vectorND<3> L, concepts::vectorND<3> R>
auto cross(L const& l, R const& r) auto cross(L const& l, R const& r)
{ {
if constexpr (!use_expression_templates) if constexpr (!use_expression_templates)
{
return cross(generalize_t<R const>(l), generalize_t<R const>(r)); return cross(generalize_t<R const>(l), generalize_t<R const>(r));
}
else if constexpr ( else if constexpr (
requires { typename L::rotgen_tag; } || requires { typename L::rotgen_tag; } ||
requires { typename R::rotgen_tag; }) requires { typename R::rotgen_tag; })
return base_of(l).cross(base_of(r)); {
else return l.cross(r); return base_of(l)._cross(base_of(r));
}
else { return l._cross(r); }
} }
} }

View file

@ -1,156 +1,288 @@
//================================================================================================== //==============================================================================
/* /*
ROTGEN - Runtime Overlay for Eigen ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0 SPDX-License-Identifier: BSL-1.0
*/ */
//================================================================================================== //==============================================================================
#pragma once #pragma once
#include <rotgen/detail/assert.hpp>
#include <rotgen/detail/helpers.hpp> #include <rotgen/detail/helpers.hpp>
#include <rotgen/container/map.hpp>
namespace rotgen namespace rotgen
{ {
//----------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------
//----------------------------------------------------------------------------
template<typename T, typename... Args> void initialize_with(T&& m, Args... v)
{
using type = typename std::remove_cvref_t<T>::value_type;
using map_t = rotgen::map<rotgen::matrix<type, -1, -1, rotgen::RowMajor>>;
ROTGEN_ASSERT(sizeof...(v) == m.size(),
"Incorrect quantity of coefficients for initialization");
type data[] = {static_cast<type>(v)...};
m = map_t(data, rows(m), cols(m));
}
//----------------------------------------------------------------------------
// Generators // Generators
//----------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------
template<typename T>
auto setZero(T&& t) template<typename T> auto setZero(T&& t)
requires(requires { std::forward<T>(t).setZero(); })
{ {
return std::forward<T>(t).setZero(); if constexpr (requires { std::forward<T>(t).setZero(); })
{
return std::forward<T>(t).setZero();
}
else if constexpr (requires { std::forward<T>(t)._setZero(); })
{
return std::forward<T>(t)._setZero();
}
else
{
return detail::unsupported_parameters<T>();
}
} }
template<typename T> template<typename T> auto setZero()
auto setZero()
requires(requires { T::Zero(); })
{ {
return T::Zero(); if constexpr (requires { T::Zero(); }) { return T::Zero(); }
else if constexpr (requires { T::_Zero(); }) { return T::_Zero(); }
else
{
return detail::unsupported_parameters<T>();
}
} }
template<typename T> template<typename T> auto setZero(std::integral auto n)
auto setZero(std::integral auto n)
requires(requires { T::Zero(n); })
{ {
return T::Zero(n); if constexpr (requires { T::Zero(n); }) { return T::Zero(n); }
else if constexpr (requires { T::_Zero(n); }) { return T::_Zero(n); }
else
{
return detail::unsupported_parameters<T>();
}
} }
template<typename T> template<typename T> auto setZero(std::integral auto r, std::integral auto c)
auto setZero(std::integral auto r, std::integral auto c)
requires(requires { T::Zero(r, c); })
{ {
return T::Zero(r, c); if constexpr (requires { T::Zero(r, c); }) { return T::Zero(r, c); }
else if constexpr (requires { T::_Zero(r, c); }) { return T::_Zero(r, c); }
else
{
return detail::unsupported_parameters<T>();
}
} }
template<typename T> template<typename T> auto setOnes(T&& t)
auto setOnes(T&& t)
requires(requires { std::forward<T>(t).setOnes(); })
{ {
return std::forward<T>(t).setOnes(); if constexpr (requires { std::forward<T>(t).setOnes(); })
{
return std::forward<T>(t).setOnes();
}
else if constexpr (requires { std::forward<T>(t)._setOnes(); })
{
return std::forward<T>(t)._setOnes();
}
else
{
return detail::unsupported_parameters<T>();
}
} }
template<typename T> template<typename T> auto setOnes()
auto setOnes()
requires(requires { T::Ones(); })
{ {
return T::Ones(); if constexpr (requires { T::Ones(); }) { return T::Ones(); }
else if constexpr (requires { T::_Ones(); }) { return T::_Ones(); }
else
{
return detail::unsupported_parameters<T>();
}
} }
template<typename T> template<typename T> auto setOnes(std::integral auto n)
auto setOnes(std::integral auto n)
requires(requires { T::Ones(n); })
{ {
return T::Ones(n); if constexpr (requires { T::Ones(n); }) { return T::Ones(n); }
else if constexpr (requires { T::_Ones(n); }) { return T::_Ones(n); }
else
{
return detail::unsupported_parameters<T>();
}
} }
template<typename T> template<typename T> auto setOnes(std::integral auto r, std::integral auto c)
auto setOnes(std::integral auto r, std::integral auto c)
requires(requires { T::Ones(r, c); })
{ {
return T::Ones(r, c); if constexpr (requires { T::Ones(r, c); }) { return T::Ones(r, c); }
else if constexpr (requires { T::_Ones(r, c); }) { return T::_Ones(r, c); }
else
{
return detail::unsupported_parameters<T>();
}
} }
template<typename T> template<typename T> auto setIdentity(T&& t)
auto setIdentity(T&& t)
requires(requires { std::forward<T>(t).setIdentity(); })
{ {
return std::forward<T>(t).setIdentity(); if constexpr (requires { std::forward<T>(t).setIdentity(); })
{
return std::forward<T>(t).setIdentity();
}
else if constexpr (requires { std::forward<T>(t)._setIdentity(); })
{
return std::forward<T>(t)._setIdentity();
}
else
{
return detail::unsupported_parameters<T>();
}
} }
template<typename T> template<typename T> auto setIdentity()
auto setIdentity()
requires(requires { T::Identity(); })
{ {
return T::Identity(); if constexpr (requires { T::Identity(); }) { return T::Identity(); }
else if constexpr (requires { T::_Identity(); }) { return T::_Identity(); }
else
{
return detail::unsupported_parameters<T>();
}
} }
template<typename T> template<typename T> auto setIdentity(std::integral auto n)
auto setIdentity(std::integral auto n)
requires(requires { T::Identity(n); })
{ {
return T::Identity(n); if constexpr (requires { T::Identity(n); }) { return T::Identity(n); }
else if constexpr (requires { T::_Identity(n); })
{
return T::_Identity(n);
}
else
{
return detail::unsupported_parameters<T>();
}
} }
template<typename T> template<typename T>
auto setIdentity(std::integral auto r, std::integral auto c) auto setIdentity(std::integral auto r, std::integral auto c)
requires(requires { T::Identity(r, c); })
{ {
return T::Identity(r, c); if constexpr (requires { T::Identity(r, c); }) { return T::Identity(r, c); }
else if constexpr (requires { T::_Identity(r, c); })
{
return T::_Identity(r, c);
}
else
{
return detail::unsupported_parameters<T>();
}
} }
template<typename T> template<typename T> auto setRandom(T&& t)
auto setRandom(T&& t)
requires(requires { std::forward<T>(t).setRandom(); })
{ {
return std::forward<T>(t).setRandom(); if constexpr (requires { std::forward<T>(t).setRandom(); })
{
return std::forward<T>(t).setRandom();
}
else if constexpr (requires { std::forward<T>(t)._setRandom(); })
{
return std::forward<T>(t)._setRandom();
}
else
{
return detail::unsupported_parameters<T>();
}
} }
template<typename T> template<typename T> auto setRandom()
auto setRandom()
requires(requires { T::Random(); })
{ {
return T::Random(); if constexpr (requires { T::Random(); }) { return T::Random(); }
else if constexpr (requires { T::_Random(); }) { return T::_Random(); }
else
{
return detail::unsupported_parameters<T>();
}
} }
template<typename T> template<typename T> auto setRandom(std::integral auto n)
auto setRandom(std::integral auto n)
requires(requires { T::Random(n); })
{ {
return T::Random(n); if constexpr (requires { T::Random(n); }) { return T::Random(n); }
else if constexpr (requires { T::_Random(n); }) { return T::_Random(n); }
else
{
return detail::unsupported_parameters<T>();
}
} }
template<typename T> template<typename T>
auto setRandom(std::integral auto r, std::integral auto c) auto setRandom(std::integral auto r, std::integral auto c)
requires(requires { T::Random(r, c); })
{ {
return T::Random(r, c); if constexpr (requires { T::Random(r, c); }) { return T::Random(r, c); }
else if constexpr (requires { T::_Random(r, c); })
{
return T::_Random(r, c);
}
else
{
return detail::unsupported_parameters<T>();
}
} }
template<typename T> template<typename T> auto setConstant(T&& t, auto v)
auto setConstant(T&& t, auto v)
requires(requires { std::forward<T>(t).setConstant(v); })
{ {
return std::forward<T>(t).setConstant(v); if constexpr (requires { std::forward<T>(t).setConstant(v); })
{
return std::forward<T>(t).setConstant(v);
}
else if constexpr (requires { std::forward<T>(t)._setConstant(v); })
{
return std::forward<T>(t)._setConstant(v);
}
else
{
return detail::unsupported_parameters<T>();
}
} }
template<typename T> template<typename T> auto setConstant(auto v)
auto setConstant(auto v)
requires(requires { T::Constant(v); })
{ {
return T::Constant(v); if constexpr (requires { T::Constant(v); }) { return T::Constant(v); }
else if constexpr (requires { T::_Constant(v); })
{
return T::_Constant(v);
}
else
{
return detail::unsupported_parameters<T>();
}
} }
template<typename T> template<typename T> auto setConstant(std::integral auto n, auto v)
auto setConstant(std::integral auto n, auto v)
requires(requires { T::Constant(n, v); })
{ {
return T::Constant(n, v); if constexpr (requires { T::Constant(n, v); }) { return T::Constant(n, v); }
else if constexpr (requires { T::_Constant(n, v); })
{
return T::_Constant(n, v);
}
else
{
return detail::unsupported_parameters<T>();
}
} }
template<typename T> template<typename T>
auto setConstant(std::integral auto r, std::integral auto c, auto v) 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); if constexpr (requires { T::Constant(r, c, v); })
{
return T::Constant(r, c, v);
}
else if constexpr (requires { T::_Constant(r, c, v); })
{
return T::_Constant(r, c, v);
}
else
{
return detail::unsupported_parameters<T>();
}
} }
} }

View file

@ -7,9 +7,10 @@
//================================================================================================== //==================================================================================================
#pragma once #pragma once
#include <rotgen/detail/product.hpp>
#include <rotgen/concepts.hpp> #include <rotgen/concepts.hpp>
#include <cassert>
#include <iosfwd> #include <iosfwd>
namespace rotgen namespace rotgen
@ -80,30 +81,27 @@ namespace rotgen
//------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------
// Compounds operators across types // Compounds operators across types
template<typename A, typename B> template<concepts::entity A, concepts::entity B>
auto operator+=(A& a, B const& b) decltype(auto) operator+=(A&& a, B const& b)
requires(concepts::entity<A> && concepts::entity<B>) requires(!concepts::block<A>)
{ {
if constexpr (!use_expression_templates) generalize_t<A>(ROTGEN_FWD(a)) += generalize_t<B const>(b);
return generalize_t<A>(a) += generalize_t<B const>(b); return ROTGEN_FWD(a);
else return base_of(a) += base_of(b);
} }
template<typename A, typename B> template<concepts::entity A, concepts::entity B>
auto operator-=(A& a, B const& b) decltype(auto) operator-=(A&& a, B const& b)
requires(concepts::entity<A> && concepts::entity<B>) requires(!concepts::block<A>)
{ {
if constexpr (!use_expression_templates) generalize_t<A>(ROTGEN_FWD(a)) -= generalize_t<B const>(b);
return generalize_t<A>(a) -= generalize_t<B const>(b); return ROTGEN_FWD(a);
else return base_of(a) -= base_of(b);
} }
template<typename A, typename B> template<concepts::entity A, concepts::entity B>
auto operator*=(A& a, B const& b) decltype(auto) operator*=(A&& a, B const& b)
requires(concepts::entity<A> && concepts::entity<B>) requires(!concepts::block<A>)
{ {
if constexpr (!use_expression_templates) generalize_t<A>(ROTGEN_FWD(a)) *= generalize_t<B const>(b);
return generalize_t<A>(a) *= generalize_t<B const>(b); return ROTGEN_FWD(a);
else return base_of(a) *= base_of(b);
} }
} }

View file

@ -7,6 +7,11 @@
//================================================================================================== //==================================================================================================
#pragma once #pragma once
#include <rotgen/config.hpp>
#include <rotgen/functions/functions.hpp>
#include <type_traits>
namespace rotgen namespace rotgen
{ {
template<typename Ref> struct rowwise_adaptor template<typename Ref> struct rowwise_adaptor
@ -14,64 +19,64 @@ namespace rotgen
using concrete_type = typename std::remove_cvref_t<Ref>::concrete_type; using concrete_type = typename std::remove_cvref_t<Ref>::concrete_type;
Ref& target_; Ref& target_;
concrete_type sum() const concrete_type _sum() const
{ {
concrete_type res(target_.rows(), 1); concrete_type res(rows(target_), 1);
apply([&](auto r, auto i) { res(i) = r.sum(); }); apply([&](auto r, auto i) { res(i) = rotgen::sum(r); });
return res; return res;
} }
concrete_type mean() const concrete_type _mean() const
{ {
concrete_type res(target_.rows(), 1); concrete_type res(rows(target_), 1);
apply([&](auto r, auto i) { res(i) = r.mean(); }); apply([&](auto r, auto i) { res(i) = rotgen::mean(r); });
return res; return res;
} }
concrete_type prod() const concrete_type _prod() const
{ {
concrete_type res(target_.rows(), 1); concrete_type res(rows(target_), 1);
apply([&](auto r, auto i) { res(i) = r.prod(); }); apply([&](auto r, auto i) { res(i) = rotgen::prod(r); });
return res; return res;
} }
concrete_type maxCoeff() const concrete_type _maxCoeff() const
{ {
concrete_type res(target_.rows(), 1); concrete_type res(rows(target_), 1);
apply([&](auto r, auto i) { res(i) = r.maxCoeff(); }); apply([&](auto r, auto i) { res(i) = rotgen::maxCoeff(r); });
return res; return res;
} }
concrete_type minCoeff() const concrete_type _minCoeff() const
{ {
concrete_type res(target_.rows(), 1); concrete_type res(rows(target_), 1);
apply([&](auto r, auto i) { res(i) = r.minCoeff(); }); apply([&](auto r, auto i) { res(i) = rotgen::minCoeff(r); });
return res; return res;
} }
concrete_type squaredNorm() const concrete_type _squaredNorm() const
{ {
concrete_type res(target_.rows(), 1); concrete_type res(rows(target_), 1);
apply([&](auto r, auto i) { res(i) = r.squaredNorm(); }); apply([&](auto r, auto i) { res(i) = rotgen::squaredNorm(r); });
return res; return res;
} }
concrete_type norm() const concrete_type _norm() const
{ {
concrete_type res(target_.rows(), 1); concrete_type res(rows(target_), 1);
apply([&](auto r, auto i) { res(i) = r.norm(); }); apply([&](auto r, auto i) { res(i) = rotgen::norm(r); });
return res; return res;
} }
private: private:
template<typename Func> void apply(Func f) template<typename Func> void apply(Func f)
{ {
for (Index i = 0; i < target_.rows(); ++i) f(row(target_, i), i); for (Index i = 0; i < rows(target_); ++i) { f(row(target_, i), i); }
} }
template<typename Func> void apply(Func f) const template<typename Func> void apply(Func f) const
{ {
for (Index i = 0; i < target_.rows(); ++i) f(row(target_, i), i); for (Index i = 0; i < rows(target_); ++i) { f(row(target_, i), i); }
} }
}; };
@ -80,76 +85,82 @@ namespace rotgen
using concrete_type = typename std::remove_cvref_t<Ref>::concrete_type; using concrete_type = typename std::remove_cvref_t<Ref>::concrete_type;
Ref& target_; Ref& target_;
concrete_type sum() const concrete_type _sum() const
{ {
concrete_type res(1, target_.cols()); concrete_type res(1, cols(target_));
apply([&](auto r, auto i) { res(i) = r.sum(); }); apply([&](auto r, auto i) { res(i) = rotgen::sum(r); });
return res; return res;
} }
concrete_type mean() const concrete_type _mean() const
{ {
concrete_type res(1, target_.cols()); concrete_type res(1, cols(target_));
apply([&](auto r, auto i) { res(i) = r.mean(); }); apply([&](auto r, auto i) { res(i) = rotgen::mean(r); });
return res; return res;
} }
concrete_type prod() const concrete_type _prod() const
{ {
concrete_type res(1, target_.cols()); concrete_type res(1, cols(target_));
apply([&](auto r, auto i) { res(i) = r.prod(); }); apply([&](auto r, auto i) { res(i) = rotgen::prod(r); });
return res; return res;
} }
concrete_type maxCoeff() const concrete_type _maxCoeff() const
{ {
concrete_type res(1, target_.cols()); concrete_type res(1, cols(target_));
apply([&](auto r, auto i) { res(i) = r.maxCoeff(); }); apply([&](auto r, auto i) { res(i) = rotgen::maxCoeff(r); });
return res; return res;
} }
concrete_type minCoeff() const concrete_type _minCoeff() const
{ {
concrete_type res(1, target_.cols()); concrete_type res(1, cols(target_));
apply([&](auto r, auto i) { res(i) = r.minCoeff(); }); apply([&](auto r, auto i) { res(i) = rotgen::minCoeff(r); });
return res; return res;
} }
concrete_type squaredNorm() const concrete_type _squaredNorm() const
{ {
concrete_type res(1, target_.cols()); concrete_type res(1, cols(target_));
apply([&](auto r, auto i) { res(i) = r.squaredNorm(); }); apply([&](auto r, auto i) { res(i) = rotgen::squaredNorm(r); });
return res; return res;
} }
concrete_type norm() const concrete_type _norm() const
{ {
concrete_type res(1, target_.cols()); concrete_type res(1, cols(target_));
apply([&](auto r, auto i) { res(i) = r.norm(); }); apply([&](auto r, auto i) { res(i) = rotgen::norm(r); });
return res; return res;
} }
private: private:
template<typename Func> void apply(Func f) template<typename Func> void apply(Func f)
{ {
for (Index i = 0; i < target_.cols(); ++i) f(col(target_, i), i); for (Index i = 0; i < cols(target_); ++i) { f(col(target_, i), i); }
} }
template<typename Func> void apply(Func f) const template<typename Func> void apply(Func f) const
{ {
for (Index i = 0; i < target_.cols(); ++i) f(col(target_, i), i); for (Index i = 0; i < cols(target_); ++i) { f(col(target_, i), i); }
} }
}; };
template<typename T> auto rowwise(T&& t) template<typename T> auto rowwise(T&& t)
{ {
if constexpr (use_expression_templates) return t.base().rowwise(); if constexpr (use_expression_templates) { return t.base().rowwise(); }
else return rowwise_adaptor<T>{t}; else
{
return rowwise_adaptor<T>{t};
}
} }
template<typename T> auto colwise(T&& t) template<typename T> auto colwise(T&& t)
{ {
if constexpr (use_expression_templates) return t.base().colwise(); if constexpr (use_expression_templates) { return t.base().colwise(); }
else return colwise_adaptor<T>{t}; else
{
return colwise_adaptor<T>{t};
}
} }
} }

View file

@ -10,30 +10,38 @@
#define STORAGE_ORDER Eigen::ColMajor #define STORAGE_ORDER Eigen::ColMajor
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col) #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _col)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row) #define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row) #define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col) #define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
#include "model.cpp" #include "model.cpp"
#undef CLASSNAME #undef CLASSNAME
#undef CLASSCONSTNAME
#undef TRANSNAME #undef TRANSNAME
#undef TRANSCLASSNAME #undef TRANSCLASSNAME
#undef SOURCENAME #undef SOURCENAME
#undef MAPNAME #undef MAPNAME
#undef TRANSMAPNAME
#undef STORAGE_ORDER #undef STORAGE_ORDER
#define STORAGE_ORDER Eigen::RowMajor #define STORAGE_ORDER Eigen::RowMajor
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row) #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _row)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col) #define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col) #define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row) #define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
#include "model.cpp" #include "model.cpp"
#undef CLASSNAME #undef CLASSNAME
#undef CLASSCONSTNAME
#undef TRANSNAME #undef TRANSNAME
#undef TRANSCLASSNAME #undef TRANSCLASSNAME
#undef SOURCENAME #undef SOURCENAME
#undef MAPNAME #undef MAPNAME
#undef TRANSMAPNAME
#undef STORAGE_ORDER #undef STORAGE_ORDER
#undef SIZE #undef SIZE
@ -44,30 +52,38 @@
#define STORAGE_ORDER Eigen::ColMajor #define STORAGE_ORDER Eigen::ColMajor
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col) #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _col)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row) #define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row) #define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col) #define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
#include "model.cpp" #include "model.cpp"
#undef CLASSNAME #undef CLASSNAME
#undef CLASSCONSTNAME
#undef TRANSNAME #undef TRANSNAME
#undef TRANSCLASSNAME #undef TRANSCLASSNAME
#undef SOURCENAME #undef SOURCENAME
#undef MAPNAME #undef MAPNAME
#undef TRANSMAPNAME
#undef STORAGE_ORDER #undef STORAGE_ORDER
#define STORAGE_ORDER Eigen::RowMajor #define STORAGE_ORDER Eigen::RowMajor
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row) #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(block_const_impl, SIZE, _row)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col) #define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col) #define TRANSNAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row) #define MAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _row)
#define TRANSMAPNAME ROTGEN_MATRIX_NAME(BASEMAP, SIZE, _col)
#include "model.cpp" #include "model.cpp"
#undef CLASSNAME #undef CLASSNAME
#undef CLASSCONSTNAME
#undef TRANSNAME #undef TRANSNAME
#undef TRANSCLASSNAME #undef TRANSCLASSNAME
#undef SOURCENAME #undef SOURCENAME
#undef MAPNAME #undef MAPNAME
#undef TRANSMAPNAME
#undef STORAGE_ORDER #undef STORAGE_ORDER
#undef SIZE #undef SIZE

View file

@ -1,20 +1,20 @@
//================================================================================================== //==============================================================================
/* /*
ROTGEN - Runtime Overlay for Eigen ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0 SPDX-License-Identifier: BSL-1.0
*/ */
//================================================================================================== //==============================================================================
//================================================================================================== //==============================================================================
/* /*
This file is a X-File to generate various block_impl_* definitions variant This file is a X-File to generate various block_impl_* definitions variant
*/ */
//================================================================================================== //==============================================================================
//================================================================================================== //==============================================================================
// Constructors & Special Members // Constructors & Special Members
//================================================================================================== //==============================================================================
CLASSNAME::CLASSNAME( CLASSNAME::CLASSNAME(
SOURCENAME CONST& r, Index i0, Index j0, Index ni, Index nj) SOURCENAME CONST& r, Index i0, Index j0, Index ni, Index nj)
: storage_( : storage_(
@ -33,6 +33,12 @@ CLASSNAME::CLASSNAME(MAPNAME CONST& r, Index i0, Index j0, Index ni, Index nj)
{ {
} }
CLASSNAME::CLASSNAME(
TRANSMAPNAME CONST& r, Index i0, Index j0, Index ni, Index nj)
: storage_(std::make_unique<payload>(r, i0, j0, ni, nj, map_t{}, trans_t{}))
{
}
// We're building a block from a block - So we have to dig around the internals // We're building a block from a block - So we have to dig around the internals
CLASSNAME::CLASSNAME( CLASSNAME::CLASSNAME(
TRANSCLASSNAME CONST& p, Index i0, Index j0, Index ni, Index nj) TRANSCLASSNAME CONST& p, Index i0, Index j0, Index ni, Index nj)
@ -128,22 +134,9 @@ void CLASSNAME::assign(SOURCENAME const& m)
} }
#endif #endif
//================================================================================================== //==============================================================================
// Matrix API // Matrix API
//================================================================================================== //==============================================================================
rotgen::Index CLASSNAME::rows() const
{
rotgen::Index that;
storage_->apply([&](auto const& blk) { that = blk.rows(); });
return that;
}
rotgen::Index CLASSNAME::cols() const
{
rotgen::Index that;
storage_->apply([&](auto const& blk) { that = blk.cols(); });
return that;
}
rotgen::Index CLASSNAME::size() const rotgen::Index CLASSNAME::size() const
{ {
@ -152,26 +145,40 @@ rotgen::Index CLASSNAME::size() const
return that; return that;
} }
rotgen::Index CLASSNAME::innerStride() const rotgen::Index CLASSNAME::_rows() const
{
rotgen::Index that;
storage_->apply([&](auto const& blk) { that = blk.rows(); });
return that;
}
rotgen::Index CLASSNAME::_cols() const
{
rotgen::Index that;
storage_->apply([&](auto const& blk) { that = blk.cols(); });
return that;
}
rotgen::Index CLASSNAME::_innerStride() const
{ {
rotgen::Index that; rotgen::Index that;
storage_->apply([&](auto const& blk) { that = blk.innerStride(); }); storage_->apply([&](auto const& blk) { that = blk.innerStride(); });
return that; return that;
} }
rotgen::Index CLASSNAME::outerStride() const rotgen::Index CLASSNAME::_outerStride() const
{ {
rotgen::Index that; rotgen::Index that;
storage_->apply([&](auto const& blk) { that = blk.outerStride(); }); storage_->apply([&](auto const& blk) { that = blk.outerStride(); });
return that; return that;
} }
rotgen::Index CLASSNAME::startRow() const rotgen::Index CLASSNAME::_startRow() const
{ {
return storage_->rel_i0; return storage_->rel_i0;
} }
rotgen::Index CLASSNAME::startCol() const rotgen::Index CLASSNAME::_startCol() const
{ {
return storage_->rel_j0; return storage_->rel_j0;
} }
@ -197,17 +204,17 @@ TYPE CLASSNAME::operator()(Index i, Index j) const
#if !defined(USE_CONST) #if !defined(USE_CONST)
TYPE& CLASSNAME::operator()(Index index) TYPE& CLASSNAME::operator()(Index index)
{ {
TYPE* ptr = nullptr; auto r = _rows() == 1 ? 0 : index;
storage_->apply([&](auto& blk) { ptr = blk.data() + index; }); auto c = _cols() == 1 ? 0 : index;
return *ptr; return (*this)(r, c);
} }
#endif #endif
TYPE CLASSNAME::operator()(Index index) const TYPE CLASSNAME::operator()(Index index) const
{ {
TYPE ptr; auto r = _rows() == 1 ? 0 : index;
storage_->apply([&](auto const& blk) { ptr = *(blk.data() + index); }); auto c = _cols() == 1 ? 0 : index;
return ptr; return (*this)(r, c);
} }
// Raw pointer access // Raw pointer access
@ -227,10 +234,10 @@ TYPE const* CLASSNAME::data() const
return ptr; return ptr;
} }
//================================================================================================== //==============================================================================
// Matrix operations // Matrix operations
//================================================================================================== //==============================================================================
SOURCENAME CLASSNAME::normalized() const SOURCENAME CLASSNAME::_normalized() const
{ {
SOURCENAME result; SOURCENAME result;
storage_->apply([&](auto const& blk) { storage_->apply([&](auto const& blk) {
@ -239,7 +246,7 @@ SOURCENAME CLASSNAME::normalized() const
return result; return result;
} }
SOURCENAME CLASSNAME::transpose() const SOURCENAME CLASSNAME::_transpose() const
{ {
SOURCENAME result; SOURCENAME result;
storage_->apply( storage_->apply(
@ -247,7 +254,7 @@ SOURCENAME CLASSNAME::transpose() const
return result; return result;
} }
SOURCENAME CLASSNAME::conjugate() const SOURCENAME CLASSNAME::_conjugate() const
{ {
SOURCENAME result; SOURCENAME result;
storage_->apply( storage_->apply(
@ -255,7 +262,7 @@ SOURCENAME CLASSNAME::conjugate() const
return result; return result;
} }
SOURCENAME CLASSNAME::adjoint() const SOURCENAME CLASSNAME::_adjoint() const
{ {
SOURCENAME result; SOURCENAME result;
storage_->apply( storage_->apply(
@ -263,7 +270,7 @@ SOURCENAME CLASSNAME::adjoint() const
return result; return result;
} }
SOURCENAME CLASSNAME::cwiseAbs() const SOURCENAME CLASSNAME::_cwiseAbs() const
{ {
SOURCENAME result; SOURCENAME result;
storage_->apply( storage_->apply(
@ -271,7 +278,7 @@ SOURCENAME CLASSNAME::cwiseAbs() const
return result; return result;
} }
SOURCENAME CLASSNAME::cwiseAbs2() const SOURCENAME CLASSNAME::_cwiseAbs2() const
{ {
SOURCENAME result; SOURCENAME result;
storage_->apply( storage_->apply(
@ -279,7 +286,7 @@ SOURCENAME CLASSNAME::cwiseAbs2() const
return result; return result;
} }
SOURCENAME CLASSNAME::cwiseInverse() const SOURCENAME CLASSNAME::_cwiseInverse() const
{ {
SOURCENAME result; SOURCENAME result;
storage_->apply([&](auto const& blk) { storage_->apply([&](auto const& blk) {
@ -288,7 +295,7 @@ SOURCENAME CLASSNAME::cwiseInverse() const
return result; return result;
} }
SOURCENAME CLASSNAME::cwiseSqrt() const SOURCENAME CLASSNAME::_cwiseSqrt() const
{ {
SOURCENAME result; SOURCENAME result;
storage_->apply( storage_->apply(
@ -297,96 +304,96 @@ SOURCENAME CLASSNAME::cwiseSqrt() const
} }
#if !defined(USE_CONST) #if !defined(USE_CONST)
void CLASSNAME::normalize() void CLASSNAME::_normalize()
{ {
storage_->apply([](auto& blk) { blk.normalize(); }); storage_->apply([](auto& blk) { blk.normalize(); });
} }
void CLASSNAME::transposeInPlace() void CLASSNAME::_transposeInPlace()
{ {
storage_->apply([](auto& blk) { blk.transposeInPlace(); }); storage_->apply([](auto& blk) { blk.transposeInPlace(); });
} }
void CLASSNAME::adjointInPlace() void CLASSNAME::_adjointInPlace()
{ {
storage_->apply([](auto& blk) { blk.adjointInPlace(); }); storage_->apply([](auto& blk) { blk.adjointInPlace(); });
} }
#endif #endif
//================================================================================================== //==============================================================================
// Reductions // Reductions
//================================================================================================== //==============================================================================
TYPE CLASSNAME::sum() const TYPE CLASSNAME::_sum() const
{ {
TYPE val{}; TYPE val{};
storage_->apply([&](auto const& blk) { val = blk.sum(); }); storage_->apply([&](auto const& blk) { val = blk.sum(); });
return val; return val;
} }
TYPE CLASSNAME::prod() const TYPE CLASSNAME::_prod() const
{ {
TYPE val{}; TYPE val{};
storage_->apply([&](auto const& blk) { val = blk.prod(); }); storage_->apply([&](auto const& blk) { val = blk.prod(); });
return val; return val;
} }
TYPE CLASSNAME::mean() const TYPE CLASSNAME::_mean() const
{ {
TYPE val{}; TYPE val{};
storage_->apply([&](auto const& blk) { val = blk.mean(); }); storage_->apply([&](auto const& blk) { val = blk.mean(); });
return val; return val;
} }
TYPE CLASSNAME::trace() const TYPE CLASSNAME::_trace() const
{ {
TYPE val{}; TYPE val{};
storage_->apply([&](auto const& blk) { val = blk.trace(); }); storage_->apply([&](auto const& blk) { val = blk.trace(); });
return val; return val;
} }
TYPE CLASSNAME::minCoeff() const TYPE CLASSNAME::_minCoeff() const
{ {
TYPE val{}; TYPE val{};
storage_->apply([&](auto const& blk) { val = blk.minCoeff(); }); storage_->apply([&](auto const& blk) { val = blk.minCoeff(); });
return val; return val;
} }
TYPE CLASSNAME::maxCoeff() const TYPE CLASSNAME::_maxCoeff() const
{ {
TYPE val{}; TYPE val{};
storage_->apply([&](auto const& blk) { val = blk.maxCoeff(); }); storage_->apply([&](auto const& blk) { val = blk.maxCoeff(); });
return val; return val;
} }
TYPE CLASSNAME::minCoeff(Index* row, Index* col) const TYPE CLASSNAME::_minCoeff(Index* row, Index* col) const
{ {
TYPE val{}; TYPE val{};
storage_->apply([&](auto const& blk) { val = blk.minCoeff(row, col); }); storage_->apply([&](auto const& blk) { val = blk.minCoeff(row, col); });
return val; return val;
} }
TYPE CLASSNAME::maxCoeff(Index* row, Index* col) const TYPE CLASSNAME::_maxCoeff(Index* row, Index* col) const
{ {
TYPE val{}; TYPE val{};
storage_->apply([&](auto const& blk) { val = blk.maxCoeff(row, col); }); storage_->apply([&](auto const& blk) { val = blk.maxCoeff(row, col); });
return val; return val;
} }
TYPE CLASSNAME::squaredNorm() const TYPE CLASSNAME::_squaredNorm() const
{ {
TYPE val{}; TYPE val{};
storage_->apply([&](auto const& blk) { val = blk.squaredNorm(); }); storage_->apply([&](auto const& blk) { val = blk.squaredNorm(); });
return val; return val;
} }
TYPE CLASSNAME::norm() const TYPE CLASSNAME::_norm() const
{ {
TYPE val{}; TYPE val{};
storage_->apply([&](auto const& blk) { val = blk.norm(); }); storage_->apply([&](auto const& blk) { val = blk.norm(); });
return val; return val;
} }
TYPE CLASSNAME::lpNorm(int p) const TYPE CLASSNAME::_lpNorm(int p) const
{ {
TYPE val{}; TYPE val{};
storage_->apply([&](auto const& blk) { storage_->apply([&](auto const& blk) {
@ -397,9 +404,9 @@ TYPE CLASSNAME::lpNorm(int p) const
return val; return val;
} }
//================================================================================================== //==============================================================================
// Operators // Operators
//================================================================================================== //==============================================================================
ROTGEN_EXPORT std::ostream& operator<<(std::ostream& os, CLASSNAME const& m) ROTGEN_EXPORT std::ostream& operator<<(std::ostream& os, CLASSNAME const& m)
{ {
m.storage_->apply([&](auto const& blk) { os << blk; }); m.storage_->apply([&](auto const& blk) { os << blk; });
@ -448,6 +455,28 @@ CLASSNAME& CLASSNAME::operator+=(CLASSNAME const& rhs)
return *this; return *this;
} }
CLASSNAME& CLASSNAME::operator+=(CLASSCONSTNAME const& rhs)
{
std::visit(
[](auto& lhs_blk, auto const& rhs_blk) { lhs_blk.first += rhs_blk.first; },
storage_->data, rhs.storage()->data);
return *this;
}
CLASSNAME& CLASSNAME::operator+=(SOURCENAME const& rhs)
{
std::visit([&](auto& lhs_blk) { lhs_blk.first += rhs.storage()->data; },
storage_->data);
return *this;
}
CLASSNAME& CLASSNAME::operator+=(TRANSNAME const& rhs)
{
std::visit([&](auto& lhs_blk) { lhs_blk.first += rhs.storage()->data; },
storage_->data);
return *this;
}
CLASSNAME& CLASSNAME::operator-=(CLASSNAME const& rhs) CLASSNAME& CLASSNAME::operator-=(CLASSNAME const& rhs)
{ {
std::visit( std::visit(
@ -456,6 +485,28 @@ CLASSNAME& CLASSNAME::operator-=(CLASSNAME const& rhs)
return *this; return *this;
} }
CLASSNAME& CLASSNAME::operator-=(CLASSCONSTNAME const& rhs)
{
std::visit(
[](auto& lhs_blk, auto const& rhs_blk) { lhs_blk.first -= rhs_blk.first; },
storage_->data, rhs.storage()->data);
return *this;
}
CLASSNAME& CLASSNAME::operator-=(SOURCENAME const& rhs)
{
std::visit([&](auto& lhs_blk) { lhs_blk.first -= rhs.storage()->data; },
storage_->data);
return *this;
}
CLASSNAME& CLASSNAME::operator-=(TRANSNAME const& rhs)
{
std::visit([&](auto& lhs_blk) { lhs_blk.first -= rhs.storage()->data; },
storage_->data);
return *this;
}
CLASSNAME& CLASSNAME::operator*=(CLASSNAME const& rhs) CLASSNAME& CLASSNAME::operator*=(CLASSNAME const& rhs)
{ {
std::visit( std::visit(
@ -464,6 +515,28 @@ CLASSNAME& CLASSNAME::operator*=(CLASSNAME const& rhs)
return *this; return *this;
} }
CLASSNAME& CLASSNAME::operator*=(CLASSCONSTNAME const& rhs)
{
std::visit(
[](auto& lhs_blk, auto const& rhs_blk) { lhs_blk.first *= rhs_blk.first; },
storage_->data, rhs.storage()->data);
return *this;
}
CLASSNAME& CLASSNAME::operator*=(SOURCENAME const& rhs)
{
std::visit([&](auto& lhs_blk) { lhs_blk.first *= rhs.storage()->data; },
storage_->data);
return *this;
}
CLASSNAME& CLASSNAME::operator*=(TRANSNAME const& rhs)
{
std::visit([&](auto& lhs_blk) { lhs_blk.first *= rhs.storage()->data; },
storage_->data);
return *this;
}
CLASSNAME& CLASSNAME::operator*=(TYPE s) CLASSNAME& CLASSNAME::operator*=(TYPE s)
{ {
storage_->apply([&](auto& blk) { blk *= s; }); storage_->apply([&](auto& blk) { blk *= s; });
@ -477,7 +550,7 @@ CLASSNAME& CLASSNAME::operator/=(TYPE s)
} }
#endif #endif
SOURCENAME CLASSNAME::add(CLASSNAME const& rhs) const SOURCENAME CLASSNAME::_add(CLASSNAME const& rhs) const
{ {
SOURCENAME result; SOURCENAME result;
std::visit( std::visit(
@ -488,7 +561,7 @@ SOURCENAME CLASSNAME::add(CLASSNAME const& rhs) const
return result; return result;
} }
SOURCENAME CLASSNAME::sub(CLASSNAME const& rhs) const SOURCENAME CLASSNAME::_sub(CLASSNAME const& rhs) const
{ {
SOURCENAME result; SOURCENAME result;
std::visit( std::visit(
@ -499,7 +572,7 @@ SOURCENAME CLASSNAME::sub(CLASSNAME const& rhs) const
return result; return result;
} }
SOURCENAME CLASSNAME::mul(CLASSNAME const& rhs) const SOURCENAME CLASSNAME::_mul(CLASSNAME const& rhs) const
{ {
SOURCENAME result; SOURCENAME result;
std::visit( std::visit(
@ -510,7 +583,7 @@ SOURCENAME CLASSNAME::mul(CLASSNAME const& rhs) const
return result; return result;
} }
SOURCENAME CLASSNAME::mul(TYPE s) const SOURCENAME CLASSNAME::_mul(TYPE s) const
{ {
SOURCENAME result; SOURCENAME result;
std::visit( std::visit(
@ -521,7 +594,7 @@ SOURCENAME CLASSNAME::mul(TYPE s) const
return result; return result;
} }
SOURCENAME CLASSNAME::div(TYPE s) const SOURCENAME CLASSNAME::_div(TYPE s) const
{ {
SOURCENAME result; SOURCENAME result;
std::visit( std::visit(

View file

@ -11,29 +11,41 @@
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col) #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row) #define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row) #define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col) #define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#include "model.cpp" #include "model.cpp"
#undef CLASSNAME #undef CLASSNAME
#undef TRANSCLASSNAME #undef TRANSCLASSNAME
#undef TRANSCLASSCONSTNAME
#undef TRANSCLASSNONCONSTNAME
#undef TRANSSOURCENAME #undef TRANSSOURCENAME
#undef CLASSCONSTNAME #undef CLASSCONSTNAME
#undef CLASSNONCONSTNAME
#undef SOURCENAME #undef SOURCENAME
#undef STORAGE_ORDER #undef STORAGE_ORDER
#define STORAGE_ORDER Eigen::RowMajor #define STORAGE_ORDER Eigen::RowMajor
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row) #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col) #define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col) #define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row) #define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#include "model.cpp" #include "model.cpp"
#undef CLASSNAME #undef CLASSNAME
#undef TRANSCLASSNAME #undef TRANSCLASSNAME
#undef TRANSCLASSCONSTNAME
#undef TRANSCLASSNONCONSTNAME
#undef TRANSSOURCENAME #undef TRANSSOURCENAME
#undef SOURCENAME #undef SOURCENAME
#undef CLASSCONSTNAME #undef CLASSCONSTNAME
#undef CLASSNONCONSTNAME
#undef STORAGE_ORDER #undef STORAGE_ORDER
#undef SIZE #undef SIZE
@ -45,28 +57,40 @@
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col) #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row) #define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row) #define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col) #define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#include "model.cpp" #include "model.cpp"
#undef CLASSNAME #undef CLASSNAME
#undef TRANSCLASSNAME #undef TRANSCLASSNAME
#undef TRANSCLASSCONSTNAME
#undef TRANSCLASSNONCONSTNAME
#undef TRANSSOURCENAME #undef TRANSSOURCENAME
#undef CLASSCONSTNAME #undef CLASSCONSTNAME
#undef CLASSNONCONSTNAME
#undef SOURCENAME #undef SOURCENAME
#undef STORAGE_ORDER #undef STORAGE_ORDER
#define STORAGE_ORDER Eigen::RowMajor #define STORAGE_ORDER Eigen::RowMajor
#define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row) #define CLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _row)
#define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col) #define TRANSCLASSNAME ROTGEN_MATRIX_NAME(BASENAME, SIZE, _col)
#define TRANSCLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _col)
#define TRANSCLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _col)
#define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col) #define TRANSSOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _col)
#define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row) #define CLASSCONSTNAME ROTGEN_MATRIX_NAME(map_const_impl, SIZE, _row)
#define CLASSNONCONSTNAME ROTGEN_MATRIX_NAME(map_impl, SIZE, _row)
#define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row) #define SOURCENAME ROTGEN_MATRIX_NAME(matrix_impl, SIZE, _row)
#include "model.cpp" #include "model.cpp"
#undef CLASSNAME #undef CLASSNAME
#undef TRANSCLASSNAME #undef TRANSCLASSNAME
#undef TRANSCLASSCONSTNAME
#undef TRANSCLASSNONCONSTNAME
#undef TRANSSOURCENAME #undef TRANSSOURCENAME
#undef CLASSCONSTNAME #undef CLASSCONSTNAME
#undef CLASSNONCONSTNAME
#undef SOURCENAME #undef SOURCENAME
#undef STORAGE_ORDER #undef STORAGE_ORDER

View file

@ -58,12 +58,12 @@ CLASSNAME::~CLASSNAME() = default;
//================================================================================================== //==================================================================================================
// Matrix API // Matrix API
//================================================================================================== //==================================================================================================
rotgen::Index CLASSNAME::rows() const rotgen::Index CLASSNAME::_rows() const
{ {
return storage_->data.rows(); return storage_->data.rows();
} }
rotgen::Index CLASSNAME::cols() const rotgen::Index CLASSNAME::_cols() const
{ {
return storage_->data.cols(); return storage_->data.cols();
} }
@ -73,12 +73,12 @@ rotgen::Index CLASSNAME::size() const
return storage_->data.size(); return storage_->data.size();
} }
rotgen::Index CLASSNAME::innerStride() const rotgen::Index CLASSNAME::_innerStride() const
{ {
return storage_->data.innerStride(); return storage_->data.innerStride();
} }
rotgen::Index CLASSNAME::outerStride() const rotgen::Index CLASSNAME::_outerStride() const
{ {
return storage_->data.outerStride(); return storage_->data.outerStride();
} }
@ -115,77 +115,77 @@ TYPE CLASSNAME::operator()(Index i) const
return storage_->data.data()[i]; return storage_->data.data()[i];
} }
SOURCENAME CLASSNAME::normalized() const SOURCENAME CLASSNAME::_normalized() const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data.normalized().eval()); result.storage()->assign(storage_->data.normalized().eval());
return result; return result;
} }
SOURCENAME CLASSNAME::transpose() const SOURCENAME CLASSNAME::_transpose() const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data.transpose().eval()); result.storage()->assign(storage_->data.transpose().eval());
return result; return result;
} }
SOURCENAME CLASSNAME::conjugate() const SOURCENAME CLASSNAME::_conjugate() const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data.conjugate().eval()); result.storage()->assign(storage_->data.conjugate().eval());
return result; return result;
} }
SOURCENAME CLASSNAME::adjoint() const SOURCENAME CLASSNAME::_adjoint() const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data.adjoint().eval()); result.storage()->assign(storage_->data.adjoint().eval());
return result; return result;
} }
SOURCENAME CLASSNAME::cwiseAbs() const SOURCENAME CLASSNAME::_cwiseAbs() const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data.cwiseAbs().eval()); result.storage()->assign(storage_->data.cwiseAbs().eval());
return result; return result;
} }
SOURCENAME CLASSNAME::cwiseAbs2() const SOURCENAME CLASSNAME::_cwiseAbs2() const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data.cwiseAbs2().eval()); result.storage()->assign(storage_->data.cwiseAbs2().eval());
return result; return result;
} }
SOURCENAME CLASSNAME::cwiseInverse() const SOURCENAME CLASSNAME::_cwiseInverse() const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data.cwiseInverse().eval()); result.storage()->assign(storage_->data.cwiseInverse().eval());
return result; return result;
} }
SOURCENAME CLASSNAME::cwiseSqrt() const SOURCENAME CLASSNAME::_cwiseSqrt() const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data.cwiseSqrt().eval()); result.storage()->assign(storage_->data.cwiseSqrt().eval());
return result; return result;
} }
SOURCENAME CLASSNAME::cwiseMin(CLASSNAME const& rhs) const SOURCENAME CLASSNAME::_cwiseMin(CLASSNAME const& rhs) const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data.cwiseMin(rhs.storage()->data).eval()); result.storage()->assign(storage_->data.cwiseMin(rhs.storage()->data).eval());
return result; return result;
} }
SOURCENAME CLASSNAME::cwiseMax(CLASSNAME const& rhs) const SOURCENAME CLASSNAME::_cwiseMax(CLASSNAME const& rhs) const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data.cwiseMax(rhs.storage()->data).eval()); result.storage()->assign(storage_->data.cwiseMax(rhs.storage()->data).eval());
return result; return result;
} }
SOURCENAME CLASSNAME::cwiseProduct(CLASSNAME const& rhs) const SOURCENAME CLASSNAME::_cwiseProduct(CLASSNAME const& rhs) const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign( result.storage()->assign(
@ -193,7 +193,7 @@ SOURCENAME CLASSNAME::cwiseProduct(CLASSNAME const& rhs) const
return result; return result;
} }
SOURCENAME CLASSNAME::cwiseQuotient(CLASSNAME const& rhs) const SOURCENAME CLASSNAME::_cwiseQuotient(CLASSNAME const& rhs) const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign( result.storage()->assign(
@ -201,21 +201,21 @@ SOURCENAME CLASSNAME::cwiseQuotient(CLASSNAME const& rhs) const
return result; return result;
} }
SOURCENAME CLASSNAME::cwiseMin(TYPE rhs) const SOURCENAME CLASSNAME::_cwiseMin(TYPE rhs) const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data.cwiseMin(rhs).eval()); result.storage()->assign(storage_->data.cwiseMin(rhs).eval());
return result; return result;
} }
SOURCENAME CLASSNAME::cwiseMax(TYPE rhs) const SOURCENAME CLASSNAME::_cwiseMax(TYPE rhs) const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data.cwiseMax(rhs).eval()); result.storage()->assign(storage_->data.cwiseMax(rhs).eval());
return result; return result;
} }
SOURCENAME CLASSNAME::inverse() const SOURCENAME CLASSNAME::_inverse() const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data.inverse().eval()); result.storage()->assign(storage_->data.inverse().eval());
@ -223,83 +223,93 @@ SOURCENAME CLASSNAME::inverse() const
} }
#if !defined(USE_CONST) #if !defined(USE_CONST)
void CLASSNAME::normalize() void CLASSNAME::_normalize()
{ {
storage_->data.normalize(); storage_->data.normalize();
} }
void CLASSNAME::transposeInPlace() void CLASSNAME::_transposeInPlace()
{ {
storage_->data.transposeInPlace(); storage_->data.transposeInPlace();
} }
void CLASSNAME::adjointInPlace() void CLASSNAME::_adjointInPlace()
{ {
storage_->data.adjointInPlace(); storage_->data.adjointInPlace();
} }
#endif #endif
TYPE CLASSNAME::dot(CLASSNAME const& rhs) const TYPE CLASSNAME::_dot(CLASSNONCONSTNAME const& rhs) const
{ {
return storage_->data.reshaped().dot(rhs.storage()->data.reshaped()); return storage_->data.reshaped().dot(rhs.storage()->data.reshaped());
} }
TYPE CLASSNAME::dot(TRANSCLASSNAME const& rhs) const TYPE CLASSNAME::_dot(CLASSCONSTNAME const& rhs) const
{ {
return storage_->data.reshaped().dot(rhs.storage()->data.reshaped()); return storage_->data.reshaped().dot(rhs.storage()->data.reshaped());
} }
TYPE CLASSNAME::sum() const TYPE CLASSNAME::_dot(TRANSCLASSNONCONSTNAME const& rhs) const
{
return storage_->data.reshaped().dot(rhs.storage()->data.reshaped());
}
TYPE CLASSNAME::_dot(TRANSCLASSCONSTNAME const& rhs) const
{
return storage_->data.reshaped().dot(rhs.storage()->data.reshaped());
}
TYPE CLASSNAME::_sum() const
{ {
return storage_->data.sum(); return storage_->data.sum();
} }
TYPE CLASSNAME::prod() const TYPE CLASSNAME::_prod() const
{ {
return storage_->data.prod(); return storage_->data.prod();
} }
TYPE CLASSNAME::mean() const TYPE CLASSNAME::_mean() const
{ {
return storage_->data.mean(); return storage_->data.mean();
} }
TYPE CLASSNAME::trace() const TYPE CLASSNAME::_trace() const
{ {
return storage_->data.trace(); return storage_->data.trace();
} }
TYPE CLASSNAME::minCoeff() const TYPE CLASSNAME::_minCoeff() const
{ {
return storage_->data.minCoeff(); return storage_->data.minCoeff();
} }
TYPE CLASSNAME::maxCoeff() const TYPE CLASSNAME::_maxCoeff() const
{ {
return storage_->data.maxCoeff(); return storage_->data.maxCoeff();
} }
TYPE CLASSNAME::minCoeff(Index* row, Index* col) const TYPE CLASSNAME::_minCoeff(Index* row, Index* col) const
{ {
return storage_->data.minCoeff(row, col); return storage_->data.minCoeff(row, col);
} }
TYPE CLASSNAME::maxCoeff(Index* row, Index* col) const TYPE CLASSNAME::_maxCoeff(Index* row, Index* col) const
{ {
return storage_->data.maxCoeff(row, col); return storage_->data.maxCoeff(row, col);
} }
TYPE CLASSNAME::squaredNorm() const TYPE CLASSNAME::_squaredNorm() const
{ {
return storage_->data.squaredNorm(); return storage_->data.squaredNorm();
} }
TYPE CLASSNAME::norm() const TYPE CLASSNAME::_norm() const
{ {
return storage_->data.norm(); return storage_->data.norm();
} }
TYPE CLASSNAME::lpNorm(int p) const TYPE CLASSNAME::_lpNorm(int p) const
{ {
if (p == 1) return storage_->data.lpNorm<1>(); if (p == 1) return storage_->data.lpNorm<1>();
else if (p == 2) return storage_->data.lpNorm<2>(); else if (p == 2) return storage_->data.lpNorm<2>();
@ -307,27 +317,27 @@ TYPE CLASSNAME::lpNorm(int p) const
} }
#if !defined(USE_CONST) #if !defined(USE_CONST)
void CLASSNAME::setZero() void CLASSNAME::_setZero()
{ {
storage_->data.setZero(); storage_->data.setZero();
} }
void CLASSNAME::setOnes() void CLASSNAME::_setOnes()
{ {
storage_->data.setOnes(); storage_->data.setOnes();
} }
void CLASSNAME::setIdentity() void CLASSNAME::_setIdentity()
{ {
storage_->data.setIdentity(); storage_->data.setIdentity();
} }
void CLASSNAME::setRandom() void CLASSNAME::_setRandom()
{ {
storage_->data.setRandom(); storage_->data.setRandom();
} }
void CLASSNAME::setConstant(TYPE s) void CLASSNAME::_setConstant(TYPE s)
{ {
storage_->data.setConstant(s); storage_->data.setConstant(s);
} }
@ -378,7 +388,7 @@ SOURCENAME CLASSNAME::operator-() const
#if !defined(USE_CONST) #if !defined(USE_CONST)
CLASSNAME& CLASSNAME::operator+=(CLASSNAME const& rhs) CLASSNAME& CLASSNAME::operator+=(CLASSNAME const& rhs)
{ {
storage_->data += rhs.storage_->data; storage_->data += rhs.storage()->data;
return *this; return *this;
} }
@ -388,9 +398,21 @@ CLASSNAME& CLASSNAME::operator+=(CLASSCONSTNAME const& rhs)
return *this; return *this;
} }
CLASSNAME& CLASSNAME::operator+=(TRANSCLASSNONCONSTNAME const& rhs)
{
storage_->data.reshaped() += rhs.storage()->data.reshaped();
return *this;
}
CLASSNAME& CLASSNAME::operator+=(TRANSCLASSCONSTNAME const& rhs)
{
storage_->data.reshaped() += rhs.storage()->data.reshaped();
return *this;
}
CLASSNAME& CLASSNAME::operator-=(CLASSNAME const& rhs) CLASSNAME& CLASSNAME::operator-=(CLASSNAME const& rhs)
{ {
storage_->data -= rhs.storage_->data; storage_->data -= rhs.storage()->data;
return *this; return *this;
} }
@ -400,9 +422,21 @@ CLASSNAME& CLASSNAME::operator-=(CLASSCONSTNAME const& rhs)
return *this; return *this;
} }
CLASSNAME& CLASSNAME::operator-=(TRANSCLASSNONCONSTNAME const& rhs)
{
storage_->data.reshaped() -= rhs.storage()->data.reshaped();
return *this;
}
CLASSNAME& CLASSNAME::operator-=(TRANSCLASSCONSTNAME const& rhs)
{
storage_->data.reshaped() -= rhs.storage()->data.reshaped();
return *this;
}
CLASSNAME& CLASSNAME::operator*=(CLASSNAME const& rhs) CLASSNAME& CLASSNAME::operator*=(CLASSNAME const& rhs)
{ {
storage_->data *= rhs.storage_->data; storage_->data *= rhs.storage()->data;
return *this; return *this;
} }
@ -412,6 +446,18 @@ CLASSNAME& CLASSNAME::operator*=(CLASSCONSTNAME const& rhs)
return *this; return *this;
} }
CLASSNAME& CLASSNAME::operator*=(TRANSCLASSNONCONSTNAME const& rhs)
{
storage_->data *= rhs.storage()->data;
return *this;
}
CLASSNAME& CLASSNAME::operator*=(TRANSCLASSCONSTNAME const& rhs)
{
storage_->data *= rhs.storage()->data;
return *this;
}
CLASSNAME& CLASSNAME::operator*=(TYPE s) CLASSNAME& CLASSNAME::operator*=(TYPE s)
{ {
storage_->data *= s; storage_->data *= s;
@ -425,56 +471,56 @@ CLASSNAME& CLASSNAME::operator/=(TYPE s)
} }
#endif #endif
SOURCENAME CLASSNAME::add(CLASSNAME const& rhs) const SOURCENAME CLASSNAME::_add(CLASSNAME const& rhs) const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data + rhs.storage_->data); result.storage()->assign(storage_->data + rhs.storage_->data);
return result; return result;
} }
SOURCENAME CLASSNAME::add(TRANSCLASSNAME const& rhs) const SOURCENAME CLASSNAME::_add(TRANSCLASSNAME const& rhs) const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data + rhs.storage()->data); result.storage()->assign(storage_->data + rhs.storage()->data);
return result; return result;
} }
SOURCENAME CLASSNAME::sub(CLASSNAME const& rhs) const SOURCENAME CLASSNAME::_sub(CLASSNAME const& rhs) const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data - rhs.storage_->data); result.storage()->assign(storage_->data - rhs.storage_->data);
return result; return result;
} }
SOURCENAME CLASSNAME::sub(TRANSCLASSNAME const& rhs) const SOURCENAME CLASSNAME::_sub(TRANSCLASSNAME const& rhs) const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data - rhs.storage()->data); result.storage()->assign(storage_->data - rhs.storage()->data);
return result; return result;
} }
SOURCENAME CLASSNAME::mul(CLASSNAME const& rhs) const SOURCENAME CLASSNAME::_mul(CLASSNAME const& rhs) const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data * rhs.storage_->data); result.storage()->assign(storage_->data * rhs.storage_->data);
return result; return result;
} }
SOURCENAME CLASSNAME::mul(TRANSCLASSNAME const& rhs) const SOURCENAME CLASSNAME::_mul(TRANSCLASSNAME const& rhs) const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data * rhs.storage()->data); result.storage()->assign(storage_->data * rhs.storage()->data);
return result; return result;
} }
SOURCENAME CLASSNAME::mul(TYPE s) const SOURCENAME CLASSNAME::_mul(TYPE s) const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data * s); result.storage()->assign(storage_->data * s);
return result; return result;
} }
SOURCENAME CLASSNAME::div(TYPE s) const SOURCENAME CLASSNAME::_div(TYPE s) const
{ {
SOURCENAME result; SOURCENAME result;
result.storage()->assign(storage_->data / s); result.storage()->assign(storage_->data / s);

View file

@ -34,7 +34,7 @@ CLASSNAME::CLASSNAME(Index r, Index c, std::initializer_list<TYPE> init)
for (std::size_t i = 0; i < init.size(); i++) (*this)(i) = first[i]; for (std::size_t i = 0; i < init.size(); i++) (*this)(i) = first[i];
} }
CLASSNAME::CLASSNAME(CLASSNAME const& o) : CLASSNAME(o.rows(), o.cols()) CLASSNAME::CLASSNAME(CLASSNAME const& o) : CLASSNAME(o._rows(), o._cols())
{ {
storage_->data = o.storage_->data; storage_->data = o.storage_->data;
} }
@ -54,27 +54,27 @@ CLASSNAME::~CLASSNAME() = default;
//================================================================================================== //==================================================================================================
// Matrix API // Matrix API
//================================================================================================== //==================================================================================================
rotgen::Index CLASSNAME::rows() const rotgen::Index CLASSNAME::size() const
{
return storage_->data.size();
}
rotgen::Index CLASSNAME::_rows() const
{ {
return storage_->data.rows(); return storage_->data.rows();
} }
rotgen::Index CLASSNAME::cols() const rotgen::Index CLASSNAME::_cols() const
{ {
return storage_->data.cols(); return storage_->data.cols();
} }
rotgen::Index CLASSNAME::size() const
{
return storage_->data.size();
}
void CLASSNAME::resize(Index new_rows, Index new_cols) void CLASSNAME::resize(Index new_rows, Index new_cols)
{ {
storage_->data.resize(new_rows, new_cols); storage_->data.resize(new_rows, new_cols);
} }
void CLASSNAME::conservativeResize(Index new_rows, Index new_cols) void CLASSNAME::_conservativeResize(Index new_rows, Index new_cols)
{ {
storage_->data.conservativeResize(new_rows, new_cols); storage_->data.conservativeResize(new_rows, new_cols);
} }
@ -109,128 +109,128 @@ TYPE* CLASSNAME::data()
return storage_->data.data(); return storage_->data.data();
} }
CLASSNAME CLASSNAME::normalized() const CLASSNAME CLASSNAME::_normalized() const
{ {
CLASSNAME result(*this); CLASSNAME result(*this);
result.storage_->data.normalize(); result.storage_->data.normalize();
return result; return result;
} }
CLASSNAME CLASSNAME::transpose() const CLASSNAME CLASSNAME::_transpose() const
{ {
CLASSNAME result; CLASSNAME result;
result.storage()->data = storage_->data.transpose(); result.storage()->data = storage_->data.transpose();
return result; return result;
} }
CLASSNAME CLASSNAME::conjugate() const CLASSNAME CLASSNAME::_conjugate() const
{ {
CLASSNAME result(*this); CLASSNAME result(*this);
result.storage_->data = storage_->data.conjugate(); result.storage_->data = storage_->data.conjugate();
return result; return result;
} }
CLASSNAME CLASSNAME::adjoint() const CLASSNAME CLASSNAME::_adjoint() const
{ {
CLASSNAME result; CLASSNAME result;
result.storage()->data = storage_->data.adjoint(); result.storage()->data = storage_->data.adjoint();
return result; return result;
} }
void CLASSNAME::normalize() void CLASSNAME::_normalize()
{ {
storage_->data.normalize(); storage_->data.normalize();
} }
void CLASSNAME::transposeInPlace() void CLASSNAME::_transposeInPlace()
{ {
storage_->data.transposeInPlace(); storage_->data.transposeInPlace();
} }
void CLASSNAME::adjointInPlace() void CLASSNAME::_adjointInPlace()
{ {
storage_->data.adjointInPlace(); storage_->data.adjointInPlace();
} }
CLASSNAME CLASSNAME::cwiseAbs() const CLASSNAME CLASSNAME::_cwiseAbs() const
{ {
CLASSNAME result(*this); CLASSNAME result(*this);
result.storage_->data = storage_->data.cwiseAbs(); result.storage_->data = storage_->data.cwiseAbs();
return result; return result;
} }
CLASSNAME CLASSNAME::cwiseAbs2() const CLASSNAME CLASSNAME::_cwiseAbs2() const
{ {
CLASSNAME result(*this); CLASSNAME result(*this);
result.storage_->data = storage_->data.cwiseAbs2(); result.storage_->data = storage_->data.cwiseAbs2();
return result; return result;
} }
CLASSNAME CLASSNAME::cwiseInverse() const CLASSNAME CLASSNAME::_cwiseInverse() const
{ {
CLASSNAME result(*this); CLASSNAME result(*this);
result.storage_->data = storage_->data.cwiseInverse(); result.storage_->data = storage_->data.cwiseInverse();
return result; return result;
} }
CLASSNAME CLASSNAME::cwiseSqrt() const CLASSNAME CLASSNAME::_cwiseSqrt() const
{ {
CLASSNAME result(*this); CLASSNAME result(*this);
result.storage_->data = storage_->data.cwiseSqrt(); result.storage_->data = storage_->data.cwiseSqrt();
return result; return result;
} }
TYPE CLASSNAME::sum() const TYPE CLASSNAME::_sum() const
{ {
return storage_->data.sum(); return storage_->data.sum();
} }
TYPE CLASSNAME::prod() const TYPE CLASSNAME::_prod() const
{ {
return storage_->data.prod(); return storage_->data.prod();
} }
TYPE CLASSNAME::mean() const TYPE CLASSNAME::_mean() const
{ {
return storage_->data.mean(); return storage_->data.mean();
} }
TYPE CLASSNAME::trace() const TYPE CLASSNAME::_trace() const
{ {
return storage_->data.trace(); return storage_->data.trace();
} }
TYPE CLASSNAME::minCoeff() const TYPE CLASSNAME::_minCoeff() const
{ {
return storage_->data.minCoeff(); return storage_->data.minCoeff();
} }
TYPE CLASSNAME::maxCoeff() const TYPE CLASSNAME::_maxCoeff() const
{ {
return storage_->data.maxCoeff(); return storage_->data.maxCoeff();
} }
TYPE CLASSNAME::minCoeff(Index* row, Index* col) const TYPE CLASSNAME::_minCoeff(Index* row, Index* col) const
{ {
return storage_->data.minCoeff(row, col); return storage_->data.minCoeff(row, col);
} }
TYPE CLASSNAME::maxCoeff(Index* row, Index* col) const TYPE CLASSNAME::_maxCoeff(Index* row, Index* col) const
{ {
return storage_->data.maxCoeff(row, col); return storage_->data.maxCoeff(row, col);
} }
TYPE CLASSNAME::squaredNorm() const TYPE CLASSNAME::_squaredNorm() const
{ {
return storage_->data.squaredNorm(); return storage_->data.squaredNorm();
} }
TYPE CLASSNAME::norm() const TYPE CLASSNAME::_norm() const
{ {
return storage_->data.norm(); return storage_->data.norm();
} }
TYPE CLASSNAME::lp_norm(int p) const TYPE CLASSNAME::_lp_norm(int p) const
{ {
if (p == 1) return storage_->data.lpNorm<1>(); if (p == 1) return storage_->data.lpNorm<1>();
else if (p == 2) return storage_->data.lpNorm<2>(); else if (p == 2) return storage_->data.lpNorm<2>();
@ -301,27 +301,27 @@ CLASSNAME& CLASSNAME::operator/=(TYPE s)
//============================================================================== //==============================================================================
// Generators functions // Generators functions
//============================================================================== //==============================================================================
void CLASSNAME::setOnes(Index rows, Index cols) void CLASSNAME::_setOnes(Index rows, Index cols)
{ {
storage_->assign(payload::data_type::Ones(rows, cols).eval()); storage_->assign(payload::data_type::Ones(rows, cols).eval());
} }
void CLASSNAME::setZero(Index rows, Index cols) void CLASSNAME::_setZero(Index rows, Index cols)
{ {
storage_->assign(payload::data_type::Zero(rows, cols).eval()); storage_->assign(payload::data_type::Zero(rows, cols).eval());
} }
void CLASSNAME::setConstant(Index rows, Index cols, TYPE value) void CLASSNAME::_setConstant(Index rows, Index cols, TYPE value)
{ {
storage_->assign(payload::data_type::Constant(rows, cols, value).eval()); storage_->assign(payload::data_type::Constant(rows, cols, value).eval());
} }
void CLASSNAME::setRandom(Index rows, Index cols) void CLASSNAME::_setRandom(Index rows, Index cols)
{ {
storage_->assign(payload::data_type::Random(rows, cols).eval()); storage_->assign(payload::data_type::Random(rows, cols).eval());
} }
void CLASSNAME::setIdentity(Index rows, Index cols) void CLASSNAME::_setIdentity(Index rows, Index cols)
{ {
storage_->assign(payload::data_type::Identity(rows, cols).eval()); storage_->assign(payload::data_type::Identity(rows, cols).eval());
} }
@ -329,21 +329,21 @@ void CLASSNAME::setIdentity(Index rows, Index cols)
//============================================================================== //==============================================================================
// Static functions // Static functions
//============================================================================== //==============================================================================
CLASSNAME CLASSNAME::Ones(Index rows, Index cols) CLASSNAME CLASSNAME::_Ones(Index rows, Index cols)
{ {
CLASSNAME m; CLASSNAME m;
m.storage_ = std::make_unique<payload>(payload::data_type::Ones(rows, cols)); m.storage_ = std::make_unique<payload>(payload::data_type::Ones(rows, cols));
return m; return m;
} }
CLASSNAME CLASSNAME::Zero(Index rows, Index cols) CLASSNAME CLASSNAME::_Zero(Index rows, Index cols)
{ {
CLASSNAME m; CLASSNAME m;
m.storage_ = std::make_unique<payload>(payload::data_type::Zero(rows, cols)); m.storage_ = std::make_unique<payload>(payload::data_type::Zero(rows, cols));
return m; return m;
} }
CLASSNAME CLASSNAME::Constant(Index rows, Index cols, TYPE value) CLASSNAME CLASSNAME::_Constant(Index rows, Index cols, TYPE value)
{ {
CLASSNAME m; CLASSNAME m;
m.storage_ = m.storage_ =
@ -351,7 +351,7 @@ CLASSNAME CLASSNAME::Constant(Index rows, Index cols, TYPE value)
return m; return m;
} }
CLASSNAME CLASSNAME::Random(Index rows, Index cols) CLASSNAME CLASSNAME::_Random(Index rows, Index cols)
{ {
CLASSNAME m; CLASSNAME m;
m.storage_ = m.storage_ =
@ -359,7 +359,7 @@ CLASSNAME CLASSNAME::Random(Index rows, Index cols)
return m; return m;
} }
CLASSNAME CLASSNAME::Identity(Index rows, Index cols) CLASSNAME CLASSNAME::_Identity(Index rows, Index cols)
{ {
CLASSNAME m; CLASSNAME m;
m.storage_ = m.storage_ =

View file

@ -14,34 +14,34 @@ TTS_CASE_TPL("Chains of extraction", rotgen::tests::types)
<typename T, typename O>(tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
constexpr int N = 8; constexpr int N = 8;
auto a = rotgen::matrix<T, N, N, O::value>::Random(); auto a = rotgen::setRandom<rotgen::matrix<T, N, N, O::value>>();
auto b = topLeftCorner(a, 5, 5); auto b = topLeftCorner(a, 5, 5);
TTS_EQUAL(b.startRow(), 0); TTS_EQUAL(startRow(b), 0);
TTS_EQUAL(b.startCol(), 0); TTS_EQUAL(startCol(b), 0);
setConstant(b, -7); setConstant(b, -7);
for (rotgen::Index r = 0; r < 5; r++) for (rotgen::Index r = 0; r < 5; r++)
for (rotgen::Index c = 0; c < 5; c++) TTS_EQUAL(a(r, c), -7); for (rotgen::Index c = 0; c < 5; c++) TTS_EQUAL(a(r, c), -7);
auto bb = bottomRightCorner(b, 3, 3); auto bb = bottomRightCorner(b, 3, 3);
TTS_EQUAL(bb.startRow(), 2); TTS_EQUAL(startRow(bb), 2);
TTS_EQUAL(bb.startCol(), 2); TTS_EQUAL(startCol(bb), 2);
setConstant(bb, 42); setConstant(bb, 42);
for (rotgen::Index r = 2; r < 5; r++) for (rotgen::Index r = 2; r < 5; r++)
for (rotgen::Index c = 2; c < 5; c++) TTS_EQUAL(a(r, c), 42); for (rotgen::Index c = 2; c < 5; c++) TTS_EQUAL(a(r, c), 42);
auto bbb = row(bb, 1); auto bbb = row(bb, 1);
TTS_EQUAL(bbb.startRow(), 1); TTS_EQUAL(startRow(bbb), 1);
TTS_EQUAL(bbb.startCol(), 0); TTS_EQUAL(startCol(bbb), 0);
setConstant(bbb, 99.5); setConstant(bbb, 99.5);
for (rotgen::Index c = 3; c < 5; c++) TTS_EQUAL(a(3, c), 99.5); for (rotgen::Index c = 3; c < 5; c++) TTS_EQUAL(a(3, c), 99.5);
auto bbbb = col(bbb, 1); auto bbbb = col(bbb, 1);
TTS_EQUAL(bbbb.startRow(), 0); TTS_EQUAL(startRow(bbbb), 0);
TTS_EQUAL(bbbb.startCol(), 1); TTS_EQUAL(startCol(bbbb), 1);
setConstant(bbbb, 0.125); setConstant(bbbb, 0.125);
TTS_EQUAL(a(3, 3), 0.125); TTS_EQUAL(a(3, 3), 0.125);
@ -77,3 +77,39 @@ TTS_CASE("Extraction of ref/ref const")
for (rotgen::Index r = 0; r < 4; r++) for (rotgen::Index r = 0; r < 4; r++)
for (rotgen::Index c = 0; c < 3; c++) TTS_EQUAL(sliced(r, c), 5.f); for (rotgen::Index c = 0; c < 3; c++) TTS_EQUAL(sliced(r, c), 5.f);
}; };
void process_col(rotgen::matrix<float, 3, 4>& m,
rotgen::matrix<float, 3, 1> const& n,
int c)
{
col(m, c) += n;
}
TTS_CASE("Compound operators on extractions")
{
rotgen::matrix<float, 3, 4> m;
rotgen::matrix<float, 3, 4> reference;
rotgen::matrix<float, 3, 1> n;
setZero(m);
setConstant(n, 10);
setConstant(reference, 10);
for (int i = 0; i < cols(m); i++) process_col(m, n, i);
TTS_EQUAL(m, reference);
};
TTS_CASE("Compatibility of 1D blocks")
{
rotgen::matrix<float, 4, 2> V;
setConstant(V, 99);
rotgen::matrix<float, 3, 1> C{12, 34, 56};
extract<1, 2>(V, 0, 0) = segment<2>(C, 0);
extract<2, 1>(V, 1, 0) = segment<2>(C, 1);
TTS_EQUAL(V(0, 0), C(0));
TTS_EQUAL(V(0, 1), C(1));
TTS_EQUAL(V(1, 0), C(1));
TTS_EQUAL(V(2, 0), C(2));
};

View file

@ -0,0 +1,123 @@
//==================================================================================================
/*
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>
TTS_CASE_TPL("Initialize a matrix with a list of scalars", rotgen::tests::types)
<typename T, typename O>(tts::type<tts::types<T, O>>)
{
using eigen_t = Eigen::Matrix<T, -1, -1, O::value>;
using rotgen_t = rotgen::matrix<T, -1, -1, O::value>;
eigen_t reference(3, 3);
reference << 1, 2, 3, 4, 5, 6, 7, 8, 9;
rotgen_t values(3, 3);
initialize_with(values, 1, 2, 3, 4, 5, 6, 7, 8, 9);
for (int r = 0; r < 3; r++)
for (int c = 0; c < 3; c++) TTS_EQUAL(values(r, c), reference(r, c));
};
TTS_CASE_TPL("Initialize a sub-matrix with a list of scalars",
rotgen::tests::types)
<typename T, typename O>(tts::type<tts::types<T, O>>)
{
using eigen_t = Eigen::Matrix<T, -1, -1, O::value>;
using rotgen_t = rotgen::matrix<T, -1, -1, O::value>;
eigen_t reference(6, 6);
reference.block(1, 1, 3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9;
rotgen_t values(6, 6);
initialize_with(extract(values, 1, 1, 3, 3), 1, 2, 3, 4, 5, 6, 7, 8, 9);
for (int r = 0; r < 3; r++)
for (int c = 0; c < 3; c++)
TTS_EQUAL(values(r + 1, c + 1), reference(r + 1, c + 1));
};
TTS_CASE_TPL("Initialize a map with a list of scalars", rotgen::tests::types)
<typename T, typename O>(tts::type<tts::types<T, O>>)
{
using eigen_t = Eigen::Matrix<T, -1, -1, O::value>;
using rotgen_t = rotgen::matrix<T, -1, -1, O::value>;
T eigen_data[9] = {};
T rotgen_data[9] = {};
Eigen::Map<eigen_t> reference(eigen_data, 3, 3);
reference << 1, 2, 3, 4, 5, 6, 7, 8, 9;
rotgen::map<rotgen_t> values(rotgen_data, 3, 3);
initialize_with(values, 1, 2, 3, 4, 5, 6, 7, 8, 9);
for (int i = 0; i < 9; i++) TTS_EQUAL(eigen_data[i], rotgen_data[i]);
};
TTS_CASE_TPL("Initialize a sub-map with a list of scalars",
rotgen::tests::types)
<typename T, typename O>(tts::type<tts::types<T, O>>)
{
using eigen_t = Eigen::Matrix<T, -1, -1, O::value>;
using rotgen_t = rotgen::matrix<T, -1, -1, O::value>;
T eigen_data[36] = {};
T rotgen_data[36] = {};
Eigen::Map<eigen_t> reference(eigen_data, 6, 6);
reference.block(1, 1, 3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9;
rotgen::map<rotgen_t> values(rotgen_data, 6, 6);
initialize_with(extract(values, 1, 1, 3, 3), 1, 2, 3, 4, 5, 6, 7, 8, 9);
for (int i = 0; i < 9; i++) TTS_EQUAL(eigen_data[i], rotgen_data[i]);
};
void process(rotgen::ref<rotgen::matrixXf> r)
{
rotgen::initialize_with(r, 1, 2, 3, 4, 5, 6, 7, 8, 9);
}
void process(rotgen::ref<rotgen::matrixXd> r)
{
rotgen::initialize_with(r, 1, 2, 3, 4, 5, 6, 7, 8, 9);
}
void process(rotgen::ref<rotgen::matrix<float, -1, -1, rotgen::RowMajor>> r)
{
rotgen::initialize_with(r, 1, 2, 3, 4, 5, 6, 7, 8, 9);
}
void process(rotgen::ref<rotgen::matrix<double, -1, -1, rotgen::RowMajor>> r)
{
rotgen::initialize_with(r, 1, 2, 3, 4, 5, 6, 7, 8, 9);
}
TTS_CASE_TPL("Initialize a ref with a list of scalars", rotgen::tests::types)
<typename T, typename O>(tts::type<tts::types<T, O>>)
{
using eigen_t = Eigen::Matrix<T, -1, -1, O::value>;
using rotgen_t = rotgen::matrix<T, -1, -1, O::value>;
eigen_t reference(3, 3);
reference << 1, 2, 3, 4, 5, 6, 7, 8, 9;
rotgen_t values(3, 3);
process(values);
for (int r = 0; r < 3; r++)
for (int c = 0; c < 3; c++) TTS_EQUAL(values(r, c), reference(r, c));
};

View file

@ -10,29 +10,29 @@
#include "unit/tests.hpp" #include "unit/tests.hpp"
#include <iostream> #include <iostream>
TTS_CASE_TPL("outer_stride<0> interactions", TTS_CASE_TPL("outer_stride<0> interactions", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>; using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
T contiguous[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; T contiguous[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
rotgen::map<mat_t, 0, rotgen::outer_stride<0>> m(&contiguous[0], 4, 3); rotgen::map<mat_t, 0, rotgen::outer_stride<0>> m(&contiguous[0], 4, 3);
TTS_EQUAL(m.innerStride(), 1); TTS_EQUAL(innerStride(m), 1);
TTS_EQUAL(m.outerStride(), O::value == rotgen::ColMajor ? 4 : 3); TTS_EQUAL(outerStride(m), O::value == rotgen::ColMajor ? 4 : 3);
if constexpr (O::value == rotgen::ColMajor) if constexpr (O::value == rotgen::ColMajor)
{ {
T padded[] = {1, 2, 3, 4, 99, 5, 6, 7, 8, 99, 9, 10, 11, 12}; 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<5>> sp(&padded[0], 4, 3);
TTS_EQUAL(sp.innerStride(), 1); TTS_EQUAL(innerStride(sp), 1);
TTS_EQUAL(sp.outerStride(), 5); TTS_EQUAL(outerStride(sp), 5);
rotgen::map<mat_t, 0, rotgen::outer_stride<>> dp(&padded[0], 4, 3, rotgen::map<mat_t, 0, rotgen::outer_stride<>> dp(&padded[0], 4, 3,
rotgen::outer_stride(5)); rotgen::outer_stride(5));
TTS_EQUAL(dp.innerStride(), 1); TTS_EQUAL(innerStride(dp), 1);
TTS_EQUAL(dp.outerStride(), 5); TTS_EQUAL(outerStride(dp), 5);
TTS_EQUAL(m, sp); TTS_EQUAL(m, sp);
TTS_EQUAL(m, dp); TTS_EQUAL(m, dp);
@ -42,13 +42,13 @@ TTS_CASE_TPL("outer_stride<0> interactions",
{ {
T padded[] = {1, 2, 3, 99, 4, 5, 6, 99, 7, 8, 9, 99, 10, 11, 12}; 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<4>> sp(&padded[0], 4, 3);
TTS_EQUAL(sp.innerStride(), 1); TTS_EQUAL(innerStride(sp), 1);
TTS_EQUAL(sp.outerStride(), 4); TTS_EQUAL(outerStride(sp), 4);
rotgen::map<mat_t, 0, rotgen::outer_stride<>> dp(&padded[0], 4, 3, rotgen::map<mat_t, 0, rotgen::outer_stride<>> dp(&padded[0], 4, 3,
rotgen::outer_stride(4)); rotgen::outer_stride(4));
TTS_EQUAL(dp.innerStride(), 1); TTS_EQUAL(innerStride(dp), 1);
TTS_EQUAL(dp.outerStride(), 4); TTS_EQUAL(outerStride(dp), 4);
TTS_EQUAL(m, sp); TTS_EQUAL(m, sp);
TTS_EQUAL(m, dp); TTS_EQUAL(m, dp);

View file

@ -48,9 +48,9 @@ auto process(column_ref<> v)
TTS_CASE("Reference of reference check") TTS_CASE("Reference of reference check")
{ {
auto v1 = rotgen::matrix<float, 1, 1>::Ones(); auto v1 = rotgen::setOnes<rotgen::matrix<float, 1, 1>>();
auto v2 = rotgen::matrix<float, 2, 1>::Random(); auto v2 = rotgen::setRandom<rotgen::matrix<float, 2, 1>>();
auto v3 = rotgen::matrix<float, 3, 1>::Constant(6.66); auto v3 = rotgen::setConstant<rotgen::matrix<float, 3, 1>>(6.66);
auto sum1 = v1(0); auto sum1 = v1(0);
auto sum2 = v2(0) + v2(1); auto sum2 = v2(0) + v2(1);

View file

@ -0,0 +1,50 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#include <rotgen/rotgen.hpp>
#include "unit/tests.hpp"
bool categorize_as_scalar(double)
{
return true;
}
bool categorize_as_scalar(rotgen::ref<rotgen::matrix<double, 1, 1>>)
{
return false;
}
TTS_CASE("Matrix product of 1xN by Nx1 yields a scalar-convertible object")
{
rotgen::matrix<double, 1, 2> a = {1, 2};
rotgen::matrix<double, 2, 1> b = {10, 20};
double n = a * b;
TTS_EQUAL(n, 50);
TTS_EXPECT(categorize_as_scalar(a * b));
};
TTS_CASE_TPL("Static 1x1 matrix-like objects can be assigned as-if",
rotgen::tests::types)
<typename T, typename O>(tts::type<tts::types<T, O>>)
{
rotgen::matrix<T, 1, 2> a = {1, 2};
rotgen::matrix<T, 2, 1> b = {10, 20};
rotgen::matrix<T, -1, -1, O::value> big(10, 10);
auto bk = extract<1, 1>(big, 2, 2);
bk = a * b;
TTS_EQUAL(big(2, 2), 50);
rotgen::map<rotgen::matrix<T, 1, 1, O::value>> big_map(big.data(), 1, 1);
big_map = a * b;
TTS_EQUAL(big(0, 0), 50);
};

View file

@ -18,8 +18,9 @@ void fill(auto& m, int r, int c, auto data[])
for (int k = 0; k < r * c; ++k) m.data()[k] = data[k]; for (int k = 0; k < r * c; ++k) m.data()[k] = data[k];
} }
TTS_CASE_TPL("Function size", rotgen::tests::types)<typename T, typename O>( TTS_CASE_TPL("Function size", rotgen::tests::types)
tts::type<tts::types<T, O>>)
<typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
T data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; T data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
@ -28,44 +29,44 @@ TTS_CASE_TPL("Function size", rotgen::tests::types)<typename T, typename O>(
fill(dm, 1, 12, data); fill(dm, 1, 12, data);
auto b1 = rotgen::block<decltype(dm), rotgen::Dynamic, rotgen::Dynamic>( auto b1 = rotgen::block<decltype(dm), rotgen::Dynamic, rotgen::Dynamic>(
dm, 0, 0, 1, 12); dm, 0, 0, 1, 12);
TTS_EQUAL(b1.rows(), rotgen::Index{1}); TTS_EQUAL(rows(b1), rotgen::Index{1});
TTS_EQUAL(b1.cols(), rotgen::Index{12}); TTS_EQUAL(cols(b1), rotgen::Index{12});
// 1x5 dynamic block at (0,2) // 1x5 dynamic block at (0,2)
auto b2 = rotgen::block<decltype(dm), rotgen::Dynamic, rotgen::Dynamic>( auto b2 = rotgen::block<decltype(dm), rotgen::Dynamic, rotgen::Dynamic>(
dm, 0, 2, 1, 5); dm, 0, 2, 1, 5);
TTS_EQUAL(b2.rows(), rotgen::Index{1}); TTS_EQUAL(rows(b2), rotgen::Index{1});
TTS_EQUAL(b2.cols(), rotgen::Index{5}); TTS_EQUAL(cols(b2), rotgen::Index{5});
// 3x2 dynamic block at (1,4) in 4x6 // 3x2 dynamic block at (1,4) in 4x6
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> dm2(4, 6); rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> dm2(4, 6);
fill(dm2, 4, 6, data); fill(dm2, 4, 6, data);
auto b3 = rotgen::block<decltype(dm2), rotgen::Dynamic, rotgen::Dynamic>( auto b3 = rotgen::block<decltype(dm2), rotgen::Dynamic, rotgen::Dynamic>(
dm2, 1, 4, 3, 2); dm2, 1, 4, 3, 2);
TTS_EQUAL(b3.rows(), rotgen::Index{3}); TTS_EQUAL(rows(b3), rotgen::Index{3});
TTS_EQUAL(b3.cols(), rotgen::Index{2}); TTS_EQUAL(cols(b3), rotgen::Index{2});
TTS_EQUAL(b3.size(), rotgen::Index{6}); TTS_EQUAL(b3.size(), rotgen::Index{6});
// 3x4 static block // 3x4 static block
rotgen::matrix<T, 3, 4, O::value> sm; rotgen::matrix<T, 3, 4, O::value> sm;
fill(sm, 3, 4, data); fill(sm, 3, 4, data);
auto b4 = rotgen::block<decltype(sm), 3, 4>(sm, 0, 0); auto b4 = rotgen::block<decltype(sm), 3, 4>(sm, 0, 0);
TTS_EQUAL(b4.rows(), rotgen::Index{3}); TTS_EQUAL(rows(b4), rotgen::Index{3});
TTS_EQUAL(b4.cols(), rotgen::Index{4}); TTS_EQUAL(cols(b4), rotgen::Index{4});
TTS_EQUAL(b4.size(), rotgen::Index{12}); TTS_EQUAL(b4.size(), rotgen::Index{12});
// 6x2 static block // 6x2 static block
rotgen::matrix<T, 6, 2, O::value> sm2; rotgen::matrix<T, 6, 2, O::value> sm2;
fill(sm2, 6, 2, data); fill(sm2, 6, 2, data);
auto b5 = rotgen::block<decltype(sm2), 6, 2>(sm2, 0, 0); auto b5 = rotgen::block<decltype(sm2), 6, 2>(sm2, 0, 0);
TTS_EQUAL(b5.rows(), rotgen::Index{6}); TTS_EQUAL(rows(b5), rotgen::Index{6});
TTS_EQUAL(b5.cols(), rotgen::Index{2}); TTS_EQUAL(cols(b5), rotgen::Index{2});
TTS_EQUAL(b5.size(), rotgen::Index{12}); TTS_EQUAL(b5.size(), rotgen::Index{12});
}; };
TTS_CASE_TPL("Test coefficient accessors", TTS_CASE_TPL("Test coefficient accessors", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
using base = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>; using base = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
@ -92,9 +93,9 @@ TTS_CASE_TPL("Test coefficient accessors",
TTS_EQUAL(b(2, 2), 17); TTS_EQUAL(b(2, 2), 17);
}; };
TTS_CASE_TPL("Test one index coefficient accessors", TTS_CASE_TPL("Test one index coefficient accessors", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto vs = [&]() { auto vs = [&]() {
if constexpr (O::value == rotgen::ColMajor) if constexpr (O::value == rotgen::ColMajor)

View file

@ -13,15 +13,15 @@
template<typename EigenType, typename F> template<typename EigenType, typename F>
void for_each_element(EigenType const& m, F&& f) void for_each_element(EigenType const& m, F&& f)
{ {
for (rotgen::Index i = 0; i < m.rows(); ++i) for (rotgen::Index i = 0; i < rows(m); ++i)
for (rotgen::Index j = 0; j < m.cols(); ++j) f(i, j, m(i, j)); for (rotgen::Index j = 0; j < cols(m); ++j) f(i, j, m(i, j));
} }
template<typename EigenType, typename F> template<typename EigenType, typename F>
void for_each_element(EigenType& m, F&& f) void for_each_element(EigenType& m, F&& f)
{ {
for (rotgen::Index i = 0; i < m.rows(); ++i) for (rotgen::Index i = 0; i < rows(m); ++i)
for (rotgen::Index j = 0; j < m.cols(); ++j) f(i, j, m(i, j)); for (rotgen::Index j = 0; j < cols(m); ++j) f(i, j, m(i, j));
} }
template<typename MatrixType, typename T> template<typename MatrixType, typename T>
@ -53,8 +53,8 @@ void validate_block_behavior(MatrixType& matrix,
rotgen::Index block_n) rotgen::Index block_n)
{ {
using T = typename MatrixType::value_type; using T = typename MatrixType::value_type;
TTS_EQUAL(block.rows(), block_m); TTS_EQUAL(rows(block), block_m);
TTS_EQUAL(block.cols(), block_n); TTS_EQUAL(cols(block), block_n);
TTS_EQUAL(block.size(), block_m * block_n); TTS_EQUAL(block.size(), block_m * block_n);
// test block values // test block values
@ -144,31 +144,31 @@ void test_dynamic_block_extraction(
std::make_tuple(c_block_top_left_corner, 0, 0, matrix_construct.ni, std::make_tuple(c_block_top_left_corner, 0, 0, matrix_construct.ni,
matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic), matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic),
std::make_tuple(c_block_top_right_corner, 0, std::make_tuple(c_block_top_right_corner, 0,
matrix.cols() - matrix_construct.nj, matrix_construct.ni, cols(matrix) - matrix_construct.nj, matrix_construct.ni,
matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic), matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic),
std::make_tuple(c_block_bottom_left_corner, std::make_tuple(c_block_bottom_left_corner,
matrix.rows() - matrix_construct.ni, 0, matrix_construct.ni, rows(matrix) - matrix_construct.ni, 0, matrix_construct.ni,
matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic), matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic),
std::make_tuple(c_block_bottom_right_corner, std::make_tuple(c_block_bottom_right_corner,
matrix.rows() - matrix_construct.ni, rows(matrix) - matrix_construct.ni,
matrix.cols() - matrix_construct.nj, matrix_construct.ni, cols(matrix) - matrix_construct.nj, matrix_construct.ni,
matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic), 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, cols(matrix),
rotgen::Dynamic, MatrixType::ColsAtCompileTime), rotgen::Dynamic, MatrixType::ColsAtCompileTime),
std::make_tuple(c_block_middle_rows, matrix_construct.i0, 0, std::make_tuple(c_block_middle_rows, matrix_construct.i0, 0,
matrix_construct.ni, matrix.cols(), rotgen::Dynamic, matrix_construct.ni, cols(matrix), rotgen::Dynamic,
MatrixType::ColsAtCompileTime), MatrixType::ColsAtCompileTime),
std::make_tuple(c_block_bottom_rows, matrix.rows() - matrix_construct.ni, 0, std::make_tuple(c_block_bottom_rows, rows(matrix) - matrix_construct.ni, 0,
matrix_construct.ni, matrix.cols(), rotgen::Dynamic, matrix_construct.ni, cols(matrix), rotgen::Dynamic,
MatrixType::ColsAtCompileTime), MatrixType::ColsAtCompileTime),
std::make_tuple(c_block_left_cols, 0, 0, matrix.rows(), matrix_construct.nj, std::make_tuple(c_block_left_cols, 0, 0, rows(matrix), matrix_construct.nj,
MatrixType::RowsAtCompileTime, rotgen::Dynamic), MatrixType::RowsAtCompileTime, rotgen::Dynamic),
std::make_tuple(c_block_middle_cols, 0, matrix_construct.j0, matrix.rows(), std::make_tuple(c_block_middle_cols, 0, matrix_construct.j0, rows(matrix),
matrix_construct.nj, MatrixType::RowsAtCompileTime, matrix_construct.nj, MatrixType::RowsAtCompileTime,
rotgen::Dynamic), rotgen::Dynamic),
std::make_tuple(c_block_right_cols, 0, matrix.cols() - matrix_construct.nj, std::make_tuple(c_block_right_cols, 0, cols(matrix) - matrix_construct.nj,
matrix.rows(), matrix_construct.nj, rows(matrix), matrix_construct.nj,
MatrixType::RowsAtCompileTime, rotgen::Dynamic), MatrixType::RowsAtCompileTime, rotgen::Dynamic),
// --- REGULAR TESTS // --- REGULAR TESTS
@ -178,31 +178,31 @@ void test_dynamic_block_extraction(
std::make_tuple(block_top_left_corner, 0, 0, matrix_construct.ni, std::make_tuple(block_top_left_corner, 0, 0, matrix_construct.ni,
matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic), matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic),
std::make_tuple(block_top_right_corner, 0, std::make_tuple(block_top_right_corner, 0,
matrix.cols() - matrix_construct.nj, matrix_construct.ni, cols(matrix) - matrix_construct.nj, matrix_construct.ni,
matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic), matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic),
std::make_tuple(block_bottom_left_corner, std::make_tuple(block_bottom_left_corner,
matrix.rows() - matrix_construct.ni, 0, matrix_construct.ni, rows(matrix) - matrix_construct.ni, 0, matrix_construct.ni,
matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic), matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic),
std::make_tuple(block_bottom_right_corner, std::make_tuple(block_bottom_right_corner,
matrix.rows() - matrix_construct.ni, rows(matrix) - matrix_construct.ni,
matrix.cols() - matrix_construct.nj, matrix_construct.ni, cols(matrix) - matrix_construct.nj, matrix_construct.ni,
matrix_construct.nj, rotgen::Dynamic, rotgen::Dynamic), 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, cols(matrix),
rotgen::Dynamic, MatrixType::ColsAtCompileTime), rotgen::Dynamic, MatrixType::ColsAtCompileTime),
std::make_tuple(block_middle_rows, matrix_construct.i0, 0, std::make_tuple(block_middle_rows, matrix_construct.i0, 0,
matrix_construct.ni, matrix.cols(), rotgen::Dynamic, matrix_construct.ni, cols(matrix), rotgen::Dynamic,
MatrixType::ColsAtCompileTime), MatrixType::ColsAtCompileTime),
std::make_tuple(block_bottom_rows, matrix.rows() - matrix_construct.ni, 0, std::make_tuple(block_bottom_rows, rows(matrix) - matrix_construct.ni, 0,
matrix_construct.ni, matrix.cols(), rotgen::Dynamic, matrix_construct.ni, cols(matrix), rotgen::Dynamic,
MatrixType::ColsAtCompileTime), MatrixType::ColsAtCompileTime),
std::make_tuple(block_left_cols, 0, 0, matrix.rows(), matrix_construct.nj, std::make_tuple(block_left_cols, 0, 0, rows(matrix), matrix_construct.nj,
MatrixType::RowsAtCompileTime, rotgen::Dynamic), MatrixType::RowsAtCompileTime, rotgen::Dynamic),
std::make_tuple(block_middle_cols, 0, matrix_construct.j0, matrix.rows(), std::make_tuple(block_middle_cols, 0, matrix_construct.j0, rows(matrix),
matrix_construct.nj, MatrixType::RowsAtCompileTime, matrix_construct.nj, MatrixType::RowsAtCompileTime,
rotgen::Dynamic), rotgen::Dynamic),
std::make_tuple(block_right_cols, 0, matrix.cols() - matrix_construct.nj, std::make_tuple(block_right_cols, 0, cols(matrix) - matrix_construct.nj,
matrix.rows(), matrix_construct.nj, rows(matrix), matrix_construct.nj,
MatrixType::RowsAtCompileTime, rotgen::Dynamic)); MatrixType::RowsAtCompileTime, rotgen::Dynamic));
std::apply( std::apply(
@ -276,68 +276,68 @@ void test_static_block_extraction(
std::make_tuple(c_block_top_left_corner, 0, 0, matrix_construct.ni, std::make_tuple(c_block_top_left_corner, 0, 0, matrix_construct.ni,
matrix_construct.nj, int(NI), int(NJ)), matrix_construct.nj, int(NI), int(NJ)),
std::make_tuple(c_block_top_right_corner, 0, std::make_tuple(c_block_top_right_corner, 0,
matrix.cols() - matrix_construct.nj, matrix_construct.ni, cols(matrix) - matrix_construct.nj, matrix_construct.ni,
matrix_construct.nj, int(NI), int(NJ)), matrix_construct.nj, int(NI), int(NJ)),
std::make_tuple(c_block_bottom_left_corner, std::make_tuple(c_block_bottom_left_corner,
matrix.rows() - matrix_construct.ni, 0, matrix_construct.ni, rows(matrix) - matrix_construct.ni, 0, matrix_construct.ni,
matrix_construct.nj, int(NI), int(NJ)), matrix_construct.nj, int(NI), int(NJ)),
std::make_tuple(c_block_bottom_right_corner, std::make_tuple(c_block_bottom_right_corner,
matrix.rows() - matrix_construct.ni, rows(matrix) - matrix_construct.ni,
matrix.cols() - matrix_construct.nj, matrix_construct.ni, cols(matrix) - matrix_construct.nj, matrix_construct.ni,
matrix_construct.nj, int(NI), int(NJ)), matrix_construct.nj, int(NI), int(NJ)),
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, cols(matrix),
int(NI), rotgen::Dynamic), int(NI), rotgen::Dynamic),
std::make_tuple(c_block_middle_rows, i0, 0, matrix_construct.ni, std::make_tuple(c_block_middle_rows, i0, 0, matrix_construct.ni,
matrix.cols(), int(NI), rotgen::Dynamic), cols(matrix), int(NI), rotgen::Dynamic),
std::make_tuple(c_block_bottom_rows, matrix.rows() - matrix_construct.ni, 0, std::make_tuple(c_block_bottom_rows, rows(matrix) - matrix_construct.ni, 0,
matrix_construct.ni, matrix.cols(), int(NI), matrix_construct.ni, cols(matrix), int(NI),
rotgen::Dynamic), rotgen::Dynamic),
std::make_tuple(c_block_left_cols, 0, 0, matrix.rows(), matrix_construct.nj, std::make_tuple(c_block_left_cols, 0, 0, rows(matrix), matrix_construct.nj,
rotgen::Dynamic, int(NJ)), rotgen::Dynamic, int(NJ)),
std::make_tuple(c_block_middle_cols, 0, j0, matrix.rows(), std::make_tuple(c_block_middle_cols, 0, j0, rows(matrix),
matrix_construct.nj, rotgen::Dynamic, int(NJ)), matrix_construct.nj, rotgen::Dynamic, int(NJ)),
std::make_tuple(c_block_right_cols, 0, matrix.cols() - matrix_construct.nj, std::make_tuple(c_block_right_cols, 0, cols(matrix) - matrix_construct.nj,
matrix.rows(), matrix_construct.nj, rotgen::Dynamic, rows(matrix), matrix_construct.nj, rotgen::Dynamic,
int(NJ)), int(NJ)),
std::make_tuple(c_block_row, i0, 0, 1, matrix.cols(), 1, rotgen::Dynamic), std::make_tuple(c_block_row, i0, 0, 1, cols(matrix), 1, rotgen::Dynamic),
std::make_tuple(c_block_col, 0, j0, matrix.rows(), 1, rotgen::Dynamic, 1), std::make_tuple(c_block_col, 0, j0, rows(matrix), 1, rotgen::Dynamic, 1),
// -- Block to NON CONST // -- Block to NON CONST
std::make_tuple(block_main, i0, j0, matrix_construct.ni, std::make_tuple(block_main, i0, j0, matrix_construct.ni,
matrix_construct.nj, int(NI), int(NJ)), matrix_construct.nj, int(NI), int(NJ)),
std::make_tuple(block_top_left_corner, 0, 0, matrix_construct.ni, std::make_tuple(block_top_left_corner, 0, 0, matrix_construct.ni,
matrix_construct.nj, int(NI), int(NJ)), matrix_construct.nj, int(NI), int(NJ)),
std::make_tuple(block_top_right_corner, 0, std::make_tuple(block_top_right_corner, 0,
matrix.cols() - matrix_construct.nj, matrix_construct.ni, cols(matrix) - matrix_construct.nj, matrix_construct.ni,
matrix_construct.nj, int(NI), int(NJ)), matrix_construct.nj, int(NI), int(NJ)),
std::make_tuple(block_bottom_left_corner, std::make_tuple(block_bottom_left_corner,
matrix.rows() - matrix_construct.ni, 0, matrix_construct.ni, rows(matrix) - matrix_construct.ni, 0, matrix_construct.ni,
matrix_construct.nj, int(NI), int(NJ)), matrix_construct.nj, int(NI), int(NJ)),
std::make_tuple(block_bottom_right_corner, std::make_tuple(block_bottom_right_corner,
matrix.rows() - matrix_construct.ni, rows(matrix) - matrix_construct.ni,
matrix.cols() - matrix_construct.nj, matrix_construct.ni, cols(matrix) - matrix_construct.nj, matrix_construct.ni,
matrix_construct.nj, int(NI), int(NJ)), matrix_construct.nj, int(NI), int(NJ)),
std::make_tuple(block_top_rows, 0, 0, matrix_construct.ni, matrix.cols(), std::make_tuple(block_top_rows, 0, 0, matrix_construct.ni, cols(matrix),
int(NI), rotgen::Dynamic), int(NI), rotgen::Dynamic),
std::make_tuple(block_middle_rows, i0, 0, matrix_construct.ni, std::make_tuple(block_middle_rows, i0, 0, matrix_construct.ni, cols(matrix),
matrix.cols(), int(NI), rotgen::Dynamic), int(NI), rotgen::Dynamic),
std::make_tuple(block_bottom_rows, matrix.rows() - matrix_construct.ni, 0, std::make_tuple(block_bottom_rows, rows(matrix) - matrix_construct.ni, 0,
matrix_construct.ni, matrix.cols(), int(NI), matrix_construct.ni, cols(matrix), int(NI),
rotgen::Dynamic), rotgen::Dynamic),
std::make_tuple(block_left_cols, 0, 0, matrix.rows(), matrix_construct.nj, std::make_tuple(block_left_cols, 0, 0, rows(matrix), matrix_construct.nj,
rotgen::Dynamic, int(NJ)), rotgen::Dynamic, int(NJ)),
std::make_tuple(block_middle_cols, 0, j0, matrix.rows(), std::make_tuple(block_middle_cols, 0, j0, rows(matrix), matrix_construct.nj,
matrix_construct.nj, rotgen::Dynamic, int(NJ)), rotgen::Dynamic, int(NJ)),
std::make_tuple(block_right_cols, 0, matrix.cols() - matrix_construct.nj, std::make_tuple(block_right_cols, 0, cols(matrix) - matrix_construct.nj,
matrix.rows(), matrix_construct.nj, rotgen::Dynamic, rows(matrix), matrix_construct.nj, rotgen::Dynamic,
int(NJ)), int(NJ)),
std::make_tuple(block_row, i0, 0, 1, matrix.cols(), 1, rotgen::Dynamic), std::make_tuple(block_row, i0, 0, 1, cols(matrix), 1, rotgen::Dynamic),
std::make_tuple(block_col, 0, j0, matrix.rows(), 1, rotgen::Dynamic, 1)); std::make_tuple(block_col, 0, j0, rows(matrix), 1, rotgen::Dynamic, 1));
std::apply( std::apply(
[&](auto&&... block_entries) { [&](auto&&... block_entries) {
@ -358,7 +358,9 @@ void test_static_block_extraction(
TTS_CASE_TPL( TTS_CASE_TPL(
"Check all dynamic block extractions on a dynamic row-major matrix", "Check all dynamic block extractions on a dynamic row-major 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>>)
{ {
using mat_t = using mat_t =
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, rotgen::RowMajor>; rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, rotgen::RowMajor>;
@ -394,7 +396,9 @@ TTS_CASE_TPL(
TTS_CASE_TPL( TTS_CASE_TPL(
"Check all dynamic block extractions on a static column-major matrix", "Check all dynamic block extractions on a static column-major 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>>)
{ {
using mat_t = rotgen::matrix<T, 4, 5, rotgen::ColMajor>; using mat_t = rotgen::matrix<T, 4, 5, rotgen::ColMajor>;
@ -417,9 +421,9 @@ TTS_CASE_TPL(
} }
}; };
TTS_CASE_TPL("Check all static block extractions", TTS_CASE_TPL("Check all static block extractions", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>; using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
@ -446,9 +450,9 @@ TTS_CASE_TPL("Check all static block extractions",
0}); 0});
}; };
TTS_CASE_TPL("Check vector-only extractions", TTS_CASE_TPL("Check vector-only extractions", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto run_case = [](auto&& matrix, auto&& block, int i_offset, int j_offset, auto run_case = [](auto&& matrix, auto&& block, int i_offset, int j_offset,
int ni, int nj, auto const& rows_ct, auto const& cols_ct) { int ni, int nj, auto const& rows_ct, auto const& cols_ct) {

View file

@ -48,9 +48,9 @@ void test_random(auto const& matrix,
} }
} }
TTS_CASE_TPL("Test dynamic block::setZero", TTS_CASE_TPL("Test dynamic block::setZero", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_block_references<T, O>(); auto const cases = rotgen::tests::generate_block_references<T, O>();
for (auto const& [matrix_desc, i0, j0, ni, nj] : cases) for (auto const& [matrix_desc, i0, j0, ni, nj] : cases)
@ -64,14 +64,14 @@ TTS_CASE_TPL("Test dynamic block::setZero",
test_value(m, T{0}, i0, j0, ni, nj); test_value(m, T{0}, i0, j0, ni, nj);
using input_type = decltype(rotgen::extract(m, i0, j0, ni, nj)); using input_type = decltype(rotgen::extract(m, i0, j0, ni, nj));
auto values = input_type::Zero(ni, nj); auto values = rotgen::setZero<input_type>(ni, nj);
test_value(values, T{0}, 0, 0, ni, nj); test_value(values, T{0}, 0, 0, ni, nj);
} }
}; };
TTS_CASE_TPL("Test static block::setZero", TTS_CASE_TPL("Test static block::setZero", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_static_block_references<T, O>(); auto const cases = rotgen::tests::generate_static_block_references<T, O>();
@ -87,16 +87,16 @@ TTS_CASE_TPL("Test static block::setZero",
test_value(m, T{0}, i0, j0, D::ni, D::nj); test_value(m, T{0}, i0, j0, D::ni, D::nj);
using input_type = decltype(rotgen::extract<D::ni, D::nj>(m, i0, j0)); using input_type = decltype(rotgen::extract<D::ni, D::nj>(m, i0, j0));
auto values = input_type::Zero(); auto values = rotgen::setZero<input_type>();
test_value(values, T{0}, 0, 0, D::ni, D::nj); test_value(values, T{0}, 0, 0, D::ni, D::nj);
}; };
std::apply([&](auto const&... d) { (process(d), ...); }, cases); std::apply([&](auto const&... d) { (process(d), ...); }, cases);
}; };
TTS_CASE_TPL("Test dynamic block::setOnes", TTS_CASE_TPL("Test dynamic block::setOnes", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_block_references<T, O>(); auto const cases = rotgen::tests::generate_block_references<T, O>();
for (auto const& [matrix_desc, i0, j0, ni, nj] : cases) for (auto const& [matrix_desc, i0, j0, ni, nj] : cases)
@ -110,14 +110,14 @@ TTS_CASE_TPL("Test dynamic block::setOnes",
test_value(m, T{1}, i0, j0, ni, nj); test_value(m, T{1}, i0, j0, ni, nj);
using input_type = decltype(rotgen::extract(m, i0, j0, ni, nj)); using input_type = decltype(rotgen::extract(m, i0, j0, ni, nj));
auto values = input_type::Ones(ni, nj); auto values = rotgen::setOnes<input_type>(ni, nj);
test_value(values, T{1}, 0, 0, ni, nj); test_value(values, T{1}, 0, 0, ni, nj);
} }
}; };
TTS_CASE_TPL("Test static block::setOnes", TTS_CASE_TPL("Test static block::setOnes", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_static_block_references<T, O>(); auto const cases = rotgen::tests::generate_static_block_references<T, O>();
@ -133,16 +133,16 @@ TTS_CASE_TPL("Test static block::setOnes",
test_value(m, T{1}, i0, j0, D::ni, D::nj); test_value(m, T{1}, i0, j0, D::ni, D::nj);
using input_type = decltype(rotgen::extract<D::ni, D::nj>(m, i0, j0)); using input_type = decltype(rotgen::extract<D::ni, D::nj>(m, i0, j0));
auto values = input_type::Ones(); auto values = rotgen::setOnes<input_type>();
test_value(values, T{1}, 0, 0, D::ni, D::nj); test_value(values, T{1}, 0, 0, D::ni, D::nj);
}; };
std::apply([&](auto const&... d) { (process(d), ...); }, cases); std::apply([&](auto const&... d) { (process(d), ...); }, cases);
}; };
TTS_CASE_TPL("Test dynamic block::setConstant", TTS_CASE_TPL("Test dynamic block::setConstant", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_block_references<T, O>(); auto const cases = rotgen::tests::generate_block_references<T, O>();
for (auto const& [matrix_desc, i0, j0, ni, nj] : cases) for (auto const& [matrix_desc, i0, j0, ni, nj] : cases)
@ -156,14 +156,14 @@ TTS_CASE_TPL("Test dynamic block::setConstant",
test_value(m, T{13.37f}, i0, j0, ni, nj); test_value(m, T{13.37f}, i0, j0, ni, nj);
using input_type = decltype(rotgen::extract(m, i0, j0, ni, nj)); using input_type = decltype(rotgen::extract(m, i0, j0, ni, nj));
auto values = input_type::Constant(ni, nj, T{13.37f}); auto values = rotgen::setConstant<input_type>(ni, nj, T{13.37f});
test_value(values, T{13.37f}, 0, 0, ni, nj); test_value(values, T{13.37f}, 0, 0, ni, nj);
} }
}; };
TTS_CASE_TPL("Test static block::setConstant", TTS_CASE_TPL("Test static block::setConstant", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_static_block_references<T, O>(); auto const cases = rotgen::tests::generate_static_block_references<T, O>();
@ -179,16 +179,16 @@ TTS_CASE_TPL("Test static block::setConstant",
test_value(m, T{13.37f}, i0, j0, D::ni, D::nj); test_value(m, T{13.37f}, i0, j0, D::ni, D::nj);
using input_type = decltype(rotgen::extract<D::ni, D::nj>(m, i0, j0)); using input_type = decltype(rotgen::extract<D::ni, D::nj>(m, i0, j0));
auto values = input_type::Constant(T{13.37f}); auto values = rotgen::setConstant<input_type>(T{13.37f});
test_value(values, T{13.37f}, 0, 0, D::ni, D::nj); test_value(values, T{13.37f}, 0, 0, D::ni, D::nj);
}; };
std::apply([&](auto const&... d) { (process(d), ...); }, cases); std::apply([&](auto const&... d) { (process(d), ...); }, cases);
}; };
TTS_CASE_TPL("Test dynamic block::setIdentity", TTS_CASE_TPL("Test dynamic block::setIdentity", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_block_references<T, O>(); auto const cases = rotgen::tests::generate_block_references<T, O>();
for (auto const& [matrix_desc, i0, j0, ni, nj] : cases) for (auto const& [matrix_desc, i0, j0, ni, nj] : cases)
@ -202,14 +202,14 @@ TTS_CASE_TPL("Test dynamic block::setIdentity",
test_identity(m, i0, j0, ni, nj); test_identity(m, i0, j0, ni, nj);
using input_type = decltype(rotgen::extract(m, i0, j0, ni, nj)); using input_type = decltype(rotgen::extract(m, i0, j0, ni, nj));
auto values = input_type::Identity(ni, nj); auto values = rotgen::setIdentity<input_type>(ni, nj);
test_identity(values, 0, 0, ni, nj); test_identity(values, 0, 0, ni, nj);
} }
}; };
TTS_CASE_TPL("Test static block::setIdentity", TTS_CASE_TPL("Test static block::setIdentity", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_static_block_references<T, O>(); auto const cases = rotgen::tests::generate_static_block_references<T, O>();
@ -225,16 +225,16 @@ TTS_CASE_TPL("Test static block::setIdentity",
test_identity(m, i0, j0, D::ni, D::nj); test_identity(m, i0, j0, D::ni, D::nj);
using input_type = decltype(rotgen::extract<D::ni, D::nj>(m, i0, j0)); using input_type = decltype(rotgen::extract<D::ni, D::nj>(m, i0, j0));
auto values = input_type::Identity(); auto values = rotgen::setIdentity<input_type>();
test_identity(values, 0, 0, D::ni, D::nj); test_identity(values, 0, 0, D::ni, D::nj);
}; };
std::apply([&](auto const&... d) { (process(d), ...); }, cases); std::apply([&](auto const&... d) { (process(d), ...); }, cases);
}; };
TTS_CASE_TPL("Test dynamic block::setRandom", TTS_CASE_TPL("Test dynamic block::setRandom", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_block_references<T, O>(); auto const cases = rotgen::tests::generate_block_references<T, O>();
for (auto const& [matrix_desc, i0, j0, ni, nj] : cases) for (auto const& [matrix_desc, i0, j0, ni, nj] : cases)
@ -248,14 +248,14 @@ TTS_CASE_TPL("Test dynamic block::setRandom",
test_random(m, i0, j0, ni, nj); test_random(m, i0, j0, ni, nj);
using input_type = decltype(rotgen::extract(m, i0, j0, ni, nj)); using input_type = decltype(rotgen::extract(m, i0, j0, ni, nj));
auto values = input_type::Random(ni, nj); auto values = rotgen::setRandom<input_type>(ni, nj);
test_random(values, 0, 0, ni, nj); test_random(values, 0, 0, ni, nj);
} }
}; };
TTS_CASE_TPL("Test static block::setRandom", TTS_CASE_TPL("Test static block::setRandom", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_static_block_references<T, O>(); auto const cases = rotgen::tests::generate_static_block_references<T, O>();
@ -271,7 +271,7 @@ TTS_CASE_TPL("Test static block::setRandom",
test_random(m, i0, j0, D::ni, D::nj); test_random(m, i0, j0, D::ni, D::nj);
using input_type = decltype(rotgen::extract<D::ni, D::nj>(m, i0, j0)); using input_type = decltype(rotgen::extract<D::ni, D::nj>(m, i0, j0));
auto values = input_type::Random(); auto values = rotgen::setRandom<input_type>();
test_random(values, 0, 0, D::ni, D::nj); test_random(values, 0, 0, D::ni, D::nj);
}; };

View file

@ -21,7 +21,7 @@ namespace rotgen::tests
using eigen_mat_t = using eigen_mat_t =
matrix<typename T::value_type, Dynamic, Dynamic, T::storage_order>; matrix<typename T::value_type, Dynamic, Dynamic, T::storage_order>;
eigen_mat_t eigen_result(rotgen_input.cols(), rotgen_input.rows()); eigen_mat_t eigen_result(cols(rotgen_input), rows(rotgen_input));
prepare([&](auto r, auto c) { return rotgen_input(c, r); }, eigen_result); prepare([&](auto r, auto c) { return rotgen_input(c, r); }, eigen_result);
TTS_EQUAL(transpose(rotgen_input), eigen_result); TTS_EQUAL(transpose(rotgen_input), eigen_result);
@ -42,7 +42,7 @@ namespace rotgen::tests
} }
else else
{ {
if (rotgen_input.rows() == rotgen_input.cols()) if (rows(rotgen_input) == cols(rotgen_input))
{ {
eigen_mat_t eigen_ref = rotgen_input; eigen_mat_t eigen_ref = rotgen_input;
transposeInPlace(rotgen_input); transposeInPlace(rotgen_input);
@ -66,7 +66,7 @@ namespace rotgen::tests
using eigen_mat_t = using eigen_mat_t =
Eigen::Matrix<typename T::value_type, Eigen::Dynamic, Eigen::Dynamic>; Eigen::Matrix<typename T::value_type, Eigen::Dynamic, Eigen::Dynamic>;
eigen_mat_t eigen_ref(rotgen_input.rows(), rotgen_input.cols()); eigen_mat_t eigen_ref(rows(rotgen_input), cols(rotgen_input));
prepare([&](auto r, auto c) { return rotgen_input(r, c); }, eigen_ref); prepare([&](auto r, auto c) { return rotgen_input(r, c); }, eigen_ref);
TTS_ULP_EQUAL(sum(rotgen_input), eigen_ref.sum(), 2); TTS_ULP_EQUAL(sum(rotgen_input), eigen_ref.sum(), 2);

View file

@ -25,10 +25,10 @@ namespace rotgen::tests
TTS_WHEN("Unary Cwise operations") TTS_WHEN("Unary Cwise operations")
{ {
eigen_mat_t eigen_ref(rotgen_input.rows(), rotgen_input.cols()); eigen_mat_t eigen_ref(rows(rotgen_input), cols(rotgen_input));
prepare([&](auto r, auto c) { return rotgen_input(r, c); }, eigen_ref); prepare([&](auto r, auto c) { return rotgen_input(r, c); }, eigen_ref);
rotgen_mat_t rotgen_ref(rotgen_input.rows(), rotgen_input.cols()); rotgen_mat_t rotgen_ref(rows(rotgen_input), cols(rotgen_input));
TTS_AND_THEN("abs()") TTS_AND_THEN("abs()")
{ {
@ -57,8 +57,8 @@ namespace rotgen::tests
auto mat = rotgen::abs(rotgen_input); auto mat = rotgen::abs(rotgen_input);
auto proper_input = rotgen::sqrt(mat); auto proper_input = rotgen::sqrt(mat);
for (rotgen::Index r = 0; r < rotgen_input.rows(); ++r) for (rotgen::Index r = 0; r < rows(rotgen_input); ++r)
for (rotgen::Index c = 0; c < rotgen_input.cols(); ++c) for (rotgen::Index c = 0; c < cols(rotgen_input); ++c)
TTS_ULP_EQUAL(proper_input(r, c), eigen_ref(r, c), 1); TTS_ULP_EQUAL(proper_input(r, c), eigen_ref(r, c), 1);
} }
} }

View file

@ -20,7 +20,7 @@ namespace rotgen::tests
using eigen_mat_t = using eigen_mat_t =
Eigen::Matrix<typename T::value_type, Eigen::Dynamic, Eigen::Dynamic>; Eigen::Matrix<typename T::value_type, Eigen::Dynamic, Eigen::Dynamic>;
eigen_mat_t eigen_ref(rotgen_input.rows(), rotgen_input.cols()); eigen_mat_t eigen_ref(rows(rotgen_input), cols(rotgen_input));
prepare([&](auto row, auto col) { return rotgen_input(row, col); }, prepare([&](auto row, auto col) { return rotgen_input(row, col); },
eigen_ref); eigen_ref);
@ -38,7 +38,7 @@ namespace rotgen::tests
using rotgen_mat_t = using rotgen_mat_t =
rotgen::matrix<typename T::value_type, rotgen::Dynamic, rotgen::Dynamic, rotgen::matrix<typename T::value_type, rotgen::Dynamic, rotgen::Dynamic,
T::storage_order>; T::storage_order>;
rotgen_mat_t rotgen_norm_ref(rotgen_input.rows(), rotgen_input.cols()); rotgen_mat_t rotgen_norm_ref(rows(rotgen_input), cols(rotgen_input));
prepare([&](auto row, auto col) { return eigen_normalized(row, col); }, prepare([&](auto row, auto col) { return eigen_normalized(row, col); },
rotgen_norm_ref); rotgen_norm_ref);

View file

@ -55,8 +55,13 @@ namespace rotgen::tests
void prepare(auto fn, auto& output) void prepare(auto fn, auto& output)
{ {
for (rotgen::Index r = 0; r < output.rows(); ++r) for (rotgen::Index r = 0; r < rows(output); ++r)
for (rotgen::Index c = 0; c < output.cols(); ++c) output(r, c) = fn(r, c); {
for (rotgen::Index c = 0; c < cols(output); ++c)
{
output(r, c) = fn(r, c);
}
}
} }
auto default_init_function = [](auto row, auto col) { auto default_init_function = [](auto row, auto col) {

View file

@ -10,8 +10,9 @@
#include "unit/common/references.hpp" #include "unit/common/references.hpp"
#include "unit/tests.hpp" #include "unit/tests.hpp"
TTS_CASE_TPL("rowwise API", rotgen::tests::types)<typename T, typename O>( TTS_CASE_TPL("rowwise API", rotgen::tests::types)
tts::type<tts::types<T, O>>)
<typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
using eigen_mat_t = using eigen_mat_t =
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, O::value>; Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, O::value>;
@ -25,24 +26,25 @@ TTS_CASE_TPL("rowwise API", rotgen::tests::types)<typename T, typename O>(
auto rotgen_rw = rotgen::rowwise(rotgen_mat); auto rotgen_rw = rotgen::rowwise(rotgen_mat);
for (rotgen::Index i = 0; i < rotgen_mat.rows(); ++i) for (rotgen::Index i = 0; i < rows(rotgen_mat); ++i)
TTS_EQUAL(rotgen::sum(rotgen_rw)(i), eigen_ref_rw.sum()(i)); TTS_EQUAL(rotgen::sum(rotgen_rw)(i), eigen_ref_rw.sum()(i));
for (rotgen::Index i = 0; i < rotgen_mat.rows(); ++i) for (rotgen::Index i = 0; i < rows(rotgen_mat); ++i)
TTS_EQUAL(rotgen::mean(rotgen_rw)(i), eigen_ref_rw.mean()(i)); TTS_EQUAL(rotgen::mean(rotgen_rw)(i), eigen_ref_rw.mean()(i));
for (rotgen::Index i = 0; i < rotgen_mat.rows(); ++i) for (rotgen::Index i = 0; i < rows(rotgen_mat); ++i)
TTS_EQUAL(rotgen::prod(rotgen_rw)(i), eigen_ref_rw.prod()(i)); TTS_EQUAL(rotgen::prod(rotgen_rw)(i), eigen_ref_rw.prod()(i));
for (rotgen::Index i = 0; i < rotgen_mat.rows(); ++i) for (rotgen::Index i = 0; i < rows(rotgen_mat); ++i)
TTS_EQUAL(rotgen::maxCoeff(rotgen_rw)(i), eigen_ref_rw.maxCoeff()(i)); TTS_EQUAL(rotgen::maxCoeff(rotgen_rw)(i), eigen_ref_rw.maxCoeff()(i));
for (rotgen::Index i = 0; i < rotgen_mat.rows(); ++i) for (rotgen::Index i = 0; i < rows(rotgen_mat); ++i)
TTS_EQUAL(rotgen::minCoeff(rotgen_rw)(i), eigen_ref_rw.minCoeff()(i)); TTS_EQUAL(rotgen::minCoeff(rotgen_rw)(i), eigen_ref_rw.minCoeff()(i));
for (rotgen::Index i = 0; i < rotgen_mat.rows(); ++i) for (rotgen::Index i = 0; i < rows(rotgen_mat); ++i)
TTS_EQUAL(rotgen::squaredNorm(rotgen_rw)(i), eigen_ref_rw.squaredNorm()(i)); TTS_EQUAL(rotgen::squaredNorm(rotgen_rw)(i), eigen_ref_rw.squaredNorm()(i));
for (rotgen::Index i = 0; i < rotgen_mat.rows(); ++i) for (rotgen::Index i = 0; i < rows(rotgen_mat); ++i)
TTS_EQUAL(rotgen::norm(rotgen_rw)(i), eigen_ref_rw.norm()(i)); TTS_EQUAL(rotgen::norm(rotgen_rw)(i), eigen_ref_rw.norm()(i));
}; };
TTS_CASE_TPL("colwise API", rotgen::tests::types)<typename T, typename O>( TTS_CASE_TPL("colwise API", rotgen::tests::types)
tts::type<tts::types<T, O>>)
<typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
using eigen_mat_t = using eigen_mat_t =
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, O::value>; Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, O::value>;
@ -56,18 +58,18 @@ TTS_CASE_TPL("colwise API", rotgen::tests::types)<typename T, typename O>(
auto rotgen_rw = rotgen::colwise(rotgen_mat); auto rotgen_rw = rotgen::colwise(rotgen_mat);
for (rotgen::Index i = 0; i < rotgen_mat.cols(); ++i) for (rotgen::Index i = 0; i < cols(rotgen_mat); ++i)
TTS_EQUAL(rotgen::sum(rotgen_rw)(i), eigen_ref_rw.sum()(i)); TTS_EQUAL(rotgen::sum(rotgen_rw)(i), eigen_ref_rw.sum()(i));
for (rotgen::Index i = 0; i < rotgen_mat.cols(); ++i) for (rotgen::Index i = 0; i < cols(rotgen_mat); ++i)
TTS_EQUAL(rotgen::mean(rotgen_rw)(i), eigen_ref_rw.mean()(i)); TTS_EQUAL(rotgen::mean(rotgen_rw)(i), eigen_ref_rw.mean()(i));
for (rotgen::Index i = 0; i < rotgen_mat.cols(); ++i) for (rotgen::Index i = 0; i < cols(rotgen_mat); ++i)
TTS_EQUAL(rotgen::prod(rotgen_rw)(i), eigen_ref_rw.prod()(i)); TTS_EQUAL(rotgen::prod(rotgen_rw)(i), eigen_ref_rw.prod()(i));
for (rotgen::Index i = 0; i < rotgen_mat.cols(); ++i) for (rotgen::Index i = 0; i < cols(rotgen_mat); ++i)
TTS_EQUAL(rotgen::maxCoeff(rotgen_rw)(i), eigen_ref_rw.maxCoeff()(i)); TTS_EQUAL(rotgen::maxCoeff(rotgen_rw)(i), eigen_ref_rw.maxCoeff()(i));
for (rotgen::Index i = 0; i < rotgen_mat.cols(); ++i) for (rotgen::Index i = 0; i < cols(rotgen_mat); ++i)
TTS_EQUAL(rotgen::minCoeff(rotgen_rw)(i), eigen_ref_rw.minCoeff()(i)); TTS_EQUAL(rotgen::minCoeff(rotgen_rw)(i), eigen_ref_rw.minCoeff()(i));
for (rotgen::Index i = 0; i < rotgen_mat.cols(); ++i) for (rotgen::Index i = 0; i < cols(rotgen_mat); ++i)
TTS_EQUAL(rotgen::squaredNorm(rotgen_rw)(i), eigen_ref_rw.squaredNorm()(i)); TTS_EQUAL(rotgen::squaredNorm(rotgen_rw)(i), eigen_ref_rw.squaredNorm()(i));
for (rotgen::Index i = 0; i < rotgen_mat.cols(); ++i) for (rotgen::Index i = 0; i < cols(rotgen_mat); ++i)
TTS_EQUAL(rotgen::norm(rotgen_rw)(i), eigen_ref_rw.norm()(i)); TTS_EQUAL(rotgen::norm(rotgen_rw)(i), eigen_ref_rw.norm()(i));
}; };

View file

@ -9,25 +9,25 @@
#include "unit/tests.hpp" #include "unit/tests.hpp"
TTS_CASE_TPL("SVD decomposition - Dynamic case", TTS_CASE_TPL("SVD decomposition - Dynamic case", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
int rank, i = 5; int rank, i = 5;
auto eps = std::numeric_limits<T>::epsilon(); auto eps = std::numeric_limits<T>::epsilon();
auto m = auto m = rotgen::setRandom<
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>::Random(5, 5); rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>>(5, 5);
auto decomp = rotgen::svd(m); auto decomp = rotgen::svd(m);
do do
{ {
rank = decomp.rank(); rank = decomp.rank();
auto u = decomp.U(rank); auto u = decomp.matrixU(rank);
auto d = decomp.singular_values(rank); auto d = decomp.singularValues(rank);
auto dd = decomp.D(rank); auto dd = decomp.matrixD(rank);
auto v = decomp.V(rank); auto v = decomp.matrixV(rank);
TTS_EQUAL(rank, i); TTS_EQUAL(rank, i);
@ -48,24 +48,24 @@ TTS_CASE_TPL("SVD decomposition - Dynamic case",
} while (rank != 1); } while (rank != 1);
}; };
TTS_CASE_TPL("SVD decomposition - Static case", TTS_CASE_TPL("SVD decomposition - Static case", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
int rank, i = 5; int rank, i = 5;
auto eps = std::numeric_limits<T>::epsilon(); auto eps = std::numeric_limits<T>::epsilon();
auto m = rotgen::matrix<T, 5, 5, O::value>::Random(); auto m = rotgen::setRandom<rotgen::matrix<T, 5, 5, O::value>>();
auto decomp = rotgen::svd(m); auto decomp = rotgen::svd(m);
do do
{ {
rank = decomp.rank(); rank = decomp.rank();
auto u = decomp.U(rank); auto u = decomp.matrixU(rank);
auto d = decomp.singular_values(rank); auto d = decomp.singularValues(rank);
auto dd = decomp.D(rank); auto dd = decomp.matrixD(rank);
auto v = decomp.V(rank); auto v = decomp.matrixV(rank);
TTS_EQUAL(rank, i); TTS_EQUAL(rank, i);

View file

@ -36,7 +36,7 @@ TTS_CASE_TPL("Test static map transposition-like operations",
auto process = []<typename D>(D const& desc) { auto process = []<typename D>(D const& desc) {
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> base(D::rows, rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> base(D::rows,
D::cols); D::cols);
rotgen::tests::prepare(base.rows(), base.cols(), desc.init_fn, base); rotgen::tests::prepare(rows(base), cols(base), desc.init_fn, base);
rotgen::map<rotgen::matrix<T, D::rows, D::cols, O::value>> input( rotgen::map<rotgen::matrix<T, D::rows, D::cols, O::value>> input(
base.data()); base.data());
@ -72,7 +72,7 @@ TTS_CASE_TPL("Test static map reduction-like operations",
auto process = []<typename D>(D const& desc) { auto process = []<typename D>(D const& desc) {
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> base(D::rows, rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> base(D::rows,
D::cols); D::cols);
rotgen::tests::prepare(base.rows(), base.cols(), desc.init_fn, base); rotgen::tests::prepare(rows(base), cols(base), desc.init_fn, base);
rotgen::map<rotgen::matrix<T, D::rows, D::cols, O::value>> input( rotgen::map<rotgen::matrix<T, D::rows, D::cols, O::value>> input(
base.data()); base.data());

View file

@ -9,40 +9,41 @@
#include "unit/tests.hpp" #include "unit/tests.hpp"
TTS_CASE_TPL("Function size", rotgen::tests::types)<typename T, typename O>( TTS_CASE_TPL("Function size", rotgen::tests::types)
tts::type<tts::types<T, O>>)
<typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
T data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; T data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
rotgen::map<rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>> rotgen::map<rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>>
dyn_map(data, 1, 12); dyn_map(data, 1, 12);
TTS_EQUAL(dyn_map.rows(), rotgen::Index{1}); TTS_EQUAL(rows(dyn_map), rotgen::Index{1});
TTS_EQUAL(dyn_map.cols(), rotgen::Index{12}); TTS_EQUAL(cols(dyn_map), rotgen::Index{12});
rotgen::map<rotgen::matrix<T, 1, 12, rotgen::RowMajor>> s112_map(data); rotgen::map<rotgen::matrix<T, 1, 12, rotgen::RowMajor>> s112_map(data);
TTS_EQUAL(s112_map.rows(), rotgen::Index{1}); TTS_EQUAL(rows(s112_map), rotgen::Index{1});
TTS_EQUAL(s112_map.cols(), rotgen::Index{12}); TTS_EQUAL(cols(s112_map), rotgen::Index{12});
TTS_EQUAL(s112_map.size(), rotgen::Index{12}); TTS_EQUAL(s112_map.size(), rotgen::Index{12});
rotgen::map<rotgen::matrix<T, 12, 1, rotgen::ColMajor>> s121_map(data); rotgen::map<rotgen::matrix<T, 12, 1, rotgen::ColMajor>> s121_map(data);
TTS_EQUAL(s121_map.rows(), rotgen::Index{12}); TTS_EQUAL(rows(s121_map), rotgen::Index{12});
TTS_EQUAL(s121_map.cols(), rotgen::Index{1}); TTS_EQUAL(cols(s121_map), rotgen::Index{1});
TTS_EQUAL(s121_map.size(), rotgen::Index{12}); TTS_EQUAL(s121_map.size(), rotgen::Index{12});
rotgen::map<rotgen::matrix<T, 3, 4, O::value>> s34_map(data); rotgen::map<rotgen::matrix<T, 3, 4, O::value>> s34_map(data);
TTS_EQUAL(s34_map.rows(), rotgen::Index{3}); TTS_EQUAL(rows(s34_map), rotgen::Index{3});
TTS_EQUAL(s34_map.cols(), rotgen::Index{4}); TTS_EQUAL(cols(s34_map), rotgen::Index{4});
TTS_EQUAL(s34_map.size(), rotgen::Index{12}); TTS_EQUAL(s34_map.size(), rotgen::Index{12});
rotgen::map<rotgen::matrix<T, 6, 2, O::value>> s62_map(data); rotgen::map<rotgen::matrix<T, 6, 2, O::value>> s62_map(data);
TTS_EQUAL(s62_map.rows(), rotgen::Index{6}); TTS_EQUAL(rows(s62_map), rotgen::Index{6});
TTS_EQUAL(s62_map.cols(), rotgen::Index{2}); TTS_EQUAL(cols(s62_map), rotgen::Index{2});
TTS_EQUAL(s62_map.size(), rotgen::Index{12}); TTS_EQUAL(s62_map.size(), rotgen::Index{12});
}; };
TTS_CASE_TPL("Test coefficient accessors", TTS_CASE_TPL("Test coefficient accessors", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
using base = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>; using base = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
@ -66,9 +67,9 @@ TTS_CASE_TPL("Test coefficient accessors",
TTS_EQUAL(a(2, 2), 17); TTS_EQUAL(a(2, 2), 17);
}; };
TTS_CASE_TPL("Test one index coefficient accessors", TTS_CASE_TPL("Test one index coefficient accessors", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
T data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; T data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};

View file

@ -11,9 +11,9 @@
#include "unit/common/references.hpp" #include "unit/common/references.hpp"
#include "unit/tests.hpp" #include "unit/tests.hpp"
TTS_CASE_TPL("Test dynamic map cwise operations", TTS_CASE_TPL("Test dynamic map cwise operations", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_matrix_references(); auto const cases = rotgen::tests::generate_matrix_references();
for (auto const& [rows, cols, fn] : cases) for (auto const& [rows, cols, fn] : cases)
@ -28,16 +28,16 @@ TTS_CASE_TPL("Test dynamic map cwise operations",
} }
}; };
TTS_CASE_TPL("Test static map cwise operations", TTS_CASE_TPL("Test static map cwise operations", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_static_matrix_references(); auto const cases = rotgen::tests::generate_static_matrix_references();
auto process = []<typename D>(D const& desc) { auto process = []<typename D>(D const& desc) {
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> base(D::rows, rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> base(D::rows,
D::cols); D::cols);
rotgen::tests::prepare(base.rows(), base.cols(), desc.init_fn, base); rotgen::tests::prepare(rows(base), cols(base), desc.init_fn, base);
rotgen::map<rotgen::matrix<T, D::rows, D::cols, O::value>> input( rotgen::map<rotgen::matrix<T, D::rows, D::cols, O::value>> input(
base.data()); base.data());

View file

@ -11,9 +11,9 @@
#include "unit/common/references.hpp" #include "unit/common/references.hpp"
#include "unit/tests.hpp" #include "unit/tests.hpp"
TTS_CASE_TPL("Test dynamic map norm operations", TTS_CASE_TPL("Test dynamic map norm operations", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_matrix_references(); auto const cases = rotgen::tests::generate_matrix_references();
for (auto const& [rows, cols, fn] : cases) for (auto const& [rows, cols, fn] : cases)
@ -28,16 +28,16 @@ TTS_CASE_TPL("Test dynamic map norm operations",
} }
}; };
TTS_CASE_TPL("Test static map norm operations", TTS_CASE_TPL("Test static map norm operations", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_static_matrix_references(); auto const cases = rotgen::tests::generate_static_matrix_references();
auto process = []<typename D>(D const& desc) { auto process = []<typename D>(D const& desc) {
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> base(D::rows, rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> base(D::rows,
D::cols); D::cols);
rotgen::tests::prepare(base.rows(), base.cols(), desc.init_fn, base); rotgen::tests::prepare(rows(base), cols(base), desc.init_fn, base);
rotgen::map<rotgen::matrix<T, D::rows, D::cols, O::value>> input( rotgen::map<rotgen::matrix<T, D::rows, D::cols, O::value>> input(
base.data()); base.data());

View file

@ -40,8 +40,8 @@ TTS_CASE("Validate Column Major Map with regular stride behavior")
r_map_t<r_mat_t<rotgen::ColMajor>> r_map(buffer.data(), rows, cols); r_map_t<r_mat_t<rotgen::ColMajor>> r_map(buffer.data(), rows, cols);
TTS_EQUAL(r_map.innerStride(), 1); TTS_EQUAL(innerStride(r_map), 1);
TTS_EQUAL(r_map.outerStride(), 3); TTS_EQUAL(outerStride(r_map), 3);
e_map_t<e_mat_t<Eigen::ColMajor>> e_map(buffer.data(), rows, cols); e_map_t<e_mat_t<Eigen::ColMajor>> e_map(buffer.data(), rows, cols);
@ -59,8 +59,8 @@ TTS_CASE("Validate Column Major Map with specific outer stride behavior")
r_map_t<r_mat_t<rotgen::ColMajor>, rotgen::outer_stride<>> r_map( 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(innerStride(r_map), 1);
TTS_EQUAL(r_map.outerStride(), 4); TTS_EQUAL(outerStride(r_map), 4);
e_map_t<e_mat_t<Eigen::ColMajor>, Eigen::OuterStride<>> e_map( e_map_t<e_mat_t<Eigen::ColMajor>, Eigen::OuterStride<>> e_map(
buffer.data(), rows, cols, Eigen::OuterStride<>(rows + 1)); buffer.data(), rows, cols, Eigen::OuterStride<>(rows + 1));
@ -79,8 +79,8 @@ TTS_CASE("Validate Column Major Map with specific inner stride behavior")
r_map_t<r_mat_t<rotgen::ColMajor>, rotgen::dynamic_stride> r_map( r_map_t<r_mat_t<rotgen::ColMajor>, rotgen::dynamic_stride> r_map(
buffer.data(), rows, cols, rotgen::dynamic_stride(rows, 2)); buffer.data(), rows, cols, rotgen::dynamic_stride(rows, 2));
TTS_EQUAL(r_map.innerStride(), 2); TTS_EQUAL(innerStride(r_map), 2);
TTS_EQUAL(r_map.outerStride(), 3); TTS_EQUAL(outerStride(r_map), 3);
e_map_t<e_mat_t<Eigen::ColMajor>, e_map_t<e_mat_t<Eigen::ColMajor>,
Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>> Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>>
@ -100,8 +100,8 @@ TTS_CASE("Validate Row Major Map with regular stride behavior")
r_map_t<r_mat_t<rotgen::RowMajor>> r_map(buffer.data(), rows, cols); r_map_t<r_mat_t<rotgen::RowMajor>> r_map(buffer.data(), rows, cols);
TTS_EQUAL(r_map.innerStride(), 1); TTS_EQUAL(innerStride(r_map), 1);
TTS_EQUAL(r_map.outerStride(), 4); TTS_EQUAL(outerStride(r_map), 4);
e_map_t<e_mat_t<Eigen::RowMajor>> e_map(buffer.data(), rows, cols); e_map_t<e_mat_t<Eigen::RowMajor>> e_map(buffer.data(), rows, cols);
@ -119,8 +119,8 @@ TTS_CASE("Validate Row Major Map with specific outer stride behavior")
r_map_t<r_mat_t<rotgen::RowMajor>, rotgen::outer_stride<>> r_map( 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(innerStride(r_map), 1);
TTS_EQUAL(r_map.outerStride(), 5); TTS_EQUAL(outerStride(r_map), 5);
e_map_t<e_mat_t<Eigen::RowMajor>, Eigen::OuterStride<>> e_map( e_map_t<e_mat_t<Eigen::RowMajor>, Eigen::OuterStride<>> e_map(
buffer.data(), rows, cols, Eigen::OuterStride<>(cols + 1)); buffer.data(), rows, cols, Eigen::OuterStride<>(cols + 1));
@ -139,8 +139,8 @@ TTS_CASE("Validate Row Major Map with specific inner stride behavior")
r_map_t<r_mat_t<rotgen::RowMajor>, rotgen::dynamic_stride> r_map( r_map_t<r_mat_t<rotgen::RowMajor>, rotgen::dynamic_stride> r_map(
buffer.data(), rows, cols, rotgen::dynamic_stride(2, cols)); buffer.data(), rows, cols, rotgen::dynamic_stride(2, cols));
TTS_EQUAL(r_map.innerStride(), 4); TTS_EQUAL(innerStride(r_map), 4);
TTS_EQUAL(r_map.outerStride(), 2); TTS_EQUAL(outerStride(r_map), 2);
e_map_t<e_mat_t<Eigen::RowMajor>, e_map_t<e_mat_t<Eigen::RowMajor>,
Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>> Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>>

View file

@ -13,8 +13,9 @@
#include "unit/tests.hpp" #include "unit/tests.hpp"
TTS_CASE_TPL("Test dynamic matrix transposition-like operations", TTS_CASE_TPL("Test dynamic matrix transposition-like operations",
rotgen::tests::types)<typename T, typename O>( rotgen::tests::types)
tts::type<tts::types<T, O>>)
<typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_matrix_references(); auto const cases = rotgen::tests::generate_matrix_references();
for (auto const& [rows, cols, fn] : cases) for (auto const& [rows, cols, fn] : cases)
@ -27,14 +28,15 @@ TTS_CASE_TPL("Test dynamic matrix transposition-like operations",
}; };
TTS_CASE_TPL("Test static matrix transposition-like operations", TTS_CASE_TPL("Test static matrix transposition-like operations",
rotgen::tests::types)<typename T, typename O>( rotgen::tests::types)
tts::type<tts::types<T, O>>)
<typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_static_matrix_references(); auto const cases = rotgen::tests::generate_static_matrix_references();
auto process = []<typename D>(D const& desc) { auto process = []<typename D>(D const& desc) {
rotgen::matrix<T, D::rows, D::cols, O::value> input; rotgen::matrix<T, D::rows, D::cols, O::value> input;
rotgen::tests::prepare(input.rows(), input.cols(), desc.init_fn, input); rotgen::tests::prepare(rows(input), cols(input), desc.init_fn, input);
rotgen::tests::check_shape_functions(input); rotgen::tests::check_shape_functions(input);
}; };
@ -42,8 +44,9 @@ TTS_CASE_TPL("Test static matrix transposition-like operations",
}; };
TTS_CASE_TPL("Test dynamic matrix reduction-like operations", TTS_CASE_TPL("Test dynamic matrix reduction-like operations",
rotgen::tests::types)<typename T, typename O>( rotgen::tests::types)
tts::type<tts::types<T, O>>)
<typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_matrix_references(); auto const cases = rotgen::tests::generate_matrix_references();
for (auto const& [rows, cols, fn] : cases) for (auto const& [rows, cols, fn] : cases)
@ -56,21 +59,23 @@ TTS_CASE_TPL("Test dynamic matrix reduction-like operations",
}; };
TTS_CASE_TPL("Test static matrix reduction-like operations", TTS_CASE_TPL("Test static matrix reduction-like operations",
rotgen::tests::types)<typename T, typename O>( rotgen::tests::types)
tts::type<tts::types<T, O>>)
<typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_static_matrix_references(); auto const cases = rotgen::tests::generate_static_matrix_references();
auto process = []<typename D>(D const& desc) { auto process = []<typename D>(D const& desc) {
rotgen::matrix<T, D::rows, D::cols, O::value> input; rotgen::matrix<T, D::rows, D::cols, O::value> input;
rotgen::tests::prepare(input.rows(), input.cols(), desc.init_fn, input); rotgen::tests::prepare(rows(input), cols(input), desc.init_fn, input);
rotgen::tests::check_reduction_functions(input); rotgen::tests::check_reduction_functions(input);
}; };
std::apply([&](auto const&... d) { (process(d), ...); }, cases); std::apply([&](auto const&... d) { (process(d), ...); }, cases);
}; };
TTS_CASE_TPL("Test dot product", float, double)<typename T>(tts::type<T>){ TTS_CASE_TPL("Test dot product", float, double)
<typename T>(tts::type<T>){
{auto a = rotgen::setConstant<rotgen::matrix<T, 1, rotgen::Dynamic>>(1, 8, 2); {auto a = rotgen::setConstant<rotgen::matrix<T, 1, rotgen::Dynamic>>(1, 8, 2);
auto b = rotgen::setConstant<rotgen::matrix<T, 1, rotgen::Dynamic>>(1, 8, 2); auto b = rotgen::setConstant<rotgen::matrix<T, 1, rotgen::Dynamic>>(1, 8, 2);

View file

@ -9,8 +9,9 @@
#include "unit/tests.hpp" #include "unit/tests.hpp"
TTS_CASE_TPL("Function size", rotgen::tests::types)<typename T, typename O>( TTS_CASE_TPL("Function size", rotgen::tests::types)
tts::type<tts::types<T, O>>)
<typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> empty_matrix; rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> empty_matrix;
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> matrix(3, 4); rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> matrix(3, 4);
@ -25,87 +26,87 @@ TTS_CASE_TPL("Function size", rotgen::tests::types)<typename T, typename O>(
TTS_EQUAL(column_vector.size(), rotgen::Index{5}); TTS_EQUAL(column_vector.size(), rotgen::Index{5});
}; };
TTS_CASE_TPL("Resizing dynamic matrix", TTS_CASE_TPL("Resizing dynamic matrix", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(2, 3); rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(2, 3);
for (rotgen::Index r = 0; r < a.rows(); ++r) for (rotgen::Index r = 0; r < rows(a); ++r)
for (rotgen::Index c = 0; c < a.cols(); ++c) a(r, c) = 42 + 2 * c + r; for (rotgen::Index c = 0; c < cols(a); ++c) a(r, c) = 42 + 2 * c + r;
rotgen::resize(a, 3, 2); rotgen::resize(a, 3, 2);
TTS_EQUAL(a.rows(), rotgen::Index(3)); TTS_EQUAL(rows(a), rotgen::Index(3));
TTS_EQUAL(a.cols(), rotgen::Index(2)); TTS_EQUAL(cols(a), rotgen::Index(2));
for (rotgen::Index r = 0; r < a.rows(); ++r) for (rotgen::Index r = 0; r < rows(a); ++r)
for (rotgen::Index c = 0; c < a.cols(); ++c) TTS_GREATER(a(r, c), 0); for (rotgen::Index c = 0; c < cols(a); ++c) TTS_GREATER(a(r, c), 0);
rotgen::resize(a, 2, 2); rotgen::resize(a, 2, 2);
TTS_EQUAL(a.rows(), rotgen::Index(2)); TTS_EQUAL(rows(a), rotgen::Index(2));
TTS_EQUAL(a.cols(), rotgen::Index(2)); TTS_EQUAL(cols(a), rotgen::Index(2));
}; };
TTS_CASE_TPL("Dynamix matrix conservative resizing", TTS_CASE_TPL("Dynamix matrix conservative resizing", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(2, 3); rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(2, 3);
int i = 1; int i = 1;
for (rotgen::Index r = 0; r < a.rows(); ++r) for (rotgen::Index r = 0; r < rows(a); ++r)
for (rotgen::Index c = 0; c < a.cols(); ++c) a(r, c) = i++; for (rotgen::Index c = 0; c < cols(a); ++c) a(r, c) = i++;
rotgen::conservativeResize(a, 2, 3); rotgen::conservativeResize(a, 2, 3);
TTS_EQUAL(a.rows(), rotgen::Index(2)); TTS_EQUAL(rows(a), rotgen::Index(2));
TTS_EQUAL(a.cols(), rotgen::Index(3)); TTS_EQUAL(cols(a), rotgen::Index(3));
i = 1; i = 1;
for (rotgen::Index r = 0; r < a.rows(); ++r) for (rotgen::Index r = 0; r < rows(a); ++r)
for (rotgen::Index c = 0; c < a.cols(); ++c) TTS_EQUAL(a(r, c), i++); for (rotgen::Index c = 0; c < cols(a); ++c) TTS_EQUAL(a(r, c), i++);
rotgen::conservativeResize(a, 3, 2); rotgen::conservativeResize(a, 3, 2);
TTS_EQUAL(a.rows(), rotgen::Index(3)); TTS_EQUAL(rows(a), rotgen::Index(3));
TTS_EQUAL(a.cols(), rotgen::Index(2)); TTS_EQUAL(cols(a), rotgen::Index(2));
int expected[3][2] = {{1, 2}, {4, 5}}; int expected[3][2] = {{1, 2}, {4, 5}};
for (rotgen::Index r = 0; r < 2; ++r) for (rotgen::Index r = 0; r < 2; ++r)
for (rotgen::Index c = 0; c < 2; ++c) TTS_EQUAL(a(r, c), expected[r][c]); for (rotgen::Index c = 0; c < 2; ++c) TTS_EQUAL(a(r, c), expected[r][c]);
rotgen::conservativeResize(a, 4, 4); rotgen::conservativeResize(a, 4, 4);
TTS_EQUAL(a.rows(), rotgen::Index(4)); TTS_EQUAL(rows(a), rotgen::Index(4));
TTS_EQUAL(a.cols(), rotgen::Index(4)); TTS_EQUAL(cols(a), rotgen::Index(4));
TTS_EQUAL(a(0, 0), 1); TTS_EQUAL(a(0, 0), 1);
TTS_EQUAL(a(3, 3), 0); TTS_EQUAL(a(3, 3), 0);
rotgen::conservativeResize(a, 2, 2); rotgen::conservativeResize(a, 2, 2);
TTS_EQUAL(a.rows(), rotgen::Index(2)); TTS_EQUAL(rows(a), rotgen::Index(2));
TTS_EQUAL(a.cols(), rotgen::Index(2)); TTS_EQUAL(cols(a), rotgen::Index(2));
TTS_EQUAL(a(0, 0), 1); TTS_EQUAL(a(0, 0), 1);
TTS_EQUAL(a(1, 1), 5); TTS_EQUAL(a(1, 1), 5);
rotgen::conservativeResize(a, 1, 2); rotgen::conservativeResize(a, 1, 2);
TTS_EQUAL(a.rows(), rotgen::Index(1)); TTS_EQUAL(rows(a), rotgen::Index(1));
TTS_EQUAL(a.cols(), rotgen::Index(2)); TTS_EQUAL(cols(a), rotgen::Index(2));
TTS_EQUAL(a(0, 0), 1); TTS_EQUAL(a(0, 0), 1);
TTS_EQUAL(a(0, 1), 2); TTS_EQUAL(a(0, 1), 2);
rotgen::conservativeResize(a, 0, 0); rotgen::conservativeResize(a, 0, 0);
TTS_EQUAL(a.rows(), rotgen::Index(0)); TTS_EQUAL(rows(a), rotgen::Index(0));
TTS_EQUAL(a.cols(), rotgen::Index(0)); TTS_EQUAL(cols(a), rotgen::Index(0));
rotgen::conservativeResize(a, 3, 3); rotgen::conservativeResize(a, 3, 3);
TTS_EQUAL(a.rows(), rotgen::Index(3)); TTS_EQUAL(rows(a), rotgen::Index(3));
TTS_EQUAL(a.cols(), rotgen::Index(3)); TTS_EQUAL(cols(a), rotgen::Index(3));
}; };
TTS_CASE_TPL("Test coefficient accessors", TTS_CASE_TPL("Test coefficient accessors", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(3, 5); rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(3, 5);
for (rotgen::Index r = 0; r < a.rows(); ++r) for (rotgen::Index r = 0; r < rows(a); ++r)
for (rotgen::Index c = 0; c < a.cols(); ++c) a(r, c) = r + 2 * c + 3; for (rotgen::Index c = 0; c < cols(a); ++c) a(r, c) = r + 2 * c + 3;
TTS_EQUAL(a(0, 0), 3); TTS_EQUAL(a(0, 0), 3);
TTS_EQUAL(a(1, 1), 6); TTS_EQUAL(a(1, 1), 6);
@ -121,9 +122,9 @@ TTS_CASE_TPL("Test coefficient accessors",
TTS_EQUAL(a(2, 2), 17); TTS_EQUAL(a(2, 2), 17);
}; };
TTS_CASE_TPL("Test one index coefficient accessors", TTS_CASE_TPL("Test one index coefficient accessors", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto a = [&]() { auto a = [&]() {
if constexpr (O::value == rotgen::ColMajor) if constexpr (O::value == rotgen::ColMajor)

View file

@ -15,8 +15,8 @@ TTS_CASE_TPL("Default matrix dynamic constructor", rotgen::tests::types)
{ {
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> matrix; rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> matrix;
TTS_EQUAL(matrix.rows(), rotgen::Index{0}); TTS_EQUAL(rows(matrix), rotgen::Index{0});
TTS_EQUAL(matrix.cols(), rotgen::Index{0}); TTS_EQUAL(cols(matrix), rotgen::Index{0});
}; };
TTS_CASE_TPL("Default matrix static constructor", rotgen::tests::types) TTS_CASE_TPL("Default matrix static constructor", rotgen::tests::types)
@ -25,8 +25,8 @@ TTS_CASE_TPL("Default matrix static constructor", rotgen::tests::types)
{ {
rotgen::matrix<T, 4, 9, O::value> matrix; rotgen::matrix<T, 4, 9, O::value> matrix;
TTS_EQUAL(matrix.rows(), rotgen::Index{4}); TTS_EQUAL(rows(matrix), rotgen::Index{4});
TTS_EQUAL(matrix.cols(), rotgen::Index{9}); TTS_EQUAL(cols(matrix), rotgen::Index{9});
}; };
TTS_CASE_TPL("Dynamic matrix constructor with row and columns", TTS_CASE_TPL("Dynamic matrix constructor with row and columns",
@ -36,8 +36,8 @@ TTS_CASE_TPL("Dynamic matrix constructor with row and columns",
{ {
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> matrix(10, 5); rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> matrix(10, 5);
TTS_EQUAL(matrix.rows(), rotgen::Index{10}); TTS_EQUAL(rows(matrix), rotgen::Index{10});
TTS_EQUAL(matrix.cols(), rotgen::Index{5}); TTS_EQUAL(cols(matrix), rotgen::Index{5});
}; };
TTS_CASE_TPL("Static matrix constructor with row and columns", float, double) TTS_CASE_TPL("Static matrix constructor with row and columns", float, double)
@ -72,16 +72,16 @@ TTS_CASE_TPL("Copy constructor produces identical but independent matrix",
{ {
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(3, 3); rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(3, 3);
for (rotgen::Index r = 0; r < a.rows(); r++) for (rotgen::Index r = 0; r < rows(a); r++)
for (rotgen::Index c = 0; c < a.cols(); c++) a(r, c) = r + c; for (rotgen::Index c = 0; c < cols(a); c++) a(r, c) = r + c;
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b = a; rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b = a;
TTS_EQUAL(b.rows(), a.rows()); TTS_EQUAL(rows(b), rows(a));
TTS_EQUAL(b.cols(), a.cols()); TTS_EQUAL(cols(b), cols(a));
for (rotgen::Index r = 0; r < a.rows(); r++) for (rotgen::Index r = 0; r < rows(a); r++)
for (rotgen::Index c = 0; c < a.cols(); c++) TTS_EQUAL(b(r, c), a(r, c)); for (rotgen::Index c = 0; c < cols(a); c++) TTS_EQUAL(b(r, c), a(r, c));
TTS_EQUAL(b(0, 0), 0.0); TTS_EQUAL(b(0, 0), 0.0);
TTS_EQUAL(b(1, 0), 1.0); TTS_EQUAL(b(1, 0), 1.0);
@ -97,8 +97,8 @@ TTS_CASE_TPL("Copy constructor on default matrix", rotgen::tests::types)
{ {
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a; rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a;
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b = a; rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b = a;
TTS_EQUAL(b.rows(), rotgen::Index{0}); TTS_EQUAL(rows(b), rotgen::Index{0});
TTS_EQUAL(b.cols(), rotgen::Index{0}); TTS_EQUAL(cols(b), rotgen::Index{0});
}; };
TTS_CASE_TPL("Copy constructor from const matrix", rotgen::tests::types) TTS_CASE_TPL("Copy constructor from const matrix", rotgen::tests::types)
@ -107,8 +107,8 @@ TTS_CASE_TPL("Copy constructor from const matrix", rotgen::tests::types)
{ {
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> const a(2, 2); rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> const a(2, 2);
auto b = a; auto b = a;
TTS_EQUAL(b.rows(), rotgen::Index{2}); TTS_EQUAL(rows(b), rotgen::Index{2});
TTS_EQUAL(b.cols(), rotgen::Index{2}); TTS_EQUAL(cols(b), rotgen::Index{2});
}; };
TTS_CASE_TPL("Copy constructor on static matrix", rotgen::tests::types) TTS_CASE_TPL("Copy constructor on static matrix", rotgen::tests::types)
@ -117,8 +117,8 @@ TTS_CASE_TPL("Copy constructor on static matrix", rotgen::tests::types)
{ {
rotgen::matrix<T, 2, 5> a; rotgen::matrix<T, 2, 5> a;
rotgen::matrix<T, 2, 5> b = a; rotgen::matrix<T, 2, 5> b = a;
TTS_EQUAL(b.rows(), rotgen::Index{2}); TTS_EQUAL(rows(b), rotgen::Index{2});
TTS_EQUAL(b.cols(), rotgen::Index{5}); TTS_EQUAL(cols(b), rotgen::Index{5});
}; };
TTS_CASE_TPL("Copy constructor on static/dynamic matrix", rotgen::tests::types) TTS_CASE_TPL("Copy constructor on static/dynamic matrix", rotgen::tests::types)
@ -127,8 +127,8 @@ TTS_CASE_TPL("Copy constructor on static/dynamic matrix", rotgen::tests::types)
{ {
rotgen::matrix<T, 11, 4, O::value> a; rotgen::matrix<T, 11, 4, O::value> a;
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b = a; rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b = a;
TTS_EQUAL(b.rows(), 11); TTS_EQUAL(rows(b), 11);
TTS_EQUAL(b.cols(), 4); TTS_EQUAL(cols(b), 4);
}; };
TTS_CASE_TPL("Copy constructor on dynamic/static matrix", rotgen::tests::types) TTS_CASE_TPL("Copy constructor on dynamic/static matrix", rotgen::tests::types)
@ -137,8 +137,8 @@ TTS_CASE_TPL("Copy constructor on dynamic/static matrix", rotgen::tests::types)
{ {
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(5, 7); rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> a(5, 7);
rotgen::matrix<T, 5, 7, O::value> b = a; rotgen::matrix<T, 5, 7, O::value> b = a;
TTS_EQUAL(b.rows(), 5); TTS_EQUAL(rows(b), 5);
TTS_EQUAL(b.cols(), 7); TTS_EQUAL(cols(b), 7);
}; };
TTS_CASE_TPL("Move constructor transfers contents", rotgen::tests::types) TTS_CASE_TPL("Move constructor transfers contents", rotgen::tests::types)
@ -153,8 +153,8 @@ TTS_CASE_TPL("Move constructor transfers contents", rotgen::tests::types)
std::move(a); std::move(a);
TTS_EQUAL(b(1, 1), 7); TTS_EQUAL(b(1, 1), 7);
TTS_EQUAL(b.rows(), rotgen::Index{3}); TTS_EQUAL(rows(b), rotgen::Index{3});
TTS_EQUAL(b.cols(), rotgen::Index{3}); TTS_EQUAL(cols(b), rotgen::Index{3});
TTS_EXPECT(b.data() == ptr); TTS_EXPECT(b.data() == ptr);
}; };
@ -164,8 +164,8 @@ TTS_CASE_TPL("Move constructor from Rvalue", rotgen::tests::types)
{ {
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b =
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>(2, 2); rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>(2, 2);
TTS_EQUAL(b.rows(), rotgen::Index{2}); TTS_EQUAL(rows(b), rotgen::Index{2});
TTS_EQUAL(b.cols(), rotgen::Index{2}); TTS_EQUAL(cols(b), rotgen::Index{2});
}; };
TTS_CASE_TPL("Constructor from Initializer list", rotgen::tests::types) TTS_CASE_TPL("Constructor from Initializer list", rotgen::tests::types)
@ -173,24 +173,24 @@ TTS_CASE_TPL("Constructor from Initializer list", rotgen::tests::types)
<typename T, typename O>(tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
rotgen::matrix<T, 1, 1, O::value> b1{3.5}; rotgen::matrix<T, 1, 1, O::value> b1{3.5};
TTS_EQUAL(b1.rows(), rotgen::Index{1}); TTS_EQUAL(rows(b1), rotgen::Index{1});
TTS_EQUAL(b1.cols(), rotgen::Index{1}); TTS_EQUAL(cols(b1), rotgen::Index{1});
TTS_EQUAL(b1(0), 3.5); TTS_EQUAL(b1(0), 3.5);
rotgen::matrix<T, 5, 1, rotgen::ColMajor> b9{0.25, 0.5, 1, 2, 4}; rotgen::matrix<T, 5, 1, rotgen::ColMajor> b9{0.25, 0.5, 1, 2, 4};
TTS_EQUAL(b9.rows(), rotgen::Index{5}); TTS_EQUAL(rows(b9), rotgen::Index{5});
TTS_EQUAL(b9.cols(), rotgen::Index{1}); TTS_EQUAL(cols(b9), rotgen::Index{1});
T i = 0.25; T i = 0.25;
for (rotgen::Index r = 0; r < b9.rows(); ++r) for (rotgen::Index r = 0; r < rows(b9); ++r)
{ {
TTS_EQUAL(b9(r, 0), i); TTS_EQUAL(b9(r, 0), i);
i *= 2; i *= 2;
} }
rotgen::matrix<T, 1, 3, rotgen::RowMajor> b13{1.2, 2.3, 3.4}; rotgen::matrix<T, 1, 3, rotgen::RowMajor> b13{1.2, 2.3, 3.4};
TTS_EQUAL(b13.rows(), rotgen::Index{1}); TTS_EQUAL(rows(b13), rotgen::Index{1});
TTS_EQUAL(b13.cols(), rotgen::Index{3}); TTS_EQUAL(cols(b13), rotgen::Index{3});
TTS_EQUAL(b13(0), T(1.2)); TTS_EQUAL(b13(0), T(1.2));
TTS_EQUAL(b13(1), T(2.3)); TTS_EQUAL(b13(1), T(2.3));
TTS_EQUAL(b13(2), T(3.4)); TTS_EQUAL(b13(2), T(3.4));
@ -201,16 +201,16 @@ TTS_CASE_TPL("Constructor from Initializer list of rows", rotgen::tests::types)
<typename T, typename O>(tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b1{{3.5}}; rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b1{{3.5}};
TTS_EQUAL(b1.rows(), rotgen::Index{1}); TTS_EQUAL(rows(b1), rotgen::Index{1});
TTS_EQUAL(b1.cols(), rotgen::Index{1}); TTS_EQUAL(cols(b1), rotgen::Index{1});
TTS_EQUAL(b1(0, 0), T(3.5)); TTS_EQUAL(b1(0, 0), T(3.5));
rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b23{ rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value> b23{
{1.2, 2.3, 3.4}, {1.2, 2.3, 3.4},
{10, 200, 3000}}; {10, 200, 3000}};
TTS_EQUAL(b23.rows(), rotgen::Index{2}); TTS_EQUAL(rows(b23), rotgen::Index{2});
TTS_EQUAL(b23.cols(), rotgen::Index{3}); TTS_EQUAL(cols(b23), rotgen::Index{3});
TTS_EQUAL(b23(0, 0), T(1.2)); TTS_EQUAL(b23(0, 0), T(1.2));
TTS_EQUAL(b23(0, 1), T(2.3)); TTS_EQUAL(b23(0, 1), T(2.3));
TTS_EQUAL(b23(0, 2), T(3.4)); TTS_EQUAL(b23(0, 2), T(3.4));

View file

@ -11,9 +11,9 @@
#include "unit/common/references.hpp" #include "unit/common/references.hpp"
#include "unit/tests.hpp" #include "unit/tests.hpp"
TTS_CASE_TPL("Test dynamic matrix cwise operations", TTS_CASE_TPL("Test dynamic matrix cwise operations", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_matrix_references(); auto const cases = rotgen::tests::generate_matrix_references();
for (auto const& [rows, cols, fn] : cases) for (auto const& [rows, cols, fn] : cases)
@ -25,15 +25,15 @@ TTS_CASE_TPL("Test dynamic matrix cwise operations",
} }
}; };
TTS_CASE_TPL("Test static matrix cwise operations", TTS_CASE_TPL("Test static matrix cwise operations", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_static_matrix_references(); auto const cases = rotgen::tests::generate_static_matrix_references();
auto process = []<typename D>(D const& desc) { auto process = []<typename D>(D const& desc) {
rotgen::matrix<T, D::rows, D::cols, O::value> input; rotgen::matrix<T, D::rows, D::cols, O::value> input;
rotgen::tests::prepare(input.rows(), input.cols(), desc.init_fn, input); rotgen::tests::prepare(rows(input), cols(input), desc.init_fn, input);
rotgen::tests::check_cwise_functions(input); rotgen::tests::check_cwise_functions(input);
}; };

View file

@ -10,9 +10,9 @@
#include "unit/common/references.hpp" #include "unit/common/references.hpp"
#include "unit/tests.hpp" #include "unit/tests.hpp"
TTS_CASE_TPL("Test dynamic matrix inverse", TTS_CASE_TPL("Test dynamic matrix inverse", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>; using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
auto eps = std::numeric_limits<T>::epsilon(); auto eps = std::numeric_limits<T>::epsilon();
@ -23,7 +23,7 @@ TTS_CASE_TPL("Test dynamic matrix inverse",
auto inv = rotgen::inverse(input); auto inv = rotgen::inverse(input);
auto rec = input * inv; auto rec = input * inv;
auto id = mat_t::Identity(rotgen::rows(rec), rotgen::cols(rec)); auto id = rotgen::setIdentity<mat_t>(rotgen::rows(rec), rotgen::cols(rec));
auto error = rec - id; auto error = rec - id;
TTS_LESS_EQUAL(rotgen::maxCoeff(rotgen::abs(error)) / eps, 256.) TTS_LESS_EQUAL(rotgen::maxCoeff(rotgen::abs(error)) / eps, 256.)
@ -43,7 +43,7 @@ template<typename T, typename O, int N> void check_static_inverse()
auto inv = rotgen::inverse(input); auto inv = rotgen::inverse(input);
auto rec = input * inv; auto rec = input * inv;
auto id = mat_t::Identity(rotgen::rows(rec), rotgen::cols(rec)); auto id = rotgen::setIdentity<mat_t>(rotgen::rows(rec), rotgen::cols(rec));
auto error = rec - id; auto error = rec - id;
TTS_LESS_EQUAL(rotgen::maxCoeff(rotgen::abs(error)) / eps, 256.) TTS_LESS_EQUAL(rotgen::maxCoeff(rotgen::abs(error)) / eps, 256.)
@ -53,9 +53,9 @@ template<typename T, typename O, int N> void check_static_inverse()
<< error << "\n"; << error << "\n";
} }
TTS_CASE_TPL("Test static matrix inverse", TTS_CASE_TPL("Test static matrix inverse", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
check_static_inverse<T, O, 2>(); check_static_inverse<T, O, 2>();
check_static_inverse<T, O, 3>(); check_static_inverse<T, O, 3>();

View file

@ -11,9 +11,9 @@
#include "unit/common/references.hpp" #include "unit/common/references.hpp"
#include "unit/tests.hpp" #include "unit/tests.hpp"
TTS_CASE_TPL("Test dynamic matrix norm operations", TTS_CASE_TPL("Test dynamic matrix norm operations", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_matrix_references(); auto const cases = rotgen::tests::generate_matrix_references();
for (auto const& [rows, cols, fn] : cases) for (auto const& [rows, cols, fn] : cases)
@ -25,15 +25,15 @@ TTS_CASE_TPL("Test dynamic matrix norm operations",
} }
}; };
TTS_CASE_TPL("Test static matrix norm operations", TTS_CASE_TPL("Test static matrix norm operations", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
auto const cases = rotgen::tests::generate_static_matrix_references(); auto const cases = rotgen::tests::generate_static_matrix_references();
auto process = []<typename D>(D const& desc) { auto process = []<typename D>(D const& desc) {
rotgen::matrix<T, D::rows, D::cols, O::value> input; rotgen::matrix<T, D::rows, D::cols, O::value> input;
rotgen::tests::prepare(input.rows(), input.cols(), desc.init_fn, input); rotgen::tests::prepare(rows(input), cols(input), desc.init_fn, input);
rotgen::tests::check_norms_functions(input); rotgen::tests::check_norms_functions(input);
}; };

View file

@ -10,20 +10,20 @@
#include "unit/tests.hpp" #include "unit/tests.hpp"
template<typename MatrixType> template<typename MatrixType>
void test_matrix_operations(rotgen::Index rows, void test_matrix_operations(rotgen::Index rr,
rotgen::Index cols, rotgen::Index cc,
auto a_init_fn, auto a_init_fn,
auto b_init_fn, auto b_init_fn,
auto ops, auto ops,
auto self_ops) auto self_ops)
{ {
MatrixType a(rows, cols); MatrixType a(rr, cc);
MatrixType b(rows, cols); MatrixType b(rr, cc);
MatrixType ref(rows, cols); MatrixType ref(rr, cc);
for (rotgen::Index r = 0; r < rows; ++r) for (rotgen::Index r = 0; r < rr; ++r)
{ {
for (rotgen::Index c = 0; c < cols; ++c) for (rotgen::Index c = 0; c < cc; ++c)
{ {
a(r, c) = a_init_fn(r, c); a(r, c) = a_init_fn(r, c);
b(r, c) = b_init_fn(r, c); b(r, c) = b_init_fn(r, c);
@ -40,19 +40,19 @@ void test_matrix_operations(rotgen::Index rows,
} }
template<typename MatrixType> template<typename MatrixType>
void test_scalar_operations(rotgen::Index rows, void test_scalar_operations(rotgen::Index rr,
rotgen::Index cols, rotgen::Index cc,
auto a_init_fn, auto a_init_fn,
auto s, auto s,
auto ops, auto ops,
auto self_ops) auto self_ops)
{ {
MatrixType a(rows, cols); MatrixType a(rr, cc);
MatrixType ref(rows, cols); MatrixType ref(rr, cc);
for (rotgen::Index r = 0; r < rows; ++r) for (rotgen::Index r = 0; r < rr; ++r)
{ {
for (rotgen::Index c = 0; c < cols; ++c) for (rotgen::Index c = 0; c < cc; ++c)
{ {
a(r, c) = a_init_fn(r, c); a(r, c) = a_init_fn(r, c);
ref(r, c) = ops(a(r, c), s); ref(r, c) = ops(a(r, c), s);
@ -68,17 +68,17 @@ void test_scalar_operations(rotgen::Index rows,
} }
template<typename MatrixType> template<typename MatrixType>
void test_scalar_multiplications(rotgen::Index rows, void test_scalar_multiplications(rotgen::Index rr,
rotgen::Index cols, rotgen::Index cc,
auto fn, auto fn,
auto s) auto s)
{ {
MatrixType a(rows, cols); MatrixType a(rr, cc);
MatrixType ref(rows, cols); MatrixType ref(rr, cc);
for (rotgen::Index r = 0; r < rows; ++r) for (rotgen::Index r = 0; r < rr; ++r)
{ {
for (rotgen::Index c = 0; c < cols; ++c) for (rotgen::Index c = 0; c < cc; ++c)
{ {
a(r, c) = fn(r, c); a(r, c) = fn(r, c);
ref(r, c) = a(r, c) * s; ref(r, c) = a(r, c) * s;
@ -96,27 +96,27 @@ void test_scalar_multiplications(rotgen::Index rows,
} }
template<typename MatrixType> template<typename MatrixType>
void test_matrix_multiplication(rotgen::Index rows, void test_matrix_multiplication(rotgen::Index rr,
rotgen::Index cols, rotgen::Index cc,
auto a_init_fn, auto a_init_fn,
auto b_init_fn) auto b_init_fn)
{ {
MatrixType a(rows, cols); MatrixType a(rr, cc);
MatrixType b(cols, rows); MatrixType b(cc, rr);
MatrixType ref(rows, rows); MatrixType ref(rr, rr);
for (rotgen::Index r = 0; r < a.rows(); ++r) for (rotgen::Index r = 0; r < rows(a); ++r)
for (rotgen::Index c = 0; c < a.cols(); ++c) a(r, c) = a_init_fn(r, c); for (rotgen::Index c = 0; c < cols(a); ++c) a(r, c) = a_init_fn(r, c);
for (rotgen::Index r = 0; r < b.rows(); ++r) for (rotgen::Index r = 0; r < rows(b); ++r)
for (rotgen::Index c = 0; c < b.cols(); ++c) b(r, c) = b_init_fn(r, c); for (rotgen::Index c = 0; c < cols(b); ++c) b(r, c) = b_init_fn(r, c);
for (rotgen::Index i = 0; i < a.rows(); ++i) for (rotgen::Index i = 0; i < rows(a); ++i)
{ {
for (rotgen::Index j = 0; j < b.cols(); ++j) for (rotgen::Index j = 0; j < cols(b); ++j)
{ {
ref(i, j) = 0; ref(i, j) = 0;
for (rotgen::Index k = 0; k < a.cols(); ++k) for (rotgen::Index k = 0; k < cols(a); ++k)
ref(i, j) += a(i, k) * b(k, j); ref(i, j) += a(i, k) * b(k, j);
} }
} }
@ -134,9 +134,9 @@ inline constexpr auto init_b = [](auto r, auto c) {
}; };
inline constexpr auto init_0 = [](auto, auto) { return 0; }; inline constexpr auto init_0 = [](auto, auto) { return 0; };
TTS_CASE_TPL("Check matrix addition", TTS_CASE_TPL("Check matrix addition", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>; using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
auto op = [](auto a, auto b) { return a + b; }; auto op = [](auto a, auto b) { return a + b; };
@ -153,9 +153,9 @@ TTS_CASE_TPL("Check matrix addition",
test_matrix_operations<mat_t>(5, 5, init_a, init_0, op, s_op); test_matrix_operations<mat_t>(5, 5, init_a, init_0, op, s_op);
}; };
TTS_CASE_TPL("Check matrix substraction", TTS_CASE_TPL("Check matrix substraction", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>; using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
auto op = [](auto a, auto b) { return a - b; }; auto op = [](auto a, auto b) { return a - b; };
@ -172,9 +172,9 @@ TTS_CASE_TPL("Check matrix substraction",
test_matrix_operations<mat_t>(5, 5, init_a, init_0, op, s_op); test_matrix_operations<mat_t>(5, 5, init_a, init_0, op, s_op);
}; };
TTS_CASE_TPL("Check matrix multiplications", TTS_CASE_TPL("Check matrix multiplications", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>; using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
auto init_id = [](auto r, auto c) { return r == c ? 1 : 0; }; auto init_id = [](auto r, auto c) { return r == c ? 1 : 0; };
@ -193,9 +193,9 @@ TTS_CASE_TPL("Check matrix multiplications",
test_matrix_multiplication<mat_t>(5, 5, init_a, init_0); test_matrix_multiplication<mat_t>(5, 5, init_a, init_0);
}; };
TTS_CASE_TPL("Check matrix multiplication with scalar", TTS_CASE_TPL("Check matrix multiplication with scalar", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>; using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
@ -209,9 +209,9 @@ TTS_CASE_TPL("Check matrix multiplication with scalar",
test_scalar_multiplications<mat_t>(1, 10, init_a, T{-0.5}); test_scalar_multiplications<mat_t>(1, 10, init_a, T{-0.5});
}; };
TTS_CASE_TPL("Check matrix division with scalar", TTS_CASE_TPL("Check matrix division with scalar", rotgen::tests::types)
rotgen::tests::types)<typename T, typename O>(
tts::type<tts::types<T, O>>) <typename T, typename O>(tts::type<tts::types<T, O>>)
{ {
using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>; using mat_t = rotgen::matrix<T, rotgen::Dynamic, rotgen::Dynamic, O::value>;
auto op = [](auto a, auto b) { return a / b; }; auto op = [](auto a, auto b) { return a / b; };

View file

@ -22,7 +22,7 @@ template<typename Ref, typename Generator> void check_acceptance(Generator f)
TTS_EQUAL(v.data(), ptr); TTS_EQUAL(v.data(), ptr);
// Setup the data correctly // Setup the data correctly
data.resize(v.rows(), v.cols()); data.resize(rows(v), cols(v));
rotgen::setRandom(data); rotgen::setRandom(data);
// Assign through the ref // Assign through the ref
@ -34,7 +34,7 @@ template<typename Ref, typename Generator> void check_acceptance(Generator f)
}; };
acceptor(in, in.data()); acceptor(in, in.data());
data.resize(in.rows(), in.cols()); data.resize(rows(in), cols(in));
TTS_EQUAL(in, data); TTS_EQUAL(in, data);
TTS_EQUAL(constant_acceptor(in), minCoeff(data)) << in << "\n" TTS_EQUAL(constant_acceptor(in), minCoeff(data)) << in << "\n"