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,128 +6,69 @@
*/
//==================================================================================================
#include "unit/tests.hpp"
#include "unit/common/arithmetic.hpp"
#include <rotgen/rotgen.hpp>
#include <Eigen/Dense>
template<typename Type1, typename Type2>
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.cols()), static_cast<std::ptrdiff_t>(t2.cols()));
for (rotgen::Index r = 0; r < static_cast<rotgen::Index>(t1.rows()); ++r)
for (rotgen::Index c = 0; c < static_cast<rotgen::Index>(t1.cols()); ++c)
TTS_EQUAL(t1(r, c), t2(r, c));
}
template<typename Matrix1, typename Matrix2, typename Block1, typename Block2>
void test_block_unary_ops(const Matrix1& original_matrix, const Matrix2& ref_matrix,
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.conjugate(), ref_block.conjugate());
test_comparison(original_block.adjoint(), ref_block.adjoint());
if (original_block.rows() == original_block.cols()) {
original_block.transposeInPlace();
ref_block.transposeInPlace();
test_comparison(original_block, ref_block);
test_comparison(original_matrix, ref_matrix);
original_block.adjointInPlace();
ref_block.adjointInPlace();
test_comparison(original_block, ref_block);
test_comparison(original_matrix, ref_matrix);
}
}
template<typename Block1, typename Block2>
void compare_reductions(const Block1& block, const Block2& ref)
{
constexpr double epsilon = 0.0001;
TTS_RELATIVE_EQUAL(block.sum(), ref.sum(), epsilon);
TTS_RELATIVE_EQUAL(block.prod(), ref.prod(), epsilon);
TTS_RELATIVE_EQUAL(block.mean(), ref.mean(), epsilon);
TTS_EQUAL(block.trace(), ref.trace());
TTS_EQUAL(block.minCoeff(), ref.minCoeff());
TTS_EQUAL(block.maxCoeff(), ref.maxCoeff());
std::ptrdiff_t row, col, ref_row, ref_col;
TTS_EQUAL(block.minCoeff(&row, &col), ref.minCoeff(&ref_row, &ref_col));
TTS_EQUAL(row, ref_row);
TTS_EQUAL(col, ref_col);
TTS_EQUAL(block.maxCoeff(&row, &col), ref.maxCoeff(&ref_row, &ref_col));
TTS_EQUAL(row, ref_row);
TTS_EQUAL(col, ref_col);
}
template <typename MatrixType, typename T>
void test_dynamic_block_reductions(rotgen::tests::matrix_block_test_case<MatrixType> const& matrix_construct)
{
using EigenMatrix = Eigen::Matrix<typename MatrixType::scalar_type, Eigen::Dynamic, Eigen::Dynamic>;
MatrixType original(matrix_construct.rows, matrix_construct.cols);
EigenMatrix ref(matrix_construct.rows, matrix_construct.cols);
for (rotgen::Index r = 0; r < matrix_construct.rows; ++r)
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));
std::vector<std::pair<rotgen::block<MatrixType>, Eigen::Block<EigenMatrix>>> test_cases {
{ rotgen::extract(original, matrix_construct.i0, matrix_construct.j0,
matrix_construct.ni, matrix_construct.nj),
ref.block(matrix_construct.i0, matrix_construct.j0,
matrix_construct.ni, matrix_construct.nj) },
{ rotgen::topLeftCorner(original, matrix_construct.ni, matrix_construct.nj),
ref.topLeftCorner(matrix_construct.ni, matrix_construct.nj) },
{ rotgen::topRightCorner(original, matrix_construct.ni, matrix_construct.nj),
ref.topRightCorner(matrix_construct.ni, matrix_construct.nj) },
{ rotgen::bottomLeftCorner(original, matrix_construct.ni, matrix_construct.nj),
ref.bottomLeftCorner(matrix_construct.ni, matrix_construct.nj) },
{ rotgen::bottomRightCorner(original, matrix_construct.ni, matrix_construct.nj),
ref.bottomRightCorner(matrix_construct.ni, matrix_construct.nj) },
{ rotgen::topRows(original, matrix_construct.ni),
ref.topRows(matrix_construct.ni) },
{ rotgen::middleRows(original, matrix_construct.i0, matrix_construct.ni),
ref.middleRows(matrix_construct.i0, matrix_construct.ni) },
{ rotgen::bottomRows(original, matrix_construct.ni),
ref.bottomRows(matrix_construct.ni) },
};
for (const auto& [original_block, ref_block] : test_cases) {
compare_reductions(original_block, ref_block);
test_block_unary_ops(original, ref, original_block, ref_block);
}
}
TTS_CASE_TPL("Test dynamic block reductions", rotgen::tests::types)
TTS_CASE_TPL("Test dynamic block transposition-like operations", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> )
{
using mat_t = rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>;
std::vector<rotgen::tests::matrix_block_test_case<mat_t>> test_cases =
{
{6, 5, [](rotgen::Index r, rotgen::Index c) { return T(r + c); }, 1, 2, 3, 2},
{9, 11, [](rotgen::Index r, rotgen::Index c) {return T(r + c); }, 0, 1, 4, 9},
{3, 3, [](rotgen::Index , rotgen::Index ) {return T(0.0); }, 1, 1, 1, 1},
{1, 4, [](rotgen::Index r, rotgen::Index c) {return T(-r -c*c - 1234); }, 0, 0, 1, 1},
{9, 9, [](rotgen::Index r, rotgen::Index c) {return T(-r + 2*c); }, 0, 1, 3, 3},
{11, 13, [](rotgen::Index r, rotgen::Index c) {return T(std::tan(r+c)); }, 1, 1, 2, 2},
{4, 1, [](rotgen::Index , rotgen::Index ) {return T(7.0); }, 2, 0, 2, 1},
{1, 1, [](rotgen::Index , rotgen::Index ) {return T(42.0); }, 0, 0, 1, 1},
{12, 13, [](rotgen::Index r, rotgen::Index c) {return T(std::sin(r + c)); }, 2, 3, 4, 5 },
{4, 9, [](rotgen::Index r, rotgen::Index c) {return T(-1.5 * r + 2.56 * c); }, 0, 1, 2, 3 },
{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)
test_dynamic_block_reductions<mat_t, T>(test_case);
auto const cases = rotgen::tests::generate_block_references<T,O>();
for (const auto& [matrix_desc, i0, j0, ni, nj] : cases)
{
auto[rows,cols,fn] = matrix_desc;
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> m(rows, cols);
rotgen::tests::prepare(rows,cols,fn,m);
auto input = rotgen::extract(m, i0, j0, ni, nj);
rotgen::tests::check_shape_functions(input);
}
};
TTS_CASE_TPL("Test static block transposition-like operations", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> )
{
auto const cases = rotgen::tests::generate_static_block_references<T,O>();
auto process = []<typename D>(D const& d)
{
auto[desc,i0,j0] = d;
auto[rows,cols,fn] = desc;
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> m(rows, cols);
rotgen::tests::prepare(rows,cols,fn,m);
auto input = rotgen::extract<D::ni,D::nj>(m, i0, j0);
rotgen::tests::check_shape_functions(input);
};
std::apply([&](auto const&... d) { (process(d),...);}, cases);
};
TTS_CASE_TPL("Test dynamic block reduction-like operations", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> )
{
auto const cases = rotgen::tests::generate_block_references<T,O>();
for (const auto& [matrix_desc, i0, j0, ni, nj] : cases)
{
auto[rows,cols,fn] = matrix_desc;
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> m(rows, cols);
rotgen::tests::prepare(rows,cols,fn,m);
auto input = rotgen::extract(m, i0, j0, ni, nj);
rotgen::tests::check_reduction_functions(input);
}
};
TTS_CASE_TPL("Test static block reduction-like operations", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> )
{
auto const cases = rotgen::tests::generate_static_block_references<T,O>();
auto process = []<typename D>(D const& d)
{
auto[desc,i0,j0] = d;
auto[rows,cols,fn] = desc;
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> m(rows, cols);
rotgen::tests::prepare(rows,cols,fn,m);
auto input = rotgen::extract<D::ni,D::nj>(m, i0, j0);
rotgen::tests::check_reduction_functions(input);
};
std::apply([&](auto const&... d) { (process(d),...);}, cases);
};