Merge branch 'feat/fixed-impl' into 'main'

Implement fixed size options for rotgen containers


See merge request oss/rotgen!11
This commit is contained in:
Joel Falcou 2025-07-20 20:23:51 +02:00
commit 2810ad7cf8
39 changed files with 1247 additions and 323 deletions

View file

@ -1,57 +1,61 @@
# https://docs.gitlab.com/ee/ci/yaml/ # https://docs.gitlab.com/ee/ci/yaml/
# Job templates
.docker-job: &docker-job
tags: [docker]
cache:
paths: [/var/cache/pacman, build/]
image: archlinux/archlinux:base-devel
before_script: [./ci-cd/environment-setup.sh]
.native-job: &native-job .native-job: &native-job
tags: ["shell"] tags: ["shell"]
cache:
paths: [build/]
stages: stages:
- build
- test - test
# Native stuff test-debug:
build-debug-native:
<<: *native-job <<: *native-job
stage: build stage: test
artifacts:
paths:
- build/debug/
script: script:
- cmake --preset debug -DCMAKE_CXX_COMPILER=clang++ - cmake --preset debug -DCMAKE_CXX_COMPILER=clang++
- cmake --build --preset debug - cmake --build --preset debug
- cmake --build --preset debug --target rotgen-test
- cd build/debug && ctest --output-on-failure --verbose
build-release-native: test-debug-static:
<<: *native-job <<: *native-job
stage: build stage: test
artifacts: script:
paths: - cmake --preset debug-static -DCMAKE_CXX_COMPILER=clang++
- build/release/ - cmake --build --preset debug-static
- cmake --build --preset debug-static --target rotgen-test
- cd build/debug-static && ctest --output-on-failure --verbose
test-debug-et:
<<: *native-job
stage: test
script:
- cmake --preset debug-et -DCMAKE_CXX_COMPILER=clang++
- cmake --build --preset debug-et
- cmake --build --preset debug-et --target rotgen-test
- cd build/debug-et && ctest --output-on-failure --verbose
test-release:
<<: *native-job
stage: test
script: script:
- cmake --preset release -DCMAKE_CXX_COMPILER=clang++ - cmake --preset release -DCMAKE_CXX_COMPILER=clang++
- cmake --build --preset release - cmake --build --preset release
test-debug-native:
<<: *native-job
needs: ["build-debug-native"]
stage: test
script:
- cmake --build --preset debug --target rotgen-test
- cd build/debug && ctest --output-on-failure
test-release-native:
<<: *native-job
needs: ["build-release-native"]
stage: test
script:
- cmake --build --preset release --target rotgen-test - cmake --build --preset release --target rotgen-test
- cd build/release && ctest --output-on-failure - cd build/release && ctest --output-on-failure --verbose
test-release-static:
<<: *native-job
stage: test
script:
- cmake --preset release-static -DCMAKE_CXX_COMPILER=clang++
- cmake --build --preset release-static
- cmake --build --preset release-static --target rotgen-test
- cd build/release-static && ctest --output-on-failure --verbose
test-release-et:
<<: *native-job
stage: test
script:
- cmake --preset release-et -DCMAKE_CXX_COMPILER=clang++
- cmake --build --preset release-et
- cmake --build --preset release-et --target rotgen-test
- cd build/release-et && ctest --output-on-failure --verbose

View file

@ -25,13 +25,30 @@ if (${PROJECT_SOURCE_DIR} STREQUAL ${PROJECT_BINARY_DIR})
message(FATAL_ERROR "[${PROJECT_NAME}]: In-source build is not supported") message(FATAL_ERROR "[${PROJECT_NAME}]: In-source build is not supported")
endif() endif()
##======================================================================================================================
## Handle options
##======================================================================================================================
option(ROTGEN_FORCE_DYNAMIC "Force dynamic configuration for rotgen" OFF)
option(ROTGEN_DISABLE_EXPRESSION_TEMPLATES "Disable expression templates" OFF)
set(ROTGEN_MAX_SIZE "" CACHE STRING "Max matrix number of elements for rotgen (integer)")
include(${ROTGEN_SOURCE_DIR}/cmake/options.cmake)
handle_option(ROTGEN_COMPILE_DEFS)
##====================================================================================================================== ##======================================================================================================================
## Sources & Public Headers lists ## Sources & Public Headers lists
##====================================================================================================================== ##======================================================================================================================
set ( SOURCES if(ROTGEN_FORCE_DYNAMIC)
src/matrix.cpp set ( SOURCES
src/block.cpp src/matrix.cpp
) src/block.cpp
src/info.cpp
)
else()
set ( SOURCES
src/info.cpp
)
endif()
##====================================================================================================================== ##======================================================================================================================
## Setup the library's dependencies ## Setup the library's dependencies
@ -46,6 +63,7 @@ set_target_properties(rotgen PROPERTIES VERSION ${PROJECT_VERSION})
set_target_properties(rotgen PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR}) set_target_properties(rotgen PROPERTIES SOVERSION ${PROJECT_VERSION_MAJOR})
target_compile_options(rotgen PUBLIC -std=c++20 -Werror -Wall -Wextra -Wshadow -Wunused-variable) target_compile_options(rotgen PUBLIC -std=c++20 -Werror -Wall -Wextra -Wshadow -Wunused-variable)
target_compile_definitions(rotgen PUBLIC ${ROTGEN_COMPILE_DEFS})
set_target_properties(rotgen PROPERTIES EXPORT_NAME rotgen) set_target_properties(rotgen PROPERTIES EXPORT_NAME rotgen)
add_library(rotgen::rotgen ALIAS rotgen) add_library(rotgen::rotgen ALIAS rotgen)

View file

@ -40,6 +40,46 @@
"cacheVariables": { "cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug" "CMAKE_BUILD_TYPE": "Debug"
} }
},
{
"name": "release-static",
"displayName": "Release (Static size)",
"description": "Release (Static size) build",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/release-static",
"cacheVariables": {
"ROTGEN_MAX_SIZE": "4"
}
},
{
"name": "debug-static",
"displayName": "Debug (Static size)",
"description": "Debug (Static size) build",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/debug-static",
"cacheVariables": {
"ROTGEN_MAX_SIZE": "4"
}
},
{
"name": "release-et",
"displayName": "Release (No Expr. Temp.)",
"description": "Release (No Expr. Temp.) build",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/release-et",
"cacheVariables": {
"ROTGEN_DISABLE_EXPRESSION_TEMPLATES": "ON"
}
},
{
"name": "debug-et",
"displayName": "Debug (No Expr. Temp.)",
"description": "Debug (No Expr. Temp.) build",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/debug-et",
"cacheVariables": {
"ROTGEN_DISABLE_EXPRESSION_TEMPLATES": "ON"
}
} }
], ],
"buildPresets": [ "buildPresets": [
@ -47,9 +87,25 @@
"name": "release", "name": "release",
"configurePreset": "release" "configurePreset": "release"
}, },
{
"name": "release-static",
"configurePreset": "release-static"
},
{
"name": "release-et",
"configurePreset": "release-et"
},
{ {
"name": "debug", "name": "debug",
"configurePreset": "debug" "configurePreset": "debug"
},
{
"name": "debug-static",
"configurePreset": "debug-static"
},
{
"name": "debug-et",
"configurePreset": "debug-et"
} }
] ]
} }

106
cmake/options.cmake Normal file
View file

@ -0,0 +1,106 @@
##======================================================================================================================
## ROTGEN - Runtime Overlay for Eigen
## Copyright : CODE RECKONS
## SPDX-License-Identifier: BSL-1.0
##======================================================================================================================
function(assert_integer VAR_NAME)
if(DEFINED ${VAR_NAME} AND NOT ${${VAR_NAME}} STREQUAL "")
if(NOT ${${VAR_NAME}} MATCHES "^[0-9]+$")
message(FATAL_ERROR "[ROTGEN] - ${VAR_NAME} must be a non-negative integer, got '${${VAR_NAME}}'}")
endif()
endif()
endfunction()
function(check_force_dynamic_and_sizes FORCE_DYNAMIC_VAR MAX_SIZE_VAR)
if(${FORCE_DYNAMIC_VAR})
if(NOT ${MAX_SIZE_VAR} STREQUAL "")
message(FATAL_ERROR "[ROTGEN] - ROTGEN_FORCE_DYNAMIC is set, so ROTGEN_MAX_SIZE must not be defined.")
endif()
endif()
endfunction()
function(infer_force_dynamic FORCE_DYNAMIC_VAR MAX_SIZE_VAR OUT_FORCE_DYNAMIC_INFERRED)
set(${OUT_FORCE_DYNAMIC_INFERRED} OFF PARENT_SCOPE)
if(${FORCE_DYNAMIC_VAR})
if(NOT ${MAX_SIZE_VAR} STREQUAL "")
message(FATAL_ERROR "ROTGEN_FORCE_DYNAMIC cannot be used together with MAX_SIZE.")
endif()
elseif(${MAX_SIZE_VAR} STREQUAL "")
# None set, enable force_dynamic
set(${OUT_FORCE_DYNAMIC_INFERRED} ON PARENT_SCOPE)
set(${FORCE_DYNAMIC_VAR} ON PARENT_SCOPE) # update caller variable!
endif()
endfunction()
function(build_compile_definitions FORCE_DYNAMIC_VAR MAX_SIZE_VAR OUT_DEFS)
set(defs "")
if(${FORCE_DYNAMIC_VAR})
list(APPEND defs "ROTGEN_FORCE_DYNAMIC")
else()
if(NOT ${MAX_SIZE_VAR} STREQUAL "")
list(APPEND defs "ROTGEN_MAX_SIZE=${${MAX_SIZE_VAR}}")
endif()
endif()
set(${OUT_DEFS} "${defs}" PARENT_SCOPE)
endfunction()
function(print_configuration_summary FORCE_DYNAMIC_VAR FORCE_CONFIG_REASON MAX_SIZE_VAR COMPILE_DEFS)
message(STATUS "==================== Rotgen Configuration Summary ====================")
if(DEFINED ROTGEN_DISABLE_EXPRESSION_TEMPLATES AND ROTGEN_DISABLE_EXPRESSION_TEMPLATES)
message(STATUS " Configuration mode: DISABLE_EXPRESSION_TEMPLATES (overrides other settings)")
elseif(${FORCE_DYNAMIC_VAR})
message(STATUS " Configuration mode: DYNAMIC")
if(${FORCE_CONFIG_REASON})
message(STATUS " Reason : No static size options were provided")
endif()
else()
message(STATUS " Configuration mode: STATIC")
endif()
set(PREPROCESSOR_FLAGS "")
foreach(def IN LISTS COMPILE_DEFS)
string(APPEND PREPROCESSOR_FLAGS " -D${def}")
endforeach()
message(STATUS " Preprocessor flags: ${PREPROCESSOR_FLAGS}")
message(STATUS "======================================================================")
endfunction()
function(handle_option OUT_DEFS)
# Early-out if disabling expression templates
if(NOT DEFINED ROTGEN_DISABLE_EXPRESSION_TEMPLATES)
set(ROTGEN_DISABLE_EXPRESSION_TEMPLATES OFF)
endif()
if(ROTGEN_DISABLE_EXPRESSION_TEMPLATES)
# Pass only the disable flag
set(${OUT_DEFS} "ROTGEN_DISABLE_EXPRESSION_TEMPLATES" PARENT_SCOPE)
message(STATUS "==================== Rotgen Configuration Summary ====================")
message(STATUS " Configuration mode: DISABLE_EXPRESSION_TEMPLATES (overrides other settings)")
message(STATUS " Preprocessor flags: -DROTGEN_DISABLE_EXPRESSION_TEMPLATES")
message(STATUS "======================================================================")
# Propagate to parent
set(ROTGEN_DISABLE_EXPRESSION_TEMPLATES ${ROTGEN_DISABLE_EXPRESSION_TEMPLATES} PARENT_SCOPE)
return()
endif()
# Defaults for other options
if(NOT DEFINED ROTGEN_FORCE_DYNAMIC)
set(ROTGEN_FORCE_DYNAMIC OFF)
endif()
if(NOT DEFINED ROTGEN_MAX_SIZE)
set(ROTGEN_MAX_SIZE "")
endif()
assert_integer("ROTGEN_MAX_SIZE")
check_force_dynamic_and_sizes("ROTGEN_FORCE_DYNAMIC" "ROTGEN_MAX_SIZE")
infer_force_dynamic("ROTGEN_FORCE_DYNAMIC" "ROTGEN_MAX_SIZE" _force_dynamic_inferred)
build_compile_definitions("ROTGEN_FORCE_DYNAMIC" "ROTGEN_MAX_SIZE" defs)
print_configuration_summary("ROTGEN_FORCE_DYNAMIC" "_force_dynamic_inferred" "ROTGEN_MAX_SIZE" "${defs}")
set(${OUT_DEFS} "${defs}" PARENT_SCOPE)
set(ROTGEN_FORCE_DYNAMIC ${ROTGEN_FORCE_DYNAMIC} PARENT_SCOPE)
set(ROTGEN_MAX_SIZE ${ROTGEN_MAX_SIZE} PARENT_SCOPE)
endfunction()

View file

@ -0,0 +1,18 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once
namespace rotgen::concepts
{
template<typename T>
concept entity = requires(T const&)
{
typename T::rotgen_tag;
typename T::parent;
};
}

62
include/rotgen/config.hpp Normal file
View file

@ -0,0 +1,62 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once
#include <cstddef>
#include <iosfwd>
namespace rotgen
{
using Index = std::ptrdiff_t;
}
#if defined(ROTGEN_DISABLE_EXPRESSION_TEMPLATES)
#define ROTGEN_MAX_SIZE 0
#endif
#if !defined(ROTGEN_FORCE_DYNAMIC)
#if !defined(ROTGEN_MAX_SIZE)
#define ROTGEN_FORCE_DYNAMIC
#endif
#endif
#if defined(ROTGEN_FORCE_DYNAMIC)
#define ROTGEN_HAS_STATIC_LIMIT false
#else
#define ROTGEN_HAS_STATIC_LIMIT true
#endif
namespace rotgen
{
inline constexpr bool has_static_limit = ROTGEN_HAS_STATIC_LIMIT;
inline constexpr bool is_forcing_dynamic_status = !has_static_limit;
std::ostream& setup_summary(std::ostream& os);
}
#if defined(ROTGEN_FORCE_DYNAMIC)
namespace rotgen
{
inline constexpr Index max_static_size = -1;
template<int Rows, int Cols>
inline constexpr bool storage_status = false;
}
#else
namespace rotgen
{
inline constexpr Index max_static_size = ROTGEN_MAX_SIZE;
template<int Rows, int Cols>
inline constexpr bool storage_status = (Rows > 0 && Cols > 0) && ((Rows*Cols) <= max_static_size);
}
#endif
namespace rotgen
{
inline constexpr bool use_expression_templates = max_static_size > 0;
}

View file

@ -23,5 +23,5 @@ namespace rotgen
inline constexpr int AutoAlign = 0; inline constexpr int AutoAlign = 0;
inline constexpr int ColMajor = 0; inline constexpr int ColMajor = 0;
inline constexpr int RowMajor = 1; inline constexpr int RowMajor = 1;
inline constexpr int DotnAlgin = 2; inline constexpr int DontAlign = 2;
} }

View file

@ -7,8 +7,9 @@
//================================================================================================== //==================================================================================================
#pragma once #pragma once
#include <rotgen/concepts.hpp>
#include <rotgen/impl/block.hpp> #include <rotgen/impl/block.hpp>
#include <rotgen/matrix.hpp> #include <rotgen/dynamic/matrix.hpp>
#include <initializer_list> #include <initializer_list>
#include <cassert> #include <cassert>
@ -17,8 +18,13 @@ namespace rotgen
template<typename Ref, int Rows = Dynamic, int Cols = Dynamic, bool Inner = false, int ForceStorageOrder = -1> template<typename Ref, int Rows = Dynamic, int Cols = Dynamic, bool Inner = false, int ForceStorageOrder = -1>
class block : public find_block<Ref> class block : public find_block<Ref>
{ {
using parent = find_block<Ref>;
public: public:
static_assert ( concepts::entity<Ref>
, "[ROTGEN][CRITICAL] - Block of non-rotgen type instanciated"
);
using parent = find_block<Ref>;
using rotgen_tag = void;
using scalar_type = typename Ref::scalar_type; using scalar_type = typename Ref::scalar_type;
static constexpr int storage_order = (ForceStorageOrder == -1) ? Ref::storage_order : ForceStorageOrder; static constexpr int storage_order = (ForceStorageOrder == -1) ? Ref::storage_order : ForceStorageOrder;
using concrete_type = matrix<scalar_type,Rows,Cols,storage_order>; using concrete_type = matrix<scalar_type,Rows,Cols,storage_order>;

View file

@ -20,12 +20,16 @@ namespace rotgen
> >
class matrix : public find_matrix<Scalar,Options> class matrix : public find_matrix<Scalar,Options>
{ {
using parent = find_matrix<Scalar,Options>;
public: public:
using scalar_type = Scalar; using parent = find_matrix<Scalar,Options>;
using rotgen_tag = void;
using concrete_type = matrix;
using scalar_type = Scalar;
static constexpr auto storage_order = Options & 1; static constexpr auto storage_order = Options & 1;
static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols;
matrix() : parent(Rows==-1?0:Rows,Cols==-1?0:Cols) {} matrix() : parent(Rows==-1?0:Rows,Cols==-1?0:Cols) {}
matrix(int r, int c) : parent(r, c) matrix(int r, int c) : parent(r, c)
@ -36,7 +40,7 @@ namespace rotgen
matrix(parent const& base) : parent(base) {} matrix(parent const& base) : parent(base) {}
matrix(std::initializer_list<std::initializer_list<Scalar>> init) : parent(init) explicit matrix(std::initializer_list<std::initializer_list<Scalar>> init) : parent(init)
{ {
if constexpr(Rows != -1) assert(init.size() == Rows && "Mismatched between dynamic and static row size"); if constexpr(Rows != -1) assert(init.size() == Rows && "Mismatched between dynamic and static row size");
if constexpr(Cols != -1) if constexpr(Cols != -1)
@ -48,7 +52,7 @@ namespace rotgen
} }
template<std::convertible_to<Scalar>... S> template<std::convertible_to<Scalar>... S>
matrix(Scalar s0,S... init) explicit matrix(Scalar s0,S... init)
requires((Rows == 1 && Cols == (1+sizeof...(S))) || (Cols == 1 && Rows == (1+sizeof...(S)))) requires((Rows == 1 && Cols == (1+sizeof...(S))) || (Cols == 1 && Rows == (1+sizeof...(S))))
: parent(Rows, Cols, {s0,static_cast<Scalar>(init)...}) : parent(Rows, Cols, {s0,static_cast<Scalar>(init)...})
{} {}
@ -170,7 +174,7 @@ namespace rotgen
} }
template<int P> template<int P>
Scalar lp_norm() const 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);

View file

@ -7,9 +7,6 @@
//================================================================================================== //==================================================================================================
#pragma once #pragma once
#include <rotgen/matrix.hpp>
#include <rotgen/block.hpp>
namespace rotgen namespace rotgen
{ {
template< typename S, int R , int C template< typename S, int R , int C

View file

@ -0,0 +1,224 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once
#include <rotgen/detail/static_info.hpp>
#include <rotgen/fixed/common.hpp>
#include <Eigen/Dense>
#include <iostream>
namespace rotgen
{
namespace detail
{
template<typename Ref, int Rows, int Cols, bool Inner>
using block_type = std::conditional_t < storage_status<Rows,Cols>
, Eigen::Block<typename Ref::parent, Rows, Cols, Inner>
, Eigen::Block<typename Ref::parent, Eigen::Dynamic, Eigen::Dynamic, Inner>
>;
}
template< typename Ref
, int Rows = Dynamic, int Cols = Dynamic
, bool Inner = false, int ForceStorageOrder = -1
>
class block : private detail::block_type<Ref, Rows, Cols, Inner>
{
static_assert ( concepts::entity<Ref>
, "[ROTGEN][CRITICAL] - Block of non-rotgen type instanciated"
);
public:
using rotgen_tag = void;
using parent = detail::block_type<Ref, Rows, Cols, Inner>;
using value_type = typename parent::value_type;
using scalar_type = typename parent::value_type;
using Index = typename parent::Index;
static constexpr int storage_order = (ForceStorageOrder == -1) ? Ref::storage_order : ForceStorageOrder;
using concrete_type = matrix<scalar_type,Rows,Cols,storage_order>;
using concrete_dynamic_type = matrix<scalar_type>;
template<typename ET>
using as_concrete_type = as_concrete_t<ET, matrix>;
static constexpr int RowsAtCompileTime = Rows;
static constexpr int ColsAtCompileTime = Cols;
private:
static constexpr bool has_static_storage = storage_status<Rows,Cols>;
public:
block(const block& other) = default;
block(block&& other) = default;
block& operator=(const block&) = default;
block& operator=(block&&) = default;
block(Ref& r, std::size_t i0, std::size_t j0, std::size_t ni, std::size_t nj) : parent(r.base(),i0,j0,ni,nj)
{}
block(Ref& r, std::size_t i0, std::size_t j0) requires(Rows != -1 && Cols != -1)
: parent(r.base(),i0,j0,Rows,Cols)
{}
template<typename OtherDerived>
block(const Eigen::MatrixBase<OtherDerived>& other) : parent(other) {}
template<typename OtherDerived>
block(const Eigen::EigenBase<OtherDerived>& other) : parent(other) {}
template<typename OtherDerived>
block& operator=(const Eigen::MatrixBase<OtherDerived>& other)
{
parent::operator=(other);
return *this;
}
template<typename OtherDerived>
block& operator=(const Eigen::EigenBase<OtherDerived>& other)
{
parent::operator=(other);
return *this;
}
parent& base() { return static_cast<parent&>(*this); }
parent const& base() const { return static_cast<const parent&>(*this); }
concrete_type transpose() const
{
return concrete_type(static_cast<parent const &>(*this).transpose());
}
concrete_type conjugate() const
{
return concrete_type(static_cast<parent const &>(*this).conjugate());
}
concrete_type adjoint() const
{
return concrete_type(static_cast<parent const &>(*this).adjoint());
}
void transposeInPlace() { parent::transposeInPlace(); }
void adjointInPlace() { parent::adjointInPlace(); }
static concrete_type Constant(scalar_type value) requires (Rows != -1 && Cols != -1)
{
return parent::Constant(Rows, Cols, static_cast<scalar_type>(value));
}
static concrete_type Constant(int rows, int cols, scalar_type value)
{
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
return parent::Constant(rows, cols, static_cast<scalar_type>(value));
}
static concrete_type Identity() requires (Rows != -1 && Cols != -1)
{
return parent::Identity(Rows, Cols);
}
static concrete_type Identity(int rows, int cols)
{
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
return parent::Identity(rows, cols);
}
static concrete_type Zero() requires (Rows != -1 && Cols != -1)
{
return parent::Zero(Rows, Cols);
}
static concrete_type Zero(int rows, int cols)
{
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
return parent::Zero(rows, cols);
}
static concrete_type Random() requires (Rows != -1 && Cols != -1)
{
return parent::Random(Rows, Cols);
}
static concrete_type Random(int rows, int cols)
{
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
return parent::Random(rows, cols);
}
template<int P>
scalar_type lpNorm() const
{
static_assert(P == 1 || P == 2 || P == Infinity);
return parent::template lpNorm<P>();
}
using parent::operator();
using parent::rows;
using parent::cols;
using parent::size;
using parent::prod;
using parent::mean;
using parent::trace;
using parent::maxCoeff;
using parent::minCoeff;
using parent::squaredNorm;
using parent::norm;
using parent::sum;
using parent::data;
block& operator+=(block const& rhs)
{
static_cast<parent&>(*this) += static_cast<parent const&>(rhs);
return *this;
}
block& operator-=(block const& rhs)
{
static_cast<parent&>(*this) -= static_cast<parent const&>(rhs);
return *this;
}
concrete_type operator-() const
{
return concrete_type(static_cast<parent const&>(*this).operator-());
}
block& operator*=(block const& rhs)
{
static_cast<parent&>(*this) *= static_cast<parent const&>(rhs);
return *this;
}
block& operator*=(scalar_type rhs)
{
static_cast<parent&>(*this) *= rhs;
return *this;
}
block& operator/=(scalar_type rhs)
{
static_cast<parent&>(*this) /= rhs;
return *this;
}
static void print_storage_info()
{
std::cout << "Block " << Rows << "x" << Cols
<< " - Storage: " << (has_static_storage ? "Static" : "Dynamic")
<< " (from: ";
Ref::print_storage_info();
std::cout << ")" << std::endl;
}
};
}

View file

@ -0,0 +1,86 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once
#include <rotgen/concepts.hpp>
#include <concepts>
#include <iosfwd>
namespace rotgen
{
template<typename EigenType
, template<typename,int,int,int,int,int> typename Wrapper
>
struct as_concrete
{
using type = Wrapper< typename EigenType::value_type
, EigenType::RowsAtCompileTime, EigenType::ColsAtCompileTime
, EigenType::Flags
, EigenType::MaxRowsAtCompileTime, EigenType::MaxColsAtCompileTime
>;
};
template<typename EigenType
, template<typename,int,int,int,int,int> typename Wrapper
>
using as_concrete_t = typename as_concrete<EigenType,Wrapper>::type;
template<concepts::entity E1, concepts::entity E2>
bool operator==(E1 const& lhs, E2 const& rhs)
{
return lhs.base() == rhs.base();
}
template<concepts::entity E>
std::ostream& operator<<(std::ostream& os, E const& arg)
{
return os << arg.base();
}
template<concepts::entity E1, concepts::entity E2>
auto operator+(E1 const& lhs, E2 const& rhs)
{
using type = E1::template as_concrete_type<decltype(lhs.base() + rhs.base())>;
return type(lhs.base() + rhs.base());
}
template<concepts::entity E1, concepts::entity E2>
auto operator-(E1 const& lhs, E2 const& rhs)
{
using type = E1::template as_concrete_type<decltype(lhs.base() - rhs.base())>;
return type(lhs.base() - rhs.base());
}
template<concepts::entity E1, concepts::entity E2>
auto operator*(E1 const& lhs, E2 const& rhs)
{
using type = typename E1::concrete_dynamic_type;
return type(lhs.base() * rhs.base());
}
template<concepts::entity E, std::convertible_to<typename E::scalar_type> S>
auto operator*(E const& lhs, S rhs)
{
using type = E::template as_concrete_type<decltype(lhs.base() * rhs)>;
return type(lhs.base() * rhs);
}
template<concepts::entity E, std::convertible_to<typename E::scalar_type> S>
auto operator*(S lhs, E const& rhs )
{
using type = E::template as_concrete_type<decltype(lhs * rhs.base())>;
return type(lhs * rhs.base());
}
template<concepts::entity E, std::convertible_to<typename E::scalar_type> S>
auto operator/(E const& lhs, S rhs)
{
using type = E::template as_concrete_type<decltype(lhs.base() / rhs)>;
return type(lhs.base() / rhs);
}
}

View file

@ -0,0 +1,246 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#pragma once
#include <rotgen/detail/static_info.hpp>
#include <rotgen/fixed/common.hpp>
#include <Eigen/Dense>
#include <iostream>
namespace rotgen
{
namespace detail
{
template<typename Scalar, int Rows, int Cols, int Opts,int MaxRows, int MaxCols>
using storage_type = std::conditional_t < storage_status<Rows,Cols>
, Eigen::Matrix<Scalar, Rows, Cols, Opts, MaxRows, MaxCols>
, Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Opts>
>;
}
template< typename Scalar
, int Rows = Dynamic , int Cols = Dynamic
, int Options = ColMajor
, int MaxRows = Rows , int MaxCols = Cols
>
class matrix : private detail::storage_type<Scalar, Rows, Cols, Options, MaxRows, MaxCols>
{
public:
using rotgen_tag = void;
using parent = detail::storage_type<Scalar, Rows, Cols, Options, MaxRows, MaxCols>;
using value_type = Scalar;
using scalar_type = Scalar;
using Index = typename parent::Index;
static constexpr auto storage_order = Options & 1;
using concrete_type = matrix;
using concrete_dynamic_type = matrix<scalar_type>;
template<typename ET>
using as_concrete_type = as_concrete_t<ET, matrix>;
private:
static constexpr bool has_static_storage = storage_status<Rows,Cols>;
public:
matrix() requires(has_static_storage) {}
matrix() requires(!has_static_storage) : parent(Rows > 0 ? Rows : 0, Cols > 0 ? Cols : 0){}
matrix(Index r, Index c) requires(!has_static_storage) : parent(r, c) {}
matrix(const matrix& other) = default;
matrix(matrix&& other) = default;
matrix& operator=(const matrix&) = default;
matrix& operator=(matrix&&) = default;
matrix(std::initializer_list<std::initializer_list<Scalar>> init) : parent(init)
{}
template<std::convertible_to<Scalar>... S>
requires((Rows == 1 && Cols == (1+sizeof...(S))) || (Cols == 1 && Rows == (1+sizeof...(S))))
matrix(Scalar s0,S... init)
: parent ( [&]()
{
if constexpr(has_static_storage)
return parent{static_cast<Scalar>(s0),static_cast<Scalar>(init)...};
else return parent{Rows,Cols};
}()
)
{
if constexpr(!has_static_storage)
{
auto raw = {static_cast<Scalar>(s0),static_cast<Scalar>(init)...};
auto first = raw.begin();
for(rotgen::Index i=0; i < parent::size(); i++)
(*this)(i) = first[i];
}
}
template<typename OtherDerived>
matrix(const Eigen::MatrixBase<OtherDerived>& other) : parent(other)
{}
template<typename OtherDerived>
matrix& operator=(const Eigen::MatrixBase<OtherDerived>& other)
{
parent::operator=(other);
return *this;
}
template<typename OtherDerived>
matrix& operator=(const Eigen::EigenBase<OtherDerived>& other)
{
parent::operator=(other);
return *this;
}
parent& base() { return static_cast<parent&>(*this); }
parent const& base() const { return static_cast<const parent&>(*this); }
concrete_type transpose() const
{
return concrete_type(static_cast<parent const &>(*this).transpose());
}
concrete_type conjugate() const
{
return concrete_type(static_cast<parent const &>(*this).conjugate());
}
concrete_type adjoint() const
{
return concrete_type(static_cast<parent const &>(*this).adjoint());
}
void transposeInPlace() { parent::transposeInPlace(); }
void adjointInPlace() { parent::adjointInPlace(); }
void resize(int new_rows, int new_cols) requires(Rows == -1 && Cols == -1)
{
parent::resize(new_rows, new_cols);
}
void conservativeResize(int new_rows, int new_cols) requires(Rows == -1 && Cols == -1)
{
parent::conservativeResize(new_rows, new_cols);
}
static matrix Constant(Scalar value) requires (Rows != -1 && Cols != -1)
{
return parent::Constant(Rows, Cols, static_cast<Scalar>(value));
}
static matrix Constant(int rows, int cols, Scalar value)
{
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
return parent::Constant(rows, cols, static_cast<Scalar>(value));
}
static matrix Identity() requires (Rows != -1 && Cols != -1)
{
return parent::Identity(Rows, Cols);
}
static matrix Identity(int rows, int cols)
{
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
return parent::Identity(rows, cols);
}
static matrix Zero() requires (Rows != -1 && Cols != -1)
{
return parent::Zero(Rows, Cols);
}
static matrix Zero(int rows, int cols)
{
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
return parent::Zero(rows, cols);
}
static matrix Random() requires (Rows != -1 && Cols != -1)
{
return parent::Random(Rows, Cols);
}
static matrix Random(int rows, int cols)
{
if constexpr(Rows != -1) assert(rows == Rows && "Mismatched between dynamic and static row size");
if constexpr(Cols != -1) assert(cols == Cols && "Mismatched between dynamic and static column size");
return parent::Random(rows, cols);
}
template<int P>
scalar_type lpNorm() const
{
static_assert(P == 1 || P == 2 || P == Infinity);
return parent::template lpNorm<P>();
}
using parent::operator();
using parent::rows;
using parent::cols;
using parent::size;
using parent::prod;
using parent::mean;
using parent::trace;
using parent::maxCoeff;
using parent::minCoeff;
using parent::squaredNorm;
using parent::norm;
using parent::sum;
using parent::data;
matrix& operator+=(matrix const& rhs)
{
static_cast<parent&>(*this) += static_cast<parent const&>(rhs);
return *this;
}
matrix& operator-=(matrix const& rhs)
{
static_cast<parent&>(*this) -= static_cast<parent const&>(rhs);
return *this;
}
matrix operator-() const
{
return matrix(static_cast<parent const&>(*this).operator-());
}
matrix& operator*=(matrix const& rhs)
{
static_cast<parent&>(*this) *= static_cast<parent const&>(rhs);
return *this;
}
matrix& operator*=(Scalar rhs)
{
static_cast<parent&>(*this) *= rhs;
return *this;
}
matrix& operator/=(Scalar rhs)
{
static_cast<parent&>(*this) /= rhs;
return *this;
}
static void print_storage_info()
{
std::cout << "Matrix " << Rows << "x" << Cols
<< " - Storage: " << (has_static_storage ? "Static" : "Dynamic")
<< " (Max. size=" << max_static_size << ")"
<< std::endl;
}
};
}

View file

@ -6,7 +6,6 @@
*/ */
//================================================================================================== //==================================================================================================
#pragma once #pragma once
#include <rotgen/matrix.hpp>
namespace rotgen namespace rotgen
{ {
@ -88,7 +87,8 @@ namespace rotgen
double lpNorm(const rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix) double lpNorm(const rotgen::matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &matrix)
{ {
static_assert(P == 1 || P == 2 || P == Infinity); static_assert(P == 1 || P == 2 || P == Infinity);
return matrix.template lp_norm<P>();
return matrix.template lpNorm<P>();
} }
template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols > template< typename Scalar, int Rows = -1, int Cols = 1, int Options = 0, int MaxRows = Rows, int MaxCols = Cols >

View file

@ -24,9 +24,9 @@ class CLASSNAME
~CLASSNAME(); ~CLASSNAME();
std::size_t rows() const; Index rows() const;
std::size_t cols() const; Index cols() const;
std::size_t size() const; Index size() const;
SOURCENAME transpose() const; SOURCENAME transpose() const;
SOURCENAME conjugate() const; SOURCENAME conjugate() const;

View file

@ -9,6 +9,7 @@
#include <rotgen/detail/generators.hpp> #include <rotgen/detail/generators.hpp>
#include <rotgen/detail/static_info.hpp> #include <rotgen/detail/static_info.hpp>
#include <rotgen/config.hpp>
#include <initializer_list> #include <initializer_list>
#include <cstddef> #include <cstddef>
#include <memory> #include <memory>

View file

@ -27,10 +27,10 @@ class CLASSNAME
~CLASSNAME(); ~CLASSNAME();
std::size_t rows() const; Index rows() const;
std::size_t cols() const; Index cols() const;
Index size() const;
std::size_t size() const;
void resize(std::size_t new_rows, std::size_t new_cols); void resize(std::size_t new_rows, std::size_t new_cols);
void conservativeResize(std::size_t new_rows, std::size_t new_cols); void conservativeResize(std::size_t new_rows, std::size_t new_cols);

View file

@ -7,6 +7,16 @@
//================================================================================================== //==================================================================================================
#pragma once #pragma once
#include <rotgen/matrix.hpp> #include <rotgen/config.hpp>
#include <rotgen/block.hpp> #include <rotgen/concepts.hpp>
#if defined(ROTGEN_FORCE_DYNAMIC)
#include <rotgen/dynamic/matrix.hpp>
#include <rotgen/dynamic/block.hpp>
#else
#include <rotgen/fixed/matrix.hpp>
#include <rotgen/fixed/block.hpp>
#endif
#include <rotgen/extract.hpp> #include <rotgen/extract.hpp>
#include <rotgen/functions.hpp>

View file

@ -53,9 +53,9 @@ struct CLASSNAME::payload
//================================================================================================== //==================================================================================================
// Matrix API // Matrix API
//================================================================================================== //==================================================================================================
std::size_t CLASSNAME::rows() const { return static_cast<std::size_t>(storage_->data.rows()); } rotgen::Index CLASSNAME::rows() const { return storage_->data.rows(); }
std::size_t CLASSNAME::cols() const { return static_cast<std::size_t>(storage_->data.cols()); } rotgen::Index CLASSNAME::cols() const { return storage_->data.cols(); }
std::size_t CLASSNAME::size() const { return static_cast<std::size_t>(storage_->data.size()); } rotgen::Index CLASSNAME::size() const { return storage_->data.size(); }
TYPE& CLASSNAME::operator()(std::size_t i, std::size_t j) { return storage_->data(i,j); } TYPE& CLASSNAME::operator()(std::size_t i, std::size_t j) { return storage_->data(i,j); }
TYPE const& CLASSNAME::operator()(std::size_t i, std::size_t j) const { return storage_->data(i,j); } TYPE const& CLASSNAME::operator()(std::size_t i, std::size_t j) const { return storage_->data(i,j); }

30
src/info.cpp Normal file
View file

@ -0,0 +1,30 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#include <rotgen/config.hpp>
#include <iostream>
namespace rotgen
{
std::ostream& setup_summary(std::ostream& os)
{
if constexpr(rotgen::is_forcing_dynamic_status)
{
os << "[ROTGEN] - Fully Dynamic mode" << std::endl;
}
else
{
if constexpr(use_expression_templates)
os << "[ROTGEN] - Expression templates : Disabled." << std::endl;
else
os << "[ROTGEN] - Static/Dynamic mode with maximum size: " << rotgen::max_static_size << std::endl;
}
return os;
}
}

View file

@ -8,6 +8,7 @@
#include <rotgen/detail/generators.hpp> #include <rotgen/detail/generators.hpp>
#include <rotgen/impl/matrix.hpp> #include <rotgen/impl/matrix.hpp>
#include <rotgen/impl/payload.hpp> #include <rotgen/impl/payload.hpp>
#include <rotgen/config.hpp>
#include <Eigen/Dense> #include <Eigen/Dense>
namespace rotgen namespace rotgen

View file

@ -51,9 +51,9 @@ CLASSNAME::~CLASSNAME() = default;
//================================================================================================== //==================================================================================================
// Matrix API // Matrix API
//================================================================================================== //==================================================================================================
std::size_t CLASSNAME::rows() const { return static_cast<std::size_t>(storage_->data.rows()); } rotgen::Index CLASSNAME::rows() const { return storage_->data.rows(); }
std::size_t CLASSNAME::cols() const { return static_cast<std::size_t>(storage_->data.cols()); } rotgen::Index CLASSNAME::cols() const { return storage_->data.cols(); }
std::size_t CLASSNAME::size() const { return static_cast<std::size_t>(storage_->data.size()); } rotgen::Index CLASSNAME::size() const { return storage_->data.size(); }
void CLASSNAME::resize(std::size_t new_rows, std::size_t new_cols) void CLASSNAME::resize(std::size_t new_rows, std::size_t new_cols)
{ {

View file

@ -7,7 +7,7 @@ include(${ROTGEN_SOURCE_DIR}/cmake/unit.cmake)
rotgen_setup_test_targets() rotgen_setup_test_targets()
##====================================================================================================================== ##======================================================================================================================
## Compiler options for Unit Tests ## Compiler options for Unit Tests in dynamci and static mode
##====================================================================================================================== ##======================================================================================================================
add_library(rotgen_test INTERFACE) add_library(rotgen_test INTERFACE)
target_compile_options(rotgen_test INTERFACE -std=c++20 -Werror -Wall -Wextra -Wshadow -Wunused-variable) target_compile_options(rotgen_test INTERFACE -std=c++20 -Werror -Wall -Wextra -Wshadow -Wunused-variable)
@ -18,5 +18,5 @@ target_link_libraries(rotgen_test INTERFACE rotgen Eigen3::Eigen)
## Unit Tests registration ## Unit Tests registration
##====================================================================================================================== ##======================================================================================================================
rotgen_glob_unit(PATTERN "unit/free_functions/*.cpp" INTERFACE rotgen_test) rotgen_glob_unit(PATTERN "unit/free_functions/*.cpp" INTERFACE rotgen_test)
rotgen_glob_unit(PATTERN "unit/matrix/*.cpp" INTERFACE rotgen_test) rotgen_glob_unit(PATTERN "unit/matrix/*.cpp" INTERFACE rotgen_test)
rotgen_glob_unit(PATTERN "unit/block/*.cpp" INTERFACE rotgen_test) rotgen_glob_unit(PATTERN "unit/block/*.cpp" INTERFACE rotgen_test)

View file

@ -6,9 +6,7 @@
*/ */
//================================================================================================== //==================================================================================================
#include "unit/tests.hpp" #include "unit/tests.hpp"
#include <rotgen/block.hpp> #include <rotgen/rotgen.hpp>
#include <rotgen/matrix.hpp>
#include <rotgen/extract.hpp>
#include <Eigen/Dense> #include <Eigen/Dense>
template<typename Type1, typename Type2> template<typename Type1, typename Type2>
@ -16,8 +14,8 @@ void test_comparison(const Type1& t1, const Type2& t2)
{ {
TTS_EQUAL(static_cast<std::ptrdiff_t>(t1.rows()), static_cast<std::ptrdiff_t>(t2.rows())); TTS_EQUAL(static_cast<std::ptrdiff_t>(t1.rows()), static_cast<std::ptrdiff_t>(t2.rows()));
TTS_EQUAL(static_cast<std::ptrdiff_t>(t1.cols()), static_cast<std::ptrdiff_t>(t2.cols())); TTS_EQUAL(static_cast<std::ptrdiff_t>(t1.cols()), static_cast<std::ptrdiff_t>(t2.cols()));
for (std::size_t r = 0; r < static_cast<std::size_t>(t1.rows()); ++r) for (rotgen::Index r = 0; r < static_cast<rotgen::Index>(t1.rows()); ++r)
for (std::size_t c = 0; c < static_cast<std::size_t>(t1.cols()); ++c) for (rotgen::Index c = 0; c < static_cast<rotgen::Index>(t1.cols()); ++c)
TTS_EQUAL(t1(r, c), t2(r, c)); TTS_EQUAL(t1(r, c), t2(r, c));
} }
@ -25,6 +23,10 @@ template<typename Matrix1, typename Matrix2, typename Block1, typename Block2>
void test_block_unary_ops(const Matrix1& original_matrix, const Matrix2& ref_matrix, void test_block_unary_ops(const Matrix1& original_matrix, const Matrix2& ref_matrix,
Block1 original_block, Block2 ref_block) Block1 original_block, Block2 ref_block)
{ {
TTS_EXPECT(verify_rotgen_reentrance(original_block.transpose()));
TTS_EXPECT(verify_rotgen_reentrance(original_block.conjugate()));
TTS_EXPECT(verify_rotgen_reentrance(original_block.adjoint()));
test_comparison(original_block.transpose(), ref_block.transpose()); test_comparison(original_block.transpose(), ref_block.transpose());
test_comparison(original_block.conjugate(), ref_block.conjugate()); test_comparison(original_block.conjugate(), ref_block.conjugate());
test_comparison(original_block.adjoint(), ref_block.adjoint()); test_comparison(original_block.adjoint(), ref_block.adjoint());
@ -72,8 +74,8 @@ void test_dynamic_block_reductions(rotgen::tests::matrix_block_test_case<MatrixT
MatrixType original(matrix_construct.rows, matrix_construct.cols); MatrixType original(matrix_construct.rows, matrix_construct.cols);
EigenMatrix ref(matrix_construct.rows, matrix_construct.cols); EigenMatrix ref(matrix_construct.rows, matrix_construct.cols);
for (std::size_t r = 0; r < matrix_construct.rows; ++r) for (rotgen::Index r = 0; r < matrix_construct.rows; ++r)
for (std::size_t c = 0; c < matrix_construct.cols; ++c) for (rotgen::Index c = 0; c < matrix_construct.cols; ++c)
ref(r, c) = original(r,c) = static_cast<T>(matrix_construct.init_fn(r, c)); ref(r, c) = original(r,c) = static_cast<T>(matrix_construct.init_fn(r, c));
std::vector<std::pair<rotgen::block<MatrixType>, Eigen::Block<EigenMatrix>>> test_cases { std::vector<std::pair<rotgen::block<MatrixType>, Eigen::Block<EigenMatrix>>> test_cases {
@ -113,17 +115,17 @@ TTS_CASE_TPL("Test dynamic block reductions", rotgen::tests::types)
std::vector<rotgen::tests::matrix_block_test_case<mat_t>> test_cases = std::vector<rotgen::tests::matrix_block_test_case<mat_t>> test_cases =
{ {
{6, 5, [](auto r, auto c) { return T(r + c); }, 1, 2, 3, 2}, {6, 5, [](rotgen::Index r, rotgen::Index c) { return T(r + c); }, 1, 2, 3, 2},
{9, 11, [](auto r, auto c) {return T(r + c); }, 0, 1, 4, 9}, {9, 11, [](rotgen::Index r, rotgen::Index c) {return T(r + c); }, 0, 1, 4, 9},
{3, 3, [](auto , auto ) {return T(0.0); }, 1, 1, 1, 1}, {3, 3, [](rotgen::Index , rotgen::Index ) {return T(0.0); }, 1, 1, 1, 1},
{1, 4, [](auto r, auto c) {return T(-r -c*c - 1234); }, 0, 0, 1, 1}, {1, 4, [](rotgen::Index r, rotgen::Index c) {return T(-r -c*c - 1234); }, 0, 0, 1, 1},
{9, 9, [](auto r, auto c) {return T(-r + 2*c); }, 0, 1, 3, 3}, {9, 9, [](rotgen::Index r, rotgen::Index c) {return T(-r + 2*c); }, 0, 1, 3, 3},
{11, 13, [](auto r, auto c) {return T(std::tan(r+c)); }, 1, 1, 2, 2}, {11, 13, [](rotgen::Index r, rotgen::Index c) {return T(std::tan(r+c)); }, 1, 1, 2, 2},
{4, 1, [](auto , auto ) {return T(7.0); }, 2, 0, 2, 1}, {4, 1, [](rotgen::Index , rotgen::Index ) {return T(7.0); }, 2, 0, 2, 1},
{1, 1, [](auto , auto ) {return T(42.0); }, 0, 0, 1, 1}, {1, 1, [](rotgen::Index , rotgen::Index ) {return T(42.0); }, 0, 0, 1, 1},
{12, 13, [](auto r, auto c) {return T(std::sin(r + c)); }, 2, 3, 4, 5 }, {12, 13, [](rotgen::Index r, rotgen::Index c) {return T(std::sin(r + c)); }, 2, 3, 4, 5 },
{4, 9, [](auto r, auto c) {return T(-1.5 * r + 2.56 * c); }, 0, 1, 2, 3 }, {4, 9, [](rotgen::Index r, rotgen::Index c) {return T(-1.5 * r + 2.56 * c); }, 0, 1, 2, 3 },
{2, 5, [](auto r, auto c) {return T(r == c ? 1.0 : 0.0); }, 1, 1, 1, 1}, {2, 5, [](rotgen::Index r, rotgen::Index c) {return T(r == c ? 1.0 : 0.0); }, 1, 1, 1, 1},
}; };
for (const auto& test_case : test_cases) for (const auto& test_case : test_cases)

View file

@ -6,22 +6,21 @@
*/ */
//================================================================================================== //==================================================================================================
#include "unit/tests.hpp" #include "unit/tests.hpp"
#include <rotgen/matrix.hpp> #include <rotgen/rotgen.hpp>
#include <rotgen/extract.hpp>
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(std::size_t i = 0; i < m.rows(); ++i) for(rotgen::Index i = 0; i < m.rows(); ++i)
for(std::size_t j = 0; j < m.cols(); ++j) for(rotgen::Index j = 0; j < m.cols(); ++j)
f(i, j, m(i,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(std::size_t i = 0; i < m.rows(); ++i) for(rotgen::Index i = 0; i < m.rows(); ++i)
for(std::size_t j = 0; j < m.cols(); ++j) for(rotgen::Index j = 0; j < m.cols(); ++j)
f(i, j, m(i,j)); f(i, j, m(i,j));
} }
@ -30,8 +29,8 @@ MatrixType make_initialized_matrix(rotgen::tests::matrix_block_test_case<MatrixT
{ {
MatrixType matrix(matrix_construct.rows, matrix_construct.cols); MatrixType matrix(matrix_construct.rows, matrix_construct.cols);
for(std::size_t i = 0; i < matrix_construct.rows; ++i) for(rotgen::Index i = 0; i < matrix_construct.rows; ++i)
for(std::size_t j = 0; j < matrix_construct.cols; ++j) for(rotgen::Index j = 0; j < matrix_construct.cols; ++j)
matrix(i, j) = static_cast<T>(matrix_construct.init_fn(i, j)); matrix(i, j) = static_cast<T>(matrix_construct.init_fn(i, j));
return matrix; return matrix;
@ -39,8 +38,8 @@ MatrixType make_initialized_matrix(rotgen::tests::matrix_block_test_case<MatrixT
template<typename MatrixType, typename BlockType, typename T> template<typename MatrixType, typename BlockType, typename T>
void validate_block_behavior(MatrixType& matrix, BlockType& block, void validate_block_behavior(MatrixType& matrix, BlockType& block,
std::size_t i0, std::size_t j0, rotgen::Index i0, rotgen::Index j0,
std::size_t ni, std::size_t nj) rotgen::Index ni, rotgen::Index nj)
{ {
TTS_EQUAL(block.rows(), ni); TTS_EQUAL(block.rows(), ni);
TTS_EQUAL(block.cols(), nj); TTS_EQUAL(block.cols(), nj);
@ -125,13 +124,13 @@ void test_dynamic_block_extraction(rotgen::tests::matrix_block_test_case<MatrixT
} }
template<typename MatrixType, typename T, std::size_t NI, std::size_t NJ> template<typename MatrixType, typename T, rotgen::Index NI, rotgen::Index NJ>
void test_static_block_extraction(rotgen::tests::static_matrix_block_test_case<MatrixType, NI, NJ> const& matrix_construct) void test_static_block_extraction(rotgen::tests::static_matrix_block_test_case<MatrixType, NI, NJ> const& matrix_construct)
{ {
MatrixType matrix(matrix_construct.rows, matrix_construct.cols); MatrixType matrix(matrix_construct.rows, matrix_construct.cols);
for (std::size_t i = 0; i < matrix_construct.rows; ++i) for (rotgen::Index i = 0; i < matrix_construct.rows; ++i)
for (std::size_t j = 0; j < matrix_construct.cols; ++j) for (rotgen::Index j = 0; j < matrix_construct.cols; ++j)
matrix(i, j) = static_cast<T>(matrix_construct.init_fn(i, j)); matrix(i, j) = static_cast<T>(matrix_construct.init_fn(i, j));
auto block_main = rotgen::extract<NI, NJ>(matrix, matrix_construct.i0, matrix_construct.j0); auto block_main = rotgen::extract<NI, NJ>(matrix, matrix_construct.i0, matrix_construct.j0);
@ -206,10 +205,10 @@ TTS_CASE_TPL("Check all dynamic block extractions on a dynamic row-major matrix"
using mat_t = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value, 1>; using mat_t = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value, 1>;
std::vector<rotgen::tests::matrix_block_test_case<mat_t>> cases = { std::vector<rotgen::tests::matrix_block_test_case<mat_t>> cases = {
{ 6, 11, [](std::size_t i, std::size_t j) { return T(i * 10 + j); }, 1, 2, 3, 2 }, { 6, 11, [](rotgen::Index i, rotgen::Index j) { return T(i * 10 + j); }, 1, 2, 3, 2 },
{ 7, 10, [](std::size_t i, std::size_t j) { return T(std::sin(i + j)); }, 4, 4, 3, 3 }, { 7, 10, [](rotgen::Index i, rotgen::Index j) { return T(std::sin(i + j)); }, 4, 4, 3, 3 },
{ 5, 5, [](std::size_t i, std::size_t j) { return T((i + j) % 7); }, 0, 0, 5, 5 }, { 5, 5, [](rotgen::Index i, rotgen::Index j) { return T((i + j) % 7); }, 0, 0, 5, 5 },
{ 9, 14, [](std::size_t i, std::size_t j) { return T(i+j + 3*j); }, 3, 7, 1, 1 } { 9, 14, [](rotgen::Index i, rotgen::Index j) { return T(i+j + 3*j); }, 3, 7, 1, 1 }
}; };
for (auto const& matrix_case : cases) { for (auto const& matrix_case : cases) {
@ -224,9 +223,9 @@ TTS_CASE_TPL("Check all dynamic block extractions on a static column-major matri
using mat_t = rotgen::matrix<T,4,5,O::value, 0>; using mat_t = rotgen::matrix<T,4,5,O::value, 0>;
std::vector<rotgen::tests::matrix_block_test_case<mat_t>> cases = { std::vector<rotgen::tests::matrix_block_test_case<mat_t>> cases = {
{ 4, 5, [](std::size_t i, std::size_t j) { return T(2*i + j*j*j - 42); }, 1, 2, 3, 2 }, { 4, 5, [](auto i, auto j) { return T(2*i + j*j*j - 42); }, 1, 2, 3, 2 },
{ 4, 5, [](std::size_t i, std::size_t j) { return T(std::tan(i*i*j)); }, 0, 1, 2, 1 }, { 4, 5, [](auto i, auto j) { return T(std::tan(i*i*j)); }, 0, 1, 2, 1 },
{ 4, 5, [](std::size_t i, std::size_t j) { return T((i*i + j*j) / 6); }, 2, 0, 0, 0 } { 4, 5, [](auto i, auto j) { return T((i*i + j*j) / 6); }, 2, 0, 0, 0 }
}; };
for (auto const& matrix_case : cases) { for (auto const& matrix_case : cases) {
@ -241,26 +240,26 @@ TTS_CASE_TPL("Check all static block extractions", rotgen::tests::types)
using mat_t = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value, 1>; using mat_t = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value, 1>;
test_static_block_extraction<mat_t, T, 1, 2>( test_static_block_extraction<mat_t, T, 1, 2>(
rotgen::tests::static_matrix_block_test_case<mat_t, 1, 2>{ rotgen::tests::static_matrix_block_test_case<mat_t, 1, 2>{
11, 11, 11, 11,
[](std::size_t i, std::size_t j) { return T(i*i*i + 3*j - 127); }, [](rotgen::Index i, rotgen::Index j) { return T(i*i*i + 3*j - 127); },
3, 2 3, 2
} }
); );
test_static_block_extraction<mat_t, double, 4, 3>( test_static_block_extraction<mat_t, double, 4, 3>(
rotgen::tests::static_matrix_block_test_case<mat_t, 4, 3>{ rotgen::tests::static_matrix_block_test_case<mat_t, 4, 3>{
14, 15, 14, 15,
[](std::size_t i, std::size_t j) { return T(std::cos(i * j * 2)); }, [](rotgen::Index i, rotgen::Index j) { return T(std::cos(i * j * 2)); },
5, 1 5, 1
} }
); );
test_static_block_extraction<mat_t, double, 0, 0>( test_static_block_extraction<mat_t, double, 0, 0>(
rotgen::tests::static_matrix_block_test_case<mat_t, 0, 0>{ rotgen::tests::static_matrix_block_test_case<mat_t, 0, 0>{
5, 5, 5, 5,
[](std::size_t i, std::size_t j) { return T((i + j) % 9); }, [](rotgen::Index i, rotgen::Index j) { return T((i + j) % 9); },
0, 0 0, 0
} }
); );
}; };

View file

@ -6,8 +6,7 @@
*/ */
//================================================================================================== //==================================================================================================
#include "unit/tests.hpp" #include "unit/tests.hpp"
#include <rotgen/matrix.hpp> #include <rotgen/rotgen.hpp>
#include <rotgen/extract.hpp>
#include <Eigen/Dense> #include <Eigen/Dense>
TTS_CASE_TPL("Matrix norm-related operations", rotgen::tests::types) TTS_CASE_TPL("Matrix norm-related operations", rotgen::tests::types)
@ -17,15 +16,15 @@ TTS_CASE_TPL("Matrix norm-related operations", rotgen::tests::types)
std::vector<rotgen::tests::matrix_block_test_case<mat_t>> test_cases = std::vector<rotgen::tests::matrix_block_test_case<mat_t>> test_cases =
{ {
{6, 5, [](auto r, auto c) {return r + c; }, 1, 2, 3, 2}, {6, 5, [](rotgen::Index r, rotgen::Index c) {return r + c; }, 1, 2, 3, 2},
{9, 11, [](auto r, auto c) {return r + c; }, 0, 1, 4, 9}, {9, 11, [](rotgen::Index r, rotgen::Index c) {return r + c; }, 0, 1, 4, 9},
{3, 3, [](auto , auto ) {return 0.0; }, 1, 1, 1, 1}, {3, 3, [](rotgen::Index , rotgen::Index ) {return 0.0; }, 1, 1, 1, 1},
{1, 4, [](auto r, auto c) {return -r -c*c - 1234; }, 0, 0, 1, 1}, {1, 4, [](rotgen::Index r, rotgen::Index c) {return -r -c*c - 1234; }, 0, 0, 1, 1},
{4, 1, [](auto , auto ) {return 7.0; }, 2, 0, 2, 1}, {4, 1, [](rotgen::Index , rotgen::Index ) {return 7.0; }, 2, 0, 2, 1},
{1, 1, [](auto , auto ) {return 42.0; }, 0, 0, 1, 1}, {1, 1, [](rotgen::Index , rotgen::Index ) {return 42.0; }, 0, 0, 1, 1},
{12, 13, [](auto r, auto c) {return std::sin(r + c); }, 2, 3, 4, 5 }, {12, 13, [](rotgen::Index r, rotgen::Index c) {return std::sin(r + c); }, 2, 3, 4, 5 },
{4, 9, [](auto r, auto c) {return -1.5 * r + 2.56 * c; }, 0, 1, 2, 3 }, {4, 9, [](rotgen::Index r, rotgen::Index c) {return -1.5 * r + 2.56 * c; }, 0, 1, 2, 3 },
{2, 5, [](auto r, auto c) {return (r == c ? 1.0 : 0.0); }, 1, 1, 1, 1}, {2, 5, [](rotgen::Index r, rotgen::Index c) {return (r == c ? 1.0 : 0.0); }, 1, 1, 1, 1},
}; };
for (const auto& [rows, cols, fn, i0, j0, ni, nj] : test_cases) for (const auto& [rows, cols, fn, i0, j0, ni, nj] : test_cases)
@ -33,8 +32,8 @@ TTS_CASE_TPL("Matrix norm-related operations", rotgen::tests::types)
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> original_matrix(rows, cols); rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> original_matrix(rows, cols);
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic,O::value> ref_matrix(rows, cols); Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic,O::value> ref_matrix(rows, cols);
for (std::size_t r = 0; r < rows; ++r) for (rotgen::Index r = 0; r < rows; ++r)
for (std::size_t c = 0; c < cols; ++c) for (rotgen::Index c = 0; c < cols; ++c)
ref_matrix(r, c) = original_matrix(r, c) = fn(r,c); ref_matrix(r, c) = original_matrix(r, c) = fn(r,c);
auto original_block = rotgen::extract(original_matrix, i0, j0, ni, nj); auto original_block = rotgen::extract(original_matrix, i0, j0, ni, nj);

View file

@ -6,8 +6,7 @@
*/ */
//================================================================================================== //==================================================================================================
#include "unit/tests.hpp" #include "unit/tests.hpp"
#include <rotgen/matrix.hpp> #include <rotgen/rotgen.hpp>
#include <rotgen/extract.hpp>
#include <Eigen/Dense> #include <Eigen/Dense>
template <typename MatrixType, typename T> template <typename MatrixType, typename T>
@ -21,9 +20,11 @@ void test_block_matrix_operations(rotgen::tests::matrix_block_test_case<MatrixTy
EigenMatrix ref_a(matrix_construct.rows, matrix_construct.cols); EigenMatrix ref_a(matrix_construct.rows, matrix_construct.cols);
EigenMatrix ref_b(matrix_construct.rows, matrix_construct.cols); EigenMatrix ref_b(matrix_construct.rows, matrix_construct.cols);
for (std::size_t r = 0; r < matrix_construct.rows; ++r) TTS_EXPECT(verify_rotgen_reentrance(ops(a,b)));
for (rotgen::Index r = 0; r < matrix_construct.rows; ++r)
{ {
for (std::size_t c = 0; c < matrix_construct.cols; ++c) for (rotgen::Index c = 0; c < matrix_construct.cols; ++c)
{ {
ref_a(r,c) = a(r,c) = static_cast<T>(matrix_construct.init_fn(r, c)); ref_a(r,c) = a(r,c) = static_cast<T>(matrix_construct.init_fn(r, c));
ref_b(r,c) = b(r,c) = static_cast<T>(b_init_fn(r, c)); ref_b(r,c) = b(r,c) = static_cast<T>(b_init_fn(r, c));
@ -42,20 +43,20 @@ void test_block_matrix_operations(rotgen::tests::matrix_block_test_case<MatrixTy
auto result_block = ops(a_block, b_block); auto result_block = ops(a_block, b_block);
auto ref_result_block = ops(ref_a_block, ref_b_block); auto ref_result_block = ops(ref_a_block, ref_b_block);
for (std::size_t r = 0; r < matrix_construct.ni; ++r) for (rotgen::Index r = 0; r < matrix_construct.ni; ++r)
for (std::size_t c = 0; c < matrix_construct.nj; ++c) for (rotgen::Index c = 0; c < matrix_construct.nj; ++c)
TTS_EQUAL(result_block(r, c), ref_result_block(r, c)); TTS_EQUAL(result_block(r, c), ref_result_block(r, c));
self_ops(a_block,b_block); self_ops(a_block,b_block);
self_ops(ref_a_block, ref_b_block); self_ops(ref_a_block, ref_b_block);
for (std::size_t r = 0; r < matrix_construct.ni; ++r) for (rotgen::Index r = 0; r < matrix_construct.ni; ++r)
for (std::size_t c = 0; c < matrix_construct.nj; ++c) for (rotgen::Index c = 0; c < matrix_construct.nj; ++c)
TTS_EQUAL(a_block(r, c), ref_a_block(r, c)); TTS_EQUAL(a_block(r, c), ref_a_block(r, c));
for (std::size_t r = 0; r < matrix_construct.rows; ++r) for (rotgen::Index r = 0; r < matrix_construct.rows; ++r)
{ {
for (std::size_t c = 0; c < matrix_construct.cols; ++c) for (rotgen::Index c = 0; c < matrix_construct.cols; ++c)
{ {
TTS_EQUAL(a(r, c), ref_a(r, c)); TTS_EQUAL(a(r, c), ref_a(r, c));
TTS_EQUAL(b(r, c), ref_b(r, c)); TTS_EQUAL(b(r, c), ref_b(r, c));
@ -72,8 +73,10 @@ void test_block_scalar_operations(rotgen::tests::matrix_block_test_case<MatrixTy
MatrixType a(matrix_construct.rows, matrix_construct.cols); MatrixType a(matrix_construct.rows, matrix_construct.cols);
EigenMatrix ref_a(matrix_construct.rows, matrix_construct.cols); EigenMatrix ref_a(matrix_construct.rows, matrix_construct.cols);
for (std::size_t r = 0; r < matrix_construct.rows; ++r) TTS_EXPECT(verify_rotgen_reentrance(ops(a,scalar)));
for (std::size_t c = 0; c < matrix_construct.cols; ++c)
for (rotgen::Index r = 0; r < matrix_construct.rows; ++r)
for (rotgen::Index c = 0; c < matrix_construct.cols; ++c)
ref_a(r,c) = a(r,c) = static_cast<T>(matrix_construct.init_fn(r, c)); ref_a(r,c) = a(r,c) = static_cast<T>(matrix_construct.init_fn(r, c));
auto a_block = rotgen::extract(a, matrix_construct.i0, matrix_construct.j0, auto a_block = rotgen::extract(a, matrix_construct.i0, matrix_construct.j0,
@ -84,19 +87,19 @@ void test_block_scalar_operations(rotgen::tests::matrix_block_test_case<MatrixTy
auto result = ops(a_block, scalar); auto result = ops(a_block, scalar);
auto ref_result = ops(ref_a_block, scalar); auto ref_result = ops(ref_a_block, scalar);
for (std::size_t r = 0; r < matrix_construct.ni; ++r) for (rotgen::Index r = 0; r < matrix_construct.ni; ++r)
for (std::size_t c = 0; c < matrix_construct.nj; ++c) for (rotgen::Index c = 0; c < matrix_construct.nj; ++c)
TTS_EQUAL(result(r, c), ref_result(r, c)); TTS_EQUAL(result(r, c), ref_result(r, c));
self_ops(a_block,scalar); self_ops(a_block,scalar);
self_ops(ref_a_block, scalar); self_ops(ref_a_block, scalar);
for (std::size_t r = 0; r < matrix_construct.ni; ++r) for (rotgen::Index r = 0; r < matrix_construct.ni; ++r)
for (std::size_t c = 0; c < matrix_construct.nj; ++c) for (rotgen::Index c = 0; c < matrix_construct.nj; ++c)
TTS_EQUAL(a_block(r, c), ref_a_block(r, c)); TTS_EQUAL(a_block(r, c), ref_a_block(r, c));
for (std::size_t r = 0; r < matrix_construct.rows; ++r) for (rotgen::Index r = 0; r < matrix_construct.rows; ++r)
for (std::size_t c = 0; c < matrix_construct.cols; ++c) for (rotgen::Index c = 0; c < matrix_construct.cols; ++c)
TTS_EQUAL(a(r, c), ref_a(r, c)); TTS_EQUAL(a(r, c), ref_a(r, c));
} }
@ -109,8 +112,11 @@ void test_scalar_block_multiplications(rotgen::tests::matrix_block_test_case<Mat
MatrixType a(matrix_construct.rows, matrix_construct.cols); MatrixType a(matrix_construct.rows, matrix_construct.cols);
EigenMatrix ref_a(matrix_construct.rows, matrix_construct.cols); EigenMatrix ref_a(matrix_construct.rows, matrix_construct.cols);
for (std::size_t r = 0; r < matrix_construct.rows; ++r) TTS_EXPECT(verify_rotgen_reentrance(a * scalar));
for (std::size_t c = 0; c < matrix_construct.cols; ++c) TTS_EXPECT(verify_rotgen_reentrance(scalar * a));
for (rotgen::Index r = 0; r < matrix_construct.rows; ++r)
for (rotgen::Index c = 0; c < matrix_construct.cols; ++c)
ref_a(r,c) = a(r,c) = static_cast<T>(matrix_construct.init_fn(r, c)); ref_a(r,c) = a(r,c) = static_cast<T>(matrix_construct.init_fn(r, c));
auto a_block = rotgen::extract(a, matrix_construct.i0, matrix_construct.j0, auto a_block = rotgen::extract(a, matrix_construct.i0, matrix_construct.j0,
@ -123,9 +129,9 @@ void test_scalar_block_multiplications(rotgen::tests::matrix_block_test_case<Mat
auto a_scalar_multiplication_ref = ref_a_block * scalar; auto a_scalar_multiplication_ref = ref_a_block * scalar;
auto scalar_a_multiplication_ref = scalar * ref_a_block; auto scalar_a_multiplication_ref = scalar * ref_a_block;
for (std::size_t r = 0; r < matrix_construct.ni; ++r) for (rotgen::Index r = 0; r < matrix_construct.ni; ++r)
{ {
for (std::size_t c = 0; c < matrix_construct.nj; ++c) for (rotgen::Index c = 0; c < matrix_construct.nj; ++c)
{ {
TTS_EQUAL(a_scalar_multiplication (r, c), a_scalar_multiplication_ref(r, c)); TTS_EQUAL(a_scalar_multiplication (r, c), a_scalar_multiplication_ref(r, c));
TTS_EQUAL(scalar_a_multiplication(r, c), scalar_a_multiplication_ref(r, c)); TTS_EQUAL(scalar_a_multiplication(r, c), scalar_a_multiplication_ref(r, c));
@ -135,12 +141,12 @@ void test_scalar_block_multiplications(rotgen::tests::matrix_block_test_case<Mat
a_block *= scalar; a_block *= scalar;
ref_a_block *= scalar; ref_a_block *= scalar;
for (std::size_t r = 0; r < matrix_construct.ni; ++r) for (rotgen::Index r = 0; r < matrix_construct.ni; ++r)
for (std::size_t c = 0; c < matrix_construct.nj; ++c) for (rotgen::Index c = 0; c < matrix_construct.nj; ++c)
TTS_EQUAL(a_block(r, c), ref_a_block(r, c)); TTS_EQUAL(a_block(r, c), ref_a_block(r, c));
for (std::size_t r = 0; r < matrix_construct.rows; ++r) for (rotgen::Index r = 0; r < matrix_construct.rows; ++r)
for (std::size_t c = 0; c < matrix_construct.cols; ++c) for (rotgen::Index c = 0; c < matrix_construct.cols; ++c)
TTS_EQUAL(a(r, c), ref_a(r, c)); TTS_EQUAL(a(r, c), ref_a(r, c));
} }
@ -155,12 +161,12 @@ void test_block_multiplication(rotgen::tests::matrix_block_test_case<MatrixType>
EigenMatrix ref_a(a_matrix_construct.rows, a_matrix_construct.cols); EigenMatrix ref_a(a_matrix_construct.rows, a_matrix_construct.cols);
EigenMatrix ref_b(b_matrix_construct.rows, b_matrix_construct.cols); EigenMatrix ref_b(b_matrix_construct.rows, b_matrix_construct.cols);
for (std::size_t r = 0; r < a_matrix_construct.rows; ++r) for (rotgen::Index r = 0; r < a_matrix_construct.rows; ++r)
for (std::size_t c = 0; c < a_matrix_construct.cols; ++c) for (rotgen::Index c = 0; c < a_matrix_construct.cols; ++c)
ref_a(r,c) = a(r,c) = static_cast<T>(a_matrix_construct.init_fn(r, c)); ref_a(r,c) = a(r,c) = static_cast<T>(a_matrix_construct.init_fn(r, c));
for (std::size_t r = 0; r < b_matrix_construct.rows; ++r) for (rotgen::Index r = 0; r < b_matrix_construct.rows; ++r)
for (std::size_t c = 0; c < b_matrix_construct.cols; ++c) for (rotgen::Index c = 0; c < b_matrix_construct.cols; ++c)
ref_b(r,c) = b(r,c) = static_cast<T>(b_matrix_construct.init_fn(r, c)); ref_b(r,c) = b(r,c) = static_cast<T>(b_matrix_construct.init_fn(r, c));
@ -173,26 +179,28 @@ void test_block_multiplication(rotgen::tests::matrix_block_test_case<MatrixType>
auto ref_b_block = ref_b.block(b_matrix_construct.i0, b_matrix_construct.j0, auto ref_b_block = ref_b.block(b_matrix_construct.i0, b_matrix_construct.j0,
b_matrix_construct.ni, b_matrix_construct.nj); b_matrix_construct.ni, b_matrix_construct.nj);
TTS_EXPECT(verify_rotgen_reentrance(a_block * b_block));
auto a_b_product_original = a_block * b_block; auto a_b_product_original = a_block * b_block;
auto a_b_product_ref = ref_a_block * ref_b_block; auto a_b_product_ref = ref_a_block * ref_b_block;
for (std::size_t r = 0; r < a_matrix_construct.ni; ++r) for (rotgen::Index r = 0; r < a_matrix_construct.ni; ++r)
for (std::size_t c = 0; c < a_matrix_construct.nj; ++c) for (rotgen::Index c = 0; c < a_matrix_construct.nj; ++c)
TTS_EQUAL(a_b_product_original (r, c), a_b_product_ref(r, c)); TTS_EQUAL(a_b_product_original (r, c), a_b_product_ref(r, c));
a_block *= b_block; a_block *= b_block;
ref_a_block *= ref_b_block; ref_a_block *= ref_b_block;
for (std::size_t r = 0; r < a_matrix_construct.ni; ++r) for (rotgen::Index r = 0; r < a_matrix_construct.ni; ++r)
for (std::size_t c = 0; c < a_matrix_construct.nj; ++c) for (rotgen::Index c = 0; c < a_matrix_construct.nj; ++c)
TTS_EQUAL(a_block(r, c), ref_a_block(r, c)); TTS_EQUAL(a_block(r, c), ref_a_block(r, c));
for (std::size_t r = 0; r < a_matrix_construct.rows; ++r) for (rotgen::Index r = 0; r < a_matrix_construct.rows; ++r)
for (std::size_t c = 0; c < a_matrix_construct.cols; ++c) for (rotgen::Index c = 0; c < a_matrix_construct.cols; ++c)
TTS_EQUAL(a(r, c), ref_a(r, c)); TTS_EQUAL(a(r, c), ref_a(r, c));
for (std::size_t r = 0; r < b_matrix_construct.rows; ++r) for (rotgen::Index r = 0; r < b_matrix_construct.rows; ++r)
for (std::size_t c = 0; c < b_matrix_construct.cols; ++c) for (rotgen::Index c = 0; c < b_matrix_construct.cols; ++c)
TTS_EQUAL(b(r, c), ref_b(r, c)); TTS_EQUAL(b(r, c), ref_b(r, c));
} }
@ -244,7 +252,7 @@ TTS_CASE_TPL("Check block multiplications", 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 = [](rotgen::Index r, rotgen::Index c) { return r == c ? 1 : 0; };
test_block_multiplication<mat_t, T>({1 , 1, init_a, 0, 0, 1, 1}, {1 , 1, init_b, 0, 0, 1, 1}); test_block_multiplication<mat_t, T>({1 , 1, init_a, 0, 0, 1, 1}, {1 , 1, init_b, 0, 0, 1, 1});
test_block_multiplication<mat_t, T>({13 , 15, init_b, 1, 2, 4, 4}, {13 , 15, init_b, 0, 1, 4, 4}); test_block_multiplication<mat_t, T>({13 , 15, init_b, 1, 2, 4, 4}, {13 , 15, init_b, 0, 1, 4, 4});

View file

@ -6,40 +6,42 @@
*/ */
//================================================================================================== //==================================================================================================
#include "unit/tests.hpp" #include "unit/tests.hpp"
#include <rotgen/block.hpp> #include <rotgen/rotgen.hpp>
#include <rotgen/matrix.hpp>
void test_size(const auto& matrix, std::size_t rows, std::size_t cols) void test_size(const auto& matrix, rotgen::Index rows, rotgen::Index cols)
{ {
TTS_EQUAL(matrix.rows(), rows); TTS_EQUAL(matrix.rows(), rows);
TTS_EQUAL(matrix.cols(), cols); TTS_EQUAL(matrix.cols(), cols);
TTS_EQUAL(matrix.size(), rows*cols); TTS_EQUAL(matrix.size(), rows*cols);
} }
void test_value(const auto& matrix, std::size_t rows, std::size_t cols, auto constant) void test_value(const auto& matrix, rotgen::Index rows, rotgen::Index cols, auto constant)
{ {
TTS_EXPECT(verify_rotgen_reentrance(matrix));
test_size(matrix, rows, cols); test_size(matrix, rows, cols);
for(std::size_t r=0;r<rows;++r) for(rotgen::Index r=0;r<rows;++r)
for(std::size_t c=0;c<cols;++c) for(rotgen::Index c=0;c<cols;++c)
TTS_EQUAL(matrix(r, c), constant); TTS_EQUAL(matrix(r, c), constant);
} }
void test_random(const auto& matrix, std::size_t rows, std::size_t cols) void test_random(const auto& matrix, rotgen::Index rows, rotgen::Index cols)
{ {
TTS_EXPECT(verify_rotgen_reentrance(matrix));
test_size(matrix, rows, cols); test_size(matrix, rows, cols);
for(std::size_t r=0;r<rows;++r) for(rotgen::Index r=0;r<rows;++r)
for(std::size_t c=0;c<cols;++c) for(rotgen::Index c=0;c<cols;++c)
{ {
TTS_GREATER_EQUAL(matrix(r, c), -1.0); TTS_GREATER_EQUAL(matrix(r, c), -1.0);
TTS_LESS_EQUAL(matrix(r, c), 1.0); TTS_LESS_EQUAL(matrix(r, c), 1.0);
} }
} }
void test_identity(const auto& matrix, std::size_t rows, std::size_t cols) void test_identity(const auto& matrix, rotgen::Index rows, rotgen::Index cols)
{ {
TTS_EXPECT(verify_rotgen_reentrance(matrix));
test_size(matrix, rows, cols); test_size(matrix, rows, cols);
for(std::size_t r=0;r<rows;++r) for(rotgen::Index r=0;r<rows;++r)
for(std::size_t c=0;c<cols;++c) for(rotgen::Index c=0;c<cols;++c)
TTS_EQUAL(matrix(r, c), r==c ? 1 : 0); TTS_EQUAL(matrix(r, c), r==c ? 1 : 0);
} }

View file

@ -5,11 +5,9 @@
SPDX-License-Identifier: BSL-1.0 SPDX-License-Identifier: BSL-1.0
*/ */
//================================================================================================== //==================================================================================================
#define TTS_MAIN #include "unit/tests.hpp"
#include <rotgen/matrix.hpp> #include <rotgen/rotgen.hpp>
#include "tts.hpp"
#include <Eigen/Dense> #include <Eigen/Dense>
#include "rotgen/functions.hpp"
template <typename MatrixType> template <typename MatrixType>
struct MatrixDescriptor struct MatrixDescriptor
@ -38,6 +36,10 @@ void test_matrix_unary_ops(std::size_t rows, std::size_t cols,
TTS_EQUAL(rotgen::conjugate(original), original); TTS_EQUAL(rotgen::conjugate(original), original);
TTS_EQUAL(rotgen::adjoint(original), transposed_matrix); TTS_EQUAL(rotgen::adjoint(original), transposed_matrix);
TTS_EXPECT(verify_rotgen_reentrance(rotgen::transpose(original)));
TTS_EXPECT(verify_rotgen_reentrance(rotgen::conjugate(original)));
TTS_EXPECT(verify_rotgen_reentrance(rotgen::adjoint(original)));
rotgen::transposeInPlace(original); rotgen::transposeInPlace(original);
TTS_EQUAL(original, transposed_matrix); TTS_EQUAL(original, transposed_matrix);

View file

@ -5,15 +5,11 @@
SPDX-License-Identifier: BSL-1.0 SPDX-License-Identifier: BSL-1.0
*/ */
//================================================================================================== //==================================================================================================
#define TTS_MAIN #include "unit/tests.hpp"
#include <rotgen/matrix.hpp> #include <rotgen/rotgen.hpp>
#include <rotgen/functions.hpp>
#include "tts.hpp"
#include <functional> #include <functional>
#include <array> #include <array>
template <typename MatrixType> template <typename MatrixType>
struct MatrixDescriptor struct MatrixDescriptor
{ {

View file

@ -5,10 +5,8 @@
SPDX-License-Identifier: BSL-1.0 SPDX-License-Identifier: BSL-1.0
*/ */
//================================================================================================== //==================================================================================================
#define TTS_MAIN #include "unit/tests.hpp"
#include <rotgen/matrix.hpp> #include <rotgen/rotgen.hpp>
#include <rotgen/functions.hpp>
#include "tts.hpp"
#include <Eigen/Dense> #include <Eigen/Dense>
template <typename MatrixType> template <typename MatrixType>

View file

@ -6,7 +6,7 @@
*/ */
//================================================================================================== //==================================================================================================
#include "unit/tests.hpp" #include "unit/tests.hpp"
#include <rotgen/matrix.hpp> #include <rotgen/rotgen.hpp>
#include <Eigen/Dense> #include <Eigen/Dense>
template<typename MatrixType> template<typename MatrixType>
@ -27,6 +27,10 @@ void test_matrix_unary_ops(std::size_t rows, std::size_t cols, auto const &init_
TTS_EQUAL(original.conjugate(), original); TTS_EQUAL(original.conjugate(), original);
TTS_EQUAL(original.adjoint(), transposed_matrix); TTS_EQUAL(original.adjoint(), transposed_matrix);
TTS_EXPECT(verify_rotgen_reentrance(original.transpose()));
TTS_EXPECT(verify_rotgen_reentrance(original.conjugate()));
TTS_EXPECT(verify_rotgen_reentrance(original.adjoint()));
original.transposeInPlace(); original.transposeInPlace();
TTS_EQUAL(original, transposed_matrix); TTS_EQUAL(original, transposed_matrix);

View file

@ -6,15 +6,15 @@
*/ */
//================================================================================================== //==================================================================================================
#include "unit/tests.hpp" #include "unit/tests.hpp"
#include <rotgen/matrix.hpp> #include <rotgen/rotgen.hpp>
TTS_CASE_TPL("Default matrix dynamic constructor", rotgen::tests::types) TTS_CASE_TPL("Default matrix dynamic constructor", 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> matrix; rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> matrix;
TTS_EQUAL(matrix.rows(), 0ULL); TTS_EQUAL(matrix.rows(), rotgen::Index{0});
TTS_EQUAL(matrix.cols(), 0ULL); TTS_EQUAL(matrix.cols(), rotgen::Index{0});
}; };
TTS_CASE_TPL("Default matrix static constructor", rotgen::tests::types) TTS_CASE_TPL("Default matrix static constructor", rotgen::tests::types)
@ -22,8 +22,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(), 4ULL); TTS_EQUAL(matrix.rows(), rotgen::Index{4});
TTS_EQUAL(matrix.cols(), 9ULL); TTS_EQUAL(matrix.cols(), rotgen::Index{9});
}; };
TTS_CASE_TPL("Dynamic matrix constructor with row and columns", rotgen::tests::types) TTS_CASE_TPL("Dynamic matrix constructor with row and columns", rotgen::tests::types)
@ -31,8 +31,8 @@ TTS_CASE_TPL("Dynamic matrix constructor with row and columns", rotgen::tests::t
{ {
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(), 10ULL); TTS_EQUAL(matrix.rows(), rotgen::Index{10});
TTS_EQUAL(matrix.cols(), 5ULL); TTS_EQUAL(matrix.cols(), rotgen::Index{5});
}; };
TTS_CASE_TPL("Static matrix constructor with row and columns", rotgen::tests::types) TTS_CASE_TPL("Static matrix constructor with row and columns", rotgen::tests::types)
@ -40,8 +40,8 @@ TTS_CASE_TPL("Static matrix constructor with row and columns", rotgen::tests::ty
{ {
rotgen::matrix<T,6,11,O::value> matrix(6, 11); rotgen::matrix<T,6,11,O::value> matrix(6, 11);
TTS_EQUAL(matrix.rows(), 6ULL); TTS_EQUAL(matrix.rows(), rotgen::Index{6});
TTS_EQUAL(matrix.cols(), 11ULL); TTS_EQUAL(matrix.cols(), rotgen::Index{11});
}; };
TTS_CASE_TPL("Copy constructor produces identical but independent matrix", rotgen::tests::types) TTS_CASE_TPL("Copy constructor produces identical but independent matrix", rotgen::tests::types)
@ -49,8 +49,8 @@ TTS_CASE_TPL("Copy constructor produces identical but independent matrix", rotge
{ {
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(std::size_t r=0;r<a.rows();r++) for(rotgen::Index r=0;r<a.rows();r++)
for(std::size_t c=0;c<a.cols();c++) for(rotgen::Index c=0;c<a.cols();c++)
a(r,c) = r + 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;
@ -58,8 +58,8 @@ TTS_CASE_TPL("Copy constructor produces identical but independent matrix", rotge
TTS_EQUAL(b.rows(), a.rows()); TTS_EQUAL(b.rows(), a.rows());
TTS_EQUAL(b.cols(), a.cols()); TTS_EQUAL(b.cols(), a.cols());
for(std::size_t r=0;r<a.rows();r++) for(rotgen::Index r=0;r<a.rows();r++)
for(std::size_t c=0;c<a.cols();c++) for(rotgen::Index c=0;c<a.cols();c++)
TTS_EQUAL(b(r,c), a(r,c)); TTS_EQUAL(b(r,c), a(r,c));
TTS_EQUAL(b(0, 0), 0.0); TTS_EQUAL(b(0, 0), 0.0);
@ -75,8 +75,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(), 0ULL); TTS_EQUAL(b.rows(), rotgen::Index{0});
TTS_EQUAL(b.cols(), 0ULL); TTS_EQUAL(b.cols(), 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)
@ -84,17 +84,17 @@ TTS_CASE_TPL("Copy constructor from const matrix", rotgen::tests::types)
{ {
const rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> a(2, 2); const rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> a(2, 2);
auto b = a; auto b = a;
TTS_EQUAL(b.rows(), 2ULL); TTS_EQUAL(b.rows(), rotgen::Index{2});
TTS_EQUAL(b.cols(), 2ULL); TTS_EQUAL(b.cols(), 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)
<typename T, typename O>( tts::type< tts::types<T,O>> ) <typename T, typename O>( tts::type< tts::types<T,O>> )
{ {
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(), 2ULL); TTS_EQUAL(b.rows(), rotgen::Index{2});
TTS_EQUAL(b.cols(), 5ULL); TTS_EQUAL(b.cols(), rotgen::Index{5});
}; };
/* /*
@ -126,8 +126,8 @@ TTS_CASE_TPL("Move constructor transfers contents", rotgen::tests::types)
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> b = std::move(a); rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> b = std::move(a);
TTS_EQUAL(b(1,1), 7); TTS_EQUAL(b(1,1), 7);
TTS_EQUAL(b.rows(), 3ULL); TTS_EQUAL(b.rows(), rotgen::Index{3});
TTS_EQUAL(b.cols(), 3ULL); TTS_EQUAL(b.cols(), rotgen::Index{3});
TTS_EXPECT(b.data() == ptr); TTS_EXPECT(b.data() == ptr);
}; };
@ -135,31 +135,32 @@ TTS_CASE_TPL("Move constructor from Rvalue", 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> b = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>(2, 2); rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> b = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>(2, 2);
TTS_EQUAL(b.rows(), 2ULL); TTS_EQUAL(b.rows(), rotgen::Index{2});
TTS_EQUAL(b.cols(), 2ULL); TTS_EQUAL(b.cols(), rotgen::Index{2});
}; };
TTS_CASE_TPL("Constructor from Initializer list", rotgen::tests::types) 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(), 1ULL); TTS_EQUAL(b1.rows(), rotgen::Index{1});
TTS_EQUAL(b1.cols(), 1ULL); TTS_EQUAL(b1.cols(), rotgen::Index{1});
TTS_EQUAL(b1(0) , 3.5); TTS_EQUAL(b1(0) , 3.5);
rotgen::matrix<T,5,1,O::value> 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(), 5ULL); TTS_EQUAL(b9.rows(), rotgen::Index{5});
TTS_EQUAL(b9.cols(), 1ULL); TTS_EQUAL(b9.cols(), rotgen::Index{1});
T i = 0.25; T i = 0.25;
for(std::size_t r=0;r<b9.rows();++r) { for(rotgen::Index r=0;r<b9.rows();++r)
{
TTS_EQUAL(b9(r,0), i); TTS_EQUAL(b9(r,0), i);
i *= 2; i *= 2;
} }
rotgen::matrix<T,1,3,O::value> 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(), 1ULL); TTS_EQUAL(b13.rows(), rotgen::Index{1});
TTS_EQUAL(b13.cols(), 3ULL); TTS_EQUAL(b13.cols(), 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));
@ -168,16 +169,18 @@ TTS_CASE_TPL("Constructor from Initializer list", rotgen::tests::types)
TTS_CASE_TPL("Constructor from Initializer list of rows", rotgen::tests::types) 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(), 1ULL); TTS_EQUAL(b1.rows(), rotgen::Index{1});
TTS_EQUAL(b1.cols(), 1ULL); TTS_EQUAL(b1.cols(), 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 = { {1.2,2.3,3.4} rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>
, {10,200,3000} b23 { {1.2,2.3,3.4}
}; , {10,200,3000}
TTS_EQUAL(b23.rows(), 2ULL); };
TTS_EQUAL(b23.cols(), 3ULL);
TTS_EQUAL(b23.rows(), rotgen::Index{2});
TTS_EQUAL(b23.cols(), 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

@ -6,7 +6,7 @@
*/ */
//================================================================================================== //==================================================================================================
#include "unit/tests.hpp" #include "unit/tests.hpp"
#include <rotgen/matrix.hpp> #include <rotgen/rotgen.hpp>
TTS_CASE_TPL("Function size", rotgen::tests::types) TTS_CASE_TPL("Function size", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> ) <typename T, typename O>( tts::type< tts::types<T,O>> )
@ -16,10 +16,10 @@ TTS_CASE_TPL("Function size", rotgen::tests::types)
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> row_vector(9,1); rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> row_vector(9,1);
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> column_vector(1,5); rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> column_vector(1,5);
TTS_EQUAL(empty_matrix.size(), 0ULL); TTS_EQUAL(empty_matrix.size(), rotgen::Index{0});
TTS_EQUAL(matrix.size(), 12ULL); TTS_EQUAL(matrix.size(), rotgen::Index{12});
TTS_EQUAL(row_vector.size(), 9ULL); TTS_EQUAL(row_vector.size(), rotgen::Index{9});
TTS_EQUAL(column_vector.size(), 5ULL); TTS_EQUAL(column_vector.size(), rotgen::Index{5});
}; };
TTS_CASE_TPL("Resizing dynamic matrix", rotgen::tests::types) TTS_CASE_TPL("Resizing dynamic matrix", rotgen::tests::types)
@ -27,21 +27,21 @@ TTS_CASE_TPL("Resizing dynamic matrix", rotgen::tests::types)
{ {
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(std::size_t r=0;r<a.rows();++r) for(rotgen::Index r=0;r<a.rows();++r)
for(std::size_t c=0;c<a.cols();++c) for(rotgen::Index c=0;c<a.cols();++c)
a(r,c) = 42 + 2*c + r; a(r,c) = 42 + 2*c + r;
a.resize(3, 2); a.resize(3, 2);
TTS_EQUAL(a.rows(), 3ULL); TTS_EQUAL(a.rows(), rotgen::Index(3));
TTS_EQUAL(a.cols(), 2ULL); TTS_EQUAL(a.cols(), rotgen::Index(2));
for(std::size_t r=0;r<a.rows();++r) for(rotgen::Index r=0;r<a.rows();++r)
for(std::size_t c=0;c<a.cols();++c) for(rotgen::Index c=0;c<a.cols();++c)
TTS_GREATER(a(r,c),0); TTS_GREATER(a(r,c),0);
a.resize(2,2); a.resize(2,2);
TTS_EQUAL(a.rows(), 2ULL); TTS_EQUAL(a.rows(), rotgen::Index(2));
TTS_EQUAL(a.cols(), 2ULL); TTS_EQUAL(a.cols(), rotgen::Index(2));
}; };
TTS_CASE_TPL("Resizing static matrix", rotgen::tests::types) TTS_CASE_TPL("Resizing static matrix", rotgen::tests::types)
@ -57,52 +57,52 @@ TTS_CASE_TPL("Dynamix matrix conservative resizing", rotgen::tests::types)
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(std::size_t r=0;r<a.rows();++r) for(rotgen::Index r=0;r<a.rows();++r)
for(std::size_t c=0;c<a.cols();++c) for(rotgen::Index c=0;c<a.cols();++c)
a(r, c) = i++; a(r, c) = i++;
a.conservativeResize(2, 3); a.conservativeResize(2, 3);
TTS_EQUAL(a.rows(), 2ULL); TTS_EQUAL(a.rows(), rotgen::Index(2));
TTS_EQUAL(a.cols(), 3ULL); TTS_EQUAL(a.cols(), rotgen::Index(3));
i = 1; i = 1;
for(std::size_t r=0;r<a.rows();++r) for(rotgen::Index r=0;r<a.rows();++r)
for(std::size_t c=0;c<a.cols();++c) for(rotgen::Index c=0;c<a.cols();++c)
TTS_EQUAL(a(r,c),i++); TTS_EQUAL(a(r,c),i++);
a.conservativeResize(3, 2); a.conservativeResize(3, 2);
TTS_EQUAL(a.rows(), 3ULL); TTS_EQUAL(a.rows(), rotgen::Index(3));
TTS_EQUAL(a.cols(), 2ULL); TTS_EQUAL(a.cols(), rotgen::Index(2));
int expected[3][2] = { {1, 2}, {4, 5} }; int expected[3][2] = { {1, 2}, {4, 5} };
for(std::size_t r = 0; r < 2; ++r) for(rotgen::Index r = 0; r < 2; ++r)
for(std::size_t c = 0; c < 2; ++c) for(rotgen::Index c = 0; c < 2; ++c)
TTS_EQUAL(a(r, c), expected[r][c]); TTS_EQUAL(a(r, c), expected[r][c]);
a.conservativeResize(4, 4); a.conservativeResize(4, 4);
TTS_EQUAL(a.rows(), 4ULL); TTS_EQUAL(a.rows(), rotgen::Index(4));
TTS_EQUAL(a.cols(), 4ULL); TTS_EQUAL(a.cols(), 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);
a.conservativeResize(2, 2); a.conservativeResize(2, 2);
TTS_EQUAL(a.rows(), 2ULL); TTS_EQUAL(a.rows(), rotgen::Index(2));
TTS_EQUAL(a.cols(), 2ULL); TTS_EQUAL(a.cols(), 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);
a.conservativeResize(1, 2); a.conservativeResize(1, 2);
TTS_EQUAL(a.rows(), 1ULL); TTS_EQUAL(a.rows(), rotgen::Index(1));
TTS_EQUAL(a.cols(), 2ULL); TTS_EQUAL(a.cols(), 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);
a.conservativeResize(0, 0); a.conservativeResize(0, 0);
TTS_EQUAL(a.rows(), 0ULL); TTS_EQUAL(a.rows(), rotgen::Index(0));
TTS_EQUAL(a.cols(), 0ULL); TTS_EQUAL(a.cols(), rotgen::Index(0));
a.conservativeResize(3, 3); a.conservativeResize(3, 3);
TTS_EQUAL(a.rows(), 3ULL); TTS_EQUAL(a.rows(), rotgen::Index(3));
TTS_EQUAL(a.cols(), 3ULL); TTS_EQUAL(a.cols(), rotgen::Index(3));
}; };
TTS_CASE_TPL("Static matrix conservative resizing", rotgen::tests::types) TTS_CASE_TPL("Static matrix conservative resizing", rotgen::tests::types)
@ -117,8 +117,8 @@ TTS_CASE_TPL("Test coefficient accessors", rotgen::tests::types)
{ {
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(std::size_t r=0;r<a.rows();++r) for(rotgen::Index r=0;r<a.rows();++r)
for(std::size_t c=0;c<a.cols();++c) for(rotgen::Index c=0;c<a.cols();++c)
a(r, c) = r + 2 * c + 3; a(r, c) = r + 2 * c + 3;
TTS_EQUAL(a(0,0), 3); TTS_EQUAL(a(0,0), 3);
@ -143,19 +143,19 @@ TTS_CASE_TPL("Test one index coefficient accessors", rotgen::tests::types)
int i = 1; int i = 1;
if constexpr(!O::value) if constexpr(!O::value)
{ {
for(std::size_t c=0;c<a.cols();++c) for(rotgen::Index c=0;c<a.cols();++c)
for(std::size_t r=0;r<a.rows();++r) for(rotgen::Index r=0;r<a.rows();++r)
a(r, c) = i++; a(r, c) = i++;
} }
else else
{ {
for(std::size_t r=0;r<a.rows();++r) for(rotgen::Index r=0;r<a.rows();++r)
for(std::size_t c=0;c<a.cols();++c) for(rotgen::Index c=0;c<a.cols();++c)
a(r, c) = i++; a(r, c) = i++;
} }
i = 1; i = 1;
for(std::size_t r=0;r<a.rows()*a.cols();++r) for(rotgen::Index r=0;r<a.rows()*a.cols();++r)
TTS_EQUAL(a(r), i++) << a; TTS_EQUAL(a(r), i++) << a;
T& ref = a(2); T& ref = a(2);

View file

@ -6,7 +6,7 @@
*/ */
//================================================================================================== //==================================================================================================
#include "unit/tests.hpp" #include "unit/tests.hpp"
#include <rotgen/matrix.hpp> #include <rotgen/rotgen.hpp>
#include <sstream> #include <sstream>
TTS_CASE_TPL("Sample test", rotgen::tests::types) TTS_CASE_TPL("Sample test", rotgen::tests::types)

View file

@ -6,7 +6,7 @@
*/ */
//================================================================================================== //==================================================================================================
#include "unit/tests.hpp" #include "unit/tests.hpp"
#include <rotgen/matrix.hpp> #include <rotgen/rotgen.hpp>
#include <Eigen/Dense> #include <Eigen/Dense>
TTS_CASE_TPL("Matrix norm-related operations", rotgen::tests::types) TTS_CASE_TPL("Matrix norm-related operations", rotgen::tests::types)
@ -30,9 +30,9 @@ TTS_CASE_TPL("Matrix norm-related operations", rotgen::tests::types)
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> matrix(rows, cols); rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> matrix(rows, cols);
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic,O::value> ref(rows, cols); Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic,O::value> ref(rows, cols);
for (std::size_t r = 0; r < rows; ++r) for (rotgen::Index r = 0; r < rows; ++r)
{ {
for (std::size_t c = 0; c < cols; ++c) for (rotgen::Index c = 0; c < cols; ++c)
{ {
ref(r, c) = matrix(r, c) = fn(r,c); ref(r, c) = matrix(r, c) = fn(r,c);
} }
@ -40,8 +40,8 @@ TTS_CASE_TPL("Matrix norm-related operations", rotgen::tests::types)
TTS_EQUAL(matrix.norm(), ref.norm()); TTS_EQUAL(matrix.norm(), ref.norm());
TTS_EQUAL(matrix.squaredNorm(), ref.squaredNorm()); TTS_EQUAL(matrix.squaredNorm(), ref.squaredNorm());
TTS_EQUAL(matrix.template lp_norm<1>() , ref.template lpNorm<1>()); TTS_EQUAL(matrix.template lpNorm<1>() , ref.template lpNorm<1>());
TTS_EQUAL(matrix.template lp_norm<2>() , ref.template lpNorm<2>()); TTS_EQUAL(matrix.template lpNorm<2>() , ref.template lpNorm<2>());
TTS_EQUAL(matrix.template lp_norm<rotgen::Infinity>(), ref.template lpNorm<Eigen::Infinity>()); TTS_EQUAL(matrix.template lpNorm<rotgen::Infinity>(), ref.template lpNorm<Eigen::Infinity>());
} }
}; };

View file

@ -6,18 +6,18 @@
*/ */
//================================================================================================== //==================================================================================================
#include "unit/tests.hpp" #include "unit/tests.hpp"
#include <rotgen/matrix.hpp> #include <rotgen/rotgen.hpp>
template <typename MatrixType> template <typename MatrixType>
void test_matrix_operations(std::size_t rows, std::size_t cols, auto a_init_fn, auto b_init_fn, auto ops, auto self_ops) void test_matrix_operations(rotgen::Index rows, rotgen::Index cols, auto a_init_fn, auto b_init_fn, auto ops, auto self_ops)
{ {
MatrixType a(rows, cols); MatrixType a(rows, cols);
MatrixType b(rows, cols); MatrixType b(rows, cols);
MatrixType ref(rows, cols); MatrixType ref(rows, cols);
for (std::size_t r = 0; r < rows; ++r) for (rotgen::Index r = 0; r < rows; ++r)
{ {
for (std::size_t c = 0; c < cols; ++c) for (rotgen::Index c = 0; c < cols; ++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);
@ -28,17 +28,20 @@ void test_matrix_operations(std::size_t rows, std::size_t cols, auto a_init_fn,
TTS_EQUAL(ops(a, b), ref); TTS_EQUAL(ops(a, b), ref);
self_ops(a,b); self_ops(a,b);
TTS_EQUAL(a, ref); TTS_EQUAL(a, ref);
TTS_EXPECT(verify_rotgen_reentrance(ops(a, b)));
TTS_EXPECT(verify_rotgen_reentrance(self_ops(a, b)));
} }
template <typename MatrixType> template <typename MatrixType>
void test_scalar_operations(std::size_t rows, std::size_t cols, auto a_init_fn, auto s, auto ops, auto self_ops) void test_scalar_operations(rotgen::Index rows, rotgen::Index cols, auto a_init_fn, auto s, auto ops, auto self_ops)
{ {
MatrixType a(rows, cols); MatrixType a(rows, cols);
MatrixType ref(rows, cols); MatrixType ref(rows, cols);
for (std::size_t r = 0; r < rows; ++r) for (rotgen::Index r = 0; r < rows; ++r)
{ {
for (std::size_t c = 0; c < cols; ++c) for (rotgen::Index c = 0; c < cols; ++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);
@ -48,17 +51,20 @@ void test_scalar_operations(std::size_t rows, std::size_t cols, auto a_init_fn,
TTS_EQUAL(ops(a, s), ref); TTS_EQUAL(ops(a, s), ref);
self_ops(a,s); self_ops(a,s);
TTS_EQUAL(a, ref); TTS_EQUAL(a, ref);
TTS_EXPECT(verify_rotgen_reentrance(ops(a, s)));
TTS_EXPECT(verify_rotgen_reentrance(self_ops(a, s)));
} }
template <typename MatrixType> template <typename MatrixType>
void test_scalar_multiplications(std::size_t rows, std::size_t cols, auto fn, auto s) void test_scalar_multiplications(rotgen::Index rows, rotgen::Index cols, auto fn, auto s)
{ {
MatrixType a(rows, cols); MatrixType a(rows, cols);
MatrixType ref(rows, cols); MatrixType ref(rows, cols);
for (std::size_t r = 0; r < rows; ++r) for (rotgen::Index r = 0; r < rows; ++r)
{ {
for (std::size_t c = 0; c < cols; ++c) for (rotgen::Index c = 0; c < cols; ++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;
@ -69,34 +75,39 @@ void test_scalar_multiplications(std::size_t rows, std::size_t cols, auto fn, au
TTS_EQUAL(s * a, ref); TTS_EQUAL(s * a, ref);
a *= s; a *= s;
TTS_EQUAL(a, ref); TTS_EQUAL(a, ref);
TTS_EXPECT(verify_rotgen_reentrance(a*s));
TTS_EXPECT(verify_rotgen_reentrance(s*a));
TTS_EXPECT(verify_rotgen_reentrance(a*=s));
} }
template <typename MatrixType> template <typename MatrixType>
void test_matrix_multiplication(std::size_t rows, std::size_t cols, auto a_init_fn, auto b_init_fn) void test_matrix_multiplication(rotgen::Index rows, rotgen::Index cols, auto a_init_fn, auto b_init_fn)
{ {
MatrixType a(rows, cols); MatrixType a(rows, cols);
MatrixType b(cols, rows); MatrixType b(cols, rows);
MatrixType ref(rows, rows); MatrixType ref(rows, rows);
for (std::size_t r = 0; r < a.rows(); ++r) for (rotgen::Index r = 0; r < a.rows(); ++r)
for (std::size_t c = 0; c < a.cols(); ++c) for (rotgen::Index c = 0; c < a.cols(); ++c)
a(r,c) = a_init_fn(r, c); a(r,c) = a_init_fn(r, c);
for (std::size_t r = 0; r < b.rows(); ++r) for (rotgen::Index r = 0; r < b.rows(); ++r)
for (std::size_t c = 0; c < b.cols(); ++c) for (rotgen::Index c = 0; c < b.cols(); ++c)
b(r,c) = b_init_fn(r, c); b(r,c) = b_init_fn(r, c);
for (std::size_t i = 0; i < a.rows(); ++i) for (rotgen::Index i = 0; i < a.rows(); ++i)
{ {
for (std::size_t j = 0; j < b.cols(); ++j) for (rotgen::Index j = 0; j < b.cols(); ++j)
{ {
ref(i, j) = 0; ref(i, j) = 0;
for (std::size_t k = 0; k < a.cols(); ++k) for (rotgen::Index k = 0; k < a.cols(); ++k)
ref(i, j) += a(i, k) * b(k, j); ref(i, j) += a(i, k) * b(k, j);
} }
} }
TTS_EQUAL(a * b, ref); TTS_EQUAL(a * b, ref);
TTS_EXPECT(verify_rotgen_reentrance(a*b));
} }
// Basic initializers // Basic initializers

View file

@ -6,10 +6,11 @@
*/ */
//================================================================================================== //==================================================================================================
#include "unit/tests.hpp" #include "unit/tests.hpp"
#include <rotgen/matrix.hpp> #include <rotgen/rotgen.hpp>
void test_value(const auto& matrix, std::size_t rows, std::size_t cols, auto constant) void test_value(const auto& matrix, std::size_t rows, std::size_t cols, auto constant)
{ {
TTS_EXPECT(verify_rotgen_reentrance(matrix));
for(std::size_t r=0;r<rows;++r) for(std::size_t r=0;r<rows;++r)
for(std::size_t c=0;c<cols;++c) for(std::size_t c=0;c<cols;++c)
TTS_EQUAL(matrix(r, c), constant); TTS_EQUAL(matrix(r, c), constant);
@ -17,6 +18,7 @@ void test_value(const auto& matrix, std::size_t rows, std::size_t cols, auto con
void test_random(const auto& matrix, std::size_t rows, std::size_t cols) void test_random(const auto& matrix, std::size_t rows, std::size_t cols)
{ {
TTS_EXPECT(verify_rotgen_reentrance(matrix));
for(std::size_t r=0;r<rows;++r) for(std::size_t r=0;r<rows;++r)
for(std::size_t c=0;c<cols;++c) for(std::size_t c=0;c<cols;++c)
{ {
@ -27,6 +29,7 @@ void test_random(const auto& matrix, std::size_t rows, std::size_t cols)
void test_identity(const auto& matrix, std::size_t rows, std::size_t cols) void test_identity(const auto& matrix, std::size_t rows, std::size_t cols)
{ {
TTS_EXPECT(verify_rotgen_reentrance(matrix));
for(std::size_t r=0;r<rows;++r) for(std::size_t r=0;r<rows;++r)
for(std::size_t c=0;c<cols;++c) for(std::size_t c=0;c<cols;++c)
TTS_EQUAL(matrix(r, c), r==c ? 1 : 0); TTS_EQUAL(matrix(r, c), r==c ? 1 : 0);

View file

@ -6,8 +6,11 @@
*/ */
//================================================================================================== //==================================================================================================
#define TTS_MAIN #define TTS_MAIN
#define TTS_CUSTOM_DRIVER_FUNCTION rotgen_main
#include "tts.hpp" #include "tts.hpp"
#include <rotgen/detail/static_info.hpp> #include <rotgen/detail/static_info.hpp>
#include <rotgen/config.hpp>
#include <rotgen/concepts.hpp>
#include <functional> #include <functional>
namespace rotgen::tests namespace rotgen::tests
@ -25,25 +28,50 @@ namespace rotgen::tests
struct matrix_descriptor struct matrix_descriptor
{ {
std::size_t rows, cols; rotgen::Index rows, cols;
std::function<double(std::size_t,std::size_t)> init_fn; std::function<double(std::size_t,std::size_t)> init_fn;
}; };
template<typename MatrixType> template<typename MatrixType>
struct matrix_block_test_case struct matrix_block_test_case
{ {
std::size_t rows, cols; rotgen::Index rows, cols;
std::function<typename MatrixType::scalar_type(std::size_t, std::size_t)> init_fn; std::function<typename MatrixType::scalar_type(std::size_t, rotgen::Index)> init_fn;
std::size_t i0, j0, ni, nj; rotgen::Index i0, j0, ni, nj;
}; };
template<typename MatrixType, std::size_t NI, std::size_t NJ> template<typename MatrixType, rotgen::Index NI, rotgen::Index NJ>
struct static_matrix_block_test_case struct static_matrix_block_test_case
{ {
std::size_t rows, cols; rotgen::Index rows, cols;
std::function<typename MatrixType::scalar_type(std::size_t, std::size_t)> init_fn; std::function<typename MatrixType::scalar_type(std::size_t, rotgen::Index)> init_fn;
static constexpr std::size_t ni = NI; static constexpr rotgen::Index ni = NI;
static constexpr std::size_t nj = NJ; static constexpr rotgen::Index nj = NJ;
std::size_t i0, j0; rotgen::Index i0, j0;
}; };
} }
#include <iostream>
template<typename T>
constexpr bool verify_rotgen_reentrance(T const&)
{
return rotgen::concepts::entity<T>;
}
int main(int argc, char const **argv)
{
::tts::initialize(argc,argv);
#ifdef NDEBUG
constexpr auto assert_status = "Disabled";
#else
constexpr auto assert_status = "Enabled";
#endif
std::cout << "[ROTGEN] - Assertions: " << assert_status << std::endl;
rotgen::setup_summary(std::cout);
rotgen_main(argc, argv);
return tts::report(0,0);
}