bool QRDecomposition<T>::set(const MatrixT& A) { QR.copy(A); tau.resize(Min(A.m,A.n)); for (int i=0;i<Min(A.m,A.n);i++) { /* Compute the Householder transformation to reduce the j-th column of the matrix to a multiple of the j-th unit vector */ VectorT c_full,c; QR.getColRef(i,c_full); c.setRef(c_full,i); T tau_i = HouseholderTransform (c); tau(i)=tau_i; /* Apply the transformation to the remaining columns and update the norms */ if (i+1 < A.n) { MatrixT m; m.setRef(QR,i,i+1); HouseholderPreMultiply (tau_i, c, m); } } return true; }
void QRDecomposition<T>::getQ(MatrixT& Q) const { Assert(tau.n == Min(QR.m,QR.n)); Q.resize(QR.m,QR.m); int i; Q.setIdentity(); for (i=Min(QR.m,QR.n);i>0 && i--;) { VectorT c,h; QR.getColRef(i,c); h.setRef(c,i); MatrixT m; m.setRef(Q,i,i); HouseholderPreMultiply(tau(i),h,m); } }
void QRDecomposition<T>::leastSquares(const VectorT& b, VectorT& x, VectorT& residual) const { if(x.n == 0) x.resize(QR.n); Assert(QR.m >= QR.n); Assert(QR.m == b.n); Assert(QR.n == x.n); Assert(QR.m == residual.n); MatrixT R; R.setRef(QR,0,0,1,1,QR.n,QR.n); VectorT c; c.setRef(residual,0,1,QR.n); /* compute rhs = Q^T b */ QtMul(b,residual); /* Solve R x = rhs */ UBackSubstitute(R,c,x); /* Compute residual = b - A x = Q (Q^T b - R x) */ c.setZero(); QMul(residual,residual); }