11 #ifndef EIGEN_COLPIVOTINGHOUSEHOLDERQR_H
12 #define EIGEN_COLPIVOTINGHOUSEHOLDERQR_H
41 typedef _MatrixType MatrixType;
43 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
44 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
45 Options = MatrixType::Options,
46 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
47 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
49 typedef typename MatrixType::Scalar Scalar;
50 typedef typename MatrixType::RealScalar RealScalar;
51 typedef typename MatrixType::Index Index;
53 typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType;
55 typedef typename internal::plain_row_type<MatrixType, Index>::type IntRowVectorType;
56 typedef typename internal::plain_row_type<MatrixType>::type RowVectorType;
57 typedef typename internal::plain_row_type<MatrixType, RealScalar>::type RealRowVectorType;
70 m_colsTranspositions(),
73 m_isInitialized(false) {}
83 m_hCoeffs((std::min)(rows,cols)),
84 m_colsPermutation(cols),
85 m_colsTranspositions(cols),
88 m_isInitialized(false),
89 m_usePrescribedThreshold(false) {}
92 : m_qr(matrix.rows(), matrix.cols()),
93 m_hCoeffs((std::min)(matrix.rows(),matrix.cols())),
94 m_colsPermutation(matrix.cols()),
95 m_colsTranspositions(matrix.cols()),
96 m_temp(matrix.cols()),
97 m_colSqNorms(matrix.cols()),
98 m_isInitialized(false),
99 m_usePrescribedThreshold(false)
121 template<
typename Rhs>
122 inline const internal::solve_retval<ColPivHouseholderQR, Rhs>
125 eigen_assert(m_isInitialized &&
"ColPivHouseholderQR is not initialized.");
126 return internal::solve_retval<ColPivHouseholderQR, Rhs>(*
this, b.derived());
135 eigen_assert(m_isInitialized &&
"ColPivHouseholderQR is not initialized.");
141 const PermutationType& colsPermutation()
const
143 eigen_assert(m_isInitialized &&
"ColPivHouseholderQR is not initialized.");
144 return m_colsPermutation;
184 eigen_assert(m_isInitialized &&
"ColPivHouseholderQR is not initialized.");
187 for(Index i = 0; i < m_nonzero_pivots; ++i)
188 result += (
internal::abs(m_qr.coeff(i,i)) > premultiplied_threshold);
200 eigen_assert(m_isInitialized &&
"ColPivHouseholderQR is not initialized.");
201 return cols() -
rank();
213 eigen_assert(m_isInitialized &&
"ColPivHouseholderQR is not initialized.");
214 return rank() == cols();
226 eigen_assert(m_isInitialized &&
"ColPivHouseholderQR is not initialized.");
227 return rank() == rows();
238 eigen_assert(m_isInitialized &&
"ColPivHouseholderQR is not initialized.");
248 internal::solve_retval<ColPivHouseholderQR, typename MatrixType::IdentityReturnType>
251 eigen_assert(m_isInitialized &&
"ColPivHouseholderQR is not initialized.");
252 return internal::solve_retval<ColPivHouseholderQR,typename MatrixType::IdentityReturnType>
253 (*
this, MatrixType::Identity(m_qr.rows(), m_qr.cols()));
256 inline Index rows()
const {
return m_qr.rows(); }
257 inline Index cols()
const {
return m_qr.cols(); }
258 const HCoeffsType& hCoeffs()
const {
return m_hCoeffs; }
279 m_usePrescribedThreshold =
true;
294 m_usePrescribedThreshold =
false;
304 eigen_assert(m_isInitialized || m_usePrescribedThreshold);
305 return m_usePrescribedThreshold ? m_prescribedThreshold
320 eigen_assert(m_isInitialized &&
"ColPivHouseholderQR is not initialized.");
321 return m_nonzero_pivots;
331 HCoeffsType m_hCoeffs;
332 PermutationType m_colsPermutation;
333 IntRowVectorType m_colsTranspositions;
334 RowVectorType m_temp;
335 RealRowVectorType m_colSqNorms;
336 bool m_isInitialized, m_usePrescribedThreshold;
337 RealScalar m_prescribedThreshold, m_maxpivot;
338 Index m_nonzero_pivots;
342 template<
typename MatrixType>
345 eigen_assert(m_isInitialized &&
"ColPivHouseholderQR is not initialized.");
346 eigen_assert(m_qr.rows() == m_qr.cols() &&
"You can't take the determinant of a non-square matrix!");
350 template<
typename MatrixType>
353 eigen_assert(m_isInitialized &&
"ColPivHouseholderQR is not initialized.");
354 eigen_assert(m_qr.rows() == m_qr.cols() &&
"You can't take the determinant of a non-square matrix!");
355 return m_qr.diagonal().cwiseAbs().array().log().sum();
358 template<
typename MatrixType>
361 Index rows = matrix.rows();
362 Index cols = matrix.cols();
363 Index size = matrix.diagonalSize();
366 m_hCoeffs.resize(size);
370 m_colsTranspositions.resize(matrix.cols());
371 Index number_of_transpositions = 0;
373 m_colSqNorms.resize(cols);
374 for(Index k = 0; k < cols; ++k)
375 m_colSqNorms.coeffRef(k) = m_qr.col(k).squaredNorm();
379 m_nonzero_pivots = size;
380 m_maxpivot = RealScalar(0);
382 for(Index k = 0; k < size; ++k)
385 Index biggest_col_index;
386 RealScalar biggest_col_sq_norm = m_colSqNorms.tail(cols-k).maxCoeff(&biggest_col_index);
387 biggest_col_index += k;
393 biggest_col_sq_norm = m_qr.col(biggest_col_index).tail(rows-k).squaredNorm();
396 m_colSqNorms.coeffRef(biggest_col_index) = biggest_col_sq_norm;
403 if(biggest_col_sq_norm < threshold_helper * RealScalar(rows-k))
405 m_nonzero_pivots = k;
406 m_hCoeffs.tail(size-k).setZero();
407 m_qr.bottomRightCorner(rows-k,cols-k)
408 .template triangularView<StrictlyLower>()
414 m_colsTranspositions.coeffRef(k) = biggest_col_index;
415 if(k != biggest_col_index) {
416 m_qr.col(k).swap(m_qr.col(biggest_col_index));
417 std::swap(m_colSqNorms.coeffRef(k), m_colSqNorms.coeffRef(biggest_col_index));
418 ++number_of_transpositions;
423 m_qr.col(k).tail(rows-k).makeHouseholderInPlace(m_hCoeffs.coeffRef(k), beta);
426 m_qr.coeffRef(k,k) = beta;
432 m_qr.bottomRightCorner(rows-k, cols-k-1)
433 .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), m_hCoeffs.coeffRef(k), &m_temp.coeffRef(k+1));
436 m_colSqNorms.tail(cols-k-1) -= m_qr.row(k).tail(cols-k-1).cwiseAbs2();
439 m_colsPermutation.setIdentity(cols);
440 for(Index k = 0; k < m_nonzero_pivots; ++k)
441 m_colsPermutation.applyTranspositionOnTheRight(k, m_colsTranspositions.coeff(k));
443 m_det_pq = (number_of_transpositions%2) ? -1 : 1;
444 m_isInitialized =
true;
451 template<
typename _MatrixType,
typename Rhs>
452 struct solve_retval<ColPivHouseholderQR<_MatrixType>, Rhs>
453 : solve_retval_base<ColPivHouseholderQR<_MatrixType>, Rhs>
455 EIGEN_MAKE_SOLVE_HELPERS(ColPivHouseholderQR<_MatrixType>,Rhs)
457 template<typename Dest>
void evalTo(Dest& dst)
const
459 eigen_assert(rhs().rows() == dec().rows());
461 const int cols = dec().cols(),
462 nonzero_pivots = dec().nonzeroPivots();
464 if(nonzero_pivots == 0)
470 typename Rhs::PlainObject c(rhs());
474 .setLength(dec().nonzeroPivots())
479 .topLeftCorner(nonzero_pivots, nonzero_pivots)
480 .template triangularView<Upper>()
481 .solveInPlace(c.topRows(nonzero_pivots));
484 typename Rhs::PlainObject d(c);
485 d.topRows(nonzero_pivots)
487 .topLeftCorner(nonzero_pivots, nonzero_pivots)
488 .template triangularView<Upper>()
489 * c.topRows(nonzero_pivots);
491 for(Index i = 0; i < nonzero_pivots; ++i) dst.row(dec().colsPermutation().indices().coeff(i)) = c.row(i);
492 for(Index i = nonzero_pivots; i < cols; ++i) dst.row(dec().colsPermutation().indices().coeff(i)).setZero();
499 template<
typename MatrixType>
503 eigen_assert(m_isInitialized &&
"ColPivHouseholderQR is not initialized.");
511 template<
typename Derived>
520 #endif // EIGEN_COLPIVOTINGHOUSEHOLDERQR_H