diff options
author | Benoit Jacob <jacob.benoit.1@gmail.com> | 2010-10-19 21:56:11 -0400 |
---|---|---|
committer | Benoit Jacob <jacob.benoit.1@gmail.com> | 2010-10-19 21:56:11 -0400 |
commit | 9044c98cff257a4f7429deaa78cae59132957db7 (patch) | |
tree | 915a55a610fe4d8bbce080fc2d4a7184a221c948 | |
parent | e5073746f3686f01806d29724758c1df786013ed (diff) |
work around stupid msvc error when constructing at compile time an expression
that involves a division by zero, even if the numeric type has floating point
-rw-r--r-- | Eigen/src/SVD/JacobiSVD.h | 3 | ||||
-rw-r--r-- | test/jacobisvd.cpp | 16 |
2 files changed, 17 insertions, 2 deletions
diff --git a/Eigen/src/SVD/JacobiSVD.h b/Eigen/src/SVD/JacobiSVD.h index f3b0ccce4..44880dcf4 100644 --- a/Eigen/src/SVD/JacobiSVD.h +++ b/Eigen/src/SVD/JacobiSVD.h @@ -239,6 +239,9 @@ struct ei_qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, Precon * \a p is the greater dimension, meaning that it is still of the same order of complexity as the faster bidiagonalizing R-SVD algorithms. * In particular, like any R-SVD, it takes advantage of non-squareness in that its complexity is only linear in the greater dimension. * + * If the input matrix has inf or nan coefficients, the result of the computation is undefined, but the computation is guaranteed to + * terminate in finite (and reasonable) time. + * * The possible values for QRPreconditioner are: * \li ColPivHouseholderQRPreconditioner is the default. In practice it's very safe. It uses column-pivoting QR. * \li FullPivHouseholderQRPreconditioner, is the safest and slowest. It uses full-pivoting QR. diff --git a/test/jacobisvd.cpp b/test/jacobisvd.cpp index 212f7f1d7..79a05b368 100644 --- a/test/jacobisvd.cpp +++ b/test/jacobisvd.cpp @@ -209,18 +209,30 @@ void jacobisvd_method() VERIFY_IS_APPROX(m.jacobiSvd(ComputeFullU|ComputeFullV).solve(m), m); } +// work around stupid msvc error when constructing at compile time an expression that involves +// a division by zero, even if the numeric type has floating point +template<typename Scalar> +EIGEN_DONT_INLINE Scalar zero() { return Scalar(0); } + template<typename MatrixType> void jacobisvd_inf_nan() { + // all this function does is verify we don't iterate infinitely on nan/inf values + JacobiSVD<MatrixType> svd; typedef typename MatrixType::Scalar Scalar; - Scalar some_inf = Scalar(1) / Scalar(0); + Scalar some_inf = Scalar(1) / zero<Scalar>(); + VERIFY((some_inf - some_inf) != (some_inf - some_inf)); svd.compute(MatrixType::Constant(10,10,some_inf), ComputeFullU | ComputeFullV); - Scalar some_nan = Scalar(0) / Scalar(0); + + Scalar some_nan = zero<Scalar>() / zero<Scalar>(); + VERIFY(some_nan != some_nan); svd.compute(MatrixType::Constant(10,10,some_nan), ComputeFullU | ComputeFullV); + MatrixType m = MatrixType::Zero(10,10); m(ei_random<int>(0,9), ei_random<int>(0,9)) = some_inf; svd.compute(m, ComputeFullU | ComputeFullV); + m = MatrixType::Zero(10,10); m(ei_random<int>(0,9), ei_random<int>(0,9)) = some_nan; svd.compute(m, ComputeFullU | ComputeFullV); |