Implements map and ref for both static & dynamic mode

See merge request oss/rotgen!12
This commit is contained in:
Joel Falcou 2025-08-13 17:43:57 +02:00
parent aacae1cbb1
commit 6c2b260229
58 changed files with 4121 additions and 1205 deletions

View file

@ -6,113 +6,59 @@
*/
//==================================================================================================
#include "unit/tests.hpp"
#include "unit/common/arithmetic.hpp"
#include <rotgen/rotgen.hpp>
#include <Eigen/Dense>
template<typename MatrixType>
void test_matrix_unary_ops(std::size_t rows, std::size_t cols, auto const &init_fn)
{
MatrixType original(rows, cols);
MatrixType transposed_matrix(cols, rows);
for (std::size_t r = 0; r < rows; ++r)
for (std::size_t c = 0; c < cols; ++c)
original(r,c) = init_fn(r, c);
for (std::size_t r = 0; r < rows; ++r)
for (std::size_t c = 0; c < cols; ++c)
transposed_matrix(c, r) = original(r, c);
TTS_EQUAL(original.transpose(), transposed_matrix);
TTS_EQUAL(original.conjugate(), original);
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();
TTS_EQUAL(original, transposed_matrix);
original.transposeInPlace();
original.adjointInPlace();
TTS_EQUAL(original, transposed_matrix);
}
TTS_CASE_TPL("Test transpotion related operations", rotgen::tests::types)
TTS_CASE_TPL("Test dynamic matrix transposition-like operations", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> )
{
std::vector<rotgen::tests::matrix_descriptor> test_matrices =
auto const cases = rotgen::tests::generate_matrix_references();
for (const auto& [rows, cols, fn] : cases)
{
{3, 3, [](auto r, auto c) { return r + 3 * c - 2.5; }},
{4, 9, [](auto r, auto c) { return r*r + 3.12 * c + 6.87; }},
{2, 7, [](auto r, auto c) { return 1.1 * (r - c); }},
{1, 5, [](auto , auto ) { return 9.99; }},
{4, 2, [](auto , auto ) { return 0.0; }},
{3, 3, [](auto r, auto c) { return (r == c) ? 1.0 : 0.0; }},
{2, 2, [](auto r, auto c) { return (r + c) * 1e-10; }},
{2, 2, [](auto r, auto ) { return (r + 1) * 1e+10; }}
};
for (const auto& [rows, cols, fn] : test_matrices)
{
test_matrix_unary_ops<rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>>(rows, cols, fn);
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> input(rows, cols);
rotgen::tests::prepare(rows,cols,fn,input);
rotgen::tests::check_shape_functions(input);
}
};
template <typename MatrixType>
void test_matrix_reductions(std::size_t rows, std::size_t cols, auto const& init_fn)
{
using EigenMatrix = Eigen::Matrix<typename MatrixType::scalar_type, Eigen::Dynamic, Eigen::Dynamic>;
MatrixType original(rows, cols);
EigenMatrix ref(rows, cols);
for (std::size_t r = 0; r < rows; ++r)
for (std::size_t c = 0; c < cols; ++c)
ref(r, c) = original(r,c) = init_fn(r, c);
TTS_EQUAL(original.sum(), ref.sum());
TTS_EQUAL(original.prod(), ref.prod());
TTS_EQUAL(original.mean(), ref.mean());
TTS_EQUAL(original.maxCoeff(), ref.maxCoeff());
TTS_EQUAL(original.minCoeff(), ref.minCoeff());
TTS_EQUAL(original.trace(), ref.trace());
std::ptrdiff_t row, col, ref_row, ref_col;
double cmin = original.minCoeff(&row, &col);
double rmin = ref.minCoeff(&ref_row, &ref_col);
TTS_EQUAL(cmin, rmin);
TTS_EQUAL(row, ref_row);
TTS_EQUAL(col, ref_col);
double cmax = original.maxCoeff(&row, &col);
double rmax = ref.maxCoeff(&ref_row, &ref_col);
TTS_EQUAL(cmax, rmax);
TTS_EQUAL(row, ref_row);
TTS_EQUAL(col, ref_col);
}
TTS_CASE_TPL("Test reductions", rotgen::tests::types)
TTS_CASE_TPL("Test static matrix transposition-like operations", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> )
{
std::vector<rotgen::tests::matrix_descriptor> test_matrices =
auto const cases = rotgen::tests::generate_static_matrix_references();
auto process = []<typename D>(D const& desc)
{
{3, 3, [](auto r, auto c) {return r + c; }},
{3, 3, [](auto , auto ) {return 0.0; }},
{2, 4, [](auto r, auto c) {return -r -c*c - 1234; }},
{4, 4, [](auto , auto ) {return 7.0; }},
{1, 1, [](auto , auto ) {return 42.0; }},
{4, 2, [](auto r, auto c) {return std::sin(r + c); }},
{1, 5, [](auto r, auto c) {return -1.5 * r + 2.56 * c; }},
{5, 7, [](auto r, auto c) {return (r == c ? 1.0 : 0.0); }}
rotgen::matrix<T,D::rows,D::cols,O::value> input;
rotgen::tests::prepare(input.rows(),input.cols(),desc.init_fn,input);
rotgen::tests::check_shape_functions(input);
};
for (const auto& [rows, cols, fn] : test_matrices)
std::apply([&](auto const&... d) { (process(d),...);}, cases);
};
TTS_CASE_TPL("Test dynamic matrix reduction-like operations", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> )
{
auto const cases = rotgen::tests::generate_matrix_references();
for (const auto& [rows, cols, fn] : cases)
{
test_matrix_reductions<rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>>(rows, cols, fn);
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> input(rows, cols);
rotgen::tests::prepare(rows,cols,fn,input);
rotgen::tests::check_reduction_functions(input);
}
};
TTS_CASE_TPL("Test static matrix reduction-like operations", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> )
{
auto const cases = rotgen::tests::generate_static_matrix_references();
auto process = []<typename D>(D const& desc)
{
rotgen::matrix<T,D::rows,D::cols,O::value> input;
rotgen::tests::prepare(input.rows(),input.cols(),desc.init_fn,input);
rotgen::tests::check_reduction_functions(input);
};
std::apply([&](auto const&... d) { (process(d),...);}, cases);
};

View file

@ -132,7 +132,7 @@ TTS_CASE_TPL("Test coefficient accessors", rotgen::tests::types)
T& ref = a(2, 2);
ref = 17;
assert(a(2, 2) == 17);
TTS_EQUAL(a(2, 2), 17);
};
TTS_CASE_TPL("Test one index coefficient accessors", rotgen::tests::types)

View file

@ -97,7 +97,6 @@ TTS_CASE_TPL("Copy constructor on static matrix", rotgen::tests::types)
TTS_EQUAL(b.cols(), rotgen::Index{5});
};
/*
TTS_CASE_TPL("Copy constructor on static/dynamic matrix", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> )
{
@ -114,7 +113,7 @@ TTS_CASE_TPL("Copy constructor on dynamic/static matrix", rotgen::tests::types)
rotgen::matrix<T, 5, 7,O::value> b = a;
TTS_EQUAL(b.rows(), 5);
TTS_EQUAL(b.cols(), 7);
};*/
};
TTS_CASE_TPL("Move constructor transfers contents", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> )

View file

@ -38,6 +38,14 @@ void test_identity(const auto& matrix, std::size_t rows, std::size_t cols)
TTS_CASE_TPL("Test zero", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> )
{
test_value(rotgen::matrix<T, 3, 4, O::value>{}.setZero(), 3, 4, 0);
test_value(rotgen::matrix<T, 1, 1, O::value>{}.setZero(), 1, 1, 0);
test_value(rotgen::matrix<T, 10, 10, O::value>{}.setZero(), 10, 10, 0);
test_value(rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic, O::value>(1,1).setZero(3,4), 3, 4, 0);
test_value(rotgen::matrix<T, 7, 5, O::value>().setZero(7, 5), 7, 5, 0);
test_value(rotgen::matrix<T, 9,rotgen::Dynamic, O::value>(9,1).setZero(9, 3), 9, 3, 0);
test_value(rotgen::matrix<T,rotgen::Dynamic, 3, O::value>(1,3).setZero(2, 3), 2, 3, 0);
test_value(rotgen::matrix<T, 3, 4, O::value>::Zero(), 3, 4, 0);
test_value(rotgen::matrix<T, 1, 1, O::value>::Zero(), 1, 1, 0);
test_value(rotgen::matrix<T, 10, 10, O::value>::Zero(), 10, 10, 0);
@ -47,9 +55,37 @@ TTS_CASE_TPL("Test zero", rotgen::tests::types)
test_value(rotgen::matrix<T,rotgen::Dynamic, 3, O::value>::Zero(2, 3), 2, 3, 0);
};
TTS_CASE_TPL("Test ones", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> )
{
test_value(rotgen::matrix<T, 3, 4, O::value>{}.setOnes(), 3, 4, 1);
test_value(rotgen::matrix<T, 1, 1, O::value>{}.setOnes(), 1, 1, 1);
test_value(rotgen::matrix<T, 10, 10, O::value>{}.setOnes(), 10, 10, 1);
test_value(rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic, O::value>(1,1).setOnes(3, 4), 3, 4, 1);
test_value(rotgen::matrix<T, 7, 5, O::value>{}.setOnes(7, 5), 7, 5, 1);
test_value(rotgen::matrix<T, 9,rotgen::Dynamic, O::value>(9,1).setOnes(9, 3), 9, 3, 1);
test_value(rotgen::matrix<T,rotgen::Dynamic, 3, O::value>(1,3).setOnes(2, 3), 2, 3, 1);
test_value(rotgen::matrix<T, 3, 4, O::value>::Ones(), 3, 4, 1);
test_value(rotgen::matrix<T, 1, 1, O::value>::Ones(), 1, 1, 1);
test_value(rotgen::matrix<T, 10, 10, O::value>::Ones(), 10, 10, 1);
test_value(rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic, O::value>::Ones(3, 4), 3, 4, 1);
test_value(rotgen::matrix<T, 7, 5, O::value>::Ones(7, 5), 7, 5, 1);
test_value(rotgen::matrix<T, 9,rotgen::Dynamic, O::value>::Ones(9, 3), 9, 3, 1);
test_value(rotgen::matrix<T,rotgen::Dynamic, 3, O::value>::Ones(2, 3), 2, 3, 1);
};
TTS_CASE_TPL("Test constant", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> )
{
test_value(rotgen::matrix<T, 3, 8, O::value>{}.setConstant(5.12), 3, 8, T(5.12));
test_value(rotgen::matrix<T, 1, 1, O::value>{}.setConstant(2.2), 1, 1, T(2.2));
test_value(rotgen::matrix<T, 11, 12, O::value>{}.setConstant(13), 11, 12, T(13));
test_value(rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic, O::value>(1,1).setConstant(2, 7, 5.6), 2, 7, T(5.6));
test_value(rotgen::matrix<T, 2, 2, O::value>{}.setConstant(2, 2, 2.0), 2, 2, T(2.0));
test_value(rotgen::matrix<T, 9,rotgen::Dynamic, O::value>(9,1).setConstant(9, 3, 1.1), 9, 3, T(1.1));
test_value(rotgen::matrix<T,rotgen::Dynamic, 9, O::value>(1,9).setConstant(5, 9, 42), 5, 9,T(42));
test_value(rotgen::matrix<T, 3, 8, O::value>::Constant(5.12), 3, 8, T(5.12));
test_value(rotgen::matrix<T, 1, 1, O::value>::Constant(2.2), 1, 1, T(2.2));
test_value(rotgen::matrix<T, 11, 12, O::value>::Constant(13), 11, 12, T(13));
@ -62,6 +98,14 @@ TTS_CASE_TPL("Test constant", rotgen::tests::types)
TTS_CASE_TPL("Test random", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> )
{
test_random(rotgen::matrix<T, 2, 3, O::value>{}.setRandom(), 2, 3);
test_random(rotgen::matrix<T, 1, 1, O::value>{}.setRandom(), 1, 1);
test_random(rotgen::matrix<T, 11, 17, O::value>{}.setRandom(), 11, 17);
test_random(rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic, O::value>{1,1}.setRandom(7, 3), 7, 3);
test_random(rotgen::matrix<T, 2, 2, O::value>{}.setRandom(2, 2), 2, 2);
test_random(rotgen::matrix<T, 4,rotgen::Dynamic, O::value>{4,1}.setRandom(4, 3), 4, 3);
test_random(rotgen::matrix<T,rotgen::Dynamic, 5, O::value>{1,5}.setRandom(5, 5), 5, 5);
test_random(rotgen::matrix<T, 2, 3, O::value>::Random(), 2, 3);
test_random(rotgen::matrix<T, 1, 1, O::value>::Random(), 1, 1);
test_random(rotgen::matrix<T, 11, 17, O::value>::Random(), 11, 17);
@ -74,6 +118,14 @@ TTS_CASE_TPL("Test random", rotgen::tests::types)
TTS_CASE_TPL("Test identity", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> )
{
test_identity(rotgen::matrix<T, 4, 5, O::value>{}.setIdentity(), 4, 5);
test_identity(rotgen::matrix<T, 1, 1, O::value>{}.setIdentity(), 1, 1);
test_identity(rotgen::matrix<T, 21, 3, O::value>{}.setIdentity(), 21, 3);
test_identity(rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic, O::value>{1,1}.setIdentity(2, 7), 2, 7);
test_identity(rotgen::matrix<T, 2, 2, O::value>{}.setIdentity(2, 2), 2, 2);
test_identity(rotgen::matrix<T, 3,rotgen::Dynamic, O::value>{3,1}.setIdentity(3, 3), 3, 3);
test_identity(rotgen::matrix<T,rotgen::Dynamic, 11, O::value>{1,11}.setIdentity(5, 11), 5, 11);
test_identity(rotgen::matrix<T, 4, 5, O::value>::Identity(), 4, 5);
test_identity(rotgen::matrix<T, 1, 1, O::value>::Identity(), 1, 1);
test_identity(rotgen::matrix<T, 21, 3, O::value>::Identity(), 21, 3);

View file

@ -1,20 +0,0 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#include "unit/tests.hpp"
#include <rotgen/rotgen.hpp>
#include <sstream>
TTS_CASE_TPL("Sample test", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> )
{
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> x({ {1,2} , {3,4} });
std::ostringstream os;
os << x;
TTS_EQUAL(os.str(), std::string{"1 2\n3 4"});
};

View file

@ -6,42 +6,32 @@
*/
//==================================================================================================
#include "unit/tests.hpp"
#include "unit/common/norms.hpp"
#include <rotgen/rotgen.hpp>
#include <Eigen/Dense>
TTS_CASE_TPL("Matrix norm-related operations", rotgen::tests::types)
TTS_CASE_TPL("Test dynamic matrix norm operations", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> )
{
std::vector<rotgen::tests::matrix_descriptor> test_matrices =
auto const cases = rotgen::tests::generate_matrix_references();
for (const auto& [rows, cols, fn] : cases)
{
{ 3, 3, [](int r, int c) { return r + c; }},
{ 2, 3, [](int , int ) { return T{0}; }},
{ 2, 7, [](int r, int c) { return -r*r*r - c*c - T(1.23); }},
{17, 3, [](int r, int c) { return r*c + T(0.98); }},
{ 1, 1, [](int , int ) { return 42; }},
{10, 11, [](int r, int c) { return std::tan(T(r + c)); }},
{ 1, 5, [](int r, int c) { return T(-1.5)*r + T(2.56)*c + T(3.33); }},
{ 7, 1, [](int r, int c) { return r == c ? T(1) : T(0); }},
{ 0, 0, [](int r, int c) { return r == c ? T(1) : T(0); }},
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> input(rows, cols);
rotgen::tests::prepare(rows,cols,fn,input);
rotgen::tests::check_norms_functions(input);
}
};
TTS_CASE_TPL("Test static matrix norm operations", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> )
{
auto const cases = rotgen::tests::generate_static_matrix_references();
auto process = []<typename D>(D const& desc)
{
rotgen::matrix<T,D::rows,D::cols,O::value> input;
rotgen::tests::prepare(input.rows(),input.cols(),desc.init_fn,input);
rotgen::tests::check_norms_functions(input);
};
for (const auto& [rows, cols, fn] : test_matrices)
{
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> matrix(rows, cols);
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic,O::value> ref(rows, cols);
for (rotgen::Index r = 0; r < rows; ++r)
{
for (rotgen::Index c = 0; c < cols; ++c)
{
ref(r, c) = matrix(r, c) = fn(r,c);
}
}
TTS_EQUAL(matrix.norm(), ref.norm());
TTS_EQUAL(matrix.squaredNorm(), ref.squaredNorm());
TTS_EQUAL(matrix.template lpNorm<1>() , ref.template lpNorm<1>());
TTS_EQUAL(matrix.template lpNorm<2>() , ref.template lpNorm<2>());
TTS_EQUAL(matrix.template lpNorm<rotgen::Infinity>(), ref.template lpNorm<Eigen::Infinity>());
}
std::apply([&](auto const&... d) { (process(d),...);}, cases);
};