lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [lmi] master 7ddc33bb 5/6: Explore an alternative future v


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 7ddc33bb 5/6: Explore an alternative future value--for immediate reversion
Date: Sun, 1 May 2022 16:54:19 -0400 (EDT)

branch: master
commit 7ddc33bba1ba862c8a99763bb08353db6e8f7127
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>

    Explore an alternative future value--for immediate reversion
    
    Committing and then immediately reverting records an experiment like
    this in git history without permanently polluting the trunk.
---
 financial_test.cpp | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 68 insertions(+), 3 deletions(-)

diff --git a/financial_test.cpp b/financial_test.cpp
index f3554b07..11d117d1 100644
--- a/financial_test.cpp
+++ b/financial_test.cpp
@@ -29,7 +29,7 @@
 #include "test_tools.hpp"
 #include "timer.hpp"
 
-#include <cmath>                        // fabs()
+#include <cmath>                        // fabs(), expm1(), log1p()
 #include <iostream>
 #include <vector>
 
@@ -63,6 +63,43 @@ long double pv
     return z;
 }
 
+/// Alternative future value.
+///
+/// This is implemented in terms of F2XM1 and FYL2XP1, in the hope of
+/// improving accuracy. However, the speed test shows that it's twenty
+/// to forty times slower than fv().
+///
+/// Two separate accumulators, y and z, are used, on the supposition
+/// that this will improve accuracy; i.e., FV is the sum of two terms:
+///   Σ a(n)⋅(1+i)^n = Σ a(n) + Σ a(n)⋅expm1(n⋅log1p(i))
+/// of which the second could be overwhelmed by the first, resulting
+/// in loss of the precision that is hoped to be gained.
+
+template<typename InputIterator>
+long double fv_alt
+    (InputIterator first
+    ,InputIterator last
+    ,long double   i
+    )
+{
+    if(first == last)
+        {
+        return 0.0L;
+        }
+
+    long double const li = std::log1p(i);
+    long double y = 0.0L;
+    long double z = 0.0L;
+    int k = bourn_cast<int>(last - first);
+    for(InputIterator j = first; j != last; ++j)
+        {
+        y += *j;
+        z += *j * std::expm1(k * li);
+        --k;
+        }
+    return y + z;
+}
+
 void mete_0
     (std::vector<double> const& payments
     ,std::vector<double> const& benefits
@@ -108,6 +145,26 @@ void mete_1
     stifle_unused_warning(unoptimizable);
 }
 
+void mete_2(std::vector<double> const& payments)
+{
+    volatile long double unoptimizable;
+    for(int i = 0; i < 10000; ++i)
+        {
+        unoptimizable = fv(payments.begin(), payments.end(), 0.01L);
+        }
+    stifle_unused_warning(unoptimizable);
+}
+
+void mete_3(std::vector<double> const& payments)
+{
+    volatile long double unoptimizable;
+    for(int i = 0; i < 10000; ++i)
+        {
+        unoptimizable = fv_alt(payments.begin(), payments.end(), 0.01L);
+        }
+    stifle_unused_warning(unoptimizable);
+}
+
 int test_main(int, char*[])
 {
     double pmts[3] = {100.0,  200.0,  300.0};
@@ -308,13 +365,21 @@ int test_main(int, char*[])
         (std::fabs(fv(p.begin(), p.end(), i) - accum_p.back())
         <= tolerance
         );
+    LMI_TEST
+        (std::fabs(fv_alt(p.begin(), p.end(), i) - accum_p.back())
+        <= tolerance
+        );
 
     auto f0 = [&p, &b] {mete_0(p, b);};
     auto f1 = [&p, &b] {mete_1(p, b);};
+    auto f2 = [&p, &b] {mete_2(p   );};
+    auto f3 = [&p, &b] {mete_3(p   );};
     std::cout
         << "\n  Speed tests..."
-        << "\n  iterator  form: " << TimeAnAliquot(f0)
-        << "\n  container form: " << TimeAnAliquot(f1)
+        << "\n  irr, iterator  form: " << TimeAnAliquot(f0)
+        << "\n  irr, container form: " << TimeAnAliquot(f1)
+        << "\n  fv                 : " << TimeAnAliquot(f2)
+        << "\n  fv, transcendental : " << TimeAnAliquot(f3)
         << std::endl
         ;
 



reply via email to

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