diff --git a/tvmet-1.7.1/include/tvmet/Traits.h b/tvmet-1.7.1/include/tvmet/Traits.h index 10d016185..ceb4f03eb 100644 --- a/tvmet-1.7.1/include/tvmet/Traits.h +++ b/tvmet-1.7.1/include/tvmet/Traits.h @@ -56,6 +56,7 @@ struct Traits : public TraitsBase using Base::imag; using Base::conj; using Base::sqrt; + using Base::isLessThan_nonfuzzy; static value_type random() { @@ -74,7 +75,7 @@ struct Traits : public TraitsBase if(isFloat()) return(abs(a) <= abs(b) * epsilon()); else - return(a==0); + return(a==static_cast(0)); } /** @@ -105,13 +106,12 @@ struct Traits : public TraitsBase * * Full story: returns a <= b || isApprox(a, b); */ - static bool isLessThan( argument_type a, argument_type b ) + static bool isLessThan(argument_type a, argument_type b) { - assert(!isComplex()); if(isFloat()) - return(a <= b || isApprox(a, b)); + return(isLessThan_nonfuzzy(a,b) || isApprox(a, b)); else - return(a<=b); + return(isLessThan_nonfuzzy(a,b)); } }; diff --git a/tvmet-1.7.1/testsuite/main.h b/tvmet-1.7.1/testsuite/main.h index 33896662a..1ba78cd35 100644 --- a/tvmet-1.7.1/testsuite/main.h +++ b/tvmet-1.7.1/testsuite/main.h @@ -23,6 +23,8 @@ #include #include +#define EIGEN_USE_COMPLEX + #ifdef EIGEN_USE_COMPLEX #include #endif diff --git a/tvmet-1.7.1/testsuite/testtraits.cpp b/tvmet-1.7.1/testsuite/testtraits.cpp index dd7fb7bee..1a533e65b 100644 --- a/tvmet-1.7.1/testsuite/testtraits.cpp +++ b/tvmet-1.7.1/testsuite/testtraits.cpp @@ -25,12 +25,26 @@ template struct TestTraits { - void real() + void real_imag_conj_abs() { T x = Traits::random(); - typedef typename Traits::real_type real_type; - real_type r = Traits::real(x); - TEST_APPROX(r, x); + typedef typename Traits::real_type real; + real r = Traits::real(x); + real i = Traits::imag(x); + T c = Traits::conj(x); + real a = Traits::abs(x); + + // a must be real + TEST_APPROX(a, Traits::real(a)); + TEST_APPROX(a, Traits::real(a)); + TEST_ZERO(Traits::imag(a)); + TEST_ZERO(Traits::imag(a)); + + // check Pythagora's formula + if(Traits::isFloat() || !Traits::isComplex()) TEST_APPROX(r*r + i*i, a*a); + + // check complex conjugation + TEST_APPROX(-i, Traits::imag(c)); } void imag() @@ -60,20 +74,18 @@ template struct TestTraits void sqrt() { + // only test compilation here T x = Traits::random(); - T a = Traits::abs(x); - T b = Traits::sqrt(a); - // T could be an integer type, so b*b=a is not necessarily true - TEST_LESSTHAN(b*b, a); - TEST_LESSTHAN(a, (b+1)*(b+1)); + Traits::sqrt(x); } void isApprox() { T x = Traits::random(); + T e = T(Traits::epsilon()) / T(10); TEST(Traits::isApprox(x,x)); - TEST(Traits::isApprox(x,x+Traits::epsilon()/10)); - TEST(!Traits::isApprox(x,x+1)); + TEST(Traits::isApprox(x,x+e)); + TEST(!Traits::isApprox(x,x+T(1))); } void isNegligible() @@ -88,6 +100,7 @@ template struct TestTraits TEST(!Traits::isNegligible(one, x)); } + void isZero() { T zero(0), one(1), x = Traits::random(), y = Traits::random(); @@ -98,18 +111,22 @@ template struct TestTraits void isLessThan() { - T one(1), x = Traits::random(); - TEST(Traits::isLessThan(x, x+one)); - TEST(!Traits::isLessThan(x+one, x)); - TEST(Traits::isLessThan(x, x+Traits::epsilon()/10)); + if(Traits::isComplex()) { + T x = Traits::random(), y = Traits::random(); + TEST(!Traits::isLessThan(x,y)); + } + else { + T one(1), x = Traits::random(); + T e = T(Traits::epsilon()) / T(10); + TEST(Traits::isLessThan(x, x+one)); + TEST(!Traits::isLessThan(x+one, x)); + TEST(Traits::isLessThan(x, x+e)); + } } TestTraits() { - real(); - imag(); - conj(); - abs(); + real_imag_conj_abs(); sqrt(); isApprox(); isNegligible(); @@ -123,4 +140,7 @@ void TvmetTestSuite::testTraits() TestTraits(); TestTraits(); TestTraits(); + TestTraits >(); + TestTraits >(); + TestTraits >(); }