lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] master 7451ed1 2/4: Increase the precision of certai


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 7451ed1 2/4: Increase the precision of certain unit tests
Date: Wed, 14 Feb 2018 20:34:06 -0500 (EST)

branch: master
commit 7451ed1516fd8ac5abcf579babe94177ec77b5f6
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>

    Increase the precision of certain unit tests
    
    Incidentally, the second block of IRR tests formerly duplicated the
    first; the battery of tests is arguably stronger now that they differ.
---
 financial_test.cpp | 52 ++++++++++++++++++++++++++++++++++------------------
 1 file changed, 34 insertions(+), 18 deletions(-)

diff --git a/financial_test.cpp b/financial_test.cpp
index 824a914..c061d6a 100644
--- a/financial_test.cpp
+++ b/financial_test.cpp
@@ -23,6 +23,7 @@
 
 #include "financial.hpp"
 
+#include "materially_equal.hpp"
 #include "test_tools.hpp"
 #include "timer.hpp"
 
@@ -68,21 +69,32 @@ int test_main(int, char*[])
         b.push_back(100 * j);
         }
     std::vector<double> results(p.size());
-    irr(p.begin(), p.end(), b.begin(), results.begin(), 5);
 
-    double const tolerance = 0.000005;
+    // For this block of numerical tests, ask for IRR to be calculated
+    // to many more decimal places than a normal FPU can represent, to
+    // make sure that's handled gracefully and, more importantly, to
+    // get the most accurate result achievable, in order to make the
+    // NPV at the IRR rate close to zero. The constants to which
+    // results are compared were pasted from gnumeric.
 
-    BOOST_TEST(std::fabs(99.00000 - results[ 0]) <= tolerance);
-    BOOST_TEST(std::fabs(12.17744 - results[ 1]) <= tolerance);
-    BOOST_TEST(std::fabs( 4.95525 - results[ 2]) <= tolerance);
-    BOOST_TEST(std::fabs( 2.86816 - results[ 3]) <= tolerance);
-    BOOST_TEST(std::fabs( 1.94788 - results[ 4]) <= tolerance);
-    BOOST_TEST(std::fabs( 1.44618 - results[ 5]) <= tolerance);
-    BOOST_TEST(std::fabs( 1.13570 - results[ 6]) <= tolerance);
-    BOOST_TEST(std::fabs( 0.92674 - results[ 7]) <= tolerance);
-    BOOST_TEST(std::fabs( 0.77750 - results[ 8]) <= tolerance);
-    BOOST_TEST(std::fabs( 0.66612 - results[ 9]) <= tolerance);
-    BOOST_TEST(std::fabs( 0.01757 - results[99]) <= tolerance);
+    irr(p.begin(), p.end(), b.begin(), results.begin(), 123);
+
+    // Curiously, gnumeric results for durations 7..9 don't match as
+    // closely as for earlier durations or for later duration 99.
+
+    BOOST_TEST(materially_equal(99.000000000000000, results[ 0]));
+    BOOST_TEST(materially_equal(12.177446878757825, results[ 1]));
+    BOOST_TEST(materially_equal( 4.955259671231229, results[ 2]));
+    BOOST_TEST(materially_equal( 2.868166276393760, results[ 3]));
+    BOOST_TEST(materially_equal( 1.947887419010502, results[ 4]));
+    BOOST_TEST(materially_equal( 1.446186004776299, results[ 5]));
+    BOOST_TEST(materially_equal( 1.135702229722491, results[ 6]));
+    BOOST_TEST(materially_equal( 0.926742991091295, results[ 7], 1e-9));
+    BOOST_TEST(materially_equal( 0.777508398535212, results[ 8], 1e-9));
+    BOOST_TEST(materially_equal( 0.666120736082859, results[ 9], 1e-9));
+    BOOST_TEST(materially_equal( 0.017575671480682, results[99]));
+
+    // An NPV test will soon be added here.
 
     // Test const vectors.
     std::vector<double> const cp(p);
@@ -94,9 +106,14 @@ int test_main(int, char*[])
     std::vector<double> const& crcb(cb);
     irr(crcp.begin(), crcp.end(), crcb.begin(), results.begin(), 5);
 
+    // Unlike the numerical tests above, those below calculate IRR to
+    // a more typical five decimals.
+    int const decimals = 5;
+    double const tolerance = 0.000005;
+
     // Test specialized irr() for life insurance, reflecting lapse duration.
 
-    irr(p, b, results, p.size(), p.size(), 5);
+    irr(p, b, results, p.size(), p.size(), decimals);
     BOOST_TEST(std::fabs(99.00000 - results[ 0]) <= tolerance);
     BOOST_TEST(std::fabs(12.17744 - results[ 1]) <= tolerance);
     BOOST_TEST(std::fabs( 4.95525 - results[ 2]) <= tolerance);
@@ -109,7 +126,7 @@ int test_main(int, char*[])
     BOOST_TEST(std::fabs( 0.66612 - results[ 9]) <= tolerance);
     BOOST_TEST(std::fabs( 0.01757 - results[99]) <= tolerance);
 
-    irr(p, b, results, 9, p.size(), 5);
+    irr(p, b, results, 9, p.size(), decimals);
     BOOST_TEST(std::fabs(99.00000 - results[ 0]) <= tolerance);
     BOOST_TEST(std::fabs(12.17744 - results[ 1]) <= tolerance);
     BOOST_TEST(std::fabs( 4.95525 - results[ 2]) <= tolerance);
@@ -126,10 +143,10 @@ int test_main(int, char*[])
 
     // This version leaves 'results' unchanged. Test it to make
     // sure it doesn't segfault.
-    irr(p.begin(), p.begin(), b.begin(), results.begin(), 5);
+    irr(p.begin(), p.begin(), b.begin(), results.begin(), decimals);
 
     // This version fills 'results' with -100%.
-    irr(p, b, results, 0, p.size(), 5);
+    irr(p, b, results, 0, p.size(), decimals);
     BOOST_TEST(std::fabs(-1.00000 - results[ 0]) <= tolerance);
     BOOST_TEST(std::fabs(-1.00000 - results[ 1]) <= tolerance);
     BOOST_TEST(std::fabs(-1.00000 - results[ 2]) <= tolerance);
@@ -158,7 +175,6 @@ int test_main(int, char*[])
         );
 
     typedef std::vector<double>::iterator VI;
-    int const decimals = 5;
     std::cout
         << "  Speed test: vector of irrs, length "
         << p.size()



reply via email to

[Prev in Thread] Current Thread [Next in Thread]