Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
Eigen::JacobiSVD< _MatrixType, QRPreconditioner > Class Template Reference

Two-sided Jacobi SVD decomposition of a rectangular matrix. More...

#include <src/eigen/Eigen/src/SVD/JacobiSVD.h>

+ Inheritance diagram for Eigen::JacobiSVD< _MatrixType, QRPreconditioner >:
+ Collaboration diagram for Eigen::JacobiSVD< _MatrixType, QRPreconditioner >:

Public Types

enum  {
  RowsAtCompileTime = MatrixType::RowsAtCompileTime , ColsAtCompileTime = MatrixType::ColsAtCompileTime , DiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime) , MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime ,
  MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime , MaxDiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(MaxRowsAtCompileTime,MaxColsAtCompileTime) , MatrixOptions = MatrixType::Options
}
 
typedef _MatrixType MatrixType
 
typedef MatrixType::Scalar Scalar
 
typedef NumTraits< typenameMatrixType::Scalar >::Real RealScalar
 
typedef Base::MatrixUType MatrixUType
 
typedef Base::MatrixVType MatrixVType
 
typedef Base::SingularValuesType SingularValuesType
 
typedef internal::plain_row_type< MatrixType >::type RowType
 
typedef internal::plain_col_type< MatrixType >::type ColType
 
typedef Matrix< Scalar, DiagSizeAtCompileTime, DiagSizeAtCompileTime, MatrixOptions, MaxDiagSizeAtCompileTime, MaxDiagSizeAtCompileTimeWorkMatrixType
 
enum  
 
typedef MatrixType::StorageIndex StorageIndex
 
typedef Eigen::Index Index
 

Public Member Functions

 JacobiSVD ()
 Default Constructor.
 
 JacobiSVD (Index rows, Index cols, unsigned int computationOptions=0)
 Default Constructor with memory preallocation.
 
 JacobiSVD (const MatrixType &matrix, unsigned int computationOptions=0)
 Constructor performing the decomposition of given matrix.
 
JacobiSVDcompute (const MatrixType &matrix, unsigned int computationOptions)
 Method performing the decomposition of given matrix using custom options.
 
JacobiSVDcompute (const MatrixType &matrix)
 Method performing the decomposition of given matrix using current options.
 
bool computeU () const
 
bool computeV () const
 
Index rows () const
 
Index cols () const
 
Index rank () const
 
JacobiSVD< _MatrixType, QRPreconditioner > & derived ()
 
const JacobiSVD< _MatrixType, QRPreconditioner > & derived () const
 
const MatrixUTypematrixU () const
 
const MatrixVTypematrixV () const
 
const SingularValuesTypesingularValues () const
 
Index nonzeroSingularValues () const
 
JacobiSVD< _MatrixType, QRPreconditioner > & setThreshold (const RealScalar &threshold)
 
JacobiSVD< _MatrixType, QRPreconditioner > & setThreshold (Default_t)
 
RealScalar threshold () const
 
const Solve< JacobiSVD< _MatrixType, QRPreconditioner >, Rhs > solve (const MatrixBase< Rhs > &b) const
 
EIGEN_DEVICE_FUNC void _solve_impl (const RhsType &rhs, DstType &dst) const
 
void _solve_impl (const RhsType &rhs, DstType &dst) const
 

Static Protected Member Functions

static void check_template_parameters ()
 

Protected Attributes

WorkMatrixType m_workMatrix
 
internal::qr_preconditioner_impl< MatrixType, QRPreconditioner, internal::PreconditionIfMoreColsThanRowsm_qr_precond_morecols
 
internal::qr_preconditioner_impl< MatrixType, QRPreconditioner, internal::PreconditionIfMoreRowsThanColsm_qr_precond_morerows
 
MatrixType m_scaledMatrix
 
MatrixUType m_matrixU
 
MatrixVType m_matrixV
 
SingularValuesType m_singularValues
 
bool m_isInitialized
 
bool m_isAllocated
 
bool m_usePrescribedThreshold
 
bool m_computeFullU
 
bool m_computeThinU
 
bool m_computeFullV
 
bool m_computeThinV
 
unsigned int m_computationOptions
 
Index m_nonzeroSingularValues
 
Index m_rows
 
Index m_cols
 
Index m_diagSize
 
RealScalar m_prescribedThreshold
 

Private Types

typedef SVDBase< JacobiSVDBase
 

Private Member Functions

void allocate (Index rows, Index cols, unsigned int computationOptions)
 

Friends

template<typename __MatrixType , int _QRPreconditioner, bool _IsComplex>
struct internal::svd_precondition_2x2_block_to_be_real
 
template<typename __MatrixType , int _QRPreconditioner, int _Case, bool _DoAnything>
struct internal::qr_preconditioner_impl
 

Detailed Description

template<typename _MatrixType, int QRPreconditioner>
class Eigen::JacobiSVD< _MatrixType, QRPreconditioner >

Two-sided Jacobi SVD decomposition of a rectangular matrix.

Template Parameters
_MatrixTypethe type of the matrix of which we are computing the SVD decomposition
QRPreconditionerthis optional parameter allows to specify the type of QR decomposition that will be used internally for the R-SVD step for non-square matrices. See discussion of possible values below.

SVD decomposition consists in decomposing any n-by-p matrix A as a product

\[ A = U S V^* \]

where U is a n-by-n unitary, V is a p-by-p unitary, and S is a n-by-p real positive matrix which is zero outside of its main diagonal; the diagonal entries of S are known as the singular values of A and the columns of U and V are known as the left and right singular vectors of A respectively.

Singular values are always sorted in decreasing order.

This JacobiSVD decomposition computes only the singular values by default. If you want U or V, you need to ask for them explicitly.

You can ask for only thin U or V to be computed, meaning the following. In case of a rectangular n-by-p matrix, letting m be the smaller value among n and p, there are only m singular vectors; the remaining columns of U and V do not correspond to actual singular vectors. Asking for thin U or V means asking for only their m first columns to be formed. So U is then a n-by-m matrix, and V is then a p-by-m matrix. Notice that thin U and V are all you need for (least squares) solving.

Here's an example demonstrating basic usage:

Output:

This JacobiSVD class is a two-sided Jacobi R-SVD decomposition, ensuring optimal reliability and accuracy. The downside is that it's slower than bidiagonalizing SVD algorithms for large square matrices; however its complexity is still $ O(n^2p) $ where n is the smaller dimension and p is the greater dimension, meaning that it is still of the same order of complexity as the faster bidiagonalizing R-SVD algorithms. In particular, like any R-SVD, it takes advantage of non-squareness in that its complexity is only linear in the greater dimension.

If the input matrix has inf or nan coefficients, the result of the computation is undefined, but the computation is guaranteed to terminate in finite (and reasonable) time.

The possible values for QRPreconditioner are:

  • ColPivHouseholderQRPreconditioner is the default. In practice it's very safe. It uses column-pivoting QR.
  • FullPivHouseholderQRPreconditioner, is the safest and slowest. It uses full-pivoting QR. Contrary to other QRs, it doesn't allow computing thin unitaries.
  • HouseholderQRPreconditioner is the fastest, and less safe and accurate than the pivoting variants. It uses non-pivoting QR. This is very similar in safety and accuracy to the bidiagonalization process used by bidiagonalizing SVD algorithms (since bidiagonalization is inherently non-pivoting). However the resulting SVD is still more reliable than bidiagonalizing SVDs because the Jacobi-based iterarive process is more reliable than the optimized bidiagonal SVD iterations.
  • NoQRPreconditioner allows not to use a QR preconditioner at all. This is useful if you know that you will only be computing JacobiSVD decompositions of square matrices. Non-square matrices require a QR preconditioner. Using this option will result in faster compilation and smaller executable code. It won't significantly speed up computation, since JacobiSVD is always checking if QR preconditioning is needed before applying it anyway.
See also
MatrixBase::jacobiSvd()

Member Typedef Documentation

◆ Base

template<typename _MatrixType , int QRPreconditioner>
typedef SVDBase<JacobiSVD> Eigen::JacobiSVD< _MatrixType, QRPreconditioner >::Base
private

◆ ColType

template<typename _MatrixType , int QRPreconditioner>
typedef internal::plain_col_type<MatrixType>::type Eigen::JacobiSVD< _MatrixType, QRPreconditioner >::ColType

◆ Index

typedef Eigen::Index Eigen::SVDBase< JacobiSVD< _MatrixType, QRPreconditioner > >::Index
inherited

◆ MatrixType

template<typename _MatrixType , int QRPreconditioner>
typedef _MatrixType Eigen::JacobiSVD< _MatrixType, QRPreconditioner >::MatrixType

◆ MatrixUType

template<typename _MatrixType , int QRPreconditioner>
typedef Base::MatrixUType Eigen::JacobiSVD< _MatrixType, QRPreconditioner >::MatrixUType

◆ MatrixVType

template<typename _MatrixType , int QRPreconditioner>
typedef Base::MatrixVType Eigen::JacobiSVD< _MatrixType, QRPreconditioner >::MatrixVType

◆ RealScalar

template<typename _MatrixType , int QRPreconditioner>
typedef NumTraits<typenameMatrixType::Scalar>::Real Eigen::JacobiSVD< _MatrixType, QRPreconditioner >::RealScalar

◆ RowType

template<typename _MatrixType , int QRPreconditioner>
typedef internal::plain_row_type<MatrixType>::type Eigen::JacobiSVD< _MatrixType, QRPreconditioner >::RowType

◆ Scalar

template<typename _MatrixType , int QRPreconditioner>
typedef MatrixType::Scalar Eigen::JacobiSVD< _MatrixType, QRPreconditioner >::Scalar

◆ SingularValuesType

template<typename _MatrixType , int QRPreconditioner>
typedef Base::SingularValuesType Eigen::JacobiSVD< _MatrixType, QRPreconditioner >::SingularValuesType

◆ StorageIndex

typedef MatrixType::StorageIndex Eigen::SVDBase< JacobiSVD< _MatrixType, QRPreconditioner > >::StorageIndex
inherited

◆ WorkMatrixType

template<typename _MatrixType , int QRPreconditioner>
typedef Matrix<Scalar, DiagSizeAtCompileTime, DiagSizeAtCompileTime, MatrixOptions, MaxDiagSizeAtCompileTime, MaxDiagSizeAtCompileTime> Eigen::JacobiSVD< _MatrixType, QRPreconditioner >::WorkMatrixType

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
inherited
57 {
58 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
59 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
60 DiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime),
61 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
62 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
63 MaxDiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(MaxRowsAtCompileTime,MaxColsAtCompileTime),
64 MatrixOptions = MatrixType::Options
65 };
#define EIGEN_SIZE_MIN_PREFER_DYNAMIC(a, b)
Definition Macros.h:881
#define EIGEN_SIZE_MIN_PREFER_FIXED(a, b)
Definition Macros.h:889

◆ anonymous enum

template<typename _MatrixType , int QRPreconditioner>
anonymous enum
Enumerator
RowsAtCompileTime 
ColsAtCompileTime 
DiagSizeAtCompileTime 
MaxRowsAtCompileTime 
MaxColsAtCompileTime 
MaxDiagSizeAtCompileTime 
MatrixOptions 
496 {
497 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
498 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
500 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
501 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
503 MatrixOptions = MatrixType::Options
504 };
@ MaxRowsAtCompileTime
Definition JacobiSVD.h:500
@ MaxDiagSizeAtCompileTime
Definition JacobiSVD.h:502
@ MaxColsAtCompileTime
Definition JacobiSVD.h:501
@ ColsAtCompileTime
Definition JacobiSVD.h:498
@ RowsAtCompileTime
Definition JacobiSVD.h:497
@ DiagSizeAtCompileTime
Definition JacobiSVD.h:499
@ MatrixOptions
Definition JacobiSVD.h:503

Constructor & Destructor Documentation

◆ JacobiSVD() [1/3]

template<typename _MatrixType , int QRPreconditioner>
Eigen::JacobiSVD< _MatrixType, QRPreconditioner >::JacobiSVD ( )
inline

Default Constructor.

The default constructor is useful in cases in which the user intends to perform decompositions via JacobiSVD::compute(const MatrixType&).

522 {}

◆ JacobiSVD() [2/3]

template<typename _MatrixType , int QRPreconditioner>
Eigen::JacobiSVD< _MatrixType, QRPreconditioner >::JacobiSVD ( Index  rows,
Index  cols,
unsigned int  computationOptions = 0 
)
inline

Default Constructor with memory preallocation.

Like the default constructor but with preallocation of the internal data according to the specified problem size.

See also
JacobiSVD()
532 {
533 allocate(rows, cols, computationOptions);
534 }
Index cols() const
Definition SVDBase.h:195
void allocate(Index rows, Index cols, unsigned int computationOptions)
Definition JacobiSVD.h:613
Index rows() const
Definition SVDBase.h:194

◆ JacobiSVD() [3/3]

template<typename _MatrixType , int QRPreconditioner>
Eigen::JacobiSVD< _MatrixType, QRPreconditioner >::JacobiSVD ( const MatrixType matrix,
unsigned int  computationOptions = 0 
)
inlineexplicit

Constructor performing the decomposition of given matrix.

Parameters
matrixthe matrix to decompose
computationOptionsoptional parameter allowing to specify if you want full or thin U or V unitaries to be computed. By default, none is computed. This is a bit-field, the possible bits are ComputeFullU, ComputeThinU, ComputeFullV, ComputeThinV.

Thin unitaries are only available if your matrix type has a Dynamic number of columns (for example MatrixXf). They also are not available with the (non-default) FullPivHouseholderQR preconditioner.

547 {
548 compute(matrix, computationOptions);
549 }
JacobiSVD & compute(const MatrixType &matrix, unsigned int computationOptions)
Method performing the decomposition of given matrix using custom options.
Definition JacobiSVD.h:663

Member Function Documentation

◆ _solve_impl() [1/2]

EIGEN_DEVICE_FUNC void Eigen::SVDBase< JacobiSVD< _MatrixType, QRPreconditioner > >::_solve_impl ( const RhsType &  rhs,
DstType &  dst 
) const
inherited

◆ _solve_impl() [2/2]

void Eigen::SVDBase< JacobiSVD< _MatrixType, QRPreconditioner > >::_solve_impl ( const RhsType &  rhs,
DstType &  dst 
) const
inherited
262{
263 eigen_assert(rhs.rows() == rows());
264
265 // A = U S V^*
266 // So A^{-1} = V S^{-1} U^*
267
268 Matrix<Scalar, Dynamic, RhsType::ColsAtCompileTime, 0, MatrixType::MaxRowsAtCompileTime, RhsType::MaxColsAtCompileTime> tmp;
269 Index l_rank = rank();
270 tmp.noalias() = m_matrixU.leftCols(l_rank).adjoint() * rhs;
271 tmp = m_singularValues.head(l_rank).asDiagonal().inverse() * tmp;
272 dst = m_matrixV.leftCols(l_rank) * tmp;
273}
#define eigen_assert(x)
Definition Macros.h:579
SingularValuesType m_singularValues
Definition SVDBase.h:233

◆ allocate()

template<typename MatrixType , int QRPreconditioner>
void Eigen::JacobiSVD< MatrixType, QRPreconditioner >::allocate ( Index  rows,
Index  cols,
unsigned int  computationOptions 
)
private
614{
615 eigen_assert(rows >= 0 && cols >= 0);
616
617 if (m_isAllocated &&
618 rows == m_rows &&
619 cols == m_cols &&
620 computationOptions == m_computationOptions)
621 {
622 return;
623 }
624
625 m_rows = rows;
626 m_cols = cols;
627 m_isInitialized = false;
628 m_isAllocated = true;
629 m_computationOptions = computationOptions;
630 m_computeFullU = (computationOptions & ComputeFullU) != 0;
631 m_computeThinU = (computationOptions & ComputeThinU) != 0;
632 m_computeFullV = (computationOptions & ComputeFullV) != 0;
633 m_computeThinV = (computationOptions & ComputeThinV) != 0;
634 eigen_assert(!(m_computeFullU && m_computeThinU) && "JacobiSVD: you can't ask for both full and thin U");
635 eigen_assert(!(m_computeFullV && m_computeThinV) && "JacobiSVD: you can't ask for both full and thin V");
636 eigen_assert(EIGEN_IMPLIES(m_computeThinU || m_computeThinV, MatrixType::ColsAtCompileTime==Dynamic) &&
637 "JacobiSVD: thin U and V are only available when your matrix has a dynamic number of columns.");
638 if (QRPreconditioner == FullPivHouseholderQRPreconditioner)
639 {
641 "JacobiSVD: can't compute thin U or thin V with the FullPivHouseholderQR preconditioner. "
642 "Use the ColPivHouseholderQR preconditioner instead.");
643 }
644 m_diagSize = (std::min)(m_rows, m_cols);
649 : 0);
653 : 0);
655
656 if(m_cols>m_rows) m_qr_precond_morecols.allocate(*this);
657 if(m_rows>m_cols) m_qr_precond_morerows.allocate(*this);
658 if(m_rows!=m_cols) m_scaledMatrix.resize(rows,cols);
659}
#define EIGEN_IMPLIES(a, b)
Definition Macros.h:902
MatrixType m_scaledMatrix
Definition JacobiSVD.h:609
bool m_computeFullV
Definition SVDBase.h:236
bool m_computeThinU
Definition SVDBase.h:235
internal::qr_preconditioner_impl< MatrixType, QRPreconditioner, internal::PreconditionIfMoreColsThanRows > m_qr_precond_morecols
Definition JacobiSVD.h:607
WorkMatrixType m_workMatrix
Definition JacobiSVD.h:600
bool m_isInitialized
Definition SVDBase.h:234
Index m_cols
Definition SVDBase.h:238
unsigned int m_computationOptions
Definition SVDBase.h:237
MatrixVType m_matrixV
Definition SVDBase.h:232
Index m_diagSize
Definition SVDBase.h:238
Index m_rows
Definition SVDBase.h:238
SingularValuesType m_singularValues
Definition SVDBase.h:233
internal::qr_preconditioner_impl< MatrixType, QRPreconditioner, internal::PreconditionIfMoreRowsThanCols > m_qr_precond_morerows
Definition JacobiSVD.h:608
bool m_computeThinV
Definition SVDBase.h:236
bool m_computeFullU
Definition SVDBase.h:235
MatrixUType m_matrixU
Definition SVDBase.h:231
bool m_isAllocated
Definition SVDBase.h:234
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
Definition PlainObjectBase.h:279
@ FullPivHouseholderQRPreconditioner
Definition Constants.h:421
@ ComputeFullV
Definition Constants.h:387
@ ComputeThinV
Definition Constants.h:389
@ ComputeFullU
Definition Constants.h:383
@ ComputeThinU
Definition Constants.h:385
const int Dynamic
Definition Constants.h:21

References Eigen::ComputeFullU, Eigen::ComputeFullV, Eigen::ComputeThinU, Eigen::ComputeThinV, Eigen::Dynamic, eigen_assert, EIGEN_IMPLIES, and Eigen::FullPivHouseholderQRPreconditioner.

◆ check_template_parameters()

static void Eigen::SVDBase< JacobiSVD< _MatrixType, QRPreconditioner > >::check_template_parameters ( )
inlinestaticprotectedinherited
224 {
226 }
#define EIGEN_STATIC_ASSERT_NON_INTEGER(TYPE)
Definition StaticAssert.h:184

◆ cols()

◆ compute() [1/2]

template<typename _MatrixType , int QRPreconditioner>
JacobiSVD & Eigen::JacobiSVD< _MatrixType, QRPreconditioner >::compute ( const MatrixType matrix)
inline

Method performing the decomposition of given matrix using current options.

Parameters
matrixthe matrix to decompose

This method uses the current computationOptions, as already passed to the constructor or to compute(const MatrixType&, unsigned int).

570 {
571 return compute(matrix, m_computationOptions);
572 }

◆ compute() [2/2]

template<typename MatrixType , int QRPreconditioner>
JacobiSVD< MatrixType, QRPreconditioner > & Eigen::JacobiSVD< MatrixType, QRPreconditioner >::compute ( const MatrixType matrix,
unsigned int  computationOptions 
)

Method performing the decomposition of given matrix using custom options.

Parameters
matrixthe matrix to decompose
computationOptionsoptional parameter allowing to specify if you want full or thin U or V unitaries to be computed. By default, none is computed. This is a bit-field, the possible bits are ComputeFullU, ComputeThinU, ComputeFullV, ComputeThinV.

Thin unitaries are only available if your matrix type has a Dynamic number of columns (for example MatrixXf). They also are not available with the (non-default) FullPivHouseholderQR preconditioner.

664{
665 using std::abs;
666 allocate(matrix.rows(), matrix.cols(), computationOptions);
667
668 // currently we stop when we reach precision 2*epsilon as the last bit of precision can require an unreasonable number of iterations,
669 // only worsening the precision of U and V as we accumulate more rotations
670 const RealScalar precision = RealScalar(2) * NumTraits<Scalar>::epsilon();
671
672 // limit for denormal numbers to be considered zero in order to avoid infinite loops (see bug 286)
673 const RealScalar considerAsZero = (std::numeric_limits<RealScalar>::min)();
674
675 // Scaling factor to reduce over/under-flows
676 RealScalar scale = matrix.cwiseAbs().maxCoeff();
677 if(scale==RealScalar(0)) scale = RealScalar(1);
678
679 /*** step 1. The R-SVD step: we use a QR decomposition to reduce to the case of a square matrix */
680
681 if(m_rows!=m_cols)
682 {
683 m_scaledMatrix = matrix / scale;
686 }
687 else
688 {
689 m_workMatrix = matrix.block(0,0,m_diagSize,m_diagSize) / scale;
690 if(m_computeFullU) m_matrixU.setIdentity(m_rows,m_rows);
691 if(m_computeThinU) m_matrixU.setIdentity(m_rows,m_diagSize);
692 if(m_computeFullV) m_matrixV.setIdentity(m_cols,m_cols);
693 if(m_computeThinV) m_matrixV.setIdentity(m_cols, m_diagSize);
694 }
695
696 /*** step 2. The main Jacobi SVD iteration. ***/
697 RealScalar maxDiagEntry = m_workMatrix.cwiseAbs().diagonal().maxCoeff();
698
699 bool finished = false;
700 while(!finished)
701 {
702 finished = true;
703
704 // do a sweep: for all index pairs (p,q), perform SVD of the corresponding 2x2 sub-matrix
705
706 for(Index p = 1; p < m_diagSize; ++p)
707 {
708 for(Index q = 0; q < p; ++q)
709 {
710 // if this 2x2 sub-matrix is not diagonal already...
711 // notice that this comparison will evaluate to false if any NaN is involved, ensuring that NaN's don't
712 // keep us iterating forever. Similarly, small denormal numbers are considered zero.
713 RealScalar threshold = numext::maxi<RealScalar>(considerAsZero, precision * maxDiagEntry);
715 {
716 finished = false;
717 // perform SVD decomposition of 2x2 sub-matrix corresponding to indices p,q to make it diagonal
718 // the complex to real operation returns true if the updated 2x2 block is not already diagonal
719 if(internal::svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner>::run(m_workMatrix, *this, p, q, maxDiagEntry))
720 {
721 JacobiRotation<RealScalar> j_left, j_right;
722 internal::real_2x2_jacobi_svd(m_workMatrix, p, q, &j_left, &j_right);
723
724 // accumulate resulting Jacobi rotations
725 m_workMatrix.applyOnTheLeft(p,q,j_left);
726 if(computeU()) m_matrixU.applyOnTheRight(p,q,j_left.transpose());
727
728 m_workMatrix.applyOnTheRight(p,q,j_right);
729 if(computeV()) m_matrixV.applyOnTheRight(p,q,j_right);
730
731 // keep track of the largest diagonal coefficient
732 maxDiagEntry = numext::maxi<RealScalar>(maxDiagEntry,numext::maxi<RealScalar>(abs(m_workMatrix.coeff(p,p)), abs(m_workMatrix.coeff(q,q))));
733 }
734 }
735 }
736 }
737 }
738
739 /*** step 3. The work matrix is now diagonal, so ensure it's positive so its diagonal entries are the singular values ***/
740
741 for(Index i = 0; i < m_diagSize; ++i)
742 {
743 // For a complex matrix, some diagonal coefficients might note have been
744 // treated by svd_precondition_2x2_block_to_be_real, and the imaginary part
745 // of some diagonal entry might not be null.
746 if(NumTraits<Scalar>::IsComplex && abs(numext::imag(m_workMatrix.coeff(i,i)))>considerAsZero)
747 {
749 m_singularValues.coeffRef(i) = abs(a);
750 if(computeU()) m_matrixU.col(i) *= m_workMatrix.coeff(i,i)/a;
751 }
752 else
753 {
754 // m_workMatrix.coeff(i,i) is already real, no difficulty:
755 RealScalar a = numext::real(m_workMatrix.coeff(i,i));
756 m_singularValues.coeffRef(i) = abs(a);
757 if(computeU() && (a<RealScalar(0))) m_matrixU.col(i) = -m_matrixU.col(i);
758 }
759 }
760
762
763 /*** step 4. Sort singular values in descending order and compute the number of nonzero singular values ***/
764
766 for(Index i = 0; i < m_diagSize; i++)
767 {
768 Index pos;
769 RealScalar maxRemainingSingularValue = m_singularValues.tail(m_diagSize-i).maxCoeff(&pos);
770 if(maxRemainingSingularValue == RealScalar(0))
771 {
773 break;
774 }
775 if(pos)
776 {
777 pos += i;
778 std::swap(m_singularValues.coeffRef(i), m_singularValues.coeffRef(pos));
779 if(computeU()) m_matrixU.col(pos).swap(m_matrixU.col(i));
780 if(computeV()) m_matrixV.col(pos).swap(m_matrixV.col(i));
781 }
782 }
783
784 m_isInitialized = true;
785 return *this;
786}
int scale(const int val)
Definition WipeTowerDialog.cpp:14
NumTraits< typenameMatrixType::Scalar >::Real RealScalar
Definition JacobiSVD.h:495
bool computeV() const
Definition SVDBase.h:192
bool computeU() const
Definition SVDBase.h:190
Index m_nonzeroSingularValues
Definition SVDBase.h:238
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar & coeff(Index rowId, Index colId) const
Definition PlainObjectBase.h:160
EIGEN_DEVICE_FUNC void swap(DenseBase< OtherDerived > &other)
Definition PlainObjectBase.h:886
RealScalar threshold() const
Definition SVDBase.h:180
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half abs(const half &a)
Definition Half.h:445
void real_2x2_jacobi_svd(const MatrixType &matrix, Index p, Index q, JacobiRotation< RealScalar > *j_left, JacobiRotation< RealScalar > *j_right)
Definition RealSvd2x2.h:19
Vec3d pos(const Pt &p)
Definition ReprojectPointsOnMesh.hpp:14

References Eigen::internal::real_2x2_jacobi_svd(), scale(), and Eigen::JacobiRotation< Scalar >::transpose().

Referenced by igl::min_quad_dense_precompute(), and igl::polar_svd().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ computeU()

template<typename _MatrixType , int QRPreconditioner>
bool Eigen::SVDBase< Derived >::computeU ( ) const
inline

◆ computeV()

template<typename _MatrixType , int QRPreconditioner>
bool Eigen::SVDBase< Derived >::computeV ( ) const
inline

◆ derived() [1/2]

JacobiSVD< _MatrixType, QRPreconditioner > & Eigen::SVDBase< JacobiSVD< _MatrixType, QRPreconditioner > >::derived ( )
inlineinherited
71{ return *static_cast<Derived*>(this); }

◆ derived() [2/2]

const JacobiSVD< _MatrixType, QRPreconditioner > & Eigen::SVDBase< JacobiSVD< _MatrixType, QRPreconditioner > >::derived ( ) const
inlineinherited
72{ return *static_cast<const Derived*>(this); }

◆ matrixU()

const MatrixUType & Eigen::SVDBase< JacobiSVD< _MatrixType, QRPreconditioner > >::matrixU ( ) const
inlineinherited
Returns
the U matrix.

For the SVD decomposition of a n-by-p matrix, letting m be the minimum of n and p, the U matrix is n-by-n if you asked for ComputeFullU , and is n-by-m if you asked for ComputeThinU .

The m first columns of U are the left singular vectors of the matrix being decomposed.

This method asserts that you asked for U to be computed.

84 {
85 eigen_assert(m_isInitialized && "SVD is not initialized.");
86 eigen_assert(computeU() && "This SVD decomposition didn't compute U. Did you ask for it?");
87 return m_matrixU;
88 }

◆ matrixV()

const MatrixVType & Eigen::SVDBase< JacobiSVD< _MatrixType, QRPreconditioner > >::matrixV ( ) const
inlineinherited
Returns
the V matrix.

For the SVD decomposition of a n-by-p matrix, letting m be the minimum of n and p, the V matrix is p-by-p if you asked for ComputeFullV , and is p-by-m if you asked for ComputeThinV .

The m first columns of V are the right singular vectors of the matrix being decomposed.

This method asserts that you asked for V to be computed.

100 {
101 eigen_assert(m_isInitialized && "SVD is not initialized.");
102 eigen_assert(computeV() && "This SVD decomposition didn't compute V. Did you ask for it?");
103 return m_matrixV;
104 }

◆ nonzeroSingularValues()

Index Eigen::SVDBase< JacobiSVD< _MatrixType, QRPreconditioner > >::nonzeroSingularValues ( ) const
inlineinherited
Returns
the number of singular values that are not exactly 0
119 {
120 eigen_assert(m_isInitialized && "SVD is not initialized.");
122 }

◆ rank()

template<typename _MatrixType , int QRPreconditioner>
Index Eigen::SVDBase< Derived >::rank ( ) const
inline
Returns
the rank of the matrix of which *this is the SVD.
Note
This method has to determine which singular values should be considered nonzero. For that, it uses the threshold value that you can control by calling setThreshold(const RealScalar&).
131 {
132 using std::abs;
133 eigen_assert(m_isInitialized && "JacobiSVD is not initialized.");
134 if(m_singularValues.size()==0) return 0;
135 RealScalar premultiplied_threshold = numext::maxi<RealScalar>(m_singularValues.coeff(0) * threshold(), (std::numeric_limits<RealScalar>::min)());
137 while(i>=0 && m_singularValues.coeff(i) < premultiplied_threshold) --i;
138 return i+1;
139 }

Referenced by igl::null().

+ Here is the caller graph for this function:

◆ rows()

◆ setThreshold() [1/2]

JacobiSVD< _MatrixType, QRPreconditioner > & Eigen::SVDBase< JacobiSVD< _MatrixType, QRPreconditioner > >::setThreshold ( const RealScalar threshold)
inlineinherited

Allows to prescribe a threshold to be used by certain methods, such as rank() and solve(), which need to determine when singular values are to be considered nonzero. This is not used for the SVD decomposition itself.

When it needs to get the threshold value, Eigen calls threshold(). The default is NumTraits<Scalar>::epsilon()

Parameters
thresholdThe new value to use as the threshold.

A singular value will be considered nonzero if its value is strictly greater than $ \vert singular value \vert \leqslant threshold \times \vert max singular value \vert $.

If you want to come back to the default behavior, call setThreshold(Default_t)

156 {
159 return derived();
160 }
JacobiSVD< _MatrixType, QRPreconditioner > & derived()
Definition SVDBase.h:71
RealScalar m_prescribedThreshold
Definition SVDBase.h:239

◆ setThreshold() [2/2]

JacobiSVD< _MatrixType, QRPreconditioner > & Eigen::SVDBase< JacobiSVD< _MatrixType, QRPreconditioner > >::setThreshold ( Default_t  )
inlineinherited

Allows to come back to the default behavior, letting Eigen use its default formula for determining the threshold.

You should pass the special object Eigen::Default as parameter here.

svd.setThreshold(Eigen::Default);
@ Default
Definition Constants.h:352

See the documentation of setThreshold(const RealScalar&).

171 {
173 return derived();
174 }

◆ singularValues()

const SingularValuesType & Eigen::SVDBase< JacobiSVD< _MatrixType, QRPreconditioner > >::singularValues ( ) const
inlineinherited
Returns
the vector of singular values.

For the SVD decomposition of a n-by-p matrix, letting m be the minimum of n and p, the returned vector has size m. Singular values are always sorted in decreasing order.

112 {
113 eigen_assert(m_isInitialized && "SVD is not initialized.");
114 return m_singularValues;
115 }

◆ solve()

const Solve< JacobiSVD< _MatrixType, QRPreconditioner > , Rhs > Eigen::SVDBase< JacobiSVD< _MatrixType, QRPreconditioner > >::solve ( const MatrixBase< Rhs > &  b) const
inlineinherited
Returns
a (least squares) solution of $ A x = b $ using the current SVD decomposition of A.
Parameters
bthe right-hand-side of the equation to solve.
Note
Solving requires both U and V to be computed. Thin U and V are enough, there is no need for full U or V.
SVD solving is implicitly least-squares. Thus, this method serves both purposes of exact solving and least-squares solving. In other words, the returned solution is guaranteed to minimize the Euclidean norm $ \Vert A x - b \Vert $.
209 {
210 eigen_assert(m_isInitialized && "SVD is not initialized.");
211 eigen_assert(computeU() && computeV() && "SVD::solve() requires both unitaries U and V to be computed (thin unitaries suffice).");
212 return Solve<Derived, Rhs>(derived(), b.derived());
213 }

◆ threshold()

RealScalar Eigen::SVDBase< JacobiSVD< _MatrixType, QRPreconditioner > >::threshold ( ) const
inlineinherited

Returns the threshold that will be used by certain methods such as rank().

See the documentation of setThreshold(const RealScalar&).

181 {
182 eigen_assert(m_isInitialized || m_usePrescribedThreshold);
183 // this temporary is needed to workaround a MSVC issue
184 Index diagSize = (std::max<Index>)(1,m_diagSize);
186 : diagSize*NumTraits<Scalar>::epsilon();
187 }

Friends And Related Symbol Documentation

◆ internal::qr_preconditioner_impl

template<typename _MatrixType , int QRPreconditioner>
template<typename __MatrixType , int _QRPreconditioner, int _Case, bool _DoAnything>
friend struct internal::qr_preconditioner_impl
friend

◆ internal::svd_precondition_2x2_block_to_be_real

template<typename _MatrixType , int QRPreconditioner>
template<typename __MatrixType , int _QRPreconditioner, bool _IsComplex>
friend struct internal::svd_precondition_2x2_block_to_be_real
friend

Member Data Documentation

◆ m_cols

template<typename _MatrixType , int QRPreconditioner>
Index Eigen::SVDBase< Derived >::m_cols
protected

◆ m_computationOptions

template<typename _MatrixType , int QRPreconditioner>
unsigned int Eigen::SVDBase< Derived >::m_computationOptions
protected

◆ m_computeFullU

◆ m_computeFullV

◆ m_computeThinU

◆ m_computeThinV

◆ m_diagSize

template<typename _MatrixType , int QRPreconditioner>
Index Eigen::SVDBase< Derived >::m_diagSize
protected

◆ m_isAllocated

template<typename _MatrixType , int QRPreconditioner>
bool Eigen::SVDBase< Derived >::m_isAllocated
protected

◆ m_isInitialized

template<typename _MatrixType , int QRPreconditioner>
bool Eigen::SVDBase< Derived >::m_isInitialized
protected

◆ m_matrixU

◆ m_matrixV

◆ m_nonzeroSingularValues

template<typename _MatrixType , int QRPreconditioner>
Index Eigen::SVDBase< Derived >::m_nonzeroSingularValues
protected

◆ m_prescribedThreshold

template<typename _MatrixType , int QRPreconditioner>
RealScalar Eigen::SVDBase< Derived >::m_prescribedThreshold
protected

◆ m_qr_precond_morecols

template<typename _MatrixType , int QRPreconditioner>
internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreColsThanRows> Eigen::JacobiSVD< _MatrixType, QRPreconditioner >::m_qr_precond_morecols
protected

◆ m_qr_precond_morerows

template<typename _MatrixType , int QRPreconditioner>
internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreRowsThanCols> Eigen::JacobiSVD< _MatrixType, QRPreconditioner >::m_qr_precond_morerows
protected

◆ m_rows

template<typename _MatrixType , int QRPreconditioner>
Index Eigen::SVDBase< Derived >::m_rows
protected

◆ m_scaledMatrix

template<typename _MatrixType , int QRPreconditioner>
MatrixType Eigen::JacobiSVD< _MatrixType, QRPreconditioner >::m_scaledMatrix
protected

◆ m_singularValues

template<typename _MatrixType , int QRPreconditioner>
SingularValuesType Eigen::SVDBase< Derived >::m_singularValues
protected

◆ m_usePrescribedThreshold

template<typename _MatrixType , int QRPreconditioner>
bool Eigen::SVDBase< Derived >::m_usePrescribedThreshold
protected

◆ m_workMatrix


The documentation for this class was generated from the following files: