lmi-commits
[Top][All Lists]
Advanced

[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]);



reply via email to

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