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 Options = MatrixType::Options
119 Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime
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 Options = MatrixType::Options
209 Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime
214 if (svd.
cols() != m_qr.rows() || svd.
rows() != m_qr.cols())
221 m_adjoint.resize(svd.
cols(), svd.
rows());
226 if(matrix.cols() > matrix.rows())
228 m_adjoint = matrix.adjoint();
229 m_qr.compute(m_adjoint);
231 svd.
m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).
template triangularView<Upper>().adjoint();
235 svd.
m_matrixV.setIdentity(matrix.cols(), matrix.rows());
236 m_qr.householderQ().applyThisOnTheLeft(svd.
m_matrixV, m_workspace);
253 template<
typename MatrixType>
259 if (svd.
rows() != m_qr.rows() || svd.
cols() != m_qr.cols())
270 if(matrix.rows() > matrix.cols())
272 m_qr.compute(matrix);
273 svd.
m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).
template triangularView<Upper>();
277 svd.
m_matrixU.setIdentity(matrix.rows(), matrix.cols());
278 m_qr.householderQ().applyThisOnTheLeft(svd.
m_matrixU, m_workspace);
291 template<
typename MatrixType>
298 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
299 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
300 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
301 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
302 Options = MatrixType::Options
306 Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime
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>
488 template<
typename _MatrixType,
int QRPreconditioner>
class JacobiSVD 489 :
public SVDBase<JacobiSVD<_MatrixType,QRPreconditioner> >
498 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
499 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
501 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
502 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
504 MatrixOptions = MatrixType::Options
513 typedef Matrix<
Scalar, DiagSizeAtCompileTime, DiagSizeAtCompileTime,
514 MatrixOptions, MaxDiagSizeAtCompileTime, MaxDiagSizeAtCompileTime>
534 allocate(rows, cols, computationOptions);
549 compute(matrix, computationOptions);
572 return compute(matrix, m_computationOptions);
575 using Base::computeU;
576 using Base::computeV;
585 using Base::m_matrixU;
586 using Base::m_matrixV;
587 using Base::m_singularValues;
589 using Base::m_isInitialized;
590 using Base::m_isAllocated;
591 using Base::m_usePrescribedThreshold;
592 using Base::m_computeFullU;
593 using Base::m_computeThinU;
594 using Base::m_computeFullV;
595 using Base::m_computeThinV;
596 using Base::m_computationOptions;
597 using Base::m_nonzeroSingularValues;
600 using Base::m_diagSize;
601 using Base::m_prescribedThreshold;
604 template<
typename __MatrixType,
int _QRPreconditioner,
bool _IsComplex>
606 template<
typename __MatrixType,
int _QRPreconditioner,
int _Case,
bool _DoAnything>
614 template<
typename MatrixType,
int QRPreconditioner>
622 computationOptions == m_computationOptions)
630 m_isInitialized =
false;
631 m_isAllocated =
true;
632 m_computationOptions = computationOptions;
633 m_computeFullU = (computationOptions &
ComputeFullU) != 0;
634 m_computeThinU = (computationOptions &
ComputeThinU) != 0;
635 m_computeFullV = (computationOptions &
ComputeFullV) != 0;
636 m_computeThinV = (computationOptions &
ComputeThinV) != 0;
637 eigen_assert(!(m_computeFullU && m_computeThinU) &&
"JacobiSVD: you can't ask for both full and thin U");
638 eigen_assert(!(m_computeFullV && m_computeThinV) &&
"JacobiSVD: you can't ask for both full and thin V");
640 "JacobiSVD: thin U and V are only available when your matrix has a dynamic number of columns.");
644 "JacobiSVD: can't compute thin U or thin V with the FullPivHouseholderQR preconditioner. " 645 "Use the ColPivHouseholderQR preconditioner instead.");
647 m_diagSize = (
std::min)(m_rows, m_cols);
648 m_singularValues.resize(m_diagSize);
650 m_matrixU.resize(m_rows, m_computeFullU ? m_rows
651 : m_computeThinU ? m_diagSize
654 m_matrixV.resize(m_cols, m_computeFullV ? m_cols
655 : m_computeThinV ? m_diagSize
657 m_workMatrix.resize(m_diagSize, m_diagSize);
659 if(m_cols>m_rows) m_qr_precond_morecols.allocate(*
this);
660 if(m_rows>m_cols) m_qr_precond_morerows.allocate(*
this);
661 if(m_rows!=m_cols) m_scaledMatrix.resize(rows,cols);
664 template<
typename MatrixType,
int QRPreconditioner>
669 allocate(matrix.rows(), matrix.cols(), computationOptions);
679 RealScalar scale = matrix.cwiseAbs().template maxCoeff<PropagateNaN>();
681 m_isInitialized =
true;
691 m_scaledMatrix = matrix /
scale;
692 m_qr_precond_morecols.run(*
this, m_scaledMatrix);
693 m_qr_precond_morerows.run(*
this, m_scaledMatrix);
697 m_workMatrix = matrix.block(0,0,m_diagSize,m_diagSize) /
scale;
698 if(m_computeFullU) m_matrixU.setIdentity(m_rows,m_rows);
699 if(m_computeThinU) m_matrixU.setIdentity(m_rows,m_diagSize);
700 if(m_computeFullV) m_matrixV.setIdentity(m_cols,m_cols);
701 if(m_computeThinV) m_matrixV.setIdentity(m_cols, m_diagSize);
705 RealScalar maxDiagEntry = m_workMatrix.cwiseAbs().diagonal().maxCoeff();
707 bool finished =
false;
714 for(
Index p = 1;
p < m_diagSize; ++
p)
721 RealScalar threshold = numext::maxi<RealScalar>(considerAsZero, precision * maxDiagEntry);
722 if(
abs(m_workMatrix.coeff(p,
q))>threshold ||
abs(m_workMatrix.coeff(
q,p)) > threshold)
733 m_workMatrix.applyOnTheLeft(p,
q,j_left);
734 if(computeU()) m_matrixU.applyOnTheRight(p,
q,j_left.
transpose());
736 m_workMatrix.applyOnTheRight(p,
q,j_right);
737 if(computeV()) m_matrixV.applyOnTheRight(p,
q,j_right);
740 maxDiagEntry = numext::maxi<RealScalar>(maxDiagEntry,numext::maxi<RealScalar>(
abs(m_workMatrix.coeff(p,p)),
abs(m_workMatrix.coeff(
q,
q))));
749 for(
Index i = 0;
i < m_diagSize; ++
i)
757 m_singularValues.coeffRef(
i) =
abs(a);
758 if(computeU()) m_matrixU.col(
i) *= m_workMatrix.coeff(
i,
i)/
a;
764 m_singularValues.coeffRef(
i) =
abs(a);
765 if(computeU() && (a<
RealScalar(0))) m_matrixU.col(
i) = -m_matrixU.col(
i);
769 m_singularValues *=
scale;
773 m_nonzeroSingularValues = m_diagSize;
774 for(
Index i = 0;
i < m_diagSize;
i++)
777 RealScalar maxRemainingSingularValue = m_singularValues.tail(m_diagSize-
i).maxCoeff(&pos);
778 if(maxRemainingSingularValue ==
RealScalar(0))
780 m_nonzeroSingularValues =
i;
786 std::swap(m_singularValues.coeffRef(
i), m_singularValues.coeffRef(pos));
787 if(computeU()) m_matrixU.col(pos).swap(m_matrixU.col(
i));
788 if(computeV()) m_matrixV.col(pos).swap(m_matrixV.col(
i));
792 m_isInitialized =
true;
803 template<
typename Derived>
812 #endif // EIGEN_JACOBISVD_H Matrix< Scalar, DiagSizeAtCompileTime, DiagSizeAtCompileTime, MatrixOptions, MaxDiagSizeAtCompileTime, MaxDiagSizeAtCompileTime > WorkMatrixType
internal::make_proper_matrix_type< Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime >::type TransposeTypeWithSameStorageOrder
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 &)
void allocate(const JacobiSVD< MatrixType, QRPreconditioner > &)
MatrixType::RealScalar RealScalar
EIGEN_DEVICE_FUNC Scalar & c()
SVDBase< JacobiSVD > Base
internal::plain_col_type< MatrixType >::type m_workspace
void allocate(const JacobiSVD< MatrixType, HouseholderQRPreconditioner > &svd)
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)
internal::make_proper_matrix_type< Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime >::type TransposeTypeWithSameStorageOrder
Eigen::Index Index
The interface type of indices.
#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
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)
internal::make_proper_matrix_type< Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime >::type TransposeTypeWithSameStorageOrder
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.
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool() isfinite(const Eigen::bfloat16 &h)
internal::qr_preconditioner_impl< MatrixType, QRPreconditioner, internal::PreconditionIfMoreColsThanRows > m_qr_precond_morecols
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
void swap(GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &a, GeographicLib::NearestNeighbor< dist_t, pos_t, distfun_t > &b)
EIGEN_DEVICE_FUNC JacobiRotation adjoint() 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
EIGEN_DEVICE_FUNC Scalar & s()
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.
EIGEN_DEVICE_FUNC JacobiRotation transpose() const
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
Jet< T, N > sqrt(const Jet< T, N > &f)
internal::qr_preconditioner_impl< MatrixType, QRPreconditioner, internal::PreconditionIfMoreRowsThanCols > m_qr_precond_morerows
Generic expression where a coefficient-wise unary operator is applied to an expression.
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.
EIGEN_DEVICE_FUNC bool abs2(bool x)
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.
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