[Math] Accuracy test failures on QNX 6.4.0
Some of the accuracy tests fail on QNX 6.4.0 x86 with GCC 4.2.4 and Dinkumware 5. Some tests such as test_carlson have a peak error 10%-40% higher than expected while for example test_ellint_1 has huge errors. I'm not sure how to proceed. I'd appreciate of someone could take a look at the trunk regression test results (runner NA-QNX640-qcc). -- Regards Niklas Angare
Niklas Angare wrote:
Some of the accuracy tests fail on QNX 6.4.0 x86 with GCC 4.2.4 and Dinkumware 5. Some tests such as test_carlson have a peak error 10%-40% higher than expected while for example test_ellint_1 has huge errors.
I'm not sure how to proceed. I'd appreciate of someone could take a look at the trunk regression test results (runner NA-QNX640-qcc).
Hmm, the results tend to suggest an issue with the long double std lib math functions - are these supported by the Dinkumware lib? I'll try and put together a reduced test case, to see if we can narrow down the problem, Thanks for the heads-up, John.
Hmm, the results tend to suggest an issue with the long double std lib math functions - are these supported by the Dinkumware lib?
The documentation and math.h are Copyright P.J. Plauger (Dinkumware). sin(long double) for example calls _LSin() which I can't figure out where it's located.
Niklas Angare wrote:
Some of the accuracy tests fail on QNX 6.4.0 x86 with GCC 4.2.4 and Dinkumware 5. Some tests such as test_carlson have a peak error 10%-40% higher than expected while for example test_ellint_1 has huge errors.
I'm not sure how to proceed. I'd appreciate of someone could take a look at the trunk regression test results (runner NA-QNX640-qcc).
OK, looking at the results I have an idea where the problem *may* lie for some of the failures, can you try the attached updated test_constants.cpp and see if it passes or not on QNX? Thanks, John.
Niklas Angare wrote:
OK, looking at the results I have an idea where the problem *may* lie for some of the failures, can you try the attached updated test_constants.cpp and see if it passes or not on QNX?
It passes. What's the easiest way to (re-)run a single test?
Oh :-(
Single tests can be run by:
cd into libs/math/test
bjam toolsetname test_name
Anyhow, I'm stumped by what the issue could be now, so can you let me have
the output of the program below?
Many thanks, John.
#define BOOST_MATH_INSTRUMENT
#include
I've discovered that that the results are the same with GNU libstdc++ as with Dinkumware. But I belive they both bring in the math functions from libm.so.2.
Anyhow, I'm stumped by what the issue could be now, so can you let me have the output of the program below?
Here it is: .../ellint_1.hpp:48 phi = -10 .../ellint_1.hpp:49 k = 0.5 .../ellint_1.hpp:50 function = boost::math::ellint_f<%1%>(%1%,%1%) .../ellint_1.hpp:61 phi = -10 .../ellint_1.hpp:90 pi/2 = 1.57079632679489661937 .../ellint_1.hpp:92 rphi = 0.57522203923062028381 .../ellint_1.hpp:94 m = 5.99999999999999999964 .../ellint_1.hpp:101 rphi = 0.99557428756427633551 .../ellint_1.hpp:105 sinp = 0.83907152907645245276 .../ellint_1.hpp:106 cosp = 0.5440211108893698126 .../ellint_rf.hpp:67 tolerance = 0.000870018279433925102139 .../ellint_rf.hpp:96 k = 6 .../ellint_rf.hpp:102 value = 1.23050187733714060618 .../ellint_1.hpp:108 result = -1.03247909174871990352 .../ellint_rf.hpp:67 tolerance = 0.000870018279433925102139 .../ellint_rf.hpp:96 k = 7 .../ellint_rf.hpp:102 value = 1.68575035481259604281 .../ellint_1.hpp:112 result = 10.76777339193945239443 -10.76777339193945239443 I cut off most of the path in the output. The output is the same with either library.
Niklas Angare wrote:
I've discovered that that the results are the same with GNU libstdc++ as with Dinkumware. But I belive they both bring in the math functions from libm.so.2.
Anyhow, I'm stumped by what the issue could be now, so can you let me have the output of the program below?
Here it is:
Thanks, I believe it's a bug in the elliptic integral code, I'll check in a
fix shortly and we'll see what happens to the results, in the mean time can
you let me have the result of running the program below (*after* you've done
an SVN update, as I've had to update the debugging/tracing code) so I can
see what some of the other failures are doing?
Thanks, John.
#define BOOST_MATH_INSTRUMENT
#include
can you let me have the result of running the program below (*after* you've done an SVN update, as I've had to update the debugging/tracing code)
Here you go: .../expint.hpp:405 z = 0.5 .../expint.hpp:419 result = 0.028178840877963713110148 .../expint.hpp:422 result = 0.028178840877963713110148 .../expint.hpp:427 result = 0.028178840877963713110148 .../expint.hpp:428 max_iter = 0 0.028178840877963713110148 .../beta.hpp:872 a = 150.599945068359375 .../beta.hpp:873 b = 306722 .../beta.hpp:874 x = 0.91338449716567993164 .../beta.hpp:875 inv = 0 .../beta.hpp:876 normalised = 0 .../beta.hpp:1096 invert = 1 .../beta.hpp:1181 fract = 0 3.6860205160884932633e-565 .../detail/igamma_inverse.hpp:378 a = 16.18250274658203125 .../detail/igamma_inverse.hpp:379 p = 0.007907813991753274790426 .../detail/igamma_inverse.hpp:201 s = -2.41314250292881458062 .../detail/igamma_inverse.hpp:209 ra = 4.02274815848345535584 .../detail/igamma_inverse.hpp:216 w = 8.09144898812073984544 .../detail/igamma_inverse.hpp:278 z = 8.1669017875574152633 .../detail/igamma_inverse.hpp:291 result = 8.08379894264235578944 .../detail/igamma_inverse.hpp:393 guess = 8.08379894264235578944 Halley iteration, limit = 4.5474735088646411895e-13 Halley iteration, delta = -0.007452388058006306973197 Halley iteration, delta = -4.2590653528058823273e-08 Halley iteration, delta = nan Halley iteration, final count = 3 Maximum iterations: 3 .../detail/igamma_inverse.hpp:412 guess = nan nan .../bessel.hpp:340 v = 0 .../bessel.hpp:341 x = 1000 .../bessel.hpp:356 r = 0.004715917977622812778975 0.004715917977622812778975
Niklas Angare wrote:
can you let me have the result of running the program below (*after* you've done an SVN update, as I've had to update the debugging/tracing code)
Here you go:
Thanks, but I admit to being stuck... somewhere around line 320 of boost/math/tools/roots.hpp there's a NaN being generated for type real_concept, but not for type long double (and real_concept is just a very thin wrapper around long double). Can you set a breakpoint at that location and see what the problem is? It should be the third time through that the problem occurs. Many thanks for your help, John.
Thanks, but I admit to being stuck... somewhere around line 320 of boost/math/tools/roots.hpp there's a NaN being generated for type real_concept, but not for type long double (and real_concept is just a very thin wrapper around long double). Can you set a breakpoint at that location and see what the problem is?
It's on line 299, f(result), which in the end results in a call to std::pow(0.5, 16.182502746582031), the result of which is a NaN... The numbers may not be exact since they're just from the debugger's presentation. I've attached the call stack. After some experimentation I arrived at this test: #include <cmath> #include <iostream> #include <iomanip> #include <limits> int main() { typedef std::numeric_limits<long double> ldlimits; unsigned int raw1[3]; // garbage unsigned int raw2[3]; // garbage long double a = 0.5L; long double b1 = 16.182502746582031; long double b2 = 16.182502746582031L; long double b3 = 1.0L; // garbage long double b4 = 2.0L; // garbage long double r1 = std::pow(a, b1); long double r2 = std::pow(a, b2); long double r3 = std::pow(a, b3); // garbage #ifdef VERSION2 long double r4 = std::pow(a, b4); // garbage #endif std::cout << std::setprecision(30); std::cout << ldlimits::radix << "^" << ldlimits::digits << " (" << sizeof(long double) << ")" << std::endl; std::cout << "1) " << b1 << " " << r1 << std::endl; std::cout << "2) " << b2 << " " << r2 << std::endl; } Results with VERSION2 undefined: 2^64 (12) 1) 16.18250274658203125 nan 2) 16.18250274658203099988 1.3445633476723758172e-05 Results with VERSION2 defined: 2^64 (12) 1) 16.18250274658203125 1.3445633476723755844e-05 2) 16.18250274658203099988 1.3445633476723758172e-05 I discovered 1) when I forgot to put the L on the literal. Then I discovered that the result is sometimes correct depending on other nearby code. Seriously weird. Any ideas what could be causing this?
Niklas Angare wrote:
Thanks, but I admit to being stuck... somewhere around line 320 of boost/math/tools/roots.hpp there's a NaN being generated for type real_concept, but not for type long double (and real_concept is just a very thin wrapper around long double). Can you set a breakpoint at that location and see what the problem is?
It's on line 299, f(result), which in the end results in a call to std::pow(0.5, 16.182502746582031), the result of which is a NaN... The numbers may not be exact since they're just from the debugger's presentation. I've attached the call stack.
After some experimentation I arrived at this test: #include <cmath> #include <iostream> #include <iomanip> #include <limits>
int main() { typedef std::numeric_limits<long double> ldlimits; unsigned int raw1[3]; // garbage unsigned int raw2[3]; // garbage long double a = 0.5L; long double b1 = 16.182502746582031; long double b2 = 16.182502746582031L; long double b3 = 1.0L; // garbage long double b4 = 2.0L; // garbage long double r1 = std::pow(a, b1); long double r2 = std::pow(a, b2); long double r3 = std::pow(a, b3); // garbage #ifdef VERSION2 long double r4 = std::pow(a, b4); // garbage #endif std::cout << std::setprecision(30); std::cout << ldlimits::radix << "^" << ldlimits::digits << " (" << sizeof(long double) << ")" << std::endl; std::cout << "1) " << b1 << " " << r1 << std::endl; std::cout << "2) " << b2 << " " << r2 << std::endl; }
Results with VERSION2 undefined: 2^64 (12) 1) 16.18250274658203125 nan 2) 16.18250274658203099988 1.3445633476723758172e-05
Results with VERSION2 defined: 2^64 (12) 1) 16.18250274658203125 1.3445633476723755844e-05 2) 16.18250274658203099988 1.3445633476723758172e-05
I discovered 1) when I forgot to put the L on the literal. Then I discovered that the result is sometimes correct depending on other nearby code. Seriously weird. Any ideas what could be causing this?
Ummm, so you get a NaN or not depending upon what other code is present but not even called yet???? That's too weird, and looks like a platform bug if I've understood you correctly... but on the off chance there's some issue with FPU exception flags from previous calls messing things up, can you try the attached boost/math/tools/config.hpp and see if it clears any of the test failures? Thanks, John.
Ummm, so you get a NaN or not depending upon what other code is present but not even called yet????
I guess so!
That's too weird, and looks like a platform bug if I've understood you correctly...
It sure does. There's no boost code in my test. Thanks for the help and sorry for the trouble! I guess I'll have to file a bug report with QNX now.
but on the off chance there's some issue with FPU exception flags from previous calls messing things up, can you try the attached boost/math/tools/config.hpp and see if it clears any of the test failures?
I think you forgot to attach the file :)
Niklas Angare wrote:
but on the off chance there's some issue with FPU exception flags from previous calls messing things up, can you try the attached boost/math/tools/config.hpp and see if it clears any of the test failures?
I think you forgot to attach the file :)
Doh! Attached now, John.
but on the off chance there's some issue with FPU exception flags from previous calls messing things up, can you try the attached boost/math/tools/config.hpp and see if it clears any of the test failures?
That didn't appear to make a differance. The same tests fail with it as without. The Ellint tests pass now, though. Considering the nature of the platform bug I guess that may just be due to the code moving around.
Niklas Angare wrote:
but on the off chance there's some issue with FPU exception flags from previous calls messing things up, can you try the attached boost/math/tools/config.hpp and see if it clears any of the test failures?
That didn't appear to make a differance. The same tests fail with it as without.
Oh :-( Any feedback from QNX on the cause of the issue? It would be nice understand what's going on just in case it's something we can fix.
The Ellint tests pass now, though. Considering the nature of the platform bug I guess that may just be due to the code moving around.
Ah no, there really was a bug in the Boost.Math code that was exposed by a less than fully accurate fmod implementation on that platform. John.
Any feedback from QNX on the cause of the issue? It would be nice understand what's going on just in case it's something we can fix.
Nothing yet. I've reported the issue here: http://community.qnx.com/sf/go/projects.core_os/discussion.newcode.topc5091
Ah no, there really was a bug in the Boost.Math code that was exposed by a less than fully accurate fmod implementation on that platform.
Is this and the other accuracy problems something to worry about when doing simple calculations with doubles?
Niklas Angare wrote:
Any feedback from QNX on the cause of the issue? It would be nice understand what's going on just in case it's something we can fix.
Nothing yet. I've reported the issue here: http://community.qnx.com/sf/go/projects.core_os/discussion.newcode.topc5091
Ah no, there really was a bug in the Boost.Math code that was exposed by a less than fully accurate fmod implementation on that platform.
Is this and the other accuracy problems something to worry about when doing simple calculations with doubles?
Maybe, maybe not :-( The default behaviour is that to ensure accuracy, each special function is actually evaluated internally at the next available precision up - so for example: tgamma<float> evaluated at double precision internally. tgamma<double> evaluated at long double precision internally. There are configuration macros to change this behaviour if needed (or just disable long double support full stop): but for now the double-precision tests all appear to be passing. It's a worry though :-( John.
participants (2)
-
John Maddock
-
Niklas Angare