19#include <gtest/gtest.h>
23#include <boost/multi_array.hpp>
25#include "arccore/alina/QRFactorizationImpl.h"
26#include "arccore/alina/ValueTypeInterface.h"
27#include "arccore/alina/ValueTypeComplex.h"
28#include "arccore/alina/StaticMatrix.h"
37 static std::mt19937 gen;
38 static std::uniform_real_distribution<T> rnd;
47 return make_random<T>::get();
53 static std::complex<T> get()
55 return std::complex<T>(random<T>(), random<T>());
59template <
class T,
int N,
int M>
65 matrix A = Alina::math::zero<matrix>();
66 for (
int i = 0; i < N; ++i)
67 for (
int j = 0; j < M; ++j)
68 A(i, j) = make_random<T>::get();
73template <
class value_type, Alina::detail::storage_order order>
74void qr_factorize(
int n,
int m)
76 std::cout <<
"factorize " << n <<
" " << m << std::endl;
77 typedef typename std::conditional<order == Alina::detail::row_major,
78 boost::c_storage_order,
79 boost::fortran_storage_order>::type ma_storage_order;
81 boost::multi_array<value_type, 2> A0(boost::extents[n][m], ma_storage_order());
83 for (
int i = 0; i < n; ++i)
84 for (
int j = 0; j < m; ++j)
85 A0[i][j] = random<value_type>();
87 boost::multi_array<value_type, 2> A = A0;
91 qr.factorize(n, m, A.data(), order);
94 int p = std::min(n, m);
95 for (
int i = 0; i < n; ++i) {
96 for (
int j = 0; j < m; ++j) {
97 value_type sum = Alina::math::zero<value_type>();
99 for (
int k = 0; k < p; ++k)
100 sum += qr.Q(i, k) * qr.R(k, j);
104 ASSERT_NEAR(Alina::math::norm(sum), 0.0, 1e-8);
109template <
class value_type, Alina::detail::storage_order order>
110void qr_solve(
int n,
int m)
112 std::cout <<
"solve " << n <<
" " << m << std::endl;
113 typedef typename std::conditional<order == Alina::detail::row_major,
114 boost::c_storage_order,
115 boost::fortran_storage_order>::type ma_storage_order;
117 typedef typename Alina::math::rhs_of<value_type>::type rhs_type;
119 boost::multi_array<value_type, 2> A0(boost::extents[n][m], ma_storage_order());
121 for (
int i = 0; i < n; ++i)
122 for (
int j = 0; j < m; ++j)
123 A0[i][j] = random<value_type>();
125 boost::multi_array<value_type, 2> A = A0;
129 std::vector<rhs_type> f0(n, Alina::math::constant<rhs_type>(1));
130 std::vector<rhs_type> f = f0;
132 std::vector<rhs_type> x(m);
134 qr.solve(n, m, A.data(), f.data(), x.data(), order);
136 std::vector<rhs_type> Ax(n);
137 for (
int i = 0; i < n; ++i) {
138 rhs_type sum = Alina::math::zero<rhs_type>();
139 for (
int j = 0; j < m; ++j)
140 sum += A0[i][j] * x[j];
145 ASSERT_NEAR(Alina::math::norm(sum - f0[i]), 0.0, 1e-8);
150 for (
int i = 0; i < m; ++i) {
151 rhs_type sumx = Alina::math::zero<rhs_type>();
152 rhs_type sumf = Alina::math::zero<rhs_type>();
154 for (
int j = 0; j < n; ++j) {
155 sumx += Alina::math::adjoint(A0[j][i]) * Ax[j];
156 sumf += Alina::math::adjoint(A0[j][i]) * f0[j];
159 rhs_type delta = sumx - sumf;
161 ASSERT_NEAR(Alina::math::norm(delta), 0.0, 1e-8);
166TEST(alina_test_qr, test_qr_factorize)
168 const int shape[][2] = {
175 const int n =
sizeof(shape) /
sizeof(shape[0]);
177 for (
int i = 0; i < n; ++i) {
178 qr_factorize<double, Alina::detail::row_major>(shape[i][0], shape[i][1]);
179 qr_factorize<double, Alina::detail::col_major>(shape[i][0], shape[i][1]);
180 qr_factorize<std::complex<double>, Alina::detail::row_major>(shape[i][0], shape[i][1]);
181 qr_factorize<std::complex<double>, Alina::detail::col_major>(shape[i][0], shape[i][1]);
182 qr_factorize<Alina::StaticMatrix<double, 2, 2>, Alina::detail::row_major>(shape[i][0], shape[i][1]);
183 qr_factorize<Alina::StaticMatrix<double, 2, 2>, Alina::detail::col_major>(shape[i][0], shape[i][1]);
187TEST(alina_test_qr, test_qr_solve)
189 const int shape[][2] = {
196 const int n =
sizeof(shape) /
sizeof(shape[0]);
198 for (
int i = 0; i < n; ++i) {
199 qr_solve<double, Alina::detail::row_major>(shape[i][0], shape[i][1]);
200 qr_solve<double, Alina::detail::col_major>(shape[i][0], shape[i][1]);
201 qr_solve<std::complex<double>, Alina::detail::row_major>(shape[i][0], shape[i][1]);
202 qr_solve<std::complex<double>, Alina::detail::col_major>(shape[i][0], shape[i][1]);
203 qr_solve<Alina::StaticMatrix<double, 2, 2>, Alina::detail::row_major>(shape[i][0], shape[i][1]);
204 qr_solve<Alina::StaticMatrix<double, 2, 2>, Alina::detail::col_major>(shape[i][0], shape[i][1]);
208TEST(alina_test_qr, qr_issue_39)
210 boost::multi_array<double, 2> A0(boost::extents[2][2]);
216 boost::multi_array<double, 2> A = A0;
220 qr.factorize(2, 2, A.data());
223 for (
int i = 0; i < 2; ++i) {
224 for (
int j = 0; j < 2; ++j) {
226 for (
int k = 0; k < 2; ++k)
227 sum += qr.Q(i, k) * qr.R(k, j);
231 ASSERT_NEAR(sum, 0.0, 1e-8);
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-