Nicolas Winkler 4 lat temu
rodzic
commit
336acb06ba
1 zmienionych plików z 69 dodań i 0 usunięć
  1. 69 0
      libmandel/tests/accurate.cpp

+ 69 - 0
libmandel/tests/accurate.cpp

@@ -0,0 +1,69 @@
+#include "../include/TripleDouble.h"
+#include "../include/Types.h"
+
+#include <vector>
+#include <boost/random.hpp>
+
+const int nTests = 1000;
+
+using namespace boost::multiprecision;
+using namespace boost::random;
+
+std::vector<mnd::Real> generateRandom(int len, int seed)
+{
+    uniform_real_distribution<mnd::Real> dist(0, 1);
+    uniform_int_distribution<int> expDist(-30, 30);
+    independent_bits_engine<mt19937, std::numeric_limits<cpp_bin_float_50>::digits, cpp_int> gen(seed);
+
+    std::vector<mnd::Real> numbers;
+    for (int i = 0; i < len; i++) {
+        mnd::Real m = dist(gen);
+        int e = expDist(gen);
+        numbers.push_back(m * pow(mnd::Real(2), e));
+    }
+    return numbers;
+}
+
+
+template<typename T, typename Binary>
+mnd::Real maxErr(Binary func)
+{
+    mnd::Real maxRelErr = 0.0;
+    auto a = generateRandom(nTests, 123);
+    auto b = generateRandom(nTests, 456);
+    for (int i = 0; i < nTests; i++) {
+        T v1 = mnd::convert<T>(a[i]);
+        T v2 = mnd::convert<T>(b[i]);
+
+        mnd::Real r1 = mnd::convert<mnd::Real>(v1);
+        mnd::Real r2 = mnd::convert<mnd::Real>(v2);
+        //std::cout << r1 << " --- " << r2 << std::endl;
+
+        T res = func(v1, v2);
+        mnd::Real corrRes = func(r1, r2);
+        mnd::Real relErr = abs(corrRes - mnd::convert<mnd::Real>(res)) / corrRes;
+        if (relErr > maxRelErr)
+            maxRelErr = relErr;
+    }
+    return maxRelErr;
+}
+
+
+
+int main()
+{
+    mnd::Real doubleDoubleAdd = maxErr<mnd::LightDoubleDouble>([] (const auto& a, const auto& b) { return a + b; });
+    mnd::Real doubleDoubleMul = maxErr<mnd::LightDoubleDouble>([] (const auto& a, const auto& b) { return a * b; });
+    std::cout << "max double double add error: " << doubleDoubleAdd << std::endl;
+    std::cout << "max double double mul error: " << doubleDoubleMul << std::endl;
+
+    mnd::Real tripleDoubleAdd = maxErr<mnd::TripleDouble>([] (const auto& a, const auto& b) { return a + b; });
+    mnd::Real tripleDoubleMul = maxErr<mnd::TripleDouble>([] (const auto& a, const auto& b) { return a * b; });
+    std::cout << std::setprecision(10) << std::scientific;
+    std::cout << "max triple double add error: " << tripleDoubleAdd << std::endl;
+    std::cout << "max triple double mul error: " << tripleDoubleMul << std::endl;
+
+
+}
+
+