[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master 59860e3 14/14: Move partial mortality into ba
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master 59860e3 14/14: Move partial mortality into base class |
Date: |
Sun, 6 Sep 2020 07:50:39 -0400 (EDT) |
branch: master
commit 59860e392dcf6af1d6e71c91cc3a95348839b153
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Move partial mortality into base class
Partial mortality doesn't depend on monthiversary processing, so it
doesn't belong in class AccountValue.
Moving it to class BasicValues prevents the problems with order and
indeed multiplicity of initialization discussed in recent commits.
---
account_value.hpp | 11 --------
basic_values.hpp | 13 ++++++++++
ihs_acctval.cpp | 65 -----------------------------------------------
ihs_basicval.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++++++
ledger_invariant_init.cpp | 2 ++
5 files changed, 79 insertions(+), 76 deletions(-)
diff --git a/account_value.hpp b/account_value.hpp
index 525378c..7bb7b52 100644
--- a/account_value.hpp
+++ b/account_value.hpp
@@ -91,10 +91,6 @@ class LMI_SO AccountValue final
std::shared_ptr<Ledger const> ledger_from_av() const;
- auto const& partial_mortality_qx () const {return partial_mortality_qx_ ;}
- auto const& partial_mortality_tpx() const {return partial_mortality_tpx_;}
- auto const& partial_mortality_lx () const {return partial_mortality_lx_ ;}
-
private:
AccountValue(AccountValue const&) = delete;
AccountValue& operator=(AccountValue const&) = delete;
@@ -214,9 +210,6 @@ class LMI_SO AccountValue final
double SolveGuarPremium ();
- void set_partial_mortality ();
- double GetPartMortQ (int year) const;
-
void PerformSpecAmtStrategy();
void PerformSupplAmtStrategy();
double CalculateSpecAmtFromStrategy
@@ -588,10 +581,6 @@ class LMI_SO AccountValue final
double YearsTotalSpecAmtLoad;
double YearsTotalSepAcctLoad;
- std::vector<double> partial_mortality_qx_;
- std::vector<double> partial_mortality_tpx_;
- std::vector<double> partial_mortality_lx_;
-
// For experience rating.
double CoiRetentionRate;
double ExperienceRatingAmortizationYears;
diff --git a/basic_values.hpp b/basic_values.hpp
index 1501151..ce3816f 100644
--- a/basic_values.hpp
+++ b/basic_values.hpp
@@ -109,6 +109,11 @@ class LMI_SO BasicValues
mcenum_state GetStateOfJurisdiction() const;
mcenum_state GetStateOfDomicile() const;
mcenum_state GetPremiumTaxState() const;
+
+ auto const& partial_mortality_qx () const {return partial_mortality_qx_ ;}
+ auto const& partial_mortality_tpx() const {return partial_mortality_tpx_;}
+ auto const& partial_mortality_lx () const {return partial_mortality_lx_ ;}
+
double InvestmentManagementFee() const;
yare_input yare_input_;
@@ -382,6 +387,9 @@ class LMI_SO BasicValues
BasicValues(BasicValues const&) = delete;
BasicValues& operator=(BasicValues const&) = delete;
+ void set_partial_mortality();
+ double GetPartMortQ(int year) const;
+
double mly_ded_discount_factor(int year, mcenum_mode mode) const;
std::pair<double,double> approx_mly_ded
(int year
@@ -424,6 +432,11 @@ class LMI_SO BasicValues
mcenum_state StateOfJurisdiction_;
mcenum_state StateOfDomicile_;
mcenum_state PremiumTaxState_;
+
+ std::vector<double> partial_mortality_qx_;
+ std::vector<double> partial_mortality_tpx_;
+ std::vector<double> partial_mortality_lx_;
+
mutable double InitialTargetPremium;
void Init7702();
diff --git a/ihs_acctval.cpp b/ihs_acctval.cpp
index 0834349..decc40f 100644
--- a/ihs_acctval.cpp
+++ b/ihs_acctval.cpp
@@ -106,9 +106,6 @@ AccountValue::AccountValue(Input const& input)
PerformSupplAmtStrategy();
InvariantValues().Init(this);
- set_partial_mortality();
- InvariantValues().InforceLives = partial_mortality_lx();
-
// Explicitly initialize antediluvian members. It's generally
// better to do this in the initializer-list, but here they can
// all be kept together.
@@ -1431,68 +1428,6 @@ void AccountValue::SetAnnualInvariants()
YearsDacTaxLoadRate = Loads_->dac_tax_load ()[Year];
}
-/// Calculate and store actuarial functions for partial mortality.
-///
-/// Iff partial mortality is used, save qx, tpx, and lx in vectors
-/// for use elsewhere in this class and for compositing ledgers.
-/// The radix for lx is the number of identical lives that an input
-/// cell represents, and qx is forced to unity at the survivorship
-/// limit (if any). If partial mortality is not used, then qx is
-/// uniformly zero, tpx is one, and lx is the radix.
-///
-/// tpx and lx both have one more element than qx; dropping the first
-/// or last element gives EOY and BOY vectors, respectively.
-///
-/// Whether a contract continues after its normal maturity date does
-/// not matter. It is treated as not expiring on that date because
-/// year-end composite values are multiplied by this lx.
-///
-/// These actuarial functions reflect survivorship only, not lapses.
-/// Use AccountValue::InforceLives{E,B}oy() where lapses should be
-/// taken into account; cf. Ledger::ZeroInforceAfterLapse().
-
-void AccountValue::set_partial_mortality()
-{
- double const inforce_lives = yare_input_.NumberOfIdenticalLives;
- partial_mortality_qx_ .resize( BasicValues::GetLength());
- partial_mortality_tpx_.resize(1 + BasicValues::GetLength(), 1.0);
- partial_mortality_lx_ .resize(1 + BasicValues::GetLength(), inforce_lives);
- if(yare_input_.UsePartialMortality)
- {
- // The first elements of lx and tpx were set above.
- for(int j = 0; j < BasicValues::GetLength(); ++j)
- {
- partial_mortality_qx_[j] = GetPartMortQ(j);
- double const px = 1.0 - partial_mortality_qx_[j];
- partial_mortality_tpx_[1 + j] = px * partial_mortality_tpx_[j];
- partial_mortality_lx_ [1 + j] = px * partial_mortality_lx_ [j];
- }
- }
-}
-
-//============================================================================
-double AccountValue::GetPartMortQ(int a_year) const
-{
- LMI_ASSERT(a_year <= BasicValues::GetLength());
- if(!yare_input_.UsePartialMortality)
- {
- return 0.0;
- }
- if
- ( MaxSurvivalDur <= a_year
- || a_year == BasicValues::GetLength()
- )
- {
- return 1.0;
- }
-
- double z =
- MortalityRates_->PartialMortalityQ()[a_year]
- * yare_input_.PartialMortalityMultiplier[a_year]
- ;
- return std::max(0.0, std::min(1.0, z));
-}
-
//============================================================================
double AccountValue::GetSepAcctAssetsInforce() const
{
diff --git a/ihs_basicval.cpp b/ihs_basicval.cpp
index 592cd35..21aa86e 100644
--- a/ihs_basicval.cpp
+++ b/ihs_basicval.cpp
@@ -243,6 +243,7 @@ void BasicValues::Init()
InitialTargetPremium = 0.0;
SetMaxSurvivalDur();
+ set_partial_mortality();
Init7702();
Init7702A();
@@ -323,6 +324,7 @@ void BasicValues::GPTServerInit()
Loads_ .reset(new Loads (*this));
SetMaxSurvivalDur();
+// set_partial_mortality(); // Not needed here.
Init7702();
}
@@ -838,6 +840,68 @@ void BasicValues::SetMaxSurvivalDur()
LMI_ASSERT(MaxSurvivalDur <= EndtAge);
}
+/// Calculate and store actuarial functions for partial mortality.
+///
+/// Iff partial mortality is used, save qx, tpx, and lx in vectors
+/// for use elsewhere in this class and for compositing ledgers.
+/// The radix for lx is the number of identical lives that an input
+/// cell represents, and qx is forced to unity at the survivorship
+/// limit (if any). If partial mortality is not used, then qx is
+/// uniformly zero, tpx is one, and lx is the radix.
+///
+/// tpx and lx both have one more element than qx; dropping the first
+/// or last element gives EOY and BOY vectors, respectively.
+///
+/// Whether a contract continues after its normal maturity date does
+/// not matter. It is treated as not expiring on that date because
+/// year-end composite values are multiplied by this lx.
+///
+/// These actuarial functions reflect survivorship only, not lapses.
+/// Use AccountValue::InforceLives{E,B}oy() where lapses should be
+/// taken into account; cf. Ledger::ZeroInforceAfterLapse().
+
+void BasicValues::set_partial_mortality()
+{
+ double const inforce_lives = yare_input_.NumberOfIdenticalLives;
+ partial_mortality_qx_ .resize( BasicValues::GetLength());
+ partial_mortality_tpx_.resize(1 + BasicValues::GetLength(), 1.0);
+ partial_mortality_lx_ .resize(1 + BasicValues::GetLength(), inforce_lives);
+ if(yare_input_.UsePartialMortality)
+ {
+ // The first elements of lx and tpx were set above.
+ for(int j = 0; j < BasicValues::GetLength(); ++j)
+ {
+ partial_mortality_qx_[j] = GetPartMortQ(j);
+ double const px = 1.0 - partial_mortality_qx_[j];
+ partial_mortality_tpx_[1 + j] = px * partial_mortality_tpx_[j];
+ partial_mortality_lx_ [1 + j] = px * partial_mortality_lx_ [j];
+ }
+ }
+}
+
+//============================================================================
+double BasicValues::GetPartMortQ(int a_year) const
+{
+ LMI_ASSERT(a_year <= BasicValues::GetLength());
+ if(!yare_input_.UsePartialMortality)
+ {
+ return 0.0;
+ }
+ if
+ ( MaxSurvivalDur <= a_year
+ || a_year == BasicValues::GetLength()
+ )
+ {
+ return 1.0;
+ }
+
+ double z =
+ MortalityRates_->PartialMortalityQ()[a_year]
+ * yare_input_.PartialMortalityMultiplier[a_year]
+ ;
+ return std::max(0.0, std::min(1.0, z));
+}
+
/// Ascertain modal payment for a minimum-premium strategy.
///
/// The term "minimum premium" is overloaded. It may mean the lowest
diff --git a/ledger_invariant_init.cpp b/ledger_invariant_init.cpp
index 2900000..a174184 100644
--- a/ledger_invariant_init.cpp
+++ b/ledger_invariant_init.cpp
@@ -74,6 +74,8 @@ void LedgerInvariant::Init(BasicValues const* b)
// Zero-initialize almost everything.
Init();
+ InforceLives = b->partial_mortality_lx();
+
irr_precision_ = b->round_irr().decimals();
// BOY vectors.
- [lmi-commits] [lmi] master 338d589 10/14: Call set_partial_mortality() OAOO, (continued)
- [lmi-commits] [lmi] master 338d589 10/14: Call set_partial_mortality() OAOO, Greg Chicares, 2020/09/06
- [lmi-commits] [lmi] master 915e4ef 03/14: Avoid reading back from ledger in class AccountValue, Greg Chicares, 2020/09/06
- [lmi-commits] [lmi] master 540e3ca 04/14: Simplify, Greg Chicares, 2020/09/06
- [lmi-commits] [lmi] master 73d5f2b 06/14: Refactor for terseness, Greg Chicares, 2020/09/06
- [lmi-commits] [lmi] master 2bcf8d3 08/14: Move commentary outside function body, Greg Chicares, 2020/09/06
- [lmi-commits] [lmi] master 7b9b0cf 11/14: Resolve a marked defect [339], Greg Chicares, 2020/09/06
- [lmi-commits] [lmi] master 3cbd888 12/14: Improve documentation, Greg Chicares, 2020/09/06
- [lmi-commits] [lmi] master 3ff6e18 13/14: Add and use trivial const accessors, Greg Chicares, 2020/09/06
- [lmi-commits] [lmi] master 1f2d652 05/14: Calculate and store partial-mortality tpx along with lx, Greg Chicares, 2020/09/06
- [lmi-commits] [lmi] master a1d6c16 09/14: Improve documentation, Greg Chicares, 2020/09/06
- [lmi-commits] [lmi] master 59860e3 14/14: Move partial mortality into base class,
Greg Chicares <=