aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/SVD
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2014-09-14 17:34:54 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2014-09-14 17:34:54 +0200
commit749b56f6af4f712ccc4235a4faf7c13e09b9f3a3 (patch)
treebf77d6d609fee4e8dcf3b354582906502a4b1b90 /Eigen/src/SVD
parentaf9c9f7706bb7701a7224827e981ecc2f3bd9ac7 (diff)
parent9452eb38f812194a676edc1b9eb9d08b7bc0f297 (diff)
merge with default branch
Diffstat (limited to 'Eigen/src/SVD')
-rw-r--r--Eigen/src/SVD/JacobiSVD.h20
-rw-r--r--Eigen/src/SVD/UpperBidiagonalization.h29
2 files changed, 33 insertions, 16 deletions
diff --git a/Eigen/src/SVD/JacobiSVD.h b/Eigen/src/SVD/JacobiSVD.h
index 2b9d03c2b..f2a72faa3 100644
--- a/Eigen/src/SVD/JacobiSVD.h
+++ b/Eigen/src/SVD/JacobiSVD.h
@@ -425,18 +425,19 @@ void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q,
JacobiRotation<RealScalar> rot1;
RealScalar t = m.coeff(0,0) + m.coeff(1,1);
RealScalar d = m.coeff(1,0) - m.coeff(0,1);
- if(t == RealScalar(0))
+
+ if(d == RealScalar(0))
{
- rot1.c() = RealScalar(0);
- rot1.s() = d > RealScalar(0) ? RealScalar(1) : RealScalar(-1);
+ rot1.s() = RealScalar(0);
+ rot1.c() = RealScalar(1);
}
else
{
- RealScalar t2d2 = numext::hypot(t,d);
- rot1.c() = abs(t)/t2d2;
- rot1.s() = d/t2d2;
- if(t<RealScalar(0))
- rot1.s() = -rot1.s();
+ // If d!=0, then t/d cannot overflow because the magnitude of the
+ // entries forming d are not too small compared to the ones forming t.
+ RealScalar u = t / d;
+ rot1.s() = RealScalar(1) / sqrt(RealScalar(1) + numext::abs2(u));
+ rot1.c() = rot1.s() * u;
}
m.applyOnTheLeft(0,1,rot1);
j_right->makeJacobi(m,0,1);
@@ -726,7 +727,8 @@ JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsig
EIGEN_USING_STD_MATH(max);
RealScalar threshold = (max)(considerAsZero, precision * (max)(abs(m_workMatrix.coeff(p,p)),
abs(m_workMatrix.coeff(q,q))));
- if((max)(abs(m_workMatrix.coeff(p,q)),abs(m_workMatrix.coeff(q,p))) > threshold)
+ // We compare both values to threshold instead of calling max to be robust to NaN (See bug 791)
+ if(abs(m_workMatrix.coeff(p,q))>threshold || abs(m_workMatrix.coeff(q,p)) > threshold)
{
finished = false;
diff --git a/Eigen/src/SVD/UpperBidiagonalization.h b/Eigen/src/SVD/UpperBidiagonalization.h
index 0e081254d..40b1237a0 100644
--- a/Eigen/src/SVD/UpperBidiagonalization.h
+++ b/Eigen/src/SVD/UpperBidiagonalization.h
@@ -154,14 +154,19 @@ void upperbidiagonalization_blocked_helper(MatrixType& A,
typename MatrixType::RealScalar *diagonal,
typename MatrixType::RealScalar *upper_diagonal,
typename MatrixType::Index bs,
- Ref<Matrix<typename MatrixType::Scalar, Dynamic, Dynamic> > X,
- Ref<Matrix<typename MatrixType::Scalar, Dynamic, Dynamic> > Y)
+ Ref<Matrix<typename MatrixType::Scalar, Dynamic, Dynamic,
+ traits<MatrixType>::Flags & RowMajorBit> > X,
+ Ref<Matrix<typename MatrixType::Scalar, Dynamic, Dynamic,
+ traits<MatrixType>::Flags & RowMajorBit> > Y)
{
typedef typename MatrixType::Index Index;
typedef typename MatrixType::Scalar Scalar;
- typedef Ref<Matrix<Scalar, Dynamic, 1> > SubColumnType;
- typedef Ref<Matrix<Scalar, 1, Dynamic>, 0, InnerStride<> > SubRowType;
- typedef Ref<Matrix<Scalar, Dynamic, Dynamic> > SubMatType;
+ enum { StorageOrder = traits<MatrixType>::Flags & RowMajorBit };
+ typedef InnerStride<int(StorageOrder) == int(ColMajor) ? 1 : Dynamic> ColInnerStride;
+ typedef InnerStride<int(StorageOrder) == int(ColMajor) ? Dynamic : 1> RowInnerStride;
+ typedef Ref<Matrix<Scalar, Dynamic, 1>, 0, ColInnerStride> SubColumnType;
+ typedef Ref<Matrix<Scalar, 1, Dynamic>, 0, RowInnerStride> SubRowType;
+ typedef Ref<Matrix<Scalar, Dynamic, Dynamic, StorageOrder > > SubMatType;
Index brows = A.rows();
Index bcols = A.cols();
@@ -288,8 +293,18 @@ void upperbidiagonalization_inplace_blocked(MatrixType& A, BidiagType& bidiagona
Index cols = A.cols();
Index size = (std::min)(rows, cols);
- Matrix<Scalar,MatrixType::RowsAtCompileTime,Dynamic,ColMajor,MatrixType::MaxRowsAtCompileTime> X(rows,maxBlockSize);
- Matrix<Scalar,MatrixType::ColsAtCompileTime,Dynamic,ColMajor,MatrixType::MaxColsAtCompileTime> Y(cols,maxBlockSize);
+ // X and Y are work space
+ enum { StorageOrder = traits<MatrixType>::Flags & RowMajorBit };
+ Matrix<Scalar,
+ MatrixType::RowsAtCompileTime,
+ Dynamic,
+ StorageOrder,
+ MatrixType::MaxRowsAtCompileTime> X(rows,maxBlockSize);
+ Matrix<Scalar,
+ MatrixType::ColsAtCompileTime,
+ Dynamic,
+ StorageOrder,
+ MatrixType::MaxColsAtCompileTime> Y(cols,maxBlockSize);
Index blockSize = (std::min)(maxBlockSize,size);
Index k = 0;