1 #ifndef STAN_MATH_PRIM_FUN_QR_THIN_Q_HPP
2 #define STAN_MATH_PRIM_FUN_QR_THIN_Q_HPP
3 
4 #include <stan/math/prim/err.hpp>
5 #include <stan/math/prim/fun/Eigen.hpp>
6 #include <algorithm>
7 
8 namespace stan {
9 namespace math {
10 
11 /**
12  * Returns the orthogonal factor of the thin QR decomposition
13  *
14  * @tparam EigMat type of the matrix
15  * @param m Matrix.
16  * @return Orthogonal matrix with minimal columns
17  */
18 template <typename EigMat, require_eigen_t<EigMat>* = nullptr>
qr_thin_Q(const EigMat & m)19 Eigen::Matrix<value_type_t<EigMat>, Eigen::Dynamic, Eigen::Dynamic> qr_thin_Q(
20     const EigMat& m) {
21   using matrix_t
22       = Eigen::Matrix<value_type_t<EigMat>, Eigen::Dynamic, Eigen::Dynamic>;
23   check_nonzero_size("qr_thin_Q", "m", m);
24   Eigen::HouseholderQR<matrix_t> qr(m.rows(), m.cols());
25   qr.compute(m);
26   const int min_size = std::min(m.rows(), m.cols());
27   matrix_t Q = qr.householderQ() * matrix_t::Identity(m.rows(), min_size);
28   for (int i = 0; i < min_size; i++) {
29     if (qr.matrixQR().coeff(i, i) < 0) {
30       Q.col(i) *= -1.0;
31     }
32   }
33   return Q;
34 }
35 
36 }  // namespace math
37 }  // namespace stan
38 
39 #endif
40