Automatic Differentiation
 
Loading...
Searching...
No Matches
qr_thin.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_PRIM_FUN_QR_THIN_HPP
2#define STAN_MATH_PRIM_FUN_QR_THIN_HPP
3
7#include <algorithm>
8#include <tuple>
9
10namespace stan {
11namespace math {
12
22template <typename EigMat, require_eigen_t<EigMat>* = nullptr>
23std::tuple<Eigen::Matrix<value_type_t<EigMat>, Eigen::Dynamic, Eigen::Dynamic>,
24 Eigen::Matrix<value_type_t<EigMat>, Eigen::Dynamic, Eigen::Dynamic>>
25qr_thin(const EigMat& m) {
26 using matrix_t
27 = Eigen::Matrix<value_type_t<EigMat>, Eigen::Dynamic, Eigen::Dynamic>;
28 if (unlikely(m.size() == 0)) {
29 return std::make_tuple(matrix_t(0, 0), matrix_t(0, 0));
30 }
31
32 Eigen::HouseholderQR<matrix_t> qr(m.rows(), m.cols());
33 qr.compute(m);
34 const int min_size = std::min(m.rows(), m.cols());
35 matrix_t Q = qr.householderQ() * matrix_t::Identity(m.rows(), min_size);
36 for (int i = 0; i < min_size; i++) {
37 if (qr.matrixQR().coeff(i, i) < 0) {
38 Q.col(i) *= -1.0;
39 }
40 }
41 matrix_t R = qr.matrixQR().topLeftCorner(min_size, m.cols());
42 R.template triangularView<Eigen::StrictlyLower>().setZero();
43 for (int i = 0; i < min_size; ++i) {
44 if (R(i, i) < 0) {
45 R.row(i) *= -1.0;
46 }
47 }
48 return std::make_tuple(std::move(Q), std::move(R));
49}
50
51} // namespace math
52} // namespace stan
53
54#endif
#define unlikely(x)
std::tuple< Eigen::Matrix< value_type_t< EigMat >, Eigen::Dynamic, Eigen::Dynamic >, Eigen::Matrix< value_type_t< EigMat >, Eigen::Dynamic, Eigen::Dynamic > > qr(const EigMat &m)
Returns the fat QR decomposition.
Definition qr.hpp:25
std::tuple< Eigen::Matrix< value_type_t< EigMat >, Eigen::Dynamic, Eigen::Dynamic >, Eigen::Matrix< value_type_t< EigMat >, Eigen::Dynamic, Eigen::Dynamic > > qr_thin(const EigMat &m)
Returns the thin QR decomposition.
Definition qr_thin.hpp:25
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...