Path Tracer
FullPivLU.h
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 namespace Eigen {
14 
15 namespace internal {
16 template<typename _MatrixType> struct traits<FullPivLU<_MatrixType> >
17  : traits<_MatrixType>
18 {
19  typedef MatrixXpr XprKind;
20  typedef SolverStorage StorageKind;
21  typedef int StorageIndex;
22  enum { Flags = 0 };
23 };
24 
25 } // end namespace internal
26 
60 template<typename _MatrixType> class FullPivLU
61  : public SolverBase<FullPivLU<_MatrixType> >
62 {
63  public:
64  typedef _MatrixType MatrixType;
66  friend class SolverBase<FullPivLU>;
67 
68  EIGEN_GENERIC_PUBLIC_INTERFACE(FullPivLU)
69  enum {
70  MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
71  MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
72  };
77  typedef typename MatrixType::PlainObject PlainObject;
78 
85  FullPivLU();
86 
93  FullPivLU(Index rows, Index cols);
94 
100  template<typename InputType>
101  explicit FullPivLU(const EigenBase<InputType>& matrix);
102 
109  template<typename InputType>
110  explicit FullPivLU(EigenBase<InputType>& matrix);
111 
119  template<typename InputType>
121  m_lu = matrix.derived();
122  computeInPlace();
123  return *this;
124  }
125 
132  inline const MatrixType& matrixLU() const
133  {
134  eigen_assert(m_isInitialized && "LU is not initialized.");
135  return m_lu;
136  }
137 
145  inline Index nonzeroPivots() const
146  {
147  eigen_assert(m_isInitialized && "LU is not initialized.");
148  return m_nonzero_pivots;
149  }
150 
154  RealScalar maxPivot() const { return m_maxpivot; }
155 
160  EIGEN_DEVICE_FUNC inline const PermutationPType& permutationP() const
161  {
162  eigen_assert(m_isInitialized && "LU is not initialized.");
163  return m_p;
164  }
165 
170  inline const PermutationQType& permutationQ() const
171  {
172  eigen_assert(m_isInitialized && "LU is not initialized.");
173  return m_q;
174  }
175 
191  {
192  eigen_assert(m_isInitialized && "LU is not initialized.");
194  }
195 
216  image(const MatrixType& originalMatrix) const
217  {
218  eigen_assert(m_isInitialized && "LU is not initialized.");
219  return internal::image_retval<FullPivLU>(*this, originalMatrix);
220  }
221 
222  #ifdef EIGEN_PARSED_BY_DOXYGEN
223 
242  template<typename Rhs>
243  inline const Solve<FullPivLU, Rhs>
244  solve(const MatrixBase<Rhs>& b) const;
245  #endif
246 
250  inline RealScalar rcond() const
251  {
252  eigen_assert(m_isInitialized && "PartialPivLU is not initialized.");
253  return internal::rcond_estimate_helper(m_l1_norm, *this);
254  }
255 
272 
290  FullPivLU& setThreshold(const RealScalar& threshold)
291  {
292  m_usePrescribedThreshold = true;
293  m_prescribedThreshold = threshold;
294  return *this;
295  }
296 
306  {
307  m_usePrescribedThreshold = false;
308  return *this;
309  }
310 
315  RealScalar threshold() const
316  {
317  eigen_assert(m_isInitialized || m_usePrescribedThreshold);
318  return m_usePrescribedThreshold ? m_prescribedThreshold
319  // this formula comes from experimenting (see "LU precision tuning" thread on the list)
320  // and turns out to be identical to Higham's formula used already in LDLt.
321  : NumTraits<Scalar>::epsilon() * RealScalar(m_lu.diagonalSize());
322  }
323 
330  inline Index rank() const
331  {
332  using std::abs;
333  eigen_assert(m_isInitialized && "LU is not initialized.");
334  RealScalar premultiplied_threshold = abs(m_maxpivot) * threshold();
335  Index result = 0;
336  for(Index i = 0; i < m_nonzero_pivots; ++i)
337  result += (abs(m_lu.coeff(i,i)) > premultiplied_threshold);
338  return result;
339  }
340 
347  inline Index dimensionOfKernel() const
348  {
349  eigen_assert(m_isInitialized && "LU is not initialized.");
350  return cols() - rank();
351  }
352 
360  inline bool isInjective() const
361  {
362  eigen_assert(m_isInitialized && "LU is not initialized.");
363  return rank() == cols();
364  }
365 
373  inline bool isSurjective() const
374  {
375  eigen_assert(m_isInitialized && "LU is not initialized.");
376  return rank() == rows();
377  }
378 
385  inline bool isInvertible() const
386  {
387  eigen_assert(m_isInitialized && "LU is not initialized.");
388  return isInjective() && (m_lu.rows() == m_lu.cols());
389  }
390 
398  inline const Inverse<FullPivLU> inverse() const
399  {
400  eigen_assert(m_isInitialized && "LU is not initialized.");
401  eigen_assert(m_lu.rows() == m_lu.cols() && "You can't take the inverse of a non-square matrix!");
402  return Inverse<FullPivLU>(*this);
403  }
404 
405  MatrixType reconstructedMatrix() const;
406 
407  EIGEN_DEVICE_FUNC inline Index rows() const { return m_lu.rows(); }
408  EIGEN_DEVICE_FUNC inline Index cols() const { return m_lu.cols(); }
409 
410  #ifndef EIGEN_PARSED_BY_DOXYGEN
411  template<typename RhsType, typename DstType>
412  void _solve_impl(const RhsType &rhs, DstType &dst) const;
413 
414  template<bool Conjugate, typename RhsType, typename DstType>
415  void _solve_impl_transposed(const RhsType &rhs, DstType &dst) const;
416  #endif
417 
418  protected:
419 
420  static void check_template_parameters()
421  {
422  EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);
423  }
424 
425  void computeInPlace();
426 
427  MatrixType m_lu;
428  PermutationPType m_p;
429  PermutationQType m_q;
430  IntColVectorType m_rowsTranspositions;
431  IntRowVectorType m_colsTranspositions;
432  Index m_nonzero_pivots;
433  RealScalar m_l1_norm;
434  RealScalar m_maxpivot, m_prescribedThreshold;
435  signed char m_det_pq;
436  bool m_isInitialized, m_usePrescribedThreshold;
437 };
438 
439 template<typename MatrixType>
441  : m_isInitialized(false), m_usePrescribedThreshold(false)
442 {
443 }
444 
445 template<typename MatrixType>
447  : m_lu(rows, cols),
448  m_p(rows),
449  m_q(cols),
450  m_rowsTranspositions(rows),
451  m_colsTranspositions(cols),
452  m_isInitialized(false),
453  m_usePrescribedThreshold(false)
454 {
455 }
456 
457 template<typename MatrixType>
458 template<typename InputType>
460  : m_lu(matrix.rows(), matrix.cols()),
461  m_p(matrix.rows()),
462  m_q(matrix.cols()),
463  m_rowsTranspositions(matrix.rows()),
464  m_colsTranspositions(matrix.cols()),
465  m_isInitialized(false),
466  m_usePrescribedThreshold(false)
467 {
468  compute(matrix.derived());
469 }
470 
471 template<typename MatrixType>
472 template<typename InputType>
474  : m_lu(matrix.derived()),
475  m_p(matrix.rows()),
476  m_q(matrix.cols()),
477  m_rowsTranspositions(matrix.rows()),
478  m_colsTranspositions(matrix.cols()),
479  m_isInitialized(false),
480  m_usePrescribedThreshold(false)
481 {
482  computeInPlace();
483 }
484 
485 template<typename MatrixType>
487 {
488  check_template_parameters();
489 
490  // the permutations are stored as int indices, so just to be sure:
491  eigen_assert(m_lu.rows()<=NumTraits<int>::highest() && m_lu.cols()<=NumTraits<int>::highest());
492 
493  m_l1_norm = m_lu.cwiseAbs().colwise().sum().maxCoeff();
494 
495  const Index size = m_lu.diagonalSize();
496  const Index rows = m_lu.rows();
497  const Index cols = m_lu.cols();
498 
499  // will store the transpositions, before we accumulate them at the end.
500  // can't accumulate on-the-fly because that will be done in reverse order for the rows.
501  m_rowsTranspositions.resize(m_lu.rows());
502  m_colsTranspositions.resize(m_lu.cols());
503  Index number_of_transpositions = 0; // number of NONTRIVIAL transpositions, i.e. m_rowsTranspositions[i]!=i
504 
505  m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
506  m_maxpivot = RealScalar(0);
507 
508  for(Index k = 0; k < size; ++k)
509  {
510  // First, we need to find the pivot.
511 
512  // biggest coefficient in the remaining bottom-right corner (starting at row k, col k)
513  Index row_of_biggest_in_corner, col_of_biggest_in_corner;
515  typedef typename Scoring::result_type Score;
516  Score biggest_in_corner;
517  biggest_in_corner = m_lu.bottomRightCorner(rows-k, cols-k)
518  .unaryExpr(Scoring())
519  .maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner);
520  row_of_biggest_in_corner += k; // correct the values! since they were computed in the corner,
521  col_of_biggest_in_corner += k; // need to add k to them.
522 
523  if(biggest_in_corner==Score(0))
524  {
525  // before exiting, make sure to initialize the still uninitialized transpositions
526  // in a sane state without destroying what we already have.
527  m_nonzero_pivots = k;
528  for(Index i = k; i < size; ++i)
529  {
530  m_rowsTranspositions.coeffRef(i) = internal::convert_index<StorageIndex>(i);
531  m_colsTranspositions.coeffRef(i) = internal::convert_index<StorageIndex>(i);
532  }
533  break;
534  }
535 
536  RealScalar abs_pivot = internal::abs_knowing_score<Scalar>()(m_lu(row_of_biggest_in_corner, col_of_biggest_in_corner), biggest_in_corner);
537  if(abs_pivot > m_maxpivot) m_maxpivot = abs_pivot;
538 
539  // Now that we've found the pivot, we need to apply the row/col swaps to
540  // bring it to the location (k,k).
541 
542  m_rowsTranspositions.coeffRef(k) = internal::convert_index<StorageIndex>(row_of_biggest_in_corner);
543  m_colsTranspositions.coeffRef(k) = internal::convert_index<StorageIndex>(col_of_biggest_in_corner);
544  if(k != row_of_biggest_in_corner) {
545  m_lu.row(k).swap(m_lu.row(row_of_biggest_in_corner));
546  ++number_of_transpositions;
547  }
548  if(k != col_of_biggest_in_corner) {
549  m_lu.col(k).swap(m_lu.col(col_of_biggest_in_corner));
550  ++number_of_transpositions;
551  }
552 
553  // Now that the pivot is at the right location, we update the remaining
554  // bottom-right corner by Gaussian elimination.
555 
556  if(k<rows-1)
557  m_lu.col(k).tail(rows-k-1) /= m_lu.coeff(k,k);
558  if(k<size-1)
559  m_lu.block(k+1,k+1,rows-k-1,cols-k-1).noalias() -= m_lu.col(k).tail(rows-k-1) * m_lu.row(k).tail(cols-k-1);
560  }
561 
562  // the main loop is over, we still have to accumulate the transpositions to find the
563  // permutations P and Q
564 
565  m_p.setIdentity(rows);
566  for(Index k = size-1; k >= 0; --k)
567  m_p.applyTranspositionOnTheRight(k, m_rowsTranspositions.coeff(k));
568 
569  m_q.setIdentity(cols);
570  for(Index k = 0; k < size; ++k)
571  m_q.applyTranspositionOnTheRight(k, m_colsTranspositions.coeff(k));
572 
573  m_det_pq = (number_of_transpositions%2) ? -1 : 1;
574 
575  m_isInitialized = true;
576 }
577 
578 template<typename MatrixType>
580 {
581  eigen_assert(m_isInitialized && "LU is not initialized.");
582  eigen_assert(m_lu.rows() == m_lu.cols() && "You can't take the determinant of a non-square matrix!");
583  return Scalar(m_det_pq) * Scalar(m_lu.diagonal().prod());
584 }
585 
589 template<typename MatrixType>
591 {
592  eigen_assert(m_isInitialized && "LU is not initialized.");
593  const Index smalldim = (std::min)(m_lu.rows(), m_lu.cols());
594  // LU
595  MatrixType res(m_lu.rows(),m_lu.cols());
596  // FIXME the .toDenseMatrix() should not be needed...
597  res = m_lu.leftCols(smalldim)
598  .template triangularView<UnitLower>().toDenseMatrix()
599  * m_lu.topRows(smalldim)
600  .template triangularView<Upper>().toDenseMatrix();
601 
602  // P^{-1}(LU)
603  res = m_p.inverse() * res;
604 
605  // (P^{-1}LU)Q^{-1}
606  res = res * m_q.inverse();
607 
608  return res;
609 }
610 
611 /********* Implementation of kernel() **************************************************/
612 
613 namespace internal {
614 template<typename _MatrixType>
615 struct kernel_retval<FullPivLU<_MatrixType> >
616  : kernel_retval_base<FullPivLU<_MatrixType> >
617 {
618  EIGEN_MAKE_KERNEL_HELPERS(FullPivLU<_MatrixType>)
619 
620  enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(
621  MatrixType::MaxColsAtCompileTime,
622  MatrixType::MaxRowsAtCompileTime)
623  };
624 
625  template<typename Dest> void evalTo(Dest& dst) const
626  {
627  using std::abs;
628  const Index cols = dec().matrixLU().cols(), dimker = cols - rank();
629  if(dimker == 0)
630  {
631  // The Kernel is just {0}, so it doesn't have a basis properly speaking, but let's
632  // avoid crashing/asserting as that depends on floating point calculations. Let's
633  // just return a single column vector filled with zeros.
634  dst.setZero();
635  return;
636  }
637 
638  /* Let us use the following lemma:
639  *
640  * Lemma: If the matrix A has the LU decomposition PAQ = LU,
641  * then Ker A = Q(Ker U).
642  *
643  * Proof: trivial: just keep in mind that P, Q, L are invertible.
644  */
645 
646  /* Thus, all we need to do is to compute Ker U, and then apply Q.
647  *
648  * U is upper triangular, with eigenvalues sorted so that any zeros appear at the end.
649  * Thus, the diagonal of U ends with exactly
650  * dimKer zero's. Let us use that to construct dimKer linearly
651  * independent vectors in Ker U.
652  */
653 
655  RealScalar premultiplied_threshold = dec().maxPivot() * dec().threshold();
656  Index p = 0;
657  for(Index i = 0; i < dec().nonzeroPivots(); ++i)
658  if(abs(dec().matrixLU().coeff(i,i)) > premultiplied_threshold)
659  pivots.coeffRef(p++) = i;
660  eigen_internal_assert(p == rank());
661 
662  // we construct a temporaty trapezoid matrix m, by taking the U matrix and
663  // permuting the rows and cols to bring the nonnegligible pivots to the top of
664  // the main diagonal. We need that to be able to apply our triangular solvers.
665  // FIXME when we get triangularView-for-rectangular-matrices, this can be simplified
666  Matrix<typename MatrixType::Scalar, Dynamic, Dynamic, MatrixType::Options,
667  MaxSmallDimAtCompileTime, MatrixType::MaxColsAtCompileTime>
668  m(dec().matrixLU().block(0, 0, rank(), cols));
669  for(Index i = 0; i < rank(); ++i)
670  {
671  if(i) m.row(i).head(i).setZero();
672  m.row(i).tail(cols-i) = dec().matrixLU().row(pivots.coeff(i)).tail(cols-i);
673  }
674  m.block(0, 0, rank(), rank());
675  m.block(0, 0, rank(), rank()).template triangularView<StrictlyLower>().setZero();
676  for(Index i = 0; i < rank(); ++i)
677  m.col(i).swap(m.col(pivots.coeff(i)));
678 
679  // ok, we have our trapezoid matrix, we can apply the triangular solver.
680  // notice that the math behind this suggests that we should apply this to the
681  // negative of the RHS, but for performance we just put the negative sign elsewhere, see below.
682  m.topLeftCorner(rank(), rank())
683  .template triangularView<Upper>().solveInPlace(
684  m.topRightCorner(rank(), dimker)
685  );
686 
687  // now we must undo the column permutation that we had applied!
688  for(Index i = rank()-1; i >= 0; --i)
689  m.col(i).swap(m.col(pivots.coeff(i)));
690 
691  // see the negative sign in the next line, that's what we were talking about above.
692  for(Index i = 0; i < rank(); ++i) dst.row(dec().permutationQ().indices().coeff(i)) = -m.row(i).tail(dimker);
693  for(Index i = rank(); i < cols; ++i) dst.row(dec().permutationQ().indices().coeff(i)).setZero();
694  for(Index k = 0; k < dimker; ++k) dst.coeffRef(dec().permutationQ().indices().coeff(rank()+k), k) = Scalar(1);
695  }
696 };
697 
698 /***** Implementation of image() *****************************************************/
699 
700 template<typename _MatrixType>
701 struct image_retval<FullPivLU<_MatrixType> >
702  : image_retval_base<FullPivLU<_MatrixType> >
703 {
704  EIGEN_MAKE_IMAGE_HELPERS(FullPivLU<_MatrixType>)
705 
706  enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(
707  MatrixType::MaxColsAtCompileTime,
708  MatrixType::MaxRowsAtCompileTime)
709  };
710 
711  template<typename Dest> void evalTo(Dest& dst) const
712  {
713  using std::abs;
714  if(rank() == 0)
715  {
716  // The Image is just {0}, so it doesn't have a basis properly speaking, but let's
717  // avoid crashing/asserting as that depends on floating point calculations. Let's
718  // just return a single column vector filled with zeros.
719  dst.setZero();
720  return;
721  }
722 
724  RealScalar premultiplied_threshold = dec().maxPivot() * dec().threshold();
725  Index p = 0;
726  for(Index i = 0; i < dec().nonzeroPivots(); ++i)
727  if(abs(dec().matrixLU().coeff(i,i)) > premultiplied_threshold)
728  pivots.coeffRef(p++) = i;
729  eigen_internal_assert(p == rank());
730 
731  for(Index i = 0; i < rank(); ++i)
732  dst.col(i) = originalMatrix().col(dec().permutationQ().indices().coeff(pivots.coeff(i)));
733  }
734 };
735 
736 /***** Implementation of solve() *****************************************************/
737 
738 } // end namespace internal
739 
740 #ifndef EIGEN_PARSED_BY_DOXYGEN
741 template<typename _MatrixType>
742 template<typename RhsType, typename DstType>
743 void FullPivLU<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &dst) const
744 {
745  /* The decomposition PAQ = LU can be rewritten as A = P^{-1} L U Q^{-1}.
746  * So we proceed as follows:
747  * Step 1: compute c = P * rhs.
748  * Step 2: replace c by the solution x to Lx = c. Exists because L is invertible.
749  * Step 3: replace c by the solution x to Ux = c. May or may not exist.
750  * Step 4: result = Q * c;
751  */
752 
753  const Index rows = this->rows(),
754  cols = this->cols(),
755  nonzero_pivots = this->rank();
756  const Index smalldim = (std::min)(rows, cols);
757 
758  if(nonzero_pivots == 0)
759  {
760  dst.setZero();
761  return;
762  }
763 
764  typename RhsType::PlainObject c(rhs.rows(), rhs.cols());
765 
766  // Step 1
767  c = permutationP() * rhs;
768 
769  // Step 2
770  m_lu.topLeftCorner(smalldim,smalldim)
771  .template triangularView<UnitLower>()
772  .solveInPlace(c.topRows(smalldim));
773  if(rows>cols)
774  c.bottomRows(rows-cols) -= m_lu.bottomRows(rows-cols) * c.topRows(cols);
775 
776  // Step 3
777  m_lu.topLeftCorner(nonzero_pivots, nonzero_pivots)
778  .template triangularView<Upper>()
779  .solveInPlace(c.topRows(nonzero_pivots));
780 
781  // Step 4
782  for(Index i = 0; i < nonzero_pivots; ++i)
783  dst.row(permutationQ().indices().coeff(i)) = c.row(i);
784  for(Index i = nonzero_pivots; i < m_lu.cols(); ++i)
785  dst.row(permutationQ().indices().coeff(i)).setZero();
786 }
787 
788 template<typename _MatrixType>
789 template<bool Conjugate, typename RhsType, typename DstType>
790 void FullPivLU<_MatrixType>::_solve_impl_transposed(const RhsType &rhs, DstType &dst) const
791 {
792  /* The decomposition PAQ = LU can be rewritten as A = P^{-1} L U Q^{-1},
793  * and since permutations are real and unitary, we can write this
794  * as A^T = Q U^T L^T P,
795  * So we proceed as follows:
796  * Step 1: compute c = Q^T rhs.
797  * Step 2: replace c by the solution x to U^T x = c. May or may not exist.
798  * Step 3: replace c by the solution x to L^T x = c.
799  * Step 4: result = P^T c.
800  * If Conjugate is true, replace "^T" by "^*" above.
801  */
802 
803  const Index rows = this->rows(), cols = this->cols(),
804  nonzero_pivots = this->rank();
805  const Index smalldim = (std::min)(rows, cols);
806 
807  if(nonzero_pivots == 0)
808  {
809  dst.setZero();
810  return;
811  }
812 
813  typename RhsType::PlainObject c(rhs.rows(), rhs.cols());
814 
815  // Step 1
816  c = permutationQ().inverse() * rhs;
817 
818  // Step 2
819  m_lu.topLeftCorner(nonzero_pivots, nonzero_pivots)
820  .template triangularView<Upper>()
821  .transpose()
822  .template conjugateIf<Conjugate>()
823  .solveInPlace(c.topRows(nonzero_pivots));
824 
825  // Step 3
826  m_lu.topLeftCorner(smalldim, smalldim)
827  .template triangularView<UnitLower>()
828  .transpose()
829  .template conjugateIf<Conjugate>()
830  .solveInPlace(c.topRows(smalldim));
831 
832  // Step 4
833  PermutationPType invp = permutationP().inverse().eval();
834  for(Index i = 0; i < smalldim; ++i)
835  dst.row(invp.indices().coeff(i)) = c.row(i);
836  for(Index i = smalldim; i < rows; ++i)
837  dst.row(invp.indices().coeff(i)).setZero();
838 }
839 
840 #endif
841 
842 namespace internal {
843 
844 
845 /***** Implementation of inverse() *****************************************************/
846 template<typename DstXprType, typename MatrixType>
847 struct Assignment<DstXprType, Inverse<FullPivLU<MatrixType> >, internal::assign_op<typename DstXprType::Scalar,typename FullPivLU<MatrixType>::Scalar>, Dense2Dense>
848 {
850  typedef Inverse<LuType> SrcXprType;
851  static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename MatrixType::Scalar> &)
852  {
853  dst = src.nestedExpression().solve(MatrixType::Identity(src.rows(), src.cols()));
854  }
855 };
856 } // end namespace internal
857 
858 /******* MatrixBase methods *****************************************************************/
859 
866 template<typename Derived>
869 {
870  return FullPivLU<PlainObject>(eval());
871 }
872 
873 } // end namespace Eigen
874 
875 #endif // EIGEN_LU_H
Eigen::Inverse
Expression of the inverse of another expression.
Definition: Inverse.h:44
Eigen::FullPivLU::setThreshold
FullPivLU & setThreshold(Default_t)
Definition: FullPivLU.h:305
Eigen::MatrixXpr
Definition: Constants.h:518
Eigen
Namespace containing all symbols from the Eigen library.
Definition: LDLT.h:16
Eigen::EigenBase::derived
EIGEN_DEVICE_FUNC Derived & derived()
Definition: EigenBase.h:46
Eigen::FullPivLU::maxPivot
RealScalar maxPivot() const
Definition: FullPivLU.h:154
Eigen::EigenBase
Definition: EigenBase.h:30
Eigen::internal::kernel_retval_base
Definition: Kernel.h:39
Eigen::FullPivLU::reconstructedMatrix
MatrixType reconstructedMatrix() const
Definition: FullPivLU.h:590
Eigen::internal::Dense2Dense
Definition: AssignEvaluator.h:804
Eigen::MatrixBase::fullPivLu
const FullPivLU< PlainObject > fullPivLu() const
Definition: FullPivLU.h:868
Eigen::FullPivLU
LU decomposition of a matrix with complete pivoting, and related features.
Definition: FullPivLU.h:62
Eigen::FullPivLU::dimensionOfKernel
Index dimensionOfKernel() const
Definition: FullPivLU.h:347
Eigen::PlainObjectBase< Matrix< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > >::coeff
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar & coeff(Index rowId, Index colId) const
Definition: PlainObjectBase.h:160
Eigen::FullPivLU::nonzeroPivots
Index nonzeroPivots() const
Definition: FullPivLU.h:145
Eigen::FullPivLU::permutationQ
const PermutationQType & permutationQ() const
Definition: FullPivLU.h:170
Eigen::internal::true_type
Definition: Meta.h:63
Eigen::internal::image_retval
Definition: ForwardDeclarations.h:141
Eigen::FullPivLU::compute
FullPivLU & compute(const EigenBase< InputType > &matrix)
Definition: FullPivLU.h:120
Eigen::SolverStorage
Definition: Constants.h:509
Eigen::Dynamic
const int Dynamic
Definition: Constants.h:21
Eigen::internal::scalar_score_coeff_op
Definition: UnaryFunctors.h:64
Eigen::FullPivLU::FullPivLU
FullPivLU()
Default Constructor.
Definition: FullPivLU.h:440
Eigen::FullPivLU::rank
Index rank() const
Definition: FullPivLU.h:330
Eigen::Matrix::coeffRef
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar & coeffRef(Index rowId, Index colId)
Definition: PlainObjectBase.h:183
Eigen::internal::assign_op
Definition: AssignmentFunctors.h:21
Eigen::FullPivLU::permutationP
EIGEN_DEVICE_FUNC const PermutationPType & permutationP() const
Definition: FullPivLU.h:160
Eigen::internal::kernel_retval
Definition: ForwardDeclarations.h:139
Eigen::FullPivLU::inverse
const Inverse< FullPivLU > inverse() const
Definition: FullPivLU.h:398
Eigen::Solve
Pseudo expression representing a solving operation.
Definition: Solve.h:63
Eigen::FullPivLU::setThreshold
FullPivLU & setThreshold(const RealScalar &threshold)
Definition: FullPivLU.h:290
Eigen::internal::traits
Definition: ForwardDeclarations.h:17
Eigen::FullPivLU::kernel
const internal::kernel_retval< FullPivLU > kernel() const
Definition: FullPivLU.h:190
Eigen::PermutationMatrix< ColsAtCompileTime, MaxColsAtCompileTime >
Eigen::internal::Assignment
Definition: AssignEvaluator.h:814
Eigen::FullPivLU::determinant
internal::traits< MatrixType >::Scalar determinant() const
Definition: FullPivLU.h:579
Eigen::FullPivLU::image
const internal::image_retval< FullPivLU > image(const MatrixType &originalMatrix) const
Definition: FullPivLU.h:216
Eigen::Matrix
The matrix class, also used for vectors and row-vectors.
Definition: Matrix.h:180
Eigen::MatrixBase
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:50
Eigen::FullPivLU::rcond
RealScalar rcond() const
Definition: FullPivLU.h:250
Eigen::FullPivLU::isInvertible
bool isInvertible() const
Definition: FullPivLU.h:385
Eigen::FullPivLU::isInjective
bool isInjective() const
Definition: FullPivLU.h:360
Eigen::FullPivLU::threshold
RealScalar threshold() const
Definition: FullPivLU.h:315
Eigen::NumTraits
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:213
Eigen::FullPivLU::isSurjective
bool isSurjective() const
Definition: FullPivLU.h:373
Eigen::internal::image_retval_base
Definition: Image.h:37
Eigen::FullPivLU::matrixLU
const MatrixType & matrixLU() const
Definition: FullPivLU.h:132
Eigen::SolverBase
A base class for matrix decomposition and solvers.
Definition: SolverBase.h:69
Eigen::Index
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:42