[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master 61fe15d 4/5: Perform a transcendental calcula
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master 61fe15d 4/5: Perform a transcendental calculation OAOO: part one |
Date: |
Sat, 13 Feb 2021 18:33:36 -0500 (EST) |
branch: master
commit 61fe15d9cfac2a4bc95930a6e9e3b530c365b921
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Perform a transcendental calculation OAOO: part one
This commit leaves the old code in place for the nonce, only for
validating the new.
---
ihs_acctval.cpp | 19 ++++++++----
interest_rates.cpp | 78 +++++++++++++++++++++++++++++++++++++++----------
interest_rates.hpp | 7 +++--
ledger_variant_init.cpp | 13 ++++-----
4 files changed, 87 insertions(+), 30 deletions(-)
diff --git a/ihs_acctval.cpp b/ihs_acctval.cpp
index 5815606..3001876 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" // EXPUNGE
#include "miscellany.hpp"
#include "mortality_rates.hpp"
#include "outlay.hpp"
@@ -1311,14 +1311,21 @@ void AccountValue::SetAnnualInvariants()
)
[Year]
;
- // 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]
+ YearsSepAcctGrossRate = InterestRates_->SepAcctGrossRate
+ (SepBasis_
+ ,mce_monthly_rate
+ )
+ [Year]
+ ;
+ // EXPUNGE
+ double YearsSepAcctGrossRate2 = i_upper_12_over_12_from_i<double>()
+ (InterestRates_->SepAcctGrossRate(SepBasis_, mce_annual_rate)[Year]
);
- YearsSepAcctGrossRate = round_interest_rate()(YearsSepAcctGrossRate);
+ YearsSepAcctGrossRate2 = round_interest_rate()(YearsSepAcctGrossRate2);
+ LMI_ASSERT(materially_equal(YearsSepAcctGrossRate,
YearsSepAcctGrossRate2));
}
YearsDcvIntRate = GetMly7702iGlp()[Year];
diff --git a/interest_rates.cpp b/interest_rates.cpp
index e65f13d..bc7c62c 100644
--- a/interest_rates.cpp
+++ b/interest_rates.cpp
@@ -223,6 +223,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 +356,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 +462,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 +543,16 @@ 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).
+ // SOMEDAY !! That seems senseless: in this
+ // if(!NeedSepAcctRates_)
+ // block, it should be perfectly all right to
+ // zero out rates that aren't needed.
+ if(mce_annual_rate == i && mce_sep_full == k) continue;
+ SepAcctGrossRate_[i] [k] = Zero_;
}
}
}
@@ -584,15 +617,24 @@ 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_
+ );
+ }
+
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 +646,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_
@@ -850,11 +892,17 @@ void InterestRates::DynamicMlySepAcctRate
// TODO ?? What if it's not 'full'--what if we want 'half' or 'zero'?
MonthlySepAcctGrossRate = i_upper_12_over_12_from_i<double>()
- (SepAcctGrossRate_[mce_sep_full][year]
+ (SepAcctGrossRate_[mce_annual_rate][mce_sep_full][year]
+ );
+ LMI_ASSERT // EXPUNGE
+ ( MonthlySepAcctGrossRate
+ == SepAcctGrossRate_[mce_monthly_rate][mce_sep_full][year]
);
+ // Instead of the previous two statements, just do this:
+ MonthlySepAcctGrossRate =
SepAcctGrossRate_[mce_monthly_rate][mce_sep_full][year];
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 f01a1cf..58495ae 100644
--- a/interest_rates.hpp
+++ b/interest_rates.hpp
@@ -155,6 +155,7 @@ class InterestRates
std::vector<double> const& SepAcctGrossRate
(mcenum_sep_basis
+ ,mcenum_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 af9daa9..6651dce 100644
--- a/ledger_variant_init.cpp
+++ b/ledger_variant_init.cpp
@@ -95,19 +95,18 @@ void LedgerVariant::Init
InitAnnGenAcctInt = bv.InterestRates_->GenAcctNetRate
(GenBasis_
,mce_annual_rate
- )
- [0]
- ;
+ )[0];
- InitAnnSepAcctGrossInt = bv.InterestRates_->SepAcctGrossRate(SepBasis_)[0];
+ InitAnnSepAcctGrossInt = bv.InterestRates_->SepAcctGrossRate
+ (SepBasis_
+ ,mce_annual_rate
+ )[0];
InitAnnSepAcctNetInt = bv.InterestRates_->SepAcctNetRate
(SepBasis_
,GenBasis_
,mce_annual_rate
- )
- [0]
- ;
+ )[0];
InitTgtPremHiLoadRate =
bv.Loads_->target_premium_load_maximum_premium_tax()[bv.yare_input_.InforceYear];
InitMlyPolFee = dblize(bv.Loads_->monthly_policy_fee(GenBasis_)
[bv.yare_input_.InforceYear]);