FullPivLU.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_LU_H
11 #define EIGEN_LU_H
12 
13 // IWYU pragma: private
14 #include "./InternalHeaderCheck.h"
15 
16 namespace Eigen {
17 
18 namespace internal {
19 template <typename MatrixType_, typename PermutationIndex_>
20 struct traits<FullPivLU<MatrixType_, PermutationIndex_> > : traits<MatrixType_> {
21  typedef MatrixXpr XprKind;
23  typedef PermutationIndex_ StorageIndex;
24  enum { Flags = 0 };
25 };
26 
27 } // end namespace internal
28 
62 template <typename MatrixType_, typename PermutationIndex_>
63 class FullPivLU : public SolverBase<FullPivLU<MatrixType_, PermutationIndex_> > {
64  public:
65  typedef MatrixType_ MatrixType;
67  friend class SolverBase<FullPivLU>;
68 
70  enum {
71  MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
72  MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
73  };
74  using PermutationIndex = PermutationIndex_;
79  typedef typename MatrixType::PlainObject PlainObject;
80 
87  FullPivLU();
88 
96 
102  template <typename InputType>
103  explicit FullPivLU(const EigenBase<InputType>& matrix);
104 
112  template <typename InputType>
114 
122  template <typename InputType>
124  m_lu = matrix.derived();
125  computeInPlace();
126  return *this;
127  }
128 
135  inline const MatrixType& matrixLU() const {
136  eigen_assert(m_isInitialized && "LU is not initialized.");
137  return m_lu;
138  }
139 
147  inline Index nonzeroPivots() const {
148  eigen_assert(m_isInitialized && "LU is not initialized.");
149  return m_nonzero_pivots;
150  }
151 
155  RealScalar maxPivot() const { return m_maxpivot; }
156 
162  eigen_assert(m_isInitialized && "LU is not initialized.");
163  return m_p;
164  }
165 
170  inline const PermutationQType& permutationQ() const {
171  eigen_assert(m_isInitialized && "LU is not initialized.");
172  return m_q;
173  }
174 
190  eigen_assert(m_isInitialized && "LU is not initialized.");
192  }
193 
213  inline const internal::image_retval<FullPivLU> image(const MatrixType& originalMatrix) const {
214  eigen_assert(m_isInitialized && "LU is not initialized.");
215  return internal::image_retval<FullPivLU>(*this, originalMatrix);
216  }
217 
218 #ifdef EIGEN_PARSED_BY_DOXYGEN
238  template <typename Rhs>
239  inline const Solve<FullPivLU, Rhs> solve(const MatrixBase<Rhs>& b) const;
240 #endif
241 
245  inline RealScalar rcond() const {
246  eigen_assert(m_isInitialized && "PartialPivLU is not initialized.");
248  }
249 
266 
287  return *this;
288  }
289 
299  m_usePrescribedThreshold = false;
300  return *this;
301  }
302 
310  // this formula comes from experimenting (see "LU precision tuning" thread on the
311  // list) and turns out to be identical to Higham's formula used already in LDLt.
312  : NumTraits<Scalar>::epsilon() * RealScalar(m_lu.diagonalSize());
313  }
314 
321  inline Index rank() const {
322  using std::abs;
323  eigen_assert(m_isInitialized && "LU is not initialized.");
324  RealScalar premultiplied_threshold = abs(m_maxpivot) * threshold();
325  Index result = 0;
326  for (Index i = 0; i < m_nonzero_pivots; ++i) result += (abs(m_lu.coeff(i, i)) > premultiplied_threshold);
327  return result;
328  }
329 
336  inline Index dimensionOfKernel() const {
337  eigen_assert(m_isInitialized && "LU is not initialized.");
338  return cols() - rank();
339  }
340 
348  inline bool isInjective() const {
349  eigen_assert(m_isInitialized && "LU is not initialized.");
350  return rank() == cols();
351  }
352 
360  inline bool isSurjective() const {
361  eigen_assert(m_isInitialized && "LU is not initialized.");
362  return rank() == rows();
363  }
364 
371  inline bool isInvertible() const {
372  eigen_assert(m_isInitialized && "LU is not initialized.");
373  return isInjective() && (m_lu.rows() == m_lu.cols());
374  }
375 
383  inline const Inverse<FullPivLU> inverse() const {
384  eigen_assert(m_isInitialized && "LU is not initialized.");
385  eigen_assert(m_lu.rows() == m_lu.cols() && "You can't take the inverse of a non-square matrix!");
386  return Inverse<FullPivLU>(*this);
387  }
388 
390 
391  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index rows() const EIGEN_NOEXCEPT { return m_lu.rows(); }
392  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index cols() const EIGEN_NOEXCEPT { return m_lu.cols(); }
393 
394 #ifndef EIGEN_PARSED_BY_DOXYGEN
395  template <typename RhsType, typename DstType>
396  void _solve_impl(const RhsType& rhs, DstType& dst) const;
397 
398  template <bool Conjugate, typename RhsType, typename DstType>
399  void _solve_impl_transposed(const RhsType& rhs, DstType& dst) const;
400 #endif
401 
402  protected:
404 
405  void computeInPlace();
406 
415  signed char m_det_pq;
417 };
418 
419 template <typename MatrixType, typename PermutationIndex>
420 FullPivLU<MatrixType, PermutationIndex>::FullPivLU() : m_isInitialized(false), m_usePrescribedThreshold(false) {}
421 
422 template <typename MatrixType, typename PermutationIndex>
424  : m_lu(rows, cols),
425  m_p(rows),
426  m_q(cols),
427  m_rowsTranspositions(rows),
428  m_colsTranspositions(cols),
429  m_isInitialized(false),
430  m_usePrescribedThreshold(false) {}
431 
432 template <typename MatrixType, typename PermutationIndex>
433 template <typename InputType>
435  : m_lu(matrix.rows(), matrix.cols()),
436  m_p(matrix.rows()),
437  m_q(matrix.cols()),
438  m_rowsTranspositions(matrix.rows()),
439  m_colsTranspositions(matrix.cols()),
440  m_isInitialized(false),
441  m_usePrescribedThreshold(false) {
442  compute(matrix.derived());
443 }
444 
445 template <typename MatrixType, typename PermutationIndex>
446 template <typename InputType>
448  : m_lu(matrix.derived()),
449  m_p(matrix.rows()),
450  m_q(matrix.cols()),
451  m_rowsTranspositions(matrix.rows()),
452  m_colsTranspositions(matrix.cols()),
453  m_isInitialized(false),
454  m_usePrescribedThreshold(false) {
455  computeInPlace();
456 }
457 
458 template <typename MatrixType, typename PermutationIndex>
461  m_lu.cols() <= NumTraits<PermutationIndex>::highest());
462 
463  m_l1_norm = m_lu.cwiseAbs().colwise().sum().maxCoeff();
464 
465  const Index size = m_lu.diagonalSize();
466  const Index rows = m_lu.rows();
467  const Index cols = m_lu.cols();
468 
469  // will store the transpositions, before we accumulate them at the end.
470  // can't accumulate on-the-fly because that will be done in reverse order for the rows.
471  m_rowsTranspositions.resize(m_lu.rows());
472  m_colsTranspositions.resize(m_lu.cols());
473  Index number_of_transpositions = 0; // number of NONTRIVIAL transpositions, i.e. m_rowsTranspositions[i]!=i
474 
475  m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
476  m_maxpivot = RealScalar(0);
477 
478  for (Index k = 0; k < size; ++k) {
479  // First, we need to find the pivot.
480 
481  // biggest coefficient in the remaining bottom-right corner (starting at row k, col k)
482  Index row_of_biggest_in_corner, col_of_biggest_in_corner;
484  typedef typename Scoring::result_type Score;
485  Score biggest_in_corner;
486  biggest_in_corner = m_lu.bottomRightCorner(rows - k, cols - k)
487  .unaryExpr(Scoring())
488  .maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner);
489  row_of_biggest_in_corner += k; // correct the values! since they were computed in the corner,
490  col_of_biggest_in_corner += k; // need to add k to them.
491 
492  if (numext::is_exactly_zero(biggest_in_corner)) {
493  // before exiting, make sure to initialize the still uninitialized transpositions
494  // in a sane state without destroying what we already have.
495  m_nonzero_pivots = k;
496  for (Index i = k; i < size; ++i) {
497  m_rowsTranspositions.coeffRef(i) = internal::convert_index<StorageIndex>(i);
498  m_colsTranspositions.coeffRef(i) = internal::convert_index<StorageIndex>(i);
499  }
500  break;
501  }
502 
504  m_lu(row_of_biggest_in_corner, col_of_biggest_in_corner), biggest_in_corner);
505  if (abs_pivot > m_maxpivot) m_maxpivot = abs_pivot;
506 
507  // Now that we've found the pivot, we need to apply the row/col swaps to
508  // bring it to the location (k,k).
509 
510  m_rowsTranspositions.coeffRef(k) = internal::convert_index<StorageIndex>(row_of_biggest_in_corner);
511  m_colsTranspositions.coeffRef(k) = internal::convert_index<StorageIndex>(col_of_biggest_in_corner);
512  if (k != row_of_biggest_in_corner) {
513  m_lu.row(k).swap(m_lu.row(row_of_biggest_in_corner));
514  ++number_of_transpositions;
515  }
516  if (k != col_of_biggest_in_corner) {
517  m_lu.col(k).swap(m_lu.col(col_of_biggest_in_corner));
518  ++number_of_transpositions;
519  }
520 
521  // Now that the pivot is at the right location, we update the remaining
522  // bottom-right corner by Gaussian elimination.
523 
524  if (k < rows - 1) m_lu.col(k).tail(rows - k - 1) /= m_lu.coeff(k, k);
525  if (k < size - 1)
526  m_lu.block(k + 1, k + 1, rows - k - 1, cols - k - 1).noalias() -=
527  m_lu.col(k).tail(rows - k - 1) * m_lu.row(k).tail(cols - k - 1);
528  }
529 
530  // the main loop is over, we still have to accumulate the transpositions to find the
531  // permutations P and Q
532 
533  m_p.setIdentity(rows);
534  for (Index k = size - 1; k >= 0; --k) m_p.applyTranspositionOnTheRight(k, m_rowsTranspositions.coeff(k));
535 
536  m_q.setIdentity(cols);
537  for (Index k = 0; k < size; ++k) m_q.applyTranspositionOnTheRight(k, m_colsTranspositions.coeff(k));
538 
539  m_det_pq = (number_of_transpositions % 2) ? -1 : 1;
540 
541  m_isInitialized = true;
542 }
543 
544 template <typename MatrixType, typename PermutationIndex>
546  eigen_assert(m_isInitialized && "LU is not initialized.");
547  eigen_assert(m_lu.rows() == m_lu.cols() && "You can't take the determinant of a non-square matrix!");
548  return Scalar(m_det_pq) * Scalar(m_lu.diagonal().prod());
549 }
550 
554 template <typename MatrixType, typename PermutationIndex>
556  eigen_assert(m_isInitialized && "LU is not initialized.");
557  const Index smalldim = (std::min)(m_lu.rows(), m_lu.cols());
558  // LU
559  MatrixType res(m_lu.rows(), m_lu.cols());
560  // FIXME the .toDenseMatrix() should not be needed...
561  res = m_lu.leftCols(smalldim).template triangularView<UnitLower>().toDenseMatrix() *
562  m_lu.topRows(smalldim).template triangularView<Upper>().toDenseMatrix();
563 
564  // P^{-1}(LU)
565  res = m_p.inverse() * res;
566 
567  // (P^{-1}LU)Q^{-1}
568  res = res * m_q.inverse();
569 
570  return res;
571 }
572 
573 /********* Implementation of kernel() **************************************************/
574 
575 namespace internal {
576 template <typename MatrixType_, typename PermutationIndex_>
577 struct kernel_retval<FullPivLU<MatrixType_, PermutationIndex_> >
578  : kernel_retval_base<FullPivLU<MatrixType_, PermutationIndex_> > {
581 
582  enum {
583  MaxSmallDimAtCompileTime = min_size_prefer_fixed(MatrixType::MaxColsAtCompileTime, MatrixType::MaxRowsAtCompileTime)
584  };
585 
586  template <typename Dest>
587  void evalTo(Dest& dst) const {
588  using std::abs;
589  const Index cols = dec().matrixLU().cols(), dimker = cols - rank();
590  if (dimker == 0) {
591  // The Kernel is just {0}, so it doesn't have a basis properly speaking, but let's
592  // avoid crashing/asserting as that depends on floating point calculations. Let's
593  // just return a single column vector filled with zeros.
594  dst.setZero();
595  return;
596  }
597 
598  /* Let us use the following lemma:
599  *
600  * Lemma: If the matrix A has the LU decomposition PAQ = LU,
601  * then Ker A = Q(Ker U).
602  *
603  * Proof: trivial: just keep in mind that P, Q, L are invertible.
604  */
605 
606  /* Thus, all we need to do is to compute Ker U, and then apply Q.
607  *
608  * U is upper triangular, with eigenvalues sorted so that any zeros appear at the end.
609  * Thus, the diagonal of U ends with exactly
610  * dimKer zero's. Let us use that to construct dimKer linearly
611  * independent vectors in Ker U.
612  */
613 
615  RealScalar premultiplied_threshold = dec().maxPivot() * dec().threshold();
616  Index p = 0;
617  for (Index i = 0; i < dec().nonzeroPivots(); ++i)
618  if (abs(dec().matrixLU().coeff(i, i)) > premultiplied_threshold) pivots.coeffRef(p++) = i;
619  eigen_internal_assert(p == rank());
620 
621  // we construct a temporaty trapezoid matrix m, by taking the U matrix and
622  // permuting the rows and cols to bring the nonnegligible pivots to the top of
623  // the main diagonal. We need that to be able to apply our triangular solvers.
624  // FIXME when we get triangularView-for-rectangular-matrices, this can be simplified
626  MatrixType::MaxColsAtCompileTime>
627  m(dec().matrixLU().block(0, 0, rank(), cols));
628  for (Index i = 0; i < rank(); ++i) {
629  if (i) m.row(i).head(i).setZero();
630  m.row(i).tail(cols - i) = dec().matrixLU().row(pivots.coeff(i)).tail(cols - i);
631  }
632  m.block(0, 0, rank(), rank());
633  m.block(0, 0, rank(), rank()).template triangularView<StrictlyLower>().setZero();
634  for (Index i = 0; i < rank(); ++i) m.col(i).swap(m.col(pivots.coeff(i)));
635 
636  // ok, we have our trapezoid matrix, we can apply the triangular solver.
637  // notice that the math behind this suggests that we should apply this to the
638  // negative of the RHS, but for performance we just put the negative sign elsewhere, see below.
639  m.topLeftCorner(rank(), rank()).template triangularView<Upper>().solveInPlace(m.topRightCorner(rank(), dimker));
640 
641  // now we must undo the column permutation that we had applied!
642  for (Index i = rank() - 1; i >= 0; --i) m.col(i).swap(m.col(pivots.coeff(i)));
643 
644  // see the negative sign in the next line, that's what we were talking about above.
645  for (Index i = 0; i < rank(); ++i) dst.row(dec().permutationQ().indices().coeff(i)) = -m.row(i).tail(dimker);
646  for (Index i = rank(); i < cols; ++i) dst.row(dec().permutationQ().indices().coeff(i)).setZero();
647  for (Index k = 0; k < dimker; ++k) dst.coeffRef(dec().permutationQ().indices().coeff(rank() + k), k) = Scalar(1);
648  }
649 };
650 
651 /***** Implementation of image() *****************************************************/
652 
653 template <typename MatrixType_, typename PermutationIndex_>
654 struct image_retval<FullPivLU<MatrixType_, PermutationIndex_> >
655  : image_retval_base<FullPivLU<MatrixType_, PermutationIndex_> > {
658 
659  enum {
660  MaxSmallDimAtCompileTime = min_size_prefer_fixed(MatrixType::MaxColsAtCompileTime, MatrixType::MaxRowsAtCompileTime)
661  };
662 
663  template <typename Dest>
664  void evalTo(Dest& dst) const {
665  using std::abs;
666  if (rank() == 0) {
667  // The Image is just {0}, so it doesn't have a basis properly speaking, but let's
668  // avoid crashing/asserting as that depends on floating point calculations. Let's
669  // just return a single column vector filled with zeros.
670  dst.setZero();
671  return;
672  }
673 
675  RealScalar premultiplied_threshold = dec().maxPivot() * dec().threshold();
676  Index p = 0;
677  for (Index i = 0; i < dec().nonzeroPivots(); ++i)
678  if (abs(dec().matrixLU().coeff(i, i)) > premultiplied_threshold) pivots.coeffRef(p++) = i;
679  eigen_internal_assert(p == rank());
680 
681  for (Index i = 0; i < rank(); ++i)
682  dst.col(i) = originalMatrix().col(dec().permutationQ().indices().coeff(pivots.coeff(i)));
683  }
684 };
685 
686 /***** Implementation of solve() *****************************************************/
687 
688 } // end namespace internal
689 
690 #ifndef EIGEN_PARSED_BY_DOXYGEN
691 template <typename MatrixType_, typename PermutationIndex_>
692 template <typename RhsType, typename DstType>
693 void FullPivLU<MatrixType_, PermutationIndex_>::_solve_impl(const RhsType& rhs, DstType& dst) const {
694  /* The decomposition PAQ = LU can be rewritten as A = P^{-1} L U Q^{-1}.
695  * So we proceed as follows:
696  * Step 1: compute c = P * rhs.
697  * Step 2: replace c by the solution x to Lx = c. Exists because L is invertible.
698  * Step 3: replace c by the solution x to Ux = c. May or may not exist.
699  * Step 4: result = Q * c;
700  */
701 
702  const Index rows = this->rows(), cols = this->cols(), nonzero_pivots = this->rank();
703  const Index smalldim = (std::min)(rows, cols);
704 
705  if (nonzero_pivots == 0) {
706  dst.setZero();
707  return;
708  }
709 
710  typename RhsType::PlainObject c(rhs.rows(), rhs.cols());
711 
712  // Step 1
713  c = permutationP() * rhs;
714 
715  // Step 2
716  m_lu.topLeftCorner(smalldim, smalldim).template triangularView<UnitLower>().solveInPlace(c.topRows(smalldim));
717  if (rows > cols) c.bottomRows(rows - cols) -= m_lu.bottomRows(rows - cols) * c.topRows(cols);
718 
719  // Step 3
720  m_lu.topLeftCorner(nonzero_pivots, nonzero_pivots)
721  .template triangularView<Upper>()
722  .solveInPlace(c.topRows(nonzero_pivots));
723 
724  // Step 4
725  for (Index i = 0; i < nonzero_pivots; ++i) dst.row(permutationQ().indices().coeff(i)) = c.row(i);
726  for (Index i = nonzero_pivots; i < m_lu.cols(); ++i) dst.row(permutationQ().indices().coeff(i)).setZero();
727 }
728 
729 template <typename MatrixType_, typename PermutationIndex_>
730 template <bool Conjugate, typename RhsType, typename DstType>
731 void FullPivLU<MatrixType_, PermutationIndex_>::_solve_impl_transposed(const RhsType& rhs, DstType& dst) const {
732  /* The decomposition PAQ = LU can be rewritten as A = P^{-1} L U Q^{-1},
733  * and since permutations are real and unitary, we can write this
734  * as A^T = Q U^T L^T P,
735  * So we proceed as follows:
736  * Step 1: compute c = Q^T rhs.
737  * Step 2: replace c by the solution x to U^T x = c. May or may not exist.
738  * Step 3: replace c by the solution x to L^T x = c.
739  * Step 4: result = P^T c.
740  * If Conjugate is true, replace "^T" by "^*" above.
741  */
742 
743  const Index rows = this->rows(), cols = this->cols(), nonzero_pivots = this->rank();
744  const Index smalldim = (std::min)(rows, cols);
745 
746  if (nonzero_pivots == 0) {
747  dst.setZero();
748  return;
749  }
750 
751  typename RhsType::PlainObject c(rhs.rows(), rhs.cols());
752 
753  // Step 1
754  c = permutationQ().inverse() * rhs;
755 
756  // Step 2
757  m_lu.topLeftCorner(nonzero_pivots, nonzero_pivots)
758  .template triangularView<Upper>()
759  .transpose()
760  .template conjugateIf<Conjugate>()
761  .solveInPlace(c.topRows(nonzero_pivots));
762 
763  // Step 3
764  m_lu.topLeftCorner(smalldim, smalldim)
765  .template triangularView<UnitLower>()
766  .transpose()
767  .template conjugateIf<Conjugate>()
768  .solveInPlace(c.topRows(smalldim));
769 
770  // Step 4
771  PermutationPType invp = permutationP().inverse().eval();
772  for (Index i = 0; i < smalldim; ++i) dst.row(invp.indices().coeff(i)) = c.row(i);
773  for (Index i = smalldim; i < rows; ++i) dst.row(invp.indices().coeff(i)).setZero();
774 }
775 
776 #endif
777 
778 namespace internal {
779 
780 /***** Implementation of inverse() *****************************************************/
781 template <typename DstXprType, typename MatrixType, typename PermutationIndex>
782 struct Assignment<
783  DstXprType, Inverse<FullPivLU<MatrixType, PermutationIndex> >,
784  internal::assign_op<typename DstXprType::Scalar, typename FullPivLU<MatrixType, PermutationIndex>::Scalar>,
785  Dense2Dense> {
788  static void run(DstXprType& dst, const SrcXprType& src,
790  dst = src.nestedExpression().solve(MatrixType::Identity(src.rows(), src.cols()));
791  }
792 };
793 } // end namespace internal
794 
795 /******* MatrixBase methods *****************************************************************/
796 
803 template <typename Derived>
804 template <typename PermutationIndex>
806  const {
808 }
809 
810 } // end namespace Eigen
811 
812 #endif // EIGEN_LU_H
AnnoyingScalar abs(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:135
int i
Definition: BiCGSTAB_step_by_step.cpp:9
#define EIGEN_MAKE_IMAGE_HELPERS(DecompositionType)
Definition: Image.h:66
#define EIGEN_MAKE_KERNEL_HELPERS(DecompositionType)
Definition: Kernel.h:64
#define EIGEN_GENERIC_PUBLIC_INTERFACE(Derived)
Definition: Macros.h:1149
#define eigen_internal_assert(x)
Definition: Macros.h:916
#define EIGEN_NOEXCEPT
Definition: Macros.h:1267
#define EIGEN_CONSTEXPR
Definition: Macros.h:758
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:892
#define eigen_assert(x)
Definition: Macros.h:910
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
Definition: PartialRedux_count.cpp:3
#define EIGEN_STATIC_ASSERT_NON_INTEGER(TYPE)
Definition: StaticAssert.h:74
float * p
Definition: Tutorial_Map_using.cpp:9
m m block(1, 0, 2, 2)<< 4
int rows
Definition: Tutorial_commainit_02.cpp:1
int cols
Definition: Tutorial_commainit_02.cpp:1
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
Scalar * b
Definition: benchVecAdd.cpp:17
SCALAR Scalar
Definition: bench_gemm.cpp:45
NumTraits< Scalar >::Real RealScalar
Definition: bench_gemm.cpp:46
MatrixXf MatrixType
Definition: benchmark-blocking-sizes.cpp:52
LU decomposition of a matrix with complete pivoting, and related features.
Definition: FullPivLU.h:63
IntColVectorType m_rowsTranspositions
Definition: FullPivLU.h:410
internal::plain_row_type< MatrixType, PermutationIndex >::type IntRowVectorType
Definition: FullPivLU.h:75
FullPivLU & setThreshold(const RealScalar &threshold)
Definition: FullPivLU.h:284
bool isInjective() const
Definition: FullPivLU.h:348
bool isInvertible() const
Definition: FullPivLU.h:371
internal::traits< MatrixType >::Scalar determinant() const
Definition: FullPivLU.h:545
internal::plain_col_type< MatrixType, PermutationIndex >::type IntColVectorType
Definition: FullPivLU.h:76
MatrixType m_lu
Definition: FullPivLU.h:407
RealScalar rcond() const
Definition: FullPivLU.h:245
IntRowVectorType m_colsTranspositions
Definition: FullPivLU.h:411
void computeInPlace()
Definition: FullPivLU.h:459
MatrixType_ MatrixType
Definition: FullPivLU.h:65
Index nonzeroPivots() const
Definition: FullPivLU.h:147
RealScalar m_l1_norm
Definition: FullPivLU.h:413
bool m_usePrescribedThreshold
Definition: FullPivLU.h:416
MatrixType::PlainObject PlainObject
Definition: FullPivLU.h:79
signed char m_det_pq
Definition: FullPivLU.h:415
MatrixType reconstructedMatrix() const
Definition: FullPivLU.h:555
const MatrixType & matrixLU() const
Definition: FullPivLU.h:135
const Inverse< FullPivLU > inverse() const
Definition: FullPivLU.h:383
bool m_isInitialized
Definition: FullPivLU.h:416
Index m_nonzero_pivots
Definition: FullPivLU.h:412
FullPivLU & compute(const EigenBase< InputType > &matrix)
Definition: FullPivLU.h:123
RealScalar maxPivot() const
Definition: FullPivLU.h:155
Index rank() const
Definition: FullPivLU.h:321
PermutationIndex_ PermutationIndex
Definition: FullPivLU.h:74
FullPivLU & setThreshold(Default_t)
Definition: FullPivLU.h:298
RealScalar m_prescribedThreshold
Definition: FullPivLU.h:414
EIGEN_DEVICE_FUNC const PermutationPType & permutationP() const
Definition: FullPivLU.h:161
@ MaxRowsAtCompileTime
Definition: FullPivLU.h:71
@ MaxColsAtCompileTime
Definition: FullPivLU.h:72
SolverBase< FullPivLU > Base
Definition: FullPivLU.h:66
RealScalar m_maxpivot
Definition: FullPivLU.h:414
PermutationMatrix< ColsAtCompileTime, MaxColsAtCompileTime, PermutationIndex > PermutationQType
Definition: FullPivLU.h:77
void _solve_impl_transposed(const RhsType &rhs, DstType &dst) const
Definition: FullPivLU.h:731
bool isSurjective() const
Definition: FullPivLU.h:360
const internal::image_retval< FullPivLU > image(const MatrixType &originalMatrix) const
Definition: FullPivLU.h:213
RealScalar threshold() const
Definition: FullPivLU.h:307
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Definition: FullPivLU.h:391
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
Definition: FullPivLU.h:392
const internal::kernel_retval< FullPivLU > kernel() const
Definition: FullPivLU.h:189
PermutationMatrix< RowsAtCompileTime, MaxRowsAtCompileTime, PermutationIndex > PermutationPType
Definition: FullPivLU.h:78
PermutationPType m_p
Definition: FullPivLU.h:408
void _solve_impl(const RhsType &rhs, DstType &dst) const
Definition: FullPivLU.h:693
const PermutationQType & permutationQ() const
Definition: FullPivLU.h:170
PermutationQType m_q
Definition: FullPivLU.h:409
Index dimensionOfKernel() const
Definition: FullPivLU.h:336
FullPivLU()
Default Constructor.
Definition: FullPivLU.h:420
Expression of the inverse of another expression.
Definition: Inverse.h:43
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
Definition: Inverse.h:55
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Definition: Inverse.h:54
EIGEN_DEVICE_FUNC const XprTypeNestedCleaned & nestedExpression() const
Definition: Inverse.h:57
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:52
const FullPivLU< PlainObject, PermutationIndex > fullPivLu() const
The matrix class, also used for vectors and row-vectors.
Definition: Eigen/Eigen/src/Core/Matrix.h:186
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE Scalar & coeffRef(Index rowId, Index colId)
Definition: PlainObjectBase.h:217
InverseReturnType inverse() const
Definition: PermutationMatrix.h:172
const IndicesType & indices() const
Definition: PermutationMatrix.h:334
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE const Scalar & coeff(Index rowId, Index colId) const
Definition: PlainObjectBase.h:198
Pseudo expression representing a solving operation.
Definition: Solve.h:62
A base class for matrix decomposition and solvers.
Definition: SolverBase.h:72
const Solve< FullPivLU< MatrixType_, PermutationIndex_ >, Rhs > solve(const MatrixBase< Rhs > &b) const
Definition: SolverBase.h:106
Eigen::Map< Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor >, 0, Eigen::OuterStride<> > matrix(T *data, int rows, int cols, int stride)
Definition: common.h:85
#define min(a, b)
Definition: datatypes.h:22
int * m
Definition: level2_cplx_impl.h:294
res setZero()
char char char int int * k
Definition: level2_impl.h:374
constexpr int min_size_prefer_fixed(A a, B b)
Definition: Meta.h:683
Decomposition::RealScalar rcond_estimate_helper(typename Decomposition::RealScalar matrix_norm, const Decomposition &dec)
Reciprocal condition number estimator.
Definition: ConditionEstimator.h:157
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool is_exactly_zero(const X &x)
Definition: Meta.h:592
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
Default_t
Definition: Constants.h:361
Extend namespace for flags.
Definition: fsi_chan_precond_driver.cc:56
int c
Definition: calibrate.py:100
Definition: Eigen_Colamd.h:49
double epsilon
Definition: osc_ring_sarah_asymptotics.h:43
internal::nested_eval< T, 1 >::type eval(const T &xpr)
Definition: sparse_permutations.cpp:47
Definition: EigenBase.h:33
Eigen::Index Index
The interface type of indices.
Definition: EigenBase.h:43
Definition: Constants.h:534
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:217
Definition: Constants.h:525
static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op< typename DstXprType::Scalar, typename MatrixType::Scalar > &)
Definition: FullPivLU.h:788
Definition: AssignEvaluator.h:773
Definition: AssignEvaluator.h:756
Definition: functors/UnaryFunctors.h:71
Template functor for scalar/packet assignment.
Definition: AssignmentFunctors.h:25
Definition: ForwardDeclarations.h:207
Definition: ForwardDeclarations.h:203
std::conditional_t< is_same< typename traits< ExpressionType >::XprKind, MatrixXpr >::value, MatrixColType, ArrayColType > type
Definition: XprHelper.h:782
std::conditional_t< is_same< typename traits< ExpressionType >::XprKind, MatrixXpr >::value, MatrixRowType, ArrayRowType > type
Definition: XprHelper.h:768
Template functor to compute the score of a scalar, to chose a pivot.
Definition: functors/UnaryFunctors.h:63
PermutationIndex_ StorageIndex
Definition: FullPivLU.h:23
Definition: ForwardDeclarations.h:21