10 #include <catch2/catch_test_macros.hpp>
16 #include "Eigen/Dense"
19 using namespace nmodl;
20 using namespace Eigen;
25 template <
typename DerivedA,
typename DerivedB>
26 bool allclose(
const Eigen::DenseBase<DerivedA>& a,
27 const Eigen::DenseBase<DerivedB>& b,
28 const typename DerivedA::RealScalar& rtol =
29 Eigen::NumTraits<typename DerivedA::RealScalar>::dummy_precision(),
30 const typename DerivedA::RealScalar& atol =
31 Eigen::NumTraits<typename DerivedA::RealScalar>::epsilon()) {
32 return ((a.derived() - b.derived()).array().abs() <= (atol + rtol * b.derived().array().abs()))
39 std::random_device rd;
41 std::mt19937 mt(seed);
42 std::uniform_real_distribution<T> nums(-1e3, 1e3);
44 std::chrono::duration<double> eigen_timing(std::chrono::duration<double>::zero());
45 std::chrono::duration<double> crout_timing(std::chrono::duration<double>::zero());
47 auto t1 = std::chrono::high_resolution_clock::now();
48 auto t2 = std::chrono::high_resolution_clock::now();
50 for (
int mat_size = 5; mat_size < 15; mat_size++) {
51 Matrix<T, Dynamic, Dynamic, Eigen::ColMajor> A_ColMajor(mat_size,
53 Matrix<T, Dynamic, Dynamic, Eigen::RowMajor> A_RowMajor(mat_size, mat_size);
54 Matrix<T, Dynamic, 1> b(mat_size);
56 for (
int repetitions = 0; repetitions < static_cast<int>(1e3); ++repetitions) {
59 for (
int r = 0; r < mat_size; r++) {
60 for (
int c = 0; c < mat_size; c++) {
61 A_ColMajor(r, c) = nums(mt);
62 A_RowMajor(r, c) = A_ColMajor(r, c);
66 }
while (!A_ColMajor.fullPivLu().isInvertible());
68 t1 = std::chrono::high_resolution_clock::now();
70 Matrix<T, Dynamic, 1> eigen_x_ColMajor(mat_size);
71 eigen_x_ColMajor = A_ColMajor.partialPivLu().solve(b);
74 Matrix<T, Dynamic, 1> eigen_x_RowMajor(mat_size);
75 eigen_x_RowMajor = A_RowMajor.partialPivLu().solve(b);
76 t2 = std::chrono::high_resolution_clock::now();
77 eigen_timing += (t2 - t1);
79 if (!
allclose(eigen_x_ColMajor, eigen_x_RowMajor, rtol, atol)) {
80 cerr <<
"eigen_x_ColMajor vs eigen_x_RowMajor (issue) / seed = " << seed << endl;
84 t1 = std::chrono::high_resolution_clock::now();
86 Matrix<T, Dynamic, 1> crout_x_ColMajor(mat_size);
87 if (!A_ColMajor.IsRowMajor)
88 A_ColMajor.transposeInPlace();
89 Matrix<int, Dynamic, 1> pivot(mat_size);
90 Matrix<T, Dynamic, 1> rowmax(mat_size);
91 crout::Crout<T>(mat_size, A_ColMajor.data(), pivot.data(), rowmax.data());
93 mat_size, A_ColMajor.data(), b.data(), crout_x_ColMajor.data(), pivot.data());
96 Matrix<T, Dynamic, 1> crout_x_RowMajor(mat_size);
97 crout::Crout<T>(mat_size, A_RowMajor.data(), pivot.data(), rowmax.data());
99 mat_size, A_RowMajor.data(), b.data(), crout_x_RowMajor.data(), pivot.data());
100 t2 = std::chrono::high_resolution_clock::now();
101 crout_timing += (t2 - t1);
103 if (!
allclose(eigen_x_ColMajor, crout_x_ColMajor, rtol, atol)) {
104 cerr <<
"eigen_x_ColMajor vs crout_x_ColMajor (issue) / seed = " << seed << endl;
108 if (!
allclose(eigen_x_RowMajor, crout_x_RowMajor, rtol, atol)) {
109 cerr <<
"eigen_x_RowMajor vs crout_x_RowMajor (issue) / seed = " << seed << endl;
115 std::cout <<
"eigen_timing [ms] : " << eigen_timing.count() * 1e3 << std::endl;
116 std::cout <<
"crout_timing [ms] : " << crout_timing.count() * 1e3 << std::endl;
123 GIVEN(
"crout (double)") {
124 constexpr
double rtol = 1e-8;
125 constexpr
double atol = 1e-8;
127 auto test = test_Crout_correctness<double>(rtol, atol);
129 THEN(
"run tests & compare") {