30 template<
typename MatrixType>
class SVD 33 typedef typename MatrixType::Scalar
Scalar;
53 SVD(
const MatrixType& matrix)
54 :
m_matU(matrix.rows(), (
std::
min)(matrix.rows(), matrix.cols())),
55 m_matV(matrix.cols(),matrix.cols()),
61 template<
typename OtherDerived,
typename ResultType>
68 void compute(
const MatrixType& matrix);
71 template<
typename UnitaryType,
typename PositiveType>
73 template<
typename PositiveType,
typename UnitaryType>
75 template<
typename RotationType,
typename ScalingType>
77 template<
typename ScalingType,
typename RotationType>
93 template<
typename MatrixType>
96 const int m = matrix.rows();
97 const int n = matrix.cols();
98 const int nu = (std::min)(m,n);
99 ei_assert(m>=n &&
"In Eigen 2.0, SVD only works for MxN matrices with M>=N. Sorry!");
100 ei_assert(m>1 &&
"In Eigen 2.0, SVD doesn't work on 1x1 matrices");
109 MatrixType matA(matrix);
110 const bool wantu =
true;
111 const bool wantv =
true;
116 int nct = (std::min)(m-1,n);
117 int nrt = (std::max)(0,(std::min)(n-2,m));
118 for (k = 0; k < (std::max)(nct,nrt); ++k)
124 m_sigma[k] = matA.col(k).end(m-k).norm();
129 matA.col(k).end(m-k) /=
m_sigma[k];
135 for (j = k+1; j < n; ++j)
137 if ((k < nct) && (
m_sigma[k] != 0.0))
140 Scalar t = matA.col(k).end(m-k).eigen2_dot(matA.col(j).end(m-k));
142 matA.col(j).end(m-k) += t * matA.col(k).end(m-k);
151 if (wantu & (k < nct))
152 m_matU.col(k).end(m-k) = matA.col(k).end(m-k);
158 e[k] = e.end(n-k-1).norm();
163 e.end(n-k-1) /= e[k];
167 if ((k+1 < m) & (e[k] != 0.0))
170 work.end(m-k-1) = matA.corner(
BottomRight,m-k-1,n-k-1) * e.end(n-k-1);
171 for (j = k+1; j < n; ++j)
172 matA.col(j).end(m-k-1) += (-e[j]/e[k+1]) * work.end(m-k-1);
177 m_matV.col(k).end(n-k-1) = e.end(n-k-1);
183 int p = (std::min)(n,m+1);
189 e[nrt] = matA(nrt,p-1);
195 for (j = nct; j < nu; ++j)
200 for (k = nct-1; k >= 0; k--)
204 for (j = k+1; j < nu; ++j)
226 for (k = n-1; k >= 0; k--)
228 if ((k < nrt) & (e[k] != 0.0))
230 for (j = k+1; j < nu; ++j)
234 m_matV.col(j).end(n-k-1) += t *
m_matV.col(k).end(n-k-1);
263 for (k = p-2; k >= -1; --k)
280 for (ks = p-1; ks >= k; --ks)
316 for (j = p-2; j >= k; --j)
329 for (i = 0; i < n; ++i)
345 for (j = k; j < p; ++j)
355 for (i = 0; i < m; ++i)
370 Scalar scale = (std::max)((std::max)((std::max)((std::max)(
375 Scalar epm1 = e[p-2]/scale;
378 Scalar b = ((spm1 + sp)*(spm1 - sp) + epm1*epm1)/
Scalar(2);
379 Scalar c = (sp*epm1)*(sp*epm1);
381 if ((b != 0.0) || (c != 0.0))
386 shift = c/(b + shift);
388 Scalar f = (sk + sp)*(sk - sp) + shift;
393 for (j = k; j < p-1; ++j)
395 Scalar t = numext::hypot(f,g);
401 e[j] = cs*e[j] - sn*
m_sigma[j];
403 m_sigma[j+1] = cs*m_sigma[j+1];
406 for (i = 0; i < n; ++i)
413 t = numext::hypot(f,g);
417 f = cs*e[j] + sn*m_sigma[j+1];
418 m_sigma[j+1] = -sn*e[j] + cs*m_sigma[j+1];
421 if (wantu && (j < m-1))
423 for (i = 0; i < m; ++i)
455 if (wantv && (k < n-1))
457 if (wantu && (k < m-1))
469 template<
typename MatrixType>
476 for (
int i=0; i<n; ++i)
481 for (
int j=i+1; j<n; ++j)
495 for(
int s=0; j!=0; ++
s, --j)
499 for (
int s=0; j!=0; ++
s, --j)
511 template<
typename MatrixType>
512 template<
typename OtherDerived,
typename ResultType>
519 for (
int j=0; j<b.cols(); ++j)
532 result->col(j) =
m_matV * aux;
545 template<
typename MatrixType>
546 template<
typename UnitaryType,
typename PositiveType>
548 PositiveType *positive)
const 563 template<
typename MatrixType>
564 template<
typename UnitaryType,
typename PositiveType>
566 PositiveType *unitary)
const 582 template<
typename MatrixType>
583 template<
typename RotationType,
typename ScalingType>
590 if(scaling) scaling->lazyAssign(
m_matV * sv.asDiagonal() *
m_matV.adjoint());
595 rotation->lazyAssign(m *
m_matV.adjoint());
608 template<
typename MatrixType>
609 template<
typename ScalingType,
typename RotationType>
616 if(scaling) scaling->lazyAssign(
m_matU * sv.asDiagonal() *
m_matU.adjoint());
621 rotation->lazyAssign(m *
m_matV.adjoint());
629 template<
typename Derived>
638 #endif // EIGEN2_SVD_H
const MatrixVType & matrixV() const
void swap(MatrixBase< OtherDerived > const &other)
Matrix< Scalar, MatrixType::RowsAtCompileTime, 1 > ColVector
bool solve(const MatrixBase< OtherDerived > &b, ResultType *result) const
Matrix< Scalar, MatrixType::ColsAtCompileTime, 1 > RowVector
SingularValuesType m_sigma
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
SVD(const MatrixType &matrix)
void computeUnitaryPositive(UnitaryType *unitary, PositiveType *positive) const
EIGEN_STRONG_INLINE Index rows() const
void compute(const MatrixType &matrix)
T ei_pow(const T &x, const T &y)
EIGEN_STRONG_INLINE const Scalar & coeff(Index rowId, Index colId) const
void computePositiveUnitary(PositiveType *positive, UnitaryType *unitary) const
bool ei_isMuchSmallerThan(const Scalar &x, const OtherScalar &y, typename NumTraits< Scalar >::Real precision=NumTraits< Scalar >::dummy_precision())
EIGEN_STRONG_INLINE Scalar & coeffRef(Index rowId, Index colId)
EIGEN_STRONG_INLINE void resize(Index nbRows, Index nbCols)
Standard SVD decomposition of a matrix and associated features.
Matrix< Scalar, MatrixType::ColsAtCompileTime, MatrixType::ColsAtCompileTime > MatrixVType
TFSIMD_FORCE_INLINE const tfScalar & x() const
Derived & setZero(Index size)
const SingularValuesType & singularValues() const
void computeScalingRotation(ScalingType *positive, RotationType *unitary) const
NumTraits< T >::Real ei_abs(const T &x)
MatrixType::Scalar Scalar
NumTraits< typename MatrixType::Scalar >::Real RealScalar
#define EIGEN_SIZE_MIN_PREFER_DYNAMIC(a, b)
Matrix< Scalar, MatrixType::RowsAtCompileTime, MinSize > MatrixUType
Matrix< Scalar, MinSize, 1 > SingularValuesType
const MatrixUType & matrixU() const
The matrix class, also used for vectors and row-vectors.
EIGEN_STRONG_INLINE Index cols() const
Base class for all dense matrices, vectors, and expressions.
void computeRotationScaling(RotationType *unitary, ScalingType *positive) const