Linear Algebra  arduino
Accessible implementations of linear algebra algorithms
QR-PerfTest.cpp
Go to the documentation of this file.
1 
29 #include <chrono>
30 #include <iomanip>
31 #include <iostream>
32 
33 #include <linalg/HouseholderQR.hpp>
34 #include <Eigen/QR>
35 using EigenMat =
36  Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
37 
38 int main(int argc, const char *argv[]) {
39  // First (optional) command line argument is the matrix size
40  size_t size = 500;
41  if (argc > 1) {
42  size = std::stoi(argv[1]);
43  }
44 
45  // Generate a random matrix of the given size
46  Matrix A = Matrix::random(size, size, -1, +1);
47  // Convert it to an Eigen matrix
48  EigenMat A_eigen = EigenMat::Zero(size, size);
49  std::copy(A.begin(), A.end(), A_eigen.data());
50 
51  {
52  // Compute the QR factorization using our naive implementation:
53  HouseholderQR qr;
54  Matrix A_cpy = A; // make a copy here to prevent allocation while timing
55  auto start = std::chrono::high_resolution_clock::now();
56  qr.compute(std::move(A_cpy));
57  auto finish = std::chrono::high_resolution_clock::now();
58 
59  std::chrono::duration<double> elapsed = finish - start;
60  Matrix QR = qr.apply_Q(qr.get_R()); // Multiply Q×R
61  double err_fro = (A - QR).normFro();
62  std::cout << "Elapsed time HouseholderQR: " << elapsed.count() << " s\n"
63  << "Error QR - A in Frobenius norm: " << std::scientific
64  << err_fro << std::defaultfloat << std::endl;
65  }
66  {
67  // Now perform the factorization using Eigen:
68  Eigen::HouseholderQR<EigenMat> qr_eigen;
69  EigenMat A_eigen_cpy = A_eigen;
70  auto start = std::chrono::high_resolution_clock::now();
71  qr_eigen.compute(std::move(A_eigen_cpy));
72  auto finish = std::chrono::high_resolution_clock::now();
73 
74  std::chrono::duration<double> elapsed = finish - start;
75  EigenMat QR = qr_eigen.matrixQR().triangularView<Eigen::Upper>();
76  qr_eigen.householderQ().applyThisOnTheLeft(QR); // Multiply Q×R
77  auto err_fro = (A_eigen - QR).norm();
78  std::cout << "Elapsed time Eigen: " << elapsed.count() << " s\n"
79  << "Error QR - A in Frobenius norm: " << std::scientific
80  << err_fro << std::defaultfloat << std::endl;
81  }
82 }
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor > EigenMat
Definition: QR-PerfTest.cpp:36
int main(int argc, const char *argv[])
Definition: QR-PerfTest.cpp:38
QR factorization using Householder reflectors.
Matrix apply_Q(const Matrix &X) const
Compute the product QB.
Matrix get_R() const &
Get a copy of the upper-triangular matrix R.
void compute(Matrix &&matrix)
Perform the QR factorization of the given matrix.
General matrix class.
Definition: Matrix.hpp:34
static Matrix random(size_t rows, size_t cols, double min=0, double max=1, std::default_random_engine::result_type seed=std::default_random_engine::default_seed)
Create a matrix with uniformly distributed random values.
Definition: Matrix.cpp:172
storage_t::iterator end()
Get the iterator to the element past the end of the matrix.
Definition: Matrix.hpp:220
storage_t::iterator begin()
Get the iterator to the first element of the matrix.
Definition: Matrix.hpp:213