accurate.cpp 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include "../include/TripleDouble.h"
  2. #include "../include/Types.h"
  3. #include "../include/HexDouble.h"
  4. #include <vector>
  5. #include <boost/random.hpp>
  6. const int nTests = 10000;
  7. using namespace boost::multiprecision;
  8. using namespace boost::random;
  9. std::vector<mnd::Real> generateRandom(int len, int seed)
  10. {
  11. uniform_real_distribution<mnd::Real> dist(0, 1);
  12. uniform_int_distribution<int> expDist(-120, 120);
  13. independent_bits_engine<mt19937, std::numeric_limits<cpp_bin_float_50>::digits, cpp_int> gen(seed);
  14. std::vector<mnd::Real> numbers;
  15. for (int i = 0; i < len; i++) {
  16. mnd::Real m = dist(gen);
  17. int e = expDist(gen);
  18. numbers.push_back(m * pow(mnd::Real(2), e));
  19. }
  20. return numbers;
  21. }
  22. template<typename T, typename Binary>
  23. mnd::Real maxErr(Binary func)
  24. {
  25. mnd::Real maxRelErr = 0.0;
  26. auto a = generateRandom(nTests, 123);
  27. auto b = generateRandom(nTests, 456);
  28. for (int i = 0; i < nTests; i++) {
  29. T v1 = mnd::convert<T>(a[i]);
  30. T v2 = mnd::convert<T>(b[i]);
  31. mnd::Real r1 = mnd::convert<mnd::Real>(v1);
  32. mnd::Real r2 = mnd::convert<mnd::Real>(v2);
  33. //std::cout << r1 << " --- " << r2 << std::endl;
  34. T res = func(v1, v2);
  35. mnd::Real corrRes = func(r1, r2);
  36. mnd::Real relErr = abs(corrRes - mnd::convert<mnd::Real>(res)) / corrRes;
  37. if (relErr > maxRelErr)
  38. maxRelErr = relErr;
  39. }
  40. return maxRelErr;
  41. }
  42. int main()
  43. {
  44. mnd::Real doubleDoubleAdd = maxErr<mnd::LightDoubleDouble>([] (const auto& a, const auto& b) { return a + b; });
  45. mnd::Real doubleDoubleMul = maxErr<mnd::LightDoubleDouble>([] (const auto& a, const auto& b) { return a * b; });
  46. std::cout << "max double double add error: " << doubleDoubleAdd << std::endl;
  47. std::cout << "max double double mul error: " << doubleDoubleMul << std::endl;
  48. mnd::Real tripleDoubleAdd = maxErr<mnd::TripleDouble>([] (const auto& a, const auto& b) { return a + b; });
  49. mnd::Real tripleDoubleMul = maxErr<mnd::TripleDouble>([] (const auto& a, const auto& b) { return a * b; });
  50. mnd::Real tripleDoubleAABBA = maxErr<mnd::TripleDouble>([] (const auto& a, const auto& b) { return a * a - b * b + a; });
  51. std::cout << std::setprecision(10) << std::scientific;
  52. std::cout << "max triple double add error: " << tripleDoubleAdd << std::endl;
  53. std::cout << "max triple double mul error: " << tripleDoubleMul << std::endl;
  54. std::cout << "max triple double aa - bb + a error: " << tripleDoubleAABBA << std::endl;
  55. mnd::Real hexDoubleAdd = maxErr<mnd::HexDouble>([] (const auto& a, const auto& b) { return a + b; });
  56. mnd::Real hexDoubleMul = maxErr<mnd::HexDouble>([] (const auto& a, const auto& b) { return a * b; });
  57. mnd::Real hexDoubleAABBA = maxErr<mnd::HexDouble>([] (const auto& a, const auto& b) { return a * a - b * b + a; });
  58. std::cout << std::setprecision(10) << std::scientific;
  59. std::cout << "max hex double add error: " << hexDoubleAdd << std::endl;
  60. std::cout << "max hex double mul error: " << hexDoubleMul << std::endl;
  61. std::cout << "max hex double aa - bb + a error: " << hexDoubleAABBA << std::endl;
  62. }