lmi-commits
[Top][All Lists]
Advanced

[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_



reply via email to

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