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") {