[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] odd/transcend adb09ff 3/3: Move a transcendental cal
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] odd/transcend adb09ff 3/3: Move a transcendental calculation into class InterestRates |
Date: |
Thu, 28 Jan 2021 13:14:52 -0500 (EST) |
branch: odd/transcend
commit adb09ff75af61d3ffea17729590fc51b05f66d19
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Move a transcendental calculation into class InterestRates
Still too messy for 'master'--put this aside for now.
---
ihs_acctval.cpp | 24 +++++++--
interest_rates.cpp | 131 ++++++++++++++++++++++++++++++++++++++++++------
interest_rates.hpp | 9 ++--
ledger_variant_init.cpp | 5 +-
4 files changed, 147 insertions(+), 22 deletions(-)
diff --git a/ihs_acctval.cpp b/ihs_acctval.cpp
index bc747de..a8eedcf 100644
--- a/ihs_acctval.cpp
+++ b/ihs_acctval.cpp
@@ -39,7 +39,7 @@
#include "ledger_variant.hpp"
#include "loads.hpp"
#include "materially_equal.hpp"
-#include "math_functions.hpp"
+#include "math_functions.hpp" // i_upper_12_over_12_from_i()
CURRENCY !! expunge
#include "miscellany.hpp"
#include "mortality_rates.hpp"
#include "outlay.hpp"
@@ -1401,12 +1401,30 @@ void AccountValue::SetAnnualInvariants()
;
// SOMEDAY !! This should be done in the interest-rate class.
YearsSepAcctGrossRate = 0.0;
- if(mce_gen_mdpt != GenBasis_)
+ if(database().query<bool>(DB_AllowSepAcct) && mce_gen_mdpt != GenBasis_)
{
YearsSepAcctGrossRate = i_upper_12_over_12_from_i<double>()
- (InterestRates_->SepAcctGrossRate(SepBasis_)[Year]
+ (InterestRates_->SepAcctGrossRate(SepBasis_, mce_annual_rate)[Year]
);
YearsSepAcctGrossRate = round_interest_rate()(YearsSepAcctGrossRate);
+ double const xyzzy = InterestRates_->SepAcctGrossRate(SepBasis_,
mce_monthly_rate)[Year];
+#if 1
+ if(!materially_equal(xyzzy, YearsSepAcctGrossRate))
+ warning()
+ << InterestRates_->SepAcctGrossRate(SepBasis_,
mce_annual_rate)[Year] << "\n"
+ << InterestRates_->SepAcctGrossRate(SepBasis_,
mce_monthly_rate)[Year] << "\n"
+ << YearsSepAcctGrossRate << " YearsSepAcctGrossRate\n"
+ << xyzzy << " xyzzy\n"
+ << GenBasis_ << " GenBasis_\n"
+ << SepBasis_ << " SepBasis_\n"
+ << Year << " Year\n"
+ << YearsSepAcctIntRate << " YearsSepAcctIntRate\n"
+ << database().query<bool>(DB_AllowSepAcct)
+ << LMI_FLUSH
+ ;
+ LMI_ASSERT(materially_equal(xyzzy, YearsSepAcctGrossRate));
+#endif // 0
+ YearsSepAcctGrossRate = xyzzy;
}
YearsDcvIntRate = GetMly7702iGlp()[Year];
diff --git a/interest_rates.cpp b/interest_rates.cpp
index 282107a..6fd121c 100644
--- a/interest_rates.cpp
+++ b/interest_rates.cpp
@@ -29,6 +29,7 @@
#include "database.hpp"
#include "dbnames.hpp"
#include "irc7702_interest.hpp" // iglp(), igsp()
+#include "materially_equal.hpp" // CURRENCY !! expunge
#include "math_functions.hpp" // assign_midpoint()
#include "miscellany.hpp" // each_equal()
#include "ssize_lmi.hpp"
@@ -223,6 +224,34 @@ void convert_interest_rates
}
}
+// Transform vector of annual gross interest rates to monthly gross.
+// Often the rates are the same from one year to the next; when that
+// happens, we just replicate the previous value in order to avoid
+// costly floating point calculations.
+void convert_interest_rates
+ (std::vector<double> const& annual_gross_rate
+ ,std::vector<double> & monthly_gross_rate
+ ,round_to<double> const& round_interest_rate
+ )
+{
+ int const length = lmi::ssize(annual_gross_rate);
+ monthly_gross_rate.resize(length);
+
+ double cached_monthly_gross_rate = 0.0;
+
+ double previous_annual_gross_rate = 0.0;
+ for(int j = 0; j < length; ++j)
+ {
+ if(previous_annual_gross_rate != annual_gross_rate[j])
+ {
+ previous_annual_gross_rate = annual_gross_rate[j];
+ cached_monthly_gross_rate =
i_upper_12_over_12_from_i<double>()(annual_gross_rate[j]);
+ cached_monthly_gross_rate =
round_interest_rate(cached_monthly_gross_rate);
+ }
+ monthly_gross_rate[j] = cached_monthly_gross_rate;
+ }
+}
+
#if 0
/// Determine whether loan rates are needed; else they can be zero.
///
@@ -328,11 +357,11 @@ void InterestRates::Initialize(BasicValues const& v)
std::copy
(v.yare_input_.SeparateAccountRate.begin()
,v.yare_input_.SeparateAccountRate.end()
- ,std::back_inserter(SepAcctGrossRate_[mce_sep_full])
+ ,std::back_inserter(SepAcctGrossRate_[mce_annual_rate][mce_sep_full])
);
// TODO ?? At least for the antediluvian branch, the vector in
// the input class has an inappropriate size.
- SepAcctGrossRate_[mce_sep_full].resize(Length_);
+ SepAcctGrossRate_[mce_annual_rate][mce_sep_full].resize(Length_);
v.database().query_into(DB_GuarMandE , MAndERate_[mce_gen_guar]);
v.database().query_into(DB_CurrMandE , MAndERate_[mce_gen_curr]);
@@ -434,7 +463,7 @@ void InterestRates::Initialize(BasicValues const& v)
LMI_ASSERT(Length_ == lmi::ssize(GenAcctNetRate_ [i][j]
));
for(int k = mce_sep_full; k < mc_n_sep_bases; ++k)
{
- LMI_ASSERT(Length_ == lmi::ssize(SepAcctGrossRate_
[k]));
+ LMI_ASSERT(Length_ == lmi::ssize(SepAcctGrossRate_ [i]
[k]));
LMI_ASSERT(Length_ == lmi::ssize(SepAcctNetRate_
[i][j][k]));
}
LMI_ASSERT(Length_ == lmi::ssize(RegLnCredRate_ [i][j]
));
@@ -515,11 +544,15 @@ void InterestRates::InitializeSeparateAccountRates()
{
for(int j = mce_gen_curr; j < mc_n_gen_bases; ++j)
{
- SepAcctGrossRate_[mce_sep_zero] = Zero_;
- SepAcctGrossRate_[mce_sep_half] = Zero_;
for(int k = mce_sep_full; k < mc_n_sep_bases; ++k)
{
- SepAcctNetRate_[i][j][k] = Zero_;
+ SepAcctNetRate_ [i][j][k] = Zero_;
+ // Don't zero out input (gross, annual, full).
+ if(mce_annual_rate == i && mce_sep_full == k)
+ {
+ continue;
+ }
+ SepAcctGrossRate_[i] [k] = Zero_;
}
}
}
@@ -584,15 +617,31 @@ void InterestRates::InitializeSeparateAccountRates()
LMI_ASSERT(mce_gross_rate == SepAcctRateType_);
}
- SepAcctGrossRate_[mce_sep_zero] = Zero_;
+ SepAcctGrossRate_[mce_annual_rate][mce_sep_zero] = Zero_;
// ET !! SepAcctGrossRate_[mce_sep_half] = 0.5 *
SepAcctGrossRate_[mce_sep_full];
std::transform
- (SepAcctGrossRate_[mce_sep_full].begin()
- ,SepAcctGrossRate_[mce_sep_full].end()
- ,std::back_inserter(SepAcctGrossRate_[mce_sep_half])
+ (SepAcctGrossRate_[mce_annual_rate][mce_sep_full].begin()
+ ,SepAcctGrossRate_[mce_annual_rate][mce_sep_full].end()
+ ,std::back_inserter(SepAcctGrossRate_[mce_annual_rate][mce_sep_half])
,[](double x) { return 0.5 * x; }
);
+ for(int k = mce_sep_full; k < mc_n_sep_bases; ++k)
+ {
+ convert_interest_rates
+ (SepAcctGrossRate_[mce_annual_rate ][k]
+ ,SepAcctGrossRate_[mce_monthly_rate][k]
+ ,RoundIntRate_
+ );
+#if 0
+ warning()
+ << SepAcctGrossRate_[mce_annual_rate ][k][0] << "
SepAcctGrossRate_[mce_annual_rate ][k][0]\n"
+ << SepAcctGrossRate_[mce_monthly_rate ][k][0] << "
SepAcctGrossRate_[mce_monthly_rate ][k][0]\n"
+ << LMI_FLUSH
+ ;
+#endif // 0
+ }
+
for(int j = mce_gen_curr; j < mc_n_gen_bases; ++j)
{
for(int k = mce_sep_full; k < mc_n_sep_bases; ++k)
@@ -604,9 +653,9 @@ void InterestRates::InitializeSeparateAccountRates()
continue;
}
convert_interest_rates
- (SepAcctGrossRate_[k]
- ,SepAcctNetRate_[mce_annual_rate ][j][k]
- ,SepAcctNetRate_[mce_monthly_rate][j][k]
+ (SepAcctGrossRate_[mce_annual_rate ] [k]
+ ,SepAcctNetRate_ [mce_annual_rate ][j][k]
+ ,SepAcctNetRate_ [mce_monthly_rate][j][k]
,RoundIntRate_
,total_charges[j]
,SepAcctSpreadMethod_
@@ -615,6 +664,37 @@ void InterestRates::InitializeSeparateAccountRates()
);
}
}
+
+ return;
+ // check...
+ for(int i = mce_annual_rate; i < mc_n_rate_periods; ++i)
+ {
+ for(int j = mce_gen_curr; j < mc_n_gen_bases; ++j)
+ {
+ for(int k = mce_sep_full; k < mc_n_sep_bases; ++k)
+ {
+ LMI_ASSERT(Length_ == lmi::ssize(SepAcctGrossRate_ [i]
[k]));
+ LMI_ASSERT(Length_ == lmi::ssize(SepAcctNetRate_
[i][j][k]));
+ warning()
+ << i << " i\n"
+ << j << " j\n"
+ << k << " k\n"
+ << SepAcctGrossRate_ [0] [k][0] << "
SepAcctGrossRate_ [0] [k][0]\n"
+ << SepAcctGrossRate_ [1] [k][0] << "
SepAcctGrossRate_ [1] [k][0]\n"
+ << SepAcctNetRate_ [0][j][k][0] << " SepAcctNetRate_
[0][j][k][0]\n"
+ << SepAcctNetRate_ [1][j][k][0] << " SepAcctNetRate_
[1][j][k][0]\n"
+ << LMI_FLUSH
+ ;
+ if
+ (
+ (0.0 == SepAcctGrossRate_ [0] [k][0])
+ != (0.0 == SepAcctGrossRate_ [1] [k][0])
+ )
+ warning() << "HEY!" << LMI_FLUSH;
+ }
+ }
+ }
+
}
void InterestRates::InitializeLoanRates()
@@ -849,12 +929,33 @@ void InterestRates::DynamicMlySepAcctRate
// bases?
// TODO ?? What if it's not 'full'--what if we want 'half' or 'zero'?
+ // ALREADY CALCULATED ABOVE, MORE CAREFULLY
MonthlySepAcctGrossRate = i_upper_12_over_12_from_i<double>()
- (SepAcctGrossRate_[mce_sep_full][year]
+ (SepAcctGrossRate_[mce_annual_rate][mce_sep_full][year]
);
+#if 0
+ if(!materially_equal
+ (SepAcctGrossRate_[mce_monthly_rate][mce_sep_full][year]
+ ,RoundIntRate_(MonthlySepAcctGrossRate)
+ )
+ )
+#else // 0
+ if( SepAcctGrossRate_[mce_monthly_rate][mce_sep_full][year]
+// != RoundIntRate_(MonthlySepAcctGrossRate)
+ != MonthlySepAcctGrossRate
+ )
+#endif // 0
+ warning()
+ << "Unexpected:\n"
+ << SepAcctGrossRate_[mce_monthly_rate][mce_sep_full][year] <<
" SepAcctGrossRate_[mce_monthly_rate][mce_sep_full][year]\n"
+ << RoundIntRate_(MonthlySepAcctGrossRate) << "
RoundIntRate_(MonthlySepAcctGrossRate)\n"
+ << MonthlySepAcctGrossRate << " MonthlySepAcctGrossRate\n"
+ << LMI_FLUSH
+ ;
+// else warning() << "Success!" << LMI_FLUSH;
convert_interest_rates
- (SepAcctGrossRate_[sep_basis][year]
+ (SepAcctGrossRate_[mce_annual_rate][sep_basis][year]
,SepAcctNetRate_[mce_annual_rate ][gen_basis][sep_basis][year]
,SepAcctNetRate_[mce_monthly_rate][gen_basis][sep_basis][year]
,RoundIntRate_
diff --git a/interest_rates.hpp b/interest_rates.hpp
index b969df0..431e096 100644
--- a/interest_rates.hpp
+++ b/interest_rates.hpp
@@ -154,7 +154,8 @@ class InterestRates
) const;
std::vector<double> const& SepAcctGrossRate
- (mcenum_sep_basis
+ (mcenum_sep_basis sep_basis
+ ,mcenum_rate_period rate_period
) const;
std::vector<double> const& SepAcctNetRate
(mcenum_sep_basis
@@ -243,6 +244,7 @@ class InterestRates
bool NeedSepAcctRates_;
mcenum_sep_acct_rate_type SepAcctRateType_;
std::vector<double> SepAcctGrossRate_
+ [mc_n_rate_periods]
[mc_n_sep_bases]
;
std::vector<double> SepAcctNetRate_
@@ -318,10 +320,11 @@ inline std::vector<double> const&
InterestRates::GenAcctNetRate
}
inline std::vector<double> const& InterestRates::SepAcctGrossRate
- (mcenum_sep_basis sep_basis
+ (mcenum_sep_basis sep_basis
+ ,mcenum_rate_period rate_period
) const
{
- return SepAcctGrossRate_[sep_basis];
+ return SepAcctGrossRate_[rate_period][sep_basis];
}
inline std::vector<double> const& InterestRates::SepAcctNetRate
diff --git a/ledger_variant_init.cpp b/ledger_variant_init.cpp
index 9114690..b78263b 100644
--- a/ledger_variant_init.cpp
+++ b/ledger_variant_init.cpp
@@ -101,7 +101,10 @@ void LedgerVariant::Init
[0]
;
- InitAnnSepAcctGrossInt = bv.InterestRates_->SepAcctGrossRate(SepBasis_)[0];
+ InitAnnSepAcctGrossInt = bv.InterestRates_->SepAcctGrossRate
+ (SepBasis_
+ ,mce_annual_rate
+ )[0];
InitAnnSepAcctNetInt = bv.InterestRates_->SepAcctNetRate
(SepBasis_