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>
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>
111 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
112 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
113 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
114 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
115 TrOptions = RowsAtCompileTime==1 ? (MatrixType::Options & ~(
RowMajor))
116 : ColsAtCompileTime==1 ? (MatrixType::Options |
RowMajor)
117 : MatrixType::Options
124 if (svd.
cols() != m_qr.rows() || svd.
rows() != m_qr.cols())
129 m_adjoint.resize(svd.
cols(), svd.
rows());
135 if(matrix.cols() > matrix.rows())
137 m_adjoint = matrix.adjoint();
138 m_qr.compute(m_adjoint);
139 svd.
m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).
template triangularView<Upper>().adjoint();
155 template<
typename MatrixType>
161 if (svd.
rows() != m_qr.rows() || svd.
cols() != m_qr.cols())
172 if(matrix.rows() > matrix.cols())
174 m_qr.compute(matrix);
175 svd.
m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).
template triangularView<Upper>();
179 svd.
m_matrixU.setIdentity(matrix.rows(), matrix.cols());
180 m_qr.householderQ().applyThisOnTheLeft(svd.
m_matrixU, m_workspace);
194 template<
typename MatrixType>
201 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
202 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
203 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
204 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
205 TrOptions = RowsAtCompileTime==1 ? (MatrixType::Options & ~(
RowMajor))
206 : ColsAtCompileTime==1 ? (MatrixType::Options |
RowMajor)
207 : MatrixType::Options
215 if (svd.
cols() != m_qr.rows() || svd.
rows() != m_qr.cols())
222 m_adjoint.resize(svd.
cols(), svd.
rows());
227 if(matrix.cols() > matrix.rows())
229 m_adjoint = matrix.adjoint();
230 m_qr.compute(m_adjoint);
232 svd.
m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).
template triangularView<Upper>().adjoint();
236 svd.
m_matrixV.setIdentity(matrix.cols(), matrix.rows());
237 m_qr.householderQ().applyThisOnTheLeft(svd.
m_matrixV, m_workspace);
254 template<
typename MatrixType>
260 if (svd.
rows() != m_qr.rows() || svd.
cols() != m_qr.cols())
271 if(matrix.rows() > matrix.cols())
273 m_qr.compute(matrix);
274 svd.
m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).
template triangularView<Upper>();
278 svd.
m_matrixU.setIdentity(matrix.rows(), matrix.cols());
279 m_qr.householderQ().applyThisOnTheLeft(svd.
m_matrixU, m_workspace);
292 template<
typename MatrixType>
299 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
300 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
301 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
302 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
303 Options = MatrixType::Options
311 if (svd.
cols() != m_qr.rows() || svd.
rows() != m_qr.cols())
318 m_adjoint.resize(svd.
cols(), svd.
rows());
323 if(matrix.cols() > matrix.rows())
325 m_adjoint = matrix.adjoint();
326 m_qr.compute(m_adjoint);
328 svd.
m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).
template triangularView<Upper>().adjoint();
332 svd.
m_matrixV.setIdentity(matrix.cols(), matrix.rows());
333 m_qr.householderQ().applyThisOnTheLeft(svd.
m_matrixV, m_workspace);
353 template<
typename MatrixType,
int QRPreconditioner>
361 template<
typename MatrixType,
int QRPreconditioner>
387 work_matrix.row(p) *=
z;
393 work_matrix.row(q) *=
z;
401 rot.
s() = work_matrix.
coeff(q,p) /
n;
402 work_matrix.applyOnTheLeft(p,q,rot);
407 work_matrix.col(q) *=
z;
413 work_matrix.row(q) *=
z;
419 maxDiagEntry = numext::maxi<RealScalar>(maxDiagEntry,numext::maxi<RealScalar>(
abs(work_matrix.
coeff(p,p)),
abs(work_matrix.
coeff(q,q))));
421 RealScalar threshold = numext::maxi<RealScalar>(considerAsZero, precision * maxDiagEntry);
422 return abs(work_matrix.
coeff(p,q))>threshold ||
abs(work_matrix.
coeff(q,p)) > threshold;
426 template<
typename _MatrixType,
int QRPreconditioner>
487 template<
typename _MatrixType,
int QRPreconditioner>
class JacobiSVD 488 :
public SVDBase<JacobiSVD<_MatrixType,QRPreconditioner> >
497 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
498 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
500 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
501 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
503 MatrixOptions = MatrixType::Options
512 typedef Matrix<
Scalar, DiagSizeAtCompileTime, DiagSizeAtCompileTime,
513 MatrixOptions, MaxDiagSizeAtCompileTime, MaxDiagSizeAtCompileTime>
533 allocate(rows, cols, computationOptions);
548 compute(matrix, computationOptions);
571 return compute(matrix, m_computationOptions);
574 using Base::computeU;
575 using Base::computeV;
584 using Base::m_matrixU;
585 using Base::m_matrixV;
586 using Base::m_singularValues;
587 using Base::m_isInitialized;
588 using Base::m_isAllocated;
589 using Base::m_usePrescribedThreshold;
590 using Base::m_computeFullU;
591 using Base::m_computeThinU;
592 using Base::m_computeFullV;
593 using Base::m_computeThinV;
594 using Base::m_computationOptions;
595 using Base::m_nonzeroSingularValues;
598 using Base::m_diagSize;
599 using Base::m_prescribedThreshold;
602 template<
typename __MatrixType,
int _QRPreconditioner,
bool _IsComplex>
604 template<
typename __MatrixType,
int _QRPreconditioner,
int _Case,
bool _DoAnything>
612 template<
typename MatrixType,
int QRPreconditioner>
620 computationOptions == m_computationOptions)
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");
637 "JacobiSVD: thin U and V are only available when your matrix has a dynamic number of columns.");
641 "JacobiSVD: can't compute thin U or thin V with the FullPivHouseholderQR preconditioner. " 642 "Use the ColPivHouseholderQR preconditioner instead.");
644 m_diagSize = (
std::min)(m_rows, m_cols);
645 m_singularValues.resize(m_diagSize);
647 m_matrixU.resize(m_rows, m_computeFullU ? m_rows
648 : m_computeThinU ? m_diagSize
651 m_matrixV.resize(m_cols, m_computeFullV ? m_cols
652 : m_computeThinV ? m_diagSize
654 m_workMatrix.resize(m_diagSize, m_diagSize);
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);
661 template<
typename MatrixType,
int QRPreconditioner>
666 allocate(matrix.rows(), matrix.cols(), computationOptions);
683 m_scaledMatrix = matrix /
scale;
684 m_qr_precond_morecols.run(*
this, m_scaledMatrix);
685 m_qr_precond_morerows.run(*
this, m_scaledMatrix);
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);
697 RealScalar maxDiagEntry = m_workMatrix.cwiseAbs().diagonal().maxCoeff();
699 bool finished =
false;
706 for(
Index p = 1;
p < m_diagSize; ++
p)
713 RealScalar threshold = numext::maxi<RealScalar>(considerAsZero, precision * maxDiagEntry);
714 if(
abs(m_workMatrix.coeff(p,
q))>threshold ||
abs(m_workMatrix.coeff(
q,p)) > threshold)
725 m_workMatrix.applyOnTheLeft(p,
q,j_left);
726 if(computeU()) m_matrixU.applyOnTheRight(p,
q,j_left.
transpose());
728 m_workMatrix.applyOnTheRight(p,
q,j_right);
729 if(computeV()) m_matrixV.applyOnTheRight(p,
q,j_right);
732 maxDiagEntry = numext::maxi<RealScalar>(maxDiagEntry,numext::maxi<RealScalar>(
abs(m_workMatrix.coeff(p,p)),
abs(m_workMatrix.coeff(
q,
q))));
741 for(
Index i = 0;
i < m_diagSize; ++
i)
749 m_singularValues.coeffRef(
i) =
abs(a);
750 if(computeU()) m_matrixU.col(
i) *= m_workMatrix.coeff(
i,
i)/
a;
756 m_singularValues.coeffRef(
i) =
abs(a);
757 if(computeU() && (a<
RealScalar(0))) m_matrixU.col(
i) = -m_matrixU.col(
i);
761 m_singularValues *=
scale;
765 m_nonzeroSingularValues = m_diagSize;
766 for(
Index i = 0;
i < m_diagSize;
i++)
769 RealScalar maxRemainingSingularValue = m_singularValues.tail(m_diagSize-
i).maxCoeff(&pos);
770 if(maxRemainingSingularValue ==
RealScalar(0))
772 m_nonzeroSingularValues =
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));
784 m_isInitialized =
true;
795 template<
typename Derived>
804 #endif // EIGEN_JACOBISVD_H Matrix< Scalar, DiagSizeAtCompileTime, DiagSizeAtCompileTime, MatrixOptions, MaxDiagSizeAtCompileTime, MaxDiagSizeAtCompileTime > WorkMatrixType
bool run(JacobiSVD< MatrixType, QRPreconditioner > &, const MatrixType &)
int EIGEN_BLAS_FUNC() rot(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar *pc, RealScalar *ps)
MatrixType::Scalar Scalar
cout<< "Here is the matrix m:"<< endl<< m<< endl;JacobiSVD< MatrixXf > svd(m, ComputeThinU|ComputeThinV)
const AutoDiffScalar< DerType > & conj(const AutoDiffScalar< DerType > &x)
internal::plain_col_type< MatrixType >::type ColType
static bool run(typename SVD::WorkMatrixType &, SVD &, Index, Index, RealScalar &)
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
Namespace containing all symbols from the Eigen library.
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)
JacobiRotation transpose() const
#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
Matrix< Scalar, ColsAtCompileTime, RowsAtCompileTime, TrOptions, MaxColsAtCompileTime, MaxRowsAtCompileTime > TransposeTypeWithSameStorageOrder
WorkspaceType m_workspace
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)
TransposeTypeWithSameStorageOrder m_adjoint
FullPivHouseholderQR< MatrixType > QRType
MatrixType::Scalar Scalar
Base class of SVD algorithms.
Matrix< Scalar, ColsAtCompileTime, RowsAtCompileTime, TrOptions, MaxColsAtCompileTime, MaxRowsAtCompileTime > TransposeTypeWithSameStorageOrder
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
JacobiRotation adjoint() const
EIGEN_DEVICE_FUNC const Scalar & q
HouseholderQR< MatrixType > QRType
ColPivHouseholderQR< TransposeTypeWithSameStorageOrder > QRType
internal::plain_row_type< MatrixType >::type m_workspace
FullPivHouseholderQR< TransposeTypeWithSameStorageOrder > QRType
NumTraits< Scalar >::Real RealScalar
TransposeTypeWithSameStorageOrder m_adjoint
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Abs2ReturnType abs2() const
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.
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.
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set set set set surface set nocontour set clabel set mapping cartesian set nohidden3d set cntrparam order set cntrparam linear set cntrparam levels auto set cntrparam points set size set set xzeroaxis lt lw set x2zeroaxis lt lw set yzeroaxis lt lw set y2zeroaxis lt lw set tics in set ticslevel set tics scale
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
EIGEN_DONT_INLINE void compute(Solver &solver, const MatrixType &A)
Map< Matrix< T, Dynamic, Dynamic, ColMajor >, 0, OuterStride<> > matrix(T *data, int rows, int cols, int stride)
#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
void swap(mpfr::mpreal &x, mpfr::mpreal &y)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar & coeff(Index rowId, Index colId) const
JacobiSVD(const MatrixType &matrix, unsigned int computationOptions=0)
Constructor performing the decomposition of given matrix.
JacobiSVD< PlainObject > jacobiSvd(unsigned int computationOptions=0) const
internal::plain_row_type< MatrixType >::type m_workspace
void allocate(const JacobiSVD< MatrixType, ColPivHouseholderQRPreconditioner > &svd)
void allocate(const JacobiSVD< MatrixType, FullPivHouseholderQRPreconditioner > &svd)
MatrixType::Scalar Scalar
Base::MatrixUType MatrixUType