[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master 81ede74 5/8: Reimplement fv()
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master 81ede74 5/8: Reimplement fv() |
Date: |
Fri, 9 Jul 2021 01:41:18 -0400 (EDT) |
branch: master
commit 81ede74df7d92c8b81b2539700e4b49d97c3a414
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Reimplement fv()
For the container form actually used in production, before this change:
i686-w64-mingw32 4.571e-02 s mean; 45293 us least of 22 runs
x86_64-pc-linux-gnu 2.347e-02 s mean; 23426 us least of 43 runs
and after:
i686-w64-mingw32 8.355e-03 s mean; 8312 us least of 100 runs
x86_64-pc-linux-gnu 7.935e-03 s mean; 7807 us least of 100 runs
Avoiding NaN arithmetic has made irr() three to five times as fast.
Adjusted several unit tests. Reenabled the one that had failed in the
previous commit. The first test here changed, and another one newly
suppressed, suggest reconsidering the irr(begin,end) overload.
---
financial.hpp | 13 ++++++++-----
financial_test.cpp | 18 +++++++++++-------
2 files changed, 19 insertions(+), 12 deletions(-)
diff --git a/financial.hpp b/financial.hpp
index 7e7284b..d03390c 100644
--- a/financial.hpp
+++ b/financial.hpp
@@ -59,14 +59,17 @@ long double fv
{
return 0.0L;
}
- long double const v = 1.0L / (1.0L + i);
- long double vn = 1.0L;
+
+ // Symbol v, meaning 1/(1+i), is standard. A corresponding
+ // symbol u, meaning (1+i), is not standard, but should be.
+ long double const u = 1.0L + i;
long double z = 0.0L;
for(InputIterator j = first; j != last; ++j)
{
- z += *j * (vn *= v);
+ z += *j;
+ z *= u;
}
- return z / (vn * v);
+ return z;
}
template<typename InputIterator>
@@ -96,7 +99,7 @@ class irr_helper
(*this
,-1.0 // A priori lower bound.
,1000.0 // Assumed upper bound.
- ,bias_lower // Return the final bound with the lower fv.
+ ,bias_lower // Return the final bound with the lower FV.
,decimals_
);
switch(z.validity)
diff --git a/financial_test.cpp b/financial_test.cpp
index 0bd3f7d..423739c 100644
--- a/financial_test.cpp
+++ b/financial_test.cpp
@@ -132,24 +132,29 @@ int test_main(int, char*[])
LMI_TEST_EQUAL(-1.0, irr_helper<double*>(pmts, pmts + 3, 0.0 , 5)());
// Test with arrays.
- double cash_flows[4] = {pmts[0], pmts[1], pmts[2], -bfts[2]};
- LMI_TEST_EQUAL(2.0, irr(cash_flows, 4 + cash_flows, 5));
+ LMI_TEST_EQUAL(2.0, irr(pmts, 3 + pmts, bfts[2], 5));
+
+ double cash_flows[4] = {pmts[0], pmts[1], pmts[2], -bfts[2]};
LMI_TEST_EQUAL( 882.8125, fv(cash_flows + 0, cash_flows + 3, 0.25));
LMI_TEST_EQUAL( 2200.0 , fv(cash_flows + 0, cash_flows + 3, 1.0 ));
// Consequently:
LMI_TEST_EQUAL(0.25, irr(cash_flows, 3 + cash_flows, 882.8125, 5));
LMI_TEST_EQUAL(1.0 , irr(cash_flows, 3 + cash_flows, 2200.0 , 5));
-// For the nonce, this fails: "test failed: '0' == '-nan'"
-// LMI_TEST_EQUAL( 0.0 , fv(cash_flows + 0, cash_flows + 4, -1.0 ));
+ LMI_TEST_EQUAL( 0.0 , fv(cash_flows + 0, cash_flows + 4, -1.0 ));
LMI_TEST_EQUAL(-4800.0 , fv(cash_flows + 0, cash_flows + 4, 0.0 ));
LMI_TEST_EQUAL(-6400.0 , fv(cash_flows + 0, cash_flows + 4, 1.0 ));
// Test with vectors.
+#if 0
+ // For the nonce, these tests fail. The first one in particular
+ // is just asking for trouble: it's designed to have a root of
+ // 200%, but appending "0.0" ensures that -100% is also a root.
std::vector<double> v(cash_flows, 4 + cash_flows);
LMI_TEST_EQUAL(2.0, irr(v.begin(), v.end(), 0.0, 5));
LMI_TEST_EQUAL(2.0, irr(v.begin(), v.end(), 5));
+#endif // 0
std::vector<double> p; // Payments.
std::vector<double> b; // Benefits.
@@ -270,10 +275,9 @@ int test_main(int, char*[])
LMI_TEST_EQUAL(r0[3], 3.14);
// SOMEDAY !! The zero polynomial has an infinitude of roots,
- // but, given that we must return only one, wouldn't some
- // value like 0% or -100% be more suitable?
+ // but, given that we must return only one, -100% is suitable.
irr(p0, b0, r0, p0.size(), p0.size(), decimals);
- LMI_TEST_EQUAL(r0[3], 1000);
+ LMI_TEST_EQUAL(r0[3], -1);
// Test fv().
- [lmi-commits] [lmi] master updated (55873f1 -> ce8b814), Greg Chicares, 2021/07/09
- [lmi-commits] [lmi] master 485d642 4/8: Augment unit tests, Greg Chicares, 2021/07/09
- [lmi-commits] [lmi] master be56aad 2/8: Move and rename a present-value function, Greg Chicares, 2021/07/09
- [lmi-commits] [lmi] master 873c574 6/8: Expunge an unneeded overload, Greg Chicares, 2021/07/09
- [lmi-commits] [lmi] master ac0da7b 3/8: Use a more appropriate unit-test macro, Greg Chicares, 2021/07/09
- [lmi-commits] [lmi] master 951a9c9 1/8: Improve IRR speed measurements, Greg Chicares, 2021/07/09
- [lmi-commits] [lmi] master 81ede74 5/8: Reimplement fv(),
Greg Chicares <=
- [lmi-commits] [lmi] master ce8b814 8/8: Record speed measurements, Greg Chicares, 2021/07/09
- [lmi-commits] [lmi] master 7c21f2a 7/8: Optionally trace IRR iterations, Greg Chicares, 2021/07/09