[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master d7c5304d 6/6: Don't store unhelpful reciproca
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master d7c5304d 6/6: Don't store unhelpful reciprocals |
Date: |
Sat, 30 Apr 2022 09:13:23 -0400 (EDT) |
branch: master
commit d7c5304dd12bf929f9688a81c326be14693494ff
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Don't store unhelpful reciprocals
In one case, storing a reciprocal replaced three divisions by one
division and three multiplications, any benefit being marginal at best.
In the other cases, storing a reciprocal replaced one division by one
division and one multiplication, which seemed futile.
---
math_functions.hpp | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/math_functions.hpp b/math_functions.hpp
index 778ee1d4..47a7b601 100644
--- a/math_functions.hpp
+++ b/math_functions.hpp
@@ -137,10 +137,9 @@ struct i_upper_n_over_n_from_i
return -1.0;
}
- constexpr T reciprocal_n = T(1) / n;
// naively: (1+i)^(1/n) - 1
// substitute: (1+i)^n - 1 <-> std::expm1(std::log1p(i) * n)
- return std::expm1(std::log1p(i) * reciprocal_n);
+ return std::expm1(std::log1p(i) / n);
}
};
@@ -196,10 +195,9 @@ struct d_upper_n_from_i
throw std::range_error("i equals -100%.");
}
- constexpr T reciprocal_n = T(1) / n;
// naively: n * (1 - (1+i)^(-1/n))
// substitute: (1+i)^n - 1 <-> std::expm1(std::log1p(i) * n)
- return -n * std::expm1(std::log1p(i) * -reciprocal_n);
+ return -n * std::expm1(std::log1p(i) / -n);
}
};
@@ -226,7 +224,6 @@ struct net_i_from_gross
static_assert(0 < n);
T operator()(T const& i, T const& spread, T const& fee) const
{
- constexpr T reciprocal_n = T(1) / n;
// naively:
// (1
// + (1+ i)^(1/n)
@@ -237,9 +234,9 @@ struct net_i_from_gross
return std::expm1
(
n * std::log1p
- ( std::expm1(reciprocal_n * std::log1p(i))
- - std::expm1(reciprocal_n * std::log1p(spread))
- - reciprocal_n * fee
+ ( std::expm1(std::log1p(i) / n)
+ - std::expm1(std::log1p(spread) / n)
+ - fee / n
)
);
}
@@ -297,10 +294,9 @@ struct coi_rate_from_q
}
else
{
- constexpr T reciprocal_12 = T(1) / 12;
// naively: 1 - (1-q)^(1/12)
// substitute: (1+i)^n - 1 <-> std::expm1(std::log1p(i) * n)
- T monthly_q = -std::expm1(std::log1p(-q) * reciprocal_12);
+ T monthly_q = -std::expm1(std::log1p(-q) / 12);
if(T(1) == monthly_q)
{
throw std::logic_error("Monthly q equals unity.");
- [lmi-commits] [lmi] master updated (92d90368 -> d7c5304d), Greg Chicares, 2022/04/30
- [lmi-commits] [lmi] master 57a1b38c 1/6: Improve documentation, Greg Chicares, 2022/04/30
- [lmi-commits] [lmi] master d7c5304d 6/6: Don't store unhelpful reciprocals,
Greg Chicares <=
- [lmi-commits] [lmi] master 7ea80507 2/6: Prefer 'double' to 'long double' in a comment, Greg Chicares, 2022/04/30
- [lmi-commits] [lmi] master 44707d65 3/6: Use only unsuffixed expm1() and log1p(), Greg Chicares, 2022/04/30
- [lmi-commits] [lmi] master 8e48e14a 5/6: Don't force long double type for reciprocals, Greg Chicares, 2022/04/30
- [lmi-commits] [lmi] master 58b87552 4/6: Don't force long double into double calculations, Greg Chicares, 2022/04/30