Warning, file /include/eigen3/Eigen/src/QR/HouseholderQR.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef EIGEN_QR_H
0013 #define EIGEN_QR_H
0014
0015 namespace Eigen {
0016
0017 namespace internal {
0018 template<typename _MatrixType> struct traits<HouseholderQR<_MatrixType> >
0019 : traits<_MatrixType>
0020 {
0021 typedef MatrixXpr XprKind;
0022 typedef SolverStorage StorageKind;
0023 typedef int StorageIndex;
0024 enum { Flags = 0 };
0025 };
0026
0027 }
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056 template<typename _MatrixType> class HouseholderQR
0057 : public SolverBase<HouseholderQR<_MatrixType> >
0058 {
0059 public:
0060
0061 typedef _MatrixType MatrixType;
0062 typedef SolverBase<HouseholderQR> Base;
0063 friend class SolverBase<HouseholderQR>;
0064
0065 EIGEN_GENERIC_PUBLIC_INTERFACE(HouseholderQR)
0066 enum {
0067 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
0068 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
0069 };
0070 typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime, (MatrixType::Flags&RowMajorBit) ? RowMajor : ColMajor, MaxRowsAtCompileTime, MaxRowsAtCompileTime> MatrixQType;
0071 typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType;
0072 typedef typename internal::plain_row_type<MatrixType>::type RowVectorType;
0073 typedef HouseholderSequence<MatrixType,typename internal::remove_all<typename HCoeffsType::ConjugateReturnType>::type> HouseholderSequenceType;
0074
0075
0076
0077
0078
0079
0080
0081 HouseholderQR() : m_qr(), m_hCoeffs(), m_temp(), m_isInitialized(false) {}
0082
0083
0084
0085
0086
0087
0088
0089 HouseholderQR(Index rows, Index cols)
0090 : m_qr(rows, cols),
0091 m_hCoeffs((std::min)(rows,cols)),
0092 m_temp(cols),
0093 m_isInitialized(false) {}
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107 template<typename InputType>
0108 explicit HouseholderQR(const EigenBase<InputType>& matrix)
0109 : m_qr(matrix.rows(), matrix.cols()),
0110 m_hCoeffs((std::min)(matrix.rows(),matrix.cols())),
0111 m_temp(matrix.cols()),
0112 m_isInitialized(false)
0113 {
0114 compute(matrix.derived());
0115 }
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125 template<typename InputType>
0126 explicit HouseholderQR(EigenBase<InputType>& matrix)
0127 : m_qr(matrix.derived()),
0128 m_hCoeffs((std::min)(matrix.rows(),matrix.cols())),
0129 m_temp(matrix.cols()),
0130 m_isInitialized(false)
0131 {
0132 computeInPlace();
0133 }
0134
0135 #ifdef EIGEN_PARSED_BY_DOXYGEN
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 template<typename Rhs>
0151 inline const Solve<HouseholderQR, Rhs>
0152 solve(const MatrixBase<Rhs>& b) const;
0153 #endif
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163 HouseholderSequenceType householderQ() const
0164 {
0165 eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
0166 return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate());
0167 }
0168
0169
0170
0171
0172 const MatrixType& matrixQR() const
0173 {
0174 eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
0175 return m_qr;
0176 }
0177
0178 template<typename InputType>
0179 HouseholderQR& compute(const EigenBase<InputType>& matrix) {
0180 m_qr = matrix.derived();
0181 computeInPlace();
0182 return *this;
0183 }
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198 typename MatrixType::RealScalar absDeterminant() const;
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212 typename MatrixType::RealScalar logAbsDeterminant() const;
0213
0214 inline Index rows() const { return m_qr.rows(); }
0215 inline Index cols() const { return m_qr.cols(); }
0216
0217
0218
0219
0220
0221 const HCoeffsType& hCoeffs() const { return m_hCoeffs; }
0222
0223 #ifndef EIGEN_PARSED_BY_DOXYGEN
0224 template<typename RhsType, typename DstType>
0225 void _solve_impl(const RhsType &rhs, DstType &dst) const;
0226
0227 template<bool Conjugate, typename RhsType, typename DstType>
0228 void _solve_impl_transposed(const RhsType &rhs, DstType &dst) const;
0229 #endif
0230
0231 protected:
0232
0233 static void check_template_parameters()
0234 {
0235 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
0236 }
0237
0238 void computeInPlace();
0239
0240 MatrixType m_qr;
0241 HCoeffsType m_hCoeffs;
0242 RowVectorType m_temp;
0243 bool m_isInitialized;
0244 };
0245
0246 template<typename MatrixType>
0247 typename MatrixType::RealScalar HouseholderQR<MatrixType>::absDeterminant() const
0248 {
0249 using std::abs;
0250 eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
0251 eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
0252 return abs(m_qr.diagonal().prod());
0253 }
0254
0255 template<typename MatrixType>
0256 typename MatrixType::RealScalar HouseholderQR<MatrixType>::logAbsDeterminant() const
0257 {
0258 eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
0259 eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
0260 return m_qr.diagonal().cwiseAbs().array().log().sum();
0261 }
0262
0263 namespace internal {
0264
0265
0266 template<typename MatrixQR, typename HCoeffs>
0267 void householder_qr_inplace_unblocked(MatrixQR& mat, HCoeffs& hCoeffs, typename MatrixQR::Scalar* tempData = 0)
0268 {
0269 typedef typename MatrixQR::Scalar Scalar;
0270 typedef typename MatrixQR::RealScalar RealScalar;
0271 Index rows = mat.rows();
0272 Index cols = mat.cols();
0273 Index size = (std::min)(rows,cols);
0274
0275 eigen_assert(hCoeffs.size() == size);
0276
0277 typedef Matrix<Scalar,MatrixQR::ColsAtCompileTime,1> TempType;
0278 TempType tempVector;
0279 if(tempData==0)
0280 {
0281 tempVector.resize(cols);
0282 tempData = tempVector.data();
0283 }
0284
0285 for(Index k = 0; k < size; ++k)
0286 {
0287 Index remainingRows = rows - k;
0288 Index remainingCols = cols - k - 1;
0289
0290 RealScalar beta;
0291 mat.col(k).tail(remainingRows).makeHouseholderInPlace(hCoeffs.coeffRef(k), beta);
0292 mat.coeffRef(k,k) = beta;
0293
0294
0295 mat.bottomRightCorner(remainingRows, remainingCols)
0296 .applyHouseholderOnTheLeft(mat.col(k).tail(remainingRows-1), hCoeffs.coeffRef(k), tempData+k+1);
0297 }
0298 }
0299
0300
0301 template<typename MatrixQR, typename HCoeffs,
0302 typename MatrixQRScalar = typename MatrixQR::Scalar,
0303 bool InnerStrideIsOne = (MatrixQR::InnerStrideAtCompileTime == 1 && HCoeffs::InnerStrideAtCompileTime == 1)>
0304 struct householder_qr_inplace_blocked
0305 {
0306
0307 static void run(MatrixQR& mat, HCoeffs& hCoeffs, Index maxBlockSize=32,
0308 typename MatrixQR::Scalar* tempData = 0)
0309 {
0310 typedef typename MatrixQR::Scalar Scalar;
0311 typedef Block<MatrixQR,Dynamic,Dynamic> BlockType;
0312
0313 Index rows = mat.rows();
0314 Index cols = mat.cols();
0315 Index size = (std::min)(rows, cols);
0316
0317 typedef Matrix<Scalar,Dynamic,1,ColMajor,MatrixQR::MaxColsAtCompileTime,1> TempType;
0318 TempType tempVector;
0319 if(tempData==0)
0320 {
0321 tempVector.resize(cols);
0322 tempData = tempVector.data();
0323 }
0324
0325 Index blockSize = (std::min)(maxBlockSize,size);
0326
0327 Index k = 0;
0328 for (k = 0; k < size; k += blockSize)
0329 {
0330 Index bs = (std::min)(size-k,blockSize);
0331 Index tcols = cols - k - bs;
0332 Index brows = rows-k;
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342 BlockType A11_21 = mat.block(k,k,brows,bs);
0343 Block<HCoeffs,Dynamic,1> hCoeffsSegment = hCoeffs.segment(k,bs);
0344
0345 householder_qr_inplace_unblocked(A11_21, hCoeffsSegment, tempData);
0346
0347 if(tcols)
0348 {
0349 BlockType A21_22 = mat.block(k,k+bs,brows,tcols);
0350 apply_block_householder_on_the_left(A21_22,A11_21,hCoeffsSegment, false);
0351 }
0352 }
0353 }
0354 };
0355
0356 }
0357
0358 #ifndef EIGEN_PARSED_BY_DOXYGEN
0359 template<typename _MatrixType>
0360 template<typename RhsType, typename DstType>
0361 void HouseholderQR<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &dst) const
0362 {
0363 const Index rank = (std::min)(rows(), cols());
0364
0365 typename RhsType::PlainObject c(rhs);
0366
0367 c.applyOnTheLeft(householderQ().setLength(rank).adjoint() );
0368
0369 m_qr.topLeftCorner(rank, rank)
0370 .template triangularView<Upper>()
0371 .solveInPlace(c.topRows(rank));
0372
0373 dst.topRows(rank) = c.topRows(rank);
0374 dst.bottomRows(cols()-rank).setZero();
0375 }
0376
0377 template<typename _MatrixType>
0378 template<bool Conjugate, typename RhsType, typename DstType>
0379 void HouseholderQR<_MatrixType>::_solve_impl_transposed(const RhsType &rhs, DstType &dst) const
0380 {
0381 const Index rank = (std::min)(rows(), cols());
0382
0383 typename RhsType::PlainObject c(rhs);
0384
0385 m_qr.topLeftCorner(rank, rank)
0386 .template triangularView<Upper>()
0387 .transpose().template conjugateIf<Conjugate>()
0388 .solveInPlace(c.topRows(rank));
0389
0390 dst.topRows(rank) = c.topRows(rank);
0391 dst.bottomRows(rows()-rank).setZero();
0392
0393 dst.applyOnTheLeft(householderQ().setLength(rank).template conjugateIf<!Conjugate>() );
0394 }
0395 #endif
0396
0397
0398
0399
0400
0401
0402
0403 template<typename MatrixType>
0404 void HouseholderQR<MatrixType>::computeInPlace()
0405 {
0406 check_template_parameters();
0407
0408 Index rows = m_qr.rows();
0409 Index cols = m_qr.cols();
0410 Index size = (std::min)(rows,cols);
0411
0412 m_hCoeffs.resize(size);
0413
0414 m_temp.resize(cols);
0415
0416 internal::householder_qr_inplace_blocked<MatrixType, HCoeffsType>::run(m_qr, m_hCoeffs, 48, m_temp.data());
0417
0418 m_isInitialized = true;
0419 }
0420
0421
0422
0423
0424
0425 template<typename Derived>
0426 const HouseholderQR<typename MatrixBase<Derived>::PlainObject>
0427 MatrixBase<Derived>::householderQr() const
0428 {
0429 return HouseholderQR<PlainObject>(eval());
0430 }
0431
0432 }
0433
0434 #endif