diff options
Diffstat (limited to 'test/stable_norm.cpp')
-rw-r--r-- | test/stable_norm.cpp | 59 |
1 files changed, 56 insertions, 3 deletions
diff --git a/test/stable_norm.cpp b/test/stable_norm.cpp index c3eb5ff31..cb8a80c18 100644 --- a/test/stable_norm.cpp +++ b/test/stable_norm.cpp @@ -21,7 +21,6 @@ template<typename MatrixType> void stable_norm(const MatrixType& m) */ using std::sqrt; using std::abs; - typedef typename MatrixType::Index Index; typedef typename MatrixType::Scalar Scalar; typedef typename NumTraits<Scalar>::Real RealScalar; @@ -65,6 +64,8 @@ template<typename MatrixType> void stable_norm(const MatrixType& m) factor = internal::random<Scalar>(); Scalar small = factor * ((std::numeric_limits<RealScalar>::min)() * RealScalar(1e4)); + Scalar one(1); + MatrixType vzero = MatrixType::Zero(rows, cols), vrand = MatrixType::Random(rows, cols), vbig(rows, cols), @@ -78,6 +79,14 @@ template<typename MatrixType> void stable_norm(const MatrixType& m) VERIFY_IS_APPROX(vrand.blueNorm(), vrand.norm()); VERIFY_IS_APPROX(vrand.hypotNorm(), vrand.norm()); + // test with expressions as input + VERIFY_IS_APPROX((one*vrand).stableNorm(), vrand.norm()); + VERIFY_IS_APPROX((one*vrand).blueNorm(), vrand.norm()); + VERIFY_IS_APPROX((one*vrand).hypotNorm(), vrand.norm()); + VERIFY_IS_APPROX((one*vrand+one*vrand-one*vrand).stableNorm(), vrand.norm()); + VERIFY_IS_APPROX((one*vrand+one*vrand-one*vrand).blueNorm(), vrand.norm()); + VERIFY_IS_APPROX((one*vrand+one*vrand-one*vrand).hypotNorm(), vrand.norm()); + RealScalar size = static_cast<RealScalar>(m.size()); // test numext::isfinite @@ -161,7 +170,13 @@ template<typename MatrixType> void stable_norm(const MatrixType& m) VERIFY(!(numext::isfinite)(v.norm())); VERIFY((numext::isnan)(v.norm())); VERIFY(!(numext::isfinite)(v.stableNorm())); VERIFY((numext::isnan)(v.stableNorm())); VERIFY(!(numext::isfinite)(v.blueNorm())); VERIFY((numext::isnan)(v.blueNorm())); - VERIFY(!(numext::isfinite)(v.hypotNorm())); VERIFY((numext::isnan)(v.hypotNorm())); + if (i2 != i || j2 != j) { + // hypot propagates inf over NaN. + VERIFY(!(numext::isfinite)(v.hypotNorm())); VERIFY((numext::isinf)(v.hypotNorm())); + } else { + // inf is overwritten by NaN, expect norm to be NaN. + VERIFY(!(numext::isfinite)(v.hypotNorm())); VERIFY((numext::isnan)(v.hypotNorm())); + } } // stableNormalize[d] @@ -180,13 +195,51 @@ template<typename MatrixType> void stable_norm(const MatrixType& m) } } -void test_stable_norm() +template<typename Scalar> +void test_hypot() +{ + typedef typename NumTraits<Scalar>::Real RealScalar; + Scalar factor = internal::random<Scalar>(); + while(numext::abs2(factor)<RealScalar(1e-4)) + factor = internal::random<Scalar>(); + Scalar big = factor * ((std::numeric_limits<RealScalar>::max)() * RealScalar(1e-4)); + + factor = internal::random<Scalar>(); + while(numext::abs2(factor)<RealScalar(1e-4)) + factor = internal::random<Scalar>(); + Scalar small = factor * ((std::numeric_limits<RealScalar>::min)() * RealScalar(1e4)); + + Scalar one (1), + zero (0), + sqrt2 (std::sqrt(2)), + nan (std::numeric_limits<RealScalar>::quiet_NaN()); + + Scalar a = internal::random<Scalar>(-1,1); + Scalar b = internal::random<Scalar>(-1,1); + VERIFY_IS_APPROX(numext::hypot(a,b),std::sqrt(numext::abs2(a)+numext::abs2(b))); + VERIFY_IS_EQUAL(numext::hypot(zero,zero), zero); + VERIFY_IS_APPROX(numext::hypot(one, one), sqrt2); + VERIFY_IS_APPROX(numext::hypot(big,big), sqrt2*numext::abs(big)); + VERIFY_IS_APPROX(numext::hypot(small,small), sqrt2*numext::abs(small)); + VERIFY_IS_APPROX(numext::hypot(small,big), numext::abs(big)); + VERIFY((numext::isnan)(numext::hypot(nan,a))); + VERIFY((numext::isnan)(numext::hypot(a,nan))); +} + +EIGEN_DECLARE_TEST(stable_norm) { for(int i = 0; i < g_repeat; i++) { + CALL_SUBTEST_3( test_hypot<double>() ); + CALL_SUBTEST_4( test_hypot<float>() ); + CALL_SUBTEST_5( test_hypot<std::complex<double> >() ); + CALL_SUBTEST_6( test_hypot<std::complex<float> >() ); + CALL_SUBTEST_1( stable_norm(Matrix<float, 1, 1>()) ); CALL_SUBTEST_2( stable_norm(Vector4d()) ); CALL_SUBTEST_3( stable_norm(VectorXd(internal::random<int>(10,2000))) ); + CALL_SUBTEST_3( stable_norm(MatrixXd(internal::random<int>(10,200), internal::random<int>(10,200))) ); CALL_SUBTEST_4( stable_norm(VectorXf(internal::random<int>(10,2000))) ); CALL_SUBTEST_5( stable_norm(VectorXcd(internal::random<int>(10,2000))) ); + CALL_SUBTEST_6( stable_norm(VectorXcf(internal::random<int>(10,2000))) ); } } |