363template<
typename MatrixType>
366 eigen_assert(m_isInitialized &&
"FullPivHouseholderQR is not initialized.");
367 eigen_assert(m_qr.rows() == m_qr.cols() &&
"You can't take the determinant of a non-square matrix!");
368 return internal::abs(m_qr.diagonal().prod());
371template<
typename MatrixType>
374 eigen_assert(m_isInitialized &&
"FullPivHouseholderQR is not initialized.");
375 eigen_assert(m_qr.rows() == m_qr.cols() &&
"You can't take the determinant of a non-square matrix!");
376 return m_qr.diagonal().cwiseAbs().array().log().sum();
379template<
typename MatrixType>
382 Index rows = matrix.rows();
383 Index cols = matrix.cols();
384 Index size = (std::min)(rows,cols);
387 m_hCoeffs.resize(size);
391 m_precision = NumTraits<Scalar>::epsilon() * size;
393 m_rows_transpositions.resize(size);
394 m_cols_transpositions.resize(size);
395 Index number_of_transpositions = 0;
397 RealScalar biggest(0);
399 m_nonzero_pivots = size;
400 m_maxpivot = RealScalar(0);
402 for (Index k = 0; k < size; ++k)
404 Index row_of_biggest_in_corner, col_of_biggest_in_corner;
405 RealScalar biggest_in_corner;
407 biggest_in_corner = m_qr.bottomRightCorner(rows-k, cols-k)
409 .maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner);
410 row_of_biggest_in_corner += k;
411 col_of_biggest_in_corner += k;
412 if(k==0) biggest = biggest_in_corner;
415 if(internal::isMuchSmallerThan(biggest_in_corner, biggest, m_precision))
417 m_nonzero_pivots = k;
418 for(Index i = k; i < size; i++)
420 m_rows_transpositions.coeffRef(i) = i;
421 m_cols_transpositions.coeffRef(i) = i;
422 m_hCoeffs.coeffRef(i) = Scalar(0);
427 m_rows_transpositions.coeffRef(k) = row_of_biggest_in_corner;
428 m_cols_transpositions.coeffRef(k) = col_of_biggest_in_corner;
429 if(k != row_of_biggest_in_corner) {
430 m_qr.row(k).tail(cols-k).swap(m_qr.row(row_of_biggest_in_corner).tail(cols-k));
431 ++number_of_transpositions;
433 if(k != col_of_biggest_in_corner) {
434 m_qr.col(k).swap(m_qr.col(col_of_biggest_in_corner));
435 ++number_of_transpositions;
439 m_qr.col(k).tail(rows-k).makeHouseholderInPlace(m_hCoeffs.coeffRef(k), beta);
440 m_qr.coeffRef(k,k) = beta;
443 if(internal::abs(beta) > m_maxpivot) m_maxpivot = internal::abs(beta);
445 m_qr.bottomRightCorner(rows-k, cols-k-1)
446 .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), m_hCoeffs.coeffRef(k), &m_temp.coeffRef(k+1));
449 m_cols_permutation.setIdentity(cols);
450 for(Index k = 0; k < size; ++k)
451 m_cols_permutation.applyTranspositionOnTheRight(k, m_cols_transpositions.coeff(k));
453 m_det_pq = (number_of_transpositions%2) ? -1 : 1;
454 m_isInitialized =
true;
461template<
typename _MatrixType,
typename Rhs>
462struct solve_retval<FullPivHouseholderQR<_MatrixType>, Rhs>
463 : solve_retval_base<FullPivHouseholderQR<_MatrixType>, Rhs>
465 EIGEN_MAKE_SOLVE_HELPERS(FullPivHouseholderQR<_MatrixType>,Rhs)
467 template<
typename Dest>
void evalTo(Dest& dst)
const
469 const Index rows = dec().rows(), cols = dec().cols();
470 eigen_assert(rhs().rows() == rows);
480 typename Rhs::PlainObject c(rhs());
482 Matrix<Scalar,1,Rhs::ColsAtCompileTime> temp(rhs().cols());
483 for (Index k = 0; k < dec().rank(); ++k)
485 Index remainingSize = rows-k;
486 c.row(k).swap(c.row(dec().rowsTranspositions().coeff(k)));
487 c.bottomRightCorner(remainingSize, rhs().cols())
488 .applyHouseholderOnTheLeft(dec().matrixQR().col(k).tail(remainingSize-1),
489 dec().hCoeffs().coeff(k), &temp.coeffRef(0));
492 if(!dec().isSurjective())
495 RealScalar biggest_in_upper_part_of_c = c.topRows( dec().rank() ).cwiseAbs().maxCoeff();
496 RealScalar biggest_in_lower_part_of_c = c.bottomRows(rows-dec().rank()).cwiseAbs().maxCoeff();
498 const RealScalar m_precision = NumTraits<Scalar>::epsilon() * (std::min)(rows,cols);
500 if(!internal::isMuchSmallerThan(biggest_in_lower_part_of_c, biggest_in_upper_part_of_c, m_precision))
504 .topLeftCorner(dec().rank(), dec().rank())
505 .template triangularView<Upper>()
506 .solveInPlace(c.topRows(dec().rank()));
508 for(Index i = 0; i < dec().rank(); ++i) dst.row(dec().colsPermutation().indices().coeff(i)) = c.row(i);
509 for(Index i = dec().rank(); i < cols; ++i) dst.row(dec().colsPermutation().indices().coeff(i)).setZero();
519template<
typename MatrixType>
struct FullPivHouseholderQRMatrixQReturnType
520 :
public ReturnByValue<FullPivHouseholderQRMatrixQReturnType<MatrixType> >
523 typedef typename MatrixType::Index Index;
524 typedef typename FullPivHouseholderQR<MatrixType>::IntDiagSizeVectorType IntDiagSizeVectorType;
525 typedef typename internal::plain_diag_type<MatrixType>::type HCoeffsType;
526 typedef Matrix<
typename MatrixType::Scalar, 1, MatrixType::RowsAtCompileTime,
RowMajor, 1,
527 MatrixType::MaxRowsAtCompileTime> WorkVectorType;
529 FullPivHouseholderQRMatrixQReturnType(
const MatrixType& qr,
530 const HCoeffsType& hCoeffs,
531 const IntDiagSizeVectorType& rowsTranspositions)
534 m_rowsTranspositions(rowsTranspositions)
537 template <
typename ResultType>
538 void evalTo(ResultType& result)
const
540 const Index rows = m_qr.rows();
541 WorkVectorType workspace(rows);
542 evalTo(result, workspace);
545 template <
typename ResultType>
546 void evalTo(ResultType& result, WorkVectorType& workspace)
const
551 const Index rows = m_qr.rows();
552 const Index cols = m_qr.cols();
553 const Index size = (std::min)(rows, cols);
554 workspace.resize(rows);
555 result.setIdentity(rows, rows);
556 for (Index k = size-1; k >= 0; k--)
558 result.block(k, k, rows-k, rows-k)
559 .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), internal::conj(m_hCoeffs.coeff(k)), &workspace.coeffRef(k));
560 result.row(k).swap(result.row(m_rowsTranspositions.coeff(k)));
564 Index rows()
const {
return m_qr.rows(); }
565 Index cols()
const {
return m_qr.rows(); }
568 typename MatrixType::Nested m_qr;
569 typename HCoeffsType::Nested m_hCoeffs;
570 typename IntDiagSizeVectorType::Nested m_rowsTranspositions;
575template<
typename MatrixType>
578 eigen_assert(m_isInitialized &&
"FullPivHouseholderQR is not initialized.");
579 return MatrixQReturnType(m_qr, m_hCoeffs, m_rows_transpositions);
586template<
typename Derived>