Implement a QR solver wrapper

This commit is contained in:
Joel Falcou 2025-09-09 16:27:22 +02:00
parent bb5d739e5d
commit bb47b07422
10 changed files with 90 additions and 6 deletions

View file

@ -0,0 +1,34 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#include "unit/tests.hpp"
#include <rotgen/rotgen.hpp>
TTS_CASE_TPL("System solver using QR", rotgen::tests::types)
<typename T, typename O>( tts::type< tts::types<T,O>> )
{
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value>
a { { 2.3, -1, 0.1}
, {-1.6, 2.6, -1}
, { 0.3, -1, 2}
};
rotgen::matrix<T,rotgen::Dynamic,1,O::value> b(3,1);
b(0) = b(2) = 1; b(1) = 0;
rotgen::matrix<T,rotgen::Dynamic,rotgen::Dynamic,O::value> r(3,1), error;
auto x = rotgen::extract(r,0,0,3,1);
rotgen::solver::qr(x, a, b);
error = a * r - b;
auto eps = std::numeric_limits<T>::epsilon();
TTS_LESS(rotgen::maxCoeff(rotgen::abs(error)) / eps, 5)
<< "Result:\n" << r << "\n"
<< "Residuals:\n" << error << "\n";
};

View file

@ -0,0 +1,84 @@
//==================================================================================================
/*
ROTGEN - Runtime Overlay for Eigen
Copyright : CODE RECKONS
SPDX-License-Identifier: BSL-1.0
*/
//==================================================================================================
#include "unit/tests.hpp"
#include <rotgen/rotgen.hpp>
#include <functional>
#include <array>
template <typename MatrixType>
struct MatrixDescriptor
{
std::size_t rows, cols;
std::function<void(MatrixType &, std::size_t, std::size_t)> init_fn;
};
template <typename MatrixType, std::size_t N>
void test_matrix_sizes(std::size_t rows, std::size_t cols,
const std::function<void(MatrixType &, std::size_t, std::size_t)> &init_fn,
const std::array<std::pair<int, int>, N>& resize_dimensions)
{
MatrixType matrix(rows, cols);
for (std::size_t r = 0; r < rows; ++r)
for (std::size_t c = 0; c < cols; ++c)
init_fn(matrix, r, c);
TTS_EQUAL(rotgen::size(matrix), rows*cols);
for (std::size_t i = 0; i < N; ++i) {
int r = resize_dimensions[i].first;
int c = resize_dimensions[i].second;
rotgen::resize(matrix, r, c);
TTS_EQUAL(rotgen::rows(matrix), static_cast<size_t>(r));
TTS_EQUAL(rotgen::cols(matrix), static_cast<size_t>(c));
TTS_EQUAL(rotgen::size(matrix), static_cast<size_t>(r*c));
}
rotgen::conservativeResize(matrix, rows, cols);
TTS_EQUAL(rotgen::size(matrix), rows*cols);
int i = 1;
for(std::size_t r=0;r<rows;++r)
for(std::size_t c=0;c<cols;++c)
matrix(r, c) = i++;
rotgen::conservativeResize(matrix, rows + 3, cols + 2);
TTS_EQUAL(rotgen::size(matrix), (rows + 3)*(cols + 2));
i = 1;
for(std::size_t r=0;r<rows;++r)
for(std::size_t c=0;c<cols;++c)
TTS_EQUAL(matrix(r,c),i++);
}
TTS_CASE("Matrix size-related operations")
{
std::vector<MatrixDescriptor<rotgen::matrix<double>>> test_matrices = {
{3, 3, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = r + c; }},
{2, 3, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = 0.0; }},
{2, 7, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = -r*r*r - c*c - 1.23; }},
{17, 3, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = r*c + 0.98; }},
{1, 1, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = 42.0; }},
{10, 11, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = std::tan(r + c); }},
{1, 5, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = -1.5*r + 2.56*c + 3.33; }},
{7, 1, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = (r == c ? 1.0 : 0.0); }},
{0, 0, [](auto& m, std::size_t r, std::size_t c) { m(r, c) = (r == c ? 1.0 : 0.0); }},
};
for (const auto& [rows, cols, init_fn] : test_matrices)
test_matrix_sizes<rotgen::matrix<double>>(rows, cols, init_fn, std::array{
std::pair{1, 2}, std::pair{11, 17}, std::pair{4, 5},
std::pair{9, 1}, std::pair{3, 8}, std::pair{22, 0},
});
rotgen::matrix<double, 3, 3> a;
TTS_EXPECT_NOT_COMPILES(a, { rotgen::resize(a, 4, 5); });
TTS_EXPECT_NOT_COMPILES(a, { rotgen::conservativeResize(a, 4, 5); });
};