11 #ifndef EIGEN_JACOBISVD_H    12 #define EIGEN_JACOBISVD_H    19 template<
typename MatrixType, 
int QRPreconditioner,
    32 template<
typename MatrixType, 
int QRPreconditioner, 
int Case>
    35   enum { a = MatrixType::RowsAtCompileTime != 
Dynamic &&
    36              MatrixType::ColsAtCompileTime != 
Dynamic &&
    37              MatrixType::ColsAtCompileTime <= MatrixType::RowsAtCompileTime,
    38          b = MatrixType::RowsAtCompileTime != 
Dynamic &&
    39              MatrixType::ColsAtCompileTime != 
Dynamic &&
    40              MatrixType::RowsAtCompileTime <= MatrixType::ColsAtCompileTime,
    43                   (Case == PreconditionIfMoreRowsThanCols && 
bool(b)) )
    47 template<
typename MatrixType, 
int QRPreconditioner, 
int Case,
    51 template<
typename MatrixType, 
int QRPreconditioner, 
int Case>
    64 template<
typename MatrixType>
    68   typedef typename MatrixType::Scalar 
Scalar;
    71     RowsAtCompileTime = MatrixType::RowsAtCompileTime,
    72     MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime
    78     if (svd.
rows() != m_qr.rows() || svd.
cols() != m_qr.cols())
    88     if(matrix.rows() > matrix.cols())
    91       svd.
m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).
template triangularView<Upper>();
   104 template<
typename MatrixType>
   108   typedef typename MatrixType::Scalar 
Scalar;
   111     RowsAtCompileTime = MatrixType::RowsAtCompileTime,
   112     ColsAtCompileTime = MatrixType::ColsAtCompileTime,
   113     MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
   114     MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
   115     Options = MatrixType::Options
   122     if (svd.
cols() != m_qr.rows() || svd.
rows() != m_qr.cols())
   127     m_adjoint.resize(svd.
cols(), svd.
rows());
   133     if(matrix.cols() > matrix.rows())
   135       m_adjoint = matrix.adjoint();
   136       m_qr.compute(m_adjoint);
   137       svd.
m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).
template triangularView<Upper>().adjoint();
   153 template<
typename MatrixType>
   159     if (svd.
rows() != m_qr.rows() || svd.
cols() != m_qr.cols())
   170     if(matrix.rows() > matrix.cols())
   172       m_qr.compute(matrix);
   173       svd.
m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).
template triangularView<Upper>();
   177         svd.
m_matrixU.setIdentity(matrix.rows(), matrix.cols());
   178         m_qr.householderQ().applyThisOnTheLeft(svd.
m_matrixU, m_workspace);
   192 template<
typename MatrixType>
   196   typedef typename MatrixType::Scalar 
Scalar;
   199     RowsAtCompileTime = MatrixType::RowsAtCompileTime,
   200     ColsAtCompileTime = MatrixType::ColsAtCompileTime,
   201     MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
   202     MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
   203     Options = MatrixType::Options
   211     if (svd.
cols() != m_qr.rows() || svd.
rows() != m_qr.cols())
   218     m_adjoint.resize(svd.
cols(), svd.
rows());
   223     if(matrix.cols() > matrix.rows())
   225       m_adjoint = matrix.adjoint();
   226       m_qr.compute(m_adjoint);
   228       svd.
m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).
template triangularView<Upper>().adjoint();
   232         svd.
m_matrixV.setIdentity(matrix.cols(), matrix.rows());
   233         m_qr.householderQ().applyThisOnTheLeft(svd.
m_matrixV, m_workspace);
   250 template<
typename MatrixType>
   256     if (svd.
rows() != m_qr.rows() || svd.
cols() != m_qr.cols())
   267     if(matrix.rows() > matrix.cols())
   269       m_qr.compute(matrix);
   270       svd.
m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).
template triangularView<Upper>();
   274         svd.
m_matrixU.setIdentity(matrix.rows(), matrix.cols());
   275         m_qr.householderQ().applyThisOnTheLeft(svd.
m_matrixU, m_workspace);
   288 template<
typename MatrixType>
   292   typedef typename MatrixType::Scalar 
Scalar;
   295     RowsAtCompileTime = MatrixType::RowsAtCompileTime,
   296     ColsAtCompileTime = MatrixType::ColsAtCompileTime,
   297     MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
   298     MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
   299     Options = MatrixType::Options
   307     if (svd.
cols() != m_qr.rows() || svd.
rows() != m_qr.cols())
   314     m_adjoint.resize(svd.
cols(), svd.
rows());
   319     if(matrix.cols() > matrix.rows())
   321       m_adjoint = matrix.adjoint();
   322       m_qr.compute(m_adjoint);
   324       svd.
m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).
template triangularView<Upper>().adjoint();
   328         svd.
m_matrixV.setIdentity(matrix.cols(), matrix.rows());
   329         m_qr.householderQ().applyThisOnTheLeft(svd.
m_matrixV, m_workspace);
   349 template<
typename MatrixType, 
int QRPreconditioner>
   357 template<
typename MatrixType, 
int QRPreconditioner>
   361   typedef typename MatrixType::Scalar 
Scalar;
   383         work_matrix.row(p) *= z;
   389         work_matrix.row(q) *= z;
   396       rot.
c() = conj(work_matrix.
coeff(p,p)) / n;
   397       rot.
s() = work_matrix.
coeff(q,p) / n;
   398       work_matrix.applyOnTheLeft(p,q,rot);
   403         work_matrix.col(q) *= z;
   409         work_matrix.row(q) *= z;
   415     maxDiagEntry = numext::maxi<RealScalar>(maxDiagEntry,numext::maxi<RealScalar>(
abs(work_matrix.
coeff(p,p)), 
abs(work_matrix.
coeff(q,q))));
   417     RealScalar threshold = numext::maxi<RealScalar>(considerAsZero, precision * maxDiagEntry);
   418     return abs(work_matrix.
coeff(p,q))>threshold || 
abs(work_matrix.
coeff(q,p)) > threshold;
   422 template<
typename _MatrixType, 
int QRPreconditioner> 
   483 template<
typename _MatrixType, 
int QRPreconditioner> 
class JacobiSVD   484  : 
public SVDBase<JacobiSVD<_MatrixType,QRPreconditioner> >
   490     typedef typename MatrixType::Scalar 
Scalar;
   493       RowsAtCompileTime = MatrixType::RowsAtCompileTime,
   494       ColsAtCompileTime = MatrixType::ColsAtCompileTime,
   496       MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
   497       MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
   499       MatrixOptions = MatrixType::Options
   508     typedef Matrix<Scalar, DiagSizeAtCompileTime, DiagSizeAtCompileTime,
   509                    MatrixOptions, MaxDiagSizeAtCompileTime, MaxDiagSizeAtCompileTime>
   529       allocate(rows, cols, computationOptions);
   542     explicit JacobiSVD(
const MatrixType& matrix, 
unsigned int computationOptions = 0)
   544       compute(matrix, computationOptions);
   557     JacobiSVD& compute(
const MatrixType& matrix, 
unsigned int computationOptions);
   567       return compute(matrix, m_computationOptions);
   570     using Base::computeU;
   571     using Base::computeV;
   577     void allocate(
Index rows, 
Index cols, 
unsigned int computationOptions);
   580     using Base::m_matrixU;
   581     using Base::m_matrixV;
   582     using Base::m_singularValues;
   583     using Base::m_isInitialized;
   584     using Base::m_isAllocated;
   585     using Base::m_usePrescribedThreshold;
   586     using Base::m_computeFullU;
   587     using Base::m_computeThinU;
   588     using Base::m_computeFullV;
   589     using Base::m_computeThinV;
   590     using Base::m_computationOptions;
   591     using Base::m_nonzeroSingularValues;
   594     using Base::m_diagSize;
   595     using Base::m_prescribedThreshold;
   598     template<
typename __MatrixType, 
int _QRPreconditioner, 
bool _IsComplex>
   600     template<
typename __MatrixType, 
int _QRPreconditioner, 
int _Case, 
bool _DoAnything>
   608 template<
typename MatrixType, 
int QRPreconditioner>
   616       computationOptions == m_computationOptions)
   623   m_isInitialized = 
false;
   624   m_isAllocated = 
true;
   625   m_computationOptions = computationOptions;
   626   m_computeFullU = (computationOptions & 
ComputeFullU) != 0;
   627   m_computeThinU = (computationOptions & 
ComputeThinU) != 0;
   628   m_computeFullV = (computationOptions & 
ComputeFullV) != 0;
   629   m_computeThinV = (computationOptions & 
ComputeThinV) != 0;
   630   eigen_assert(!(m_computeFullU && m_computeThinU) && 
"JacobiSVD: you can't ask for both full and thin U");
   631   eigen_assert(!(m_computeFullV && m_computeThinV) && 
"JacobiSVD: you can't ask for both full and thin V");
   633               "JacobiSVD: thin U and V are only available when your matrix has a dynamic number of columns.");
   637               "JacobiSVD: can't compute thin U or thin V with the FullPivHouseholderQR preconditioner. "   638               "Use the ColPivHouseholderQR preconditioner instead.");
   640   m_diagSize = (
std::min)(m_rows, m_cols);
   641   m_singularValues.resize(m_diagSize);
   643     m_matrixU.resize(m_rows, m_computeFullU ? m_rows
   644                             : m_computeThinU ? m_diagSize
   647     m_matrixV.resize(m_cols, m_computeFullV ? m_cols
   648                             : m_computeThinV ? m_diagSize
   650   m_workMatrix.resize(m_diagSize, m_diagSize);
   652   if(m_cols>m_rows)   m_qr_precond_morecols.allocate(*
this);
   653   if(m_rows>m_cols)   m_qr_precond_morerows.allocate(*
this);
   654   if(m_rows!=m_cols)  m_scaledMatrix.resize(rows,cols);
   657 template<
typename MatrixType, 
int QRPreconditioner>
   662   allocate(matrix.rows(), matrix.cols(), computationOptions);
   672   RealScalar scale = matrix.cwiseAbs().maxCoeff();
   679     m_scaledMatrix = matrix / scale;
   680     m_qr_precond_morecols.run(*
this, m_scaledMatrix);
   681     m_qr_precond_morerows.run(*
this, m_scaledMatrix);
   685     m_workMatrix = matrix.block(0,0,m_diagSize,m_diagSize) / scale;
   686     if(m_computeFullU) m_matrixU.setIdentity(m_rows,m_rows);
   687     if(m_computeThinU) m_matrixU.setIdentity(m_rows,m_diagSize);
   688     if(m_computeFullV) m_matrixV.setIdentity(m_cols,m_cols);
   689     if(m_computeThinV) m_matrixV.setIdentity(m_cols, m_diagSize);
   693   RealScalar maxDiagEntry = m_workMatrix.cwiseAbs().diagonal().maxCoeff();
   695   bool finished = 
false;
   702     for(
Index p = 1; p < m_diagSize; ++p)
   704       for(
Index q = 0; q < p; ++q)
   709         RealScalar threshold = numext::maxi<RealScalar>(considerAsZero, precision * maxDiagEntry);
   710         if(
abs(m_workMatrix.coeff(p,q))>threshold || 
abs(m_workMatrix.coeff(q,p)) > threshold)
   721             m_workMatrix.applyOnTheLeft(p,q,j_left);
   722             if(computeU()) m_matrixU.applyOnTheRight(p,q,j_left.
transpose());
   724             m_workMatrix.applyOnTheRight(p,q,j_right);
   725             if(computeV()) m_matrixV.applyOnTheRight(p,q,j_right);
   728             maxDiagEntry = numext::maxi<RealScalar>(maxDiagEntry,numext::maxi<RealScalar>(
abs(m_workMatrix.coeff(p,p)), 
abs(m_workMatrix.coeff(q,q))));
   737   for(
Index i = 0; i < m_diagSize; ++i)
   745       m_singularValues.coeffRef(i) = 
abs(a);
   746       if(computeU()) m_matrixU.col(i) *= m_workMatrix.coeff(i,i)/a;
   752       m_singularValues.coeffRef(i) = 
abs(a);
   753       if(computeU() && (a<
RealScalar(0))) m_matrixU.col(i) = -m_matrixU.col(i);
   757   m_singularValues *= scale;
   761   m_nonzeroSingularValues = m_diagSize;
   762   for(
Index i = 0; i < m_diagSize; i++)
   765     RealScalar maxRemainingSingularValue = m_singularValues.tail(m_diagSize-i).maxCoeff(&pos);
   766     if(maxRemainingSingularValue == 
RealScalar(0))
   768       m_nonzeroSingularValues = i;
   774       std::swap(m_singularValues.coeffRef(i), m_singularValues.coeffRef(pos));
   775       if(computeU()) m_matrixU.col(pos).swap(m_matrixU.col(i));
   776       if(computeV()) m_matrixV.col(pos).swap(m_matrixV.col(i));
   780   m_isInitialized = 
true;
   791 template<
typename Derived>
   800 #endif // EIGEN_JACOBISVD_H Matrix< Scalar, DiagSizeAtCompileTime, DiagSizeAtCompileTime, MatrixOptions, MaxDiagSizeAtCompileTime, MaxDiagSizeAtCompileTime > WorkMatrixType
Matrix< Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime > TransposeTypeWithSameStorageOrder
bool run(JacobiSVD< MatrixType, QRPreconditioner > &, const MatrixType &)
MatrixType::Scalar Scalar
internal::plain_col_type< MatrixType >::type ColType
static bool run(typename SVD::WorkMatrixType &, SVD &, Index, Index, RealScalar &)
EIGEN_DEVICE_FUNC RealReturnType real() const
Matrix< Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime > TransposeTypeWithSameStorageOrder
void allocate(const JacobiSVD< MatrixType, QRPreconditioner > &)
MatrixType::RealScalar RealScalar
SVDBase< JacobiSVD > Base
internal::plain_col_type< MatrixType >::type m_workspace
void allocate(const JacobiSVD< MatrixType, HouseholderQRPreconditioner > &svd)
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
Rotation given by a cosine-sine pair. 
MatrixType::Scalar Scalar
void allocate(const JacobiSVD< MatrixType, FullPivHouseholderQRPreconditioner > &svd)
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
TransposeTypeWithSameStorageOrder m_adjoint
static bool run(typename SVD::WorkMatrixType &work_matrix, SVD &svd, Index p, Index q, RealScalar &maxDiagEntry)
#define EIGEN_IMPLIES(a, b)
#define EIGEN_SIZE_MIN_PREFER_FIXED(a, b)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar & coeffRef(Index rowId, Index colId)
MatrixType::Scalar Scalar
WorkspaceType m_workspace
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const AbsReturnType abs() const
bool run(JacobiSVD< MatrixType, ColPivHouseholderQRPreconditioner > &svd, const MatrixType &matrix)
void real_2x2_jacobi_svd(const MatrixType &matrix, Index p, Index q, JacobiRotation< RealScalar > *j_left, JacobiRotation< RealScalar > *j_right)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Abs2ReturnType abs2() const
TransposeTypeWithSameStorageOrder m_adjoint
FullPivHouseholderQR< MatrixType > QRType
MatrixType::Scalar Scalar
Base class of SVD algorithms. 
JacobiSVD< PlainObject > jacobiSvd(unsigned int computationOptions=0) const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar & coeff(Index rowId, Index colId) const
JacobiSVD()
Default Constructor. 
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API. 
internal::qr_preconditioner_impl< MatrixType, QRPreconditioner, internal::PreconditionIfMoreColsThanRows > m_qr_precond_morecols
HouseholderQR< MatrixType > QRType
ColPivHouseholderQR< TransposeTypeWithSameStorageOrder > QRType
Matrix< Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime > TransposeTypeWithSameStorageOrder
internal::plain_row_type< MatrixType >::type m_workspace
FullPivHouseholderQR< TransposeTypeWithSameStorageOrder > QRType
TransposeTypeWithSameStorageOrder m_adjoint
Base::MatrixVType MatrixVType
bool run(JacobiSVD< MatrixType, HouseholderQRPreconditioner > &svd, const MatrixType &matrix)
bool run(JacobiSVD< MatrixType, FullPivHouseholderQRPreconditioner > &svd, const MatrixType &matrix)
MatrixType::RealScalar RealScalar
Matrix< Scalar, 1, RowsAtCompileTime, RowMajor, 1, MaxRowsAtCompileTime > WorkspaceType
bool run(JacobiSVD< MatrixType, HouseholderQRPreconditioner > &svd, const MatrixType &matrix)
MatrixType m_scaledMatrix
void allocate(const JacobiSVD< MatrixType, ColPivHouseholderQRPreconditioner > &svd)
void allocate(const JacobiSVD< MatrixType, HouseholderQRPreconditioner > &svd)
ColPivHouseholderQR< MatrixType > QRType
HouseholderQR< TransposeTypeWithSameStorageOrder > QRType
JacobiSVD & compute(const MatrixType &matrix)
Method performing the decomposition of given matrix using current options. 
void allocate(Index rows, Index cols, unsigned int computationOptions)
Two-sided Jacobi SVD decomposition of a rectangular matrix. 
JacobiRotation transpose() const
JacobiSVD< MatrixType, QRPreconditioner > SVD
MatrixType::Scalar Scalar
internal::plain_row_type< MatrixType >::type RowType
NumTraits< typename MatrixType::Scalar >::Real RealScalar
JacobiSVD< MatrixType, QRPreconditioner > SVD
JacobiSVD & compute(const MatrixType &matrix, unsigned int computationOptions)
Method performing the decomposition of given matrix using custom options. 
bool run(JacobiSVD< MatrixType, FullPivHouseholderQRPreconditioner > &svd, const MatrixType &matrix)
EIGEN_DEVICE_FUNC const ImagReturnType imag() const
Base::SingularValuesType SingularValuesType
internal::plain_col_type< MatrixType >::type m_workspace
internal::qr_preconditioner_impl< MatrixType, QRPreconditioner, internal::PreconditionIfMoreRowsThanCols > m_qr_precond_morerows
internal::plain_row_type< MatrixType >::type m_workspace
#define EIGEN_SIZE_MIN_PREFER_DYNAMIC(a, b)
JacobiSVD(Index rows, Index cols, unsigned int computationOptions=0)
Default Constructor with memory preallocation. 
bool run(JacobiSVD< MatrixType, ColPivHouseholderQRPreconditioner > &svd, const MatrixType &matrix)
WorkMatrixType m_workMatrix
JacobiSVD(const MatrixType &matrix, unsigned int computationOptions=0)
Constructor performing the decomposition of given matrix. 
JacobiRotation adjoint() const
internal::plain_row_type< MatrixType >::type m_workspace
void allocate(const JacobiSVD< MatrixType, ColPivHouseholderQRPreconditioner > &svd)
void swap(scoped_array< T > &a, scoped_array< T > &b)
void allocate(const JacobiSVD< MatrixType, FullPivHouseholderQRPreconditioner > &svd)
MatrixType::Scalar Scalar
Base::MatrixUType MatrixUType