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