11 #ifndef EIGEN_JACOBISVD_H 12 #define EIGEN_JACOBISVD_H 19 template<
typename MatrixType,
int QRPreconditioner,
20 bool IsComplex = NumTraits<typename MatrixType::Scalar>::IsComplex>
21 struct svd_precondition_2x2_block_to_be_real {};
30 enum { PreconditionIfMoreColsThanRows, PreconditionIfMoreRowsThanCols };
32 template<
typename MatrixType,
int QRPreconditioner,
int Case>
33 struct qr_preconditioner_should_do_anything
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,
42 (Case == PreconditionIfMoreColsThanRows &&
bool(a)) ||
43 (Case == PreconditionIfMoreRowsThanCols &&
bool(b)) )
47 template<
typename MatrixType,
int QRPreconditioner,
int Case,
48 bool DoAnything = qr_preconditioner_should_do_anything<MatrixType, QRPreconditioner, Case>::ret
49 >
struct qr_preconditioner_impl {};
51 template<
typename MatrixType,
int QRPreconditioner,
int Case>
52 class qr_preconditioner_impl<MatrixType, QRPreconditioner, Case, false>
55 void allocate(
const JacobiSVD<MatrixType, QRPreconditioner>&) {}
56 bool run(JacobiSVD<MatrixType, QRPreconditioner>&,
const MatrixType&)
64 template<
typename MatrixType>
68 typedef typename MatrixType::Scalar Scalar;
71 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
72 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime
74 typedef Matrix<Scalar, 1, RowsAtCompileTime, RowMajor, 1, MaxRowsAtCompileTime> WorkspaceType;
76 void allocate(
const JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd)
78 if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols())
81 ::new (&m_qr) QRType(svd.rows(), svd.cols());
83 if (svd.m_computeFullU) m_workspace.resize(svd.rows());
86 bool run(JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd,
const MatrixType& matrix)
88 if(matrix.rows() > matrix.cols())
91 svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).
template triangularView<Upper>();
92 if(svd.m_computeFullU) m_qr.matrixQ().evalTo(svd.m_matrixU, m_workspace);
93 if(svd.computeV()) svd.m_matrixV = m_qr.colsPermutation();
99 typedef FullPivHouseholderQR<MatrixType> QRType;
101 WorkspaceType m_workspace;
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
118 typedef typename internal::make_proper_matrix_type<
119 Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime
120 >::type TransposeTypeWithSameStorageOrder;
122 void allocate(
const JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd)
124 if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols())
127 ::new (&m_qr) QRType(svd.cols(), svd.rows());
129 m_adjoint.resize(svd.cols(), svd.rows());
130 if (svd.m_computeFullV) m_workspace.resize(svd.cols());
133 bool run(JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd,
const MatrixType& matrix)
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();
140 if(svd.m_computeFullV) m_qr.matrixQ().evalTo(svd.m_matrixV, m_workspace);
141 if(svd.computeU()) svd.m_matrixU = m_qr.colsPermutation();
147 typedef FullPivHouseholderQR<TransposeTypeWithSameStorageOrder> QRType;
149 TransposeTypeWithSameStorageOrder m_adjoint;
150 typename internal::plain_row_type<MatrixType>::type m_workspace;
155 template<
typename MatrixType>
159 void allocate(
const JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd)
161 if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols())
164 ::new (&m_qr) QRType(svd.rows(), svd.cols());
166 if (svd.m_computeFullU) m_workspace.resize(svd.rows());
167 else if (svd.m_computeThinU) m_workspace.resize(svd.cols());
170 bool run(JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd,
const MatrixType& matrix)
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>();
176 if(svd.m_computeFullU) m_qr.householderQ().evalTo(svd.m_matrixU, m_workspace);
177 else if(svd.m_computeThinU)
179 svd.m_matrixU.setIdentity(matrix.rows(), matrix.cols());
180 m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixU, m_workspace);
182 if(svd.computeV()) svd.m_matrixV = m_qr.colsPermutation();
189 typedef ColPivHouseholderQR<MatrixType> QRType;
191 typename internal::plain_col_type<MatrixType>::type m_workspace;
194 template<
typename MatrixType>
198 typedef typename MatrixType::Scalar Scalar;
201 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
202 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
203 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
204 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
205 Options = MatrixType::Options
208 typedef typename internal::make_proper_matrix_type<
209 Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime
210 >::type TransposeTypeWithSameStorageOrder;
212 void allocate(
const JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd)
214 if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols())
217 ::new (&m_qr) QRType(svd.cols(), svd.rows());
219 if (svd.m_computeFullV) m_workspace.resize(svd.cols());
220 else if (svd.m_computeThinV) m_workspace.resize(svd.rows());
221 m_adjoint.resize(svd.cols(), svd.rows());
224 bool run(JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd,
const MatrixType& matrix)
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();
232 if(svd.m_computeFullV) m_qr.householderQ().evalTo(svd.m_matrixV, m_workspace);
233 else if(svd.m_computeThinV)
235 svd.m_matrixV.setIdentity(matrix.cols(), matrix.rows());
236 m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixV, m_workspace);
238 if(svd.computeU()) svd.m_matrixU = m_qr.colsPermutation();
245 typedef ColPivHouseholderQR<TransposeTypeWithSameStorageOrder> QRType;
247 TransposeTypeWithSameStorageOrder m_adjoint;
248 typename internal::plain_row_type<MatrixType>::type m_workspace;
253 template<
typename MatrixType>
257 void allocate(
const JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd)
259 if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols())
262 ::new (&m_qr) QRType(svd.rows(), svd.cols());
264 if (svd.m_computeFullU) m_workspace.resize(svd.rows());
265 else if (svd.m_computeThinU) m_workspace.resize(svd.cols());
268 bool run(JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd,
const MatrixType& matrix)
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>();
274 if(svd.m_computeFullU) m_qr.householderQ().evalTo(svd.m_matrixU, m_workspace);
275 else if(svd.m_computeThinU)
277 svd.m_matrixU.setIdentity(matrix.rows(), matrix.cols());
278 m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixU, m_workspace);
280 if(svd.computeV()) svd.m_matrixV.setIdentity(matrix.cols(), matrix.cols());
286 typedef HouseholderQR<MatrixType> QRType;
288 typename internal::plain_col_type<MatrixType>::type m_workspace;
291 template<
typename MatrixType>
295 typedef typename MatrixType::Scalar Scalar;
298 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
299 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
300 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
301 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
302 Options = MatrixType::Options
305 typedef typename internal::make_proper_matrix_type<
306 Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime
307 >::type TransposeTypeWithSameStorageOrder;
309 void allocate(
const JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd)
311 if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols())
314 ::new (&m_qr) QRType(svd.cols(), svd.rows());
316 if (svd.m_computeFullV) m_workspace.resize(svd.cols());
317 else if (svd.m_computeThinV) m_workspace.resize(svd.rows());
318 m_adjoint.resize(svd.cols(), svd.rows());
321 bool run(JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd,
const MatrixType& matrix)
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();
329 if(svd.m_computeFullV) m_qr.householderQ().evalTo(svd.m_matrixV, m_workspace);
330 else if(svd.m_computeThinV)
332 svd.m_matrixV.setIdentity(matrix.cols(), matrix.rows());
333 m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixV, m_workspace);
335 if(svd.computeU()) svd.m_matrixU.setIdentity(matrix.rows(), matrix.rows());
342 typedef HouseholderQR<TransposeTypeWithSameStorageOrder> QRType;
344 TransposeTypeWithSameStorageOrder m_adjoint;
345 typename internal::plain_row_type<MatrixType>::type m_workspace;
353 template<
typename MatrixType,
int QRPreconditioner>
354 struct svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, false>
356 typedef JacobiSVD<MatrixType, QRPreconditioner> SVD;
357 typedef typename MatrixType::RealScalar RealScalar;
358 static bool run(
typename SVD::WorkMatrixType&, SVD&,
Index,
Index, RealScalar&) {
return true; }
361 template<
typename MatrixType,
int QRPreconditioner>
362 struct svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, true>
364 typedef JacobiSVD<MatrixType, QRPreconditioner> SVD;
365 typedef typename MatrixType::Scalar Scalar;
366 typedef typename MatrixType::RealScalar RealScalar;
367 static bool run(
typename SVD::WorkMatrixType& work_matrix, SVD& svd,
Index p,
Index q, RealScalar& maxDiagEntry)
372 JacobiRotation<Scalar> rot;
373 RealScalar n =
sqrt(numext::abs2(work_matrix.coeff(p,p)) + numext::abs2(work_matrix.coeff(q,p)));
375 const RealScalar considerAsZero = (std::numeric_limits<RealScalar>::min)();
376 const RealScalar precision = NumTraits<Scalar>::epsilon();
381 work_matrix.coeffRef(p,p) = work_matrix.coeffRef(q,p) = Scalar(0);
383 if(
abs(numext::imag(work_matrix.coeff(p,q)))>considerAsZero)
386 z =
abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);
387 work_matrix.row(p) *= z;
388 if(svd.computeU()) svd.m_matrixU.col(p) *=
conj(z);
390 if(
abs(numext::imag(work_matrix.coeff(q,q)))>considerAsZero)
392 z =
abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q);
393 work_matrix.row(q) *= z;
394 if(svd.computeU()) svd.m_matrixU.col(q) *=
conj(z);
400 rot.c() =
conj(work_matrix.coeff(p,p)) / n;
401 rot.s() = work_matrix.coeff(q,p) / n;
402 work_matrix.applyOnTheLeft(p,q,rot);
403 if(svd.computeU()) svd.m_matrixU.applyOnTheRight(p,q,rot.adjoint());
404 if(
abs(numext::imag(work_matrix.coeff(p,q)))>considerAsZero)
406 z =
abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);
407 work_matrix.col(q) *= z;
408 if(svd.computeV()) svd.m_matrixV.col(q) *= z;
410 if(
abs(numext::imag(work_matrix.coeff(q,q)))>considerAsZero)
412 z =
abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q);
413 work_matrix.row(q) *= z;
414 if(svd.computeU()) svd.m_matrixU.col(q) *=
conj(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>
427 struct traits<JacobiSVD<_MatrixType,QRPreconditioner> >
428 : traits<_MatrixType>
430 typedef _MatrixType MatrixType;
488 template<
typename _MatrixType,
int QRPreconditioner>
class JacobiSVD 489 :
public SVDBase<JacobiSVD<_MatrixType,QRPreconditioner> >
494 typedef _MatrixType MatrixType;
495 typedef typename MatrixType::Scalar Scalar;
498 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
499 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
500 DiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime),
501 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
502 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
503 MaxDiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(MaxRowsAtCompileTime,MaxColsAtCompileTime),
504 MatrixOptions = MatrixType::Options
509 typedef typename Base::SingularValuesType SingularValuesType;
511 typedef typename internal::plain_row_type<MatrixType>::type RowType;
512 typedef typename internal::plain_col_type<MatrixType>::type ColType;
513 typedef Matrix<Scalar, DiagSizeAtCompileTime, DiagSizeAtCompileTime,
514 MatrixOptions, MaxDiagSizeAtCompileTime, MaxDiagSizeAtCompileTime>
534 allocate(rows, cols, computationOptions);
547 explicit JacobiSVD(
const MatrixType& matrix,
unsigned int computationOptions = 0)
549 compute(matrix, computationOptions);
562 JacobiSVD& compute(
const MatrixType& matrix,
unsigned int computationOptions);
572 return compute(matrix, m_computationOptions);
575 using Base::computeU;
576 using Base::computeV;
582 void allocate(
Index rows,
Index cols,
unsigned int computationOptions);
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;
602 WorkMatrixType m_workMatrix;
604 template<
typename __MatrixType,
int _QRPreconditioner,
bool _IsComplex>
605 friend struct internal::svd_precondition_2x2_block_to_be_real;
606 template<
typename __MatrixType,
int _QRPreconditioner,
int _Case,
bool _DoAnything>
607 friend struct internal::qr_preconditioner_impl;
609 internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreColsThanRows> m_qr_precond_morecols;
610 internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreRowsThanCols> m_qr_precond_morerows;
611 MatrixType m_scaledMatrix;
614 template<
typename MatrixType,
int QRPreconditioner>
617 eigen_assert(rows >= 0 && cols >= 0);
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");
639 eigen_assert(EIGEN_IMPLIES(m_computeThinU || m_computeThinV, MatrixType::ColsAtCompileTime==
Dynamic) &&
640 "JacobiSVD: thin U and V are only available when your matrix has a dynamic number of columns.");
643 eigen_assert(!(m_computeThinU || m_computeThinV) &&
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);
676 const RealScalar considerAsZero = (std::numeric_limits<RealScalar>::min)();
679 RealScalar scale = matrix.cwiseAbs().template maxCoeff<PropagateNaN>();
680 if (!(numext::isfinite)(scale)) {
681 m_isInitialized =
true;
685 if(scale==RealScalar(0)) scale = RealScalar(1);
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)
716 for(
Index q = 0; q < p; ++q)
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)
727 if(internal::svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner>::run(m_workMatrix, *
this, p, q, maxDiagEntry))
730 internal::real_2x2_jacobi_svd(m_workMatrix, p, q, &j_left, &j_right);
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)
756 RealScalar a =
abs(m_workMatrix.coeff(i,i));
757 m_singularValues.coeffRef(i) =
abs(a);
758 if(computeU()) m_matrixU.col(i) *= m_workMatrix.coeff(i,i)/a;
763 RealScalar a = numext::real(m_workMatrix.coeff(i,i));
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 Definition: Constants.h:393
Definition: Constants.h:425
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sqrt_op< typename Derived::Scalar >, const Derived > sqrt(const Eigen::ArrayBase< Derived > &x)
Definition: Constants.h:399
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_conjugate_op< typename Derived::Scalar >, const Derived > conj(const Eigen::ArrayBase< Derived > &x)
Namespace containing all symbols from the Eigen library.
Definition: Core:141
Rotation given by a cosine-sine pair.
Definition: Jacobi.h:34
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
Definition: NumTraits.h:232
Definition: Constants.h:427
Definition: Constants.h:429
Base class of SVD algorithms.
Definition: SVDBase.h:62
JacobiSVD< PlainObject > jacobiSvd(unsigned int computationOptions=0) const
Definition: JacobiSVD.h:805
JacobiSVD()
Default Constructor.
Definition: JacobiSVD.h:522
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:74
Definition: Constants.h:431
Definition: Constants.h:449
Definition: Constants.h:442
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)
Definition: Eigen_Colamd.h:50
JacobiSVD & compute(const MatrixType &matrix)
Method performing the decomposition of given matrix using current options.
Definition: JacobiSVD.h:570
Two-sided Jacobi SVD decomposition of a rectangular matrix.
Definition: JacobiSVD.h:488
JacobiRotation transpose() const
Definition: Jacobi.h:63
JacobiSVD & compute(const MatrixType &matrix, unsigned int computationOptions)
Method performing the decomposition of given matrix using custom options.
Definition: JacobiSVD.h:666
const int Dynamic
Definition: Constants.h:22
Definition: Constants.h:397
Definition: Constants.h:395
JacobiSVD(Index rows, Index cols, unsigned int computationOptions=0)
Default Constructor with memory preallocation.
Definition: JacobiSVD.h:532
JacobiSVD(const MatrixType &matrix, unsigned int computationOptions=0)
Constructor performing the decomposition of given matrix.
Definition: JacobiSVD.h:547