lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [5320] Refactor


From: Greg Chicares
Subject: [lmi-commits] [5320] Refactor
Date: Thu, 01 Dec 2011 03:52:15 +0000

Revision: 5320
          http://svn.sv.gnu.org/viewvc/?view=rev&root=lmi&revision=5320
Author:   chicares
Date:     2011-12-01 03:52:14 +0000 (Thu, 01 Dec 2011)
Log Message:
-----------
Refactor

Modified Paths:
--------------
    lmi/trunk/ChangeLog
    lmi/trunk/Makefile.am
    lmi/trunk/ihs_basicval.cpp
    lmi/trunk/ihs_irc7702.cpp
    lmi/trunk/ihs_irc7702.hpp
    lmi/trunk/objects.make

Added Paths:
-----------
    lmi/trunk/gpt_specamt.cpp
    lmi/trunk/gpt_specamt.hpp

Modified: lmi/trunk/ChangeLog
===================================================================
--- lmi/trunk/ChangeLog 2011-11-30 09:59:13 UTC (rev 5319)
+++ lmi/trunk/ChangeLog 2011-12-01 03:52:14 UTC (rev 5320)
@@ -28698,3 +28698,24 @@
   ihs_irc7702a.hpp
 Move and update certain documentation.
 
+20111129T1539Z <address@hidden> [603]
+
+  ihs_acctval.cpp
+Remove markers for defects already resolved.
+
+20111130T0959Z <address@hidden> [603]
+
+  ihs_acctval.cpp
+Improve documentation.
+
+20111201T0352Z <address@hidden> [603]
+
+  Makefile.am
+  gpt_specamt.cpp [new file]
+  gpt_specamt.hpp [new file]
+  ihs_basicval.cpp
+  ihs_irc7702.cpp
+  ihs_irc7702.hpp
+  objects.make
+Refactor.
+

Modified: lmi/trunk/Makefile.am
===================================================================
--- lmi/trunk/Makefile.am       2011-11-30 09:59:13 UTC (rev 5319)
+++ lmi/trunk/Makefile.am       2011-12-01 03:52:14 UTC (rev 5320)
@@ -331,6 +331,7 @@
     authenticity.cpp \
     commutation_functions.cpp \
     fund_data.cpp \
+    gpt_specamt.cpp \
     ihs_acctval.cpp \
     ihs_avdebug.cpp \
     ihs_avmly.cpp \
@@ -978,6 +979,7 @@
     fund_data.hpp \
     getopt.hpp \
     global_settings.hpp \
+    gpt_specamt.hpp \
     group_values.hpp \
     handle_exceptions.hpp \
     icon_monger.hpp \

Added: lmi/trunk/gpt_specamt.cpp
===================================================================
--- lmi/trunk/gpt_specamt.cpp                           (rev 0)
+++ lmi/trunk/gpt_specamt.cpp   2011-12-01 03:52:14 UTC (rev 5320)
@@ -0,0 +1,182 @@
+// Determine specamt from GLP or GSP.
+//
+// Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 
2010, 2011 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+#   include "pchfile.hpp"
+#   pragma hdrstop
+#endif // __BORLANDC__
+
+#include "gpt_specamt.hpp"
+
+#include "assert_lmi.hpp"
+#include "basic_values.hpp"
+#include "safely_dereference_as.hpp"
+#include "zero.hpp"
+
+double gpt_specamt::CalculateGLPSpecAmt
+    (BasicValues const& a_Values
+    ,int                a_Duration
+    ,double             a_Premium
+    ,mcenum_dbopt_7702  a_DBOpt
+    )
+{
+    Irc7702 const& z(safely_dereference_as<Irc7702>(a_Values.Irc7702_.get()));
+    return CalculateSpecAmt
+        (a_Values
+        ,Irc7702::Get4PctBasis(a_DBOpt)
+        ,a_Duration
+        ,a_Premium
+        ,z.PvNpfLvlTgt[Irc7702::Get4PctBasis(a_DBOpt)][a_Duration]
+        ,z.PvNpfLvlExc[Irc7702::Get4PctBasis(a_DBOpt)][a_Duration]
+        );
+}
+
+double gpt_specamt::CalculateGSPSpecAmt
+    (BasicValues const& a_Values
+    ,int                a_Duration
+    ,double             a_Premium
+    )
+{
+    Irc7702 const& z(safely_dereference_as<Irc7702>(a_Values.Irc7702_.get()));
+    return CalculateSpecAmt
+        (a_Values
+        ,Irc7702::Opt1Int6Pct
+        ,a_Duration
+        ,a_Premium
+        ,z.PvNpfSglTgt[Irc7702::Opt1Int6Pct][a_Duration]
+        ,z.PvNpfSglExc[Irc7702::Opt1Int6Pct][a_Duration]
+        );
+}
+
+class FindSpecAmt
+{
+    typedef Irc7702::EIOBasis EIOBasis;
+    BasicValues const& Values_;
+    Irc7702     const& Irc7702_;
+    EIOBasis    const  EIOBasis_;
+    int         const  Duration;
+    double      const  Premium;
+    double      const  NetPmtFactorTgt;
+    double      const  NetPmtFactorExc;
+    double             SpecAmt;
+
+  public:
+    FindSpecAmt
+        (BasicValues const& a_Values
+        ,Irc7702 const&     a_IRC7702
+        ,EIOBasis           a_EIOBasis
+        ,int                a_Duration
+        ,double             a_Premium
+        ,double             a_NetPmtFactorTgt
+        ,double             a_NetPmtFactorExc
+        )
+        :Values_         (a_Values)
+        ,Irc7702_        (a_IRC7702)
+        ,EIOBasis_       (a_EIOBasis)
+        ,Duration        (a_Duration)
+        ,Premium         (a_Premium)
+        ,NetPmtFactorTgt (a_NetPmtFactorTgt)
+        ,NetPmtFactorExc (a_NetPmtFactorExc)
+        ,SpecAmt         (0.0)
+        {
+        }
+    double operator()(double a_Trial)
+        {
+        SpecAmt = a_Trial;
+        Irc7702_.Initialize7702(a_Trial);
+        const_cast<double&>(Irc7702_.TargetPremium) = Values_.GetTgtPrem
+            (Duration
+            ,SpecAmt
+            ,mce_option1 // TODO ?? Should pass dbopt.
+            ,mce_annual
+            );
+        return
+                Irc7702_.CalculatePremium
+                    (EIOBasis_
+                    ,Duration
+                    ,a_Trial
+                    ,a_Trial
+                    ,a_Trial
+                    ,NetPmtFactorTgt
+                    ,NetPmtFactorExc
+                    )
+            -   Premium
+            ;
+        }
+    double Get()
+        {
+        return SpecAmt;
+        }
+};
+
+/// CalculatePremium() implements an analytic solution, while 
CalculateSpecAmt()
+/// uses iteration. Reason: we anticipate that no parameter depends on premium
+/// except load (up to target vs. excess), so the direct solution isn't too
+/// complicated. But when SpecAmt is unknown, we cannot know either the actual
+/// specified-amount (underwriting) or ADD charge if they apply only up to some
+/// maximum, or the target. So here we have eight special cases rather than
+/// two, and adding another QAB like ADD could double the eight cases.
+///
+/// Return value is both specamt and bftamt; we name it 'specamt'
+/// because it is typically used to set an input parameter, and
+/// specamt is such a parameter whereas DB is not.
+
+double gpt_specamt::CalculateSpecAmt
+    (BasicValues const& a_Values
+    ,EIOBasis           a_EIOBasis
+    ,int                a_Duration
+    ,double             a_Premium
+    ,double             a_NetPmtFactorTgt
+    ,double             a_NetPmtFactorExc
+    )
+{
+    LMI_ASSERT(0.0 != a_Premium);
+    LMI_ASSERT(0.0 != a_NetPmtFactorTgt);
+    LMI_ASSERT(0.0 != a_NetPmtFactorExc);
+
+    Irc7702 const& z(safely_dereference_as<Irc7702>(a_Values.Irc7702_.get()));
+
+    FindSpecAmt fsa
+        (a_Values
+        ,z
+        ,a_EIOBasis
+        ,a_Duration
+        ,a_Premium
+        ,a_NetPmtFactorTgt
+        ,a_NetPmtFactorExc
+        );
+
+    // TODO ?? The upper bound ideally wouldn't be hard coded; but if
+    // it must be, then it can't plausibly reach one billion dollars.
+    decimal_root
+        (0.0
+        ,999999999.99
+        ,bias_higher
+        ,z.round_min_specamt.decimals()
+        ,fsa
+        ,true
+        );
+
+    return fsa.Get();
+}
+


Property changes on: lmi/trunk/gpt_specamt.cpp
___________________________________________________________________
Added: svn:keywords
   + Id

Added: lmi/trunk/gpt_specamt.hpp
===================================================================
--- lmi/trunk/gpt_specamt.hpp                           (rev 0)
+++ lmi/trunk/gpt_specamt.hpp   2011-12-01 03:52:14 UTC (rev 5320)
@@ -0,0 +1,82 @@
+// Determine specamt from GLP or GSP.
+//
+// Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 
2010, 2011 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifndef gpt_specamt_hpp
+#define gpt_specamt_hpp
+
+#include "config.hpp"
+
+#include "ihs_irc7702.hpp"              // Irc7702::EIOBasis
+#include "mc_enum_type_enums.hpp"       // mcenum_dbopt_7702
+
+class BasicValues;
+
+/// Determine specamt from GLP or GSP.
+///
+/// This class exists for the sole purpose of determining specamt from
+/// a premium taken as the GLP or GSP. Target premium is the essential
+/// complication: it depends on specamt, and different products set it
+/// in such different ways that it's best established by calling into
+/// an instance of class BasicValues. There's no other irreducible
+/// dependency between that class and class Irc7702, so it's best to
+/// keep them separate except for this special-purpose accouplement.
+///
+/// The physical rationale is to group several functions together so
+/// that they can easily be made friends of class Irc7702. Although
+/// it's unusual for all members of a class to be static functions,
+/// the other options are worse. Befriending multiple free functions
+/// would introduce their argument types (including class BasicValues)
+/// into class Irc7702. Friendship could be avoided by adding numerous
+/// public accessors to class Irc7702, but would increase complexity
+/// and weaken encapsulation. And inheritance would just be wrong.
+
+class gpt_specamt
+{
+    typedef Irc7702::EIOBasis EIOBasis;
+
+  public:
+    static double CalculateGLPSpecAmt
+        (BasicValues const& a_Values
+        ,int                a_Duration
+        ,double             a_Premium
+        ,mcenum_dbopt_7702  a_DBOpt
+        );
+    static double CalculateGSPSpecAmt
+        (BasicValues const& a_Values
+        ,int                a_Duration
+        ,double             a_Premium
+        );
+
+  private:
+    static double CalculateSpecAmt
+        (BasicValues const& a_Values
+        ,Irc7702::EIOBasis  a_EIOBasis
+        ,int                a_Duration
+        ,double             a_Premium
+        ,double             a_NetPmtFactorTgt
+        ,double             a_NetPmtFactorExc
+        );
+};
+
+#endif // gpt_specamt_hpp
+


Property changes on: lmi/trunk/gpt_specamt.hpp
___________________________________________________________________
Added: svn:keywords
   + Id

Modified: lmi/trunk/ihs_basicval.cpp
===================================================================
--- lmi/trunk/ihs_basicval.cpp  2011-11-30 09:59:13 UTC (rev 5319)
+++ lmi/trunk/ihs_basicval.cpp  2011-12-01 03:52:14 UTC (rev 5320)
@@ -40,6 +40,7 @@
 #include "et_vector.hpp"
 #include "fund_data.hpp"
 #include "global_settings.hpp"
+#include "gpt_specamt.hpp"
 #include "ieee754.hpp"           // ldbl_eps_plus_one()
 #include "ihs_irc7702.hpp"
 #include "ihs_irc7702a.hpp"
@@ -611,8 +612,7 @@
 
     Irc7702_.reset
         (new Irc7702
-            (*this
-            ,yare_input_.DefinitionOfLifeInsurance
+            (yare_input_.DefinitionOfLifeInsurance
             ,yare_input_.IssueAge
             ,EndtAge
             ,Mly7702qc
@@ -1249,8 +1249,9 @@
     ) const
 {
     double annualized_pmt = a_ee_mode * a_ee_pmt + a_er_mode * a_er_pmt;
-    return Irc7702_->CalculateGLPSpecAmt
-        (0
+    return gpt_specamt::CalculateGLPSpecAmt
+        (*this
+        ,0
         ,annualized_pmt
         ,effective_dbopt_7702(DeathBfts_->dbopt()[0], Equiv7702DBO3)
         );
@@ -1265,8 +1266,9 @@
     ) const
 {
     double annualized_pmt = a_ee_mode * a_ee_pmt + a_er_mode * a_er_pmt;
-    return Irc7702_->CalculateGSPSpecAmt
-        (0
+    return gpt_specamt::CalculateGSPSpecAmt
+        (*this
+        ,0
         ,annualized_pmt
         );
 }

Modified: lmi/trunk/ihs_irc7702.cpp
===================================================================
--- lmi/trunk/ihs_irc7702.cpp   2011-11-30 09:59:13 UTC (rev 5319)
+++ lmi/trunk/ihs_irc7702.cpp   2011-12-01 03:52:14 UTC (rev 5320)
@@ -30,10 +30,8 @@
 
 #include "alert.hpp"
 #include "assert_lmi.hpp"
-#include "basic_values.hpp" // For target-premium callback.
 #include "commutation_functions.hpp"
 #include "materially_equal.hpp"
-#include "zero.hpp"
 
 #include <algorithm>
 #include <cmath>
@@ -112,8 +110,7 @@
 
 //============================================================================
 Irc7702::Irc7702
-    (BasicValues         const& a_Values
-    ,mcenum_defn_life_ins       a_Test7702
+    (mcenum_defn_life_ins       a_Test7702
     ,int                        a_IssueAge
     ,int                        a_EndtAge
     ,std::vector<double> const& a_Qc
@@ -145,8 +142,7 @@
     ,double                     a_LeastBftAmtEver
     ,mcenum_dbopt_7702          a_PriorDBOpt
     )
-    :Values             (a_Values)
-    ,Test7702           (a_Test7702)
+    :Test7702           (a_Test7702)
     ,IssueAge           (a_IssueAge)
     ,EndtAge            (a_EndtAge)
     ,Qc                 (a_Qc)
@@ -803,7 +799,7 @@
 //============================================================================
 Irc7702::EIOBasis Irc7702::Get4PctBasis
     (mcenum_dbopt_7702 a_DBOpt
-    ) const
+    )
 {
     switch(a_DBOpt)
         {
@@ -956,141 +952,6 @@
 */
 
 //============================================================================
-double Irc7702::CalculateGLPSpecAmt
-    (int               a_Duration
-    ,double            a_Premium
-    ,mcenum_dbopt_7702 a_DBOpt
-    ) const
-{
-    return CalculateSpecAmt
-        (Get4PctBasis(a_DBOpt)
-        ,a_Duration
-        ,a_Premium
-        ,PvNpfLvlTgt[Get4PctBasis(a_DBOpt)][a_Duration]
-        ,PvNpfLvlExc[Get4PctBasis(a_DBOpt)][a_Duration]
-        );
-}
-
-//============================================================================
-double Irc7702::CalculateGSPSpecAmt
-    (int    a_Duration
-    ,double a_Premium
-    ) const
-{
-    return CalculateSpecAmt
-        (Opt1Int6Pct
-        ,a_Duration
-        ,a_Premium
-        ,PvNpfSglTgt[Opt1Int6Pct][a_Duration]
-        ,PvNpfSglExc[Opt1Int6Pct][a_Duration]
-        );
-}
-
-//namespace
-//{
-    class FindSpecAmt
-    {
-        typedef Irc7702::EIOBasis EIOBasis;
-        Irc7702 const&  Irc7702_;
-        EIOBasis const& EIOBasis_;
-        int const       Duration;
-        double const    Premium;
-        double const    NetPmtFactorTgt;
-        double const    NetPmtFactorExc;
-        double          SpecAmt;
-
-      public:
-        FindSpecAmt
-            (Irc7702 const&  a_IRC7702
-            ,EIOBasis const& a_EIOBasis
-            ,int             a_Duration
-            ,double          a_Premium
-            ,double          a_NetPmtFactorTgt
-            ,double          a_NetPmtFactorExc
-            )
-            :Irc7702_        (a_IRC7702)
-            ,EIOBasis_       (a_EIOBasis)
-            ,Duration        (a_Duration)
-            ,Premium         (a_Premium)
-            ,NetPmtFactorTgt (a_NetPmtFactorTgt)
-            ,NetPmtFactorExc (a_NetPmtFactorExc)
-            ,SpecAmt         (0.0)
-            {
-            }
-        double operator()(double a_Trial)
-            {
-            SpecAmt = a_Trial;
-            Irc7702_.Initialize7702(a_Trial);
-            const_cast<double&>(Irc7702_.TargetPremium) = 
Irc7702_.Values.GetTgtPrem
-                (Duration
-                ,SpecAmt
-                ,mce_option1 // TODO ?? Should pass dbopt.
-                ,mce_annual
-                );
-            return
-                    Irc7702_.CalculatePremium
-                        (EIOBasis_
-                        ,Duration
-                        ,a_Trial
-                        ,a_Trial
-                        ,a_Trial
-                        ,NetPmtFactorTgt
-                        ,NetPmtFactorExc
-                        )
-                -   Premium
-                ;
-            }
-        double Get()
-            {
-            return SpecAmt;
-            }
-    };
-//} // Unnamed namespace.
-
-//============================================================================
-// CalculatePremium() implements an analytic solution, while CalculateSpecAmt()
-// uses iteration. Reason: we anticipate that no parameter depends on premium
-// except load (up to target vs. excess), so the direct solution isn't too
-// complicated. But when SpecAmt is unknown, we cannot know either the actual
-// specified-amount (underwriting) or ADD charge if they apply only up to some
-// maximum, or the target. So here we have eight special cases rather than
-// two, and adding another QAB like ADD could double the eight cases.
-double Irc7702::CalculateSpecAmt
-    (EIOBasis const& a_EIOBasis
-    ,int             a_Duration
-    ,double          a_Premium
-    ,double          a_NetPmtFactorTgt
-    ,double          a_NetPmtFactorExc
-    ) const
-{
-    LMI_ASSERT(0.0 != a_Premium);
-    LMI_ASSERT(0.0 != a_NetPmtFactorTgt);
-    LMI_ASSERT(0.0 != a_NetPmtFactorExc);
-
-    FindSpecAmt fsa
-        (*this
-        ,a_EIOBasis
-        ,a_Duration
-        ,a_Premium
-        ,a_NetPmtFactorTgt
-        ,a_NetPmtFactorExc
-        );
-
-    // TODO ?? The upper bound ideally wouldn't be hard coded; but if
-    // it must be, then it can't plausibly reach one billion dollars.
-    decimal_root
-        (0.0
-        ,999999999.99
-        ,bias_higher
-        ,round_min_specamt.decimals()
-        ,fsa
-        ,true
-        );
-
-    return fsa.Get();
-}
-
-//============================================================================
 double Irc7702::GetLeastBftAmtEver() const
 {
     return LeastBftAmtEver;

Modified: lmi/trunk/ihs_irc7702.hpp
===================================================================
--- lmi/trunk/ihs_irc7702.hpp   2011-11-30 09:59:13 UTC (rev 5319)
+++ lmi/trunk/ihs_irc7702.hpp   2011-12-01 03:52:14 UTC (rev 5320)
@@ -35,7 +35,6 @@
 
 #include <vector>
 
-class BasicValues;
 class ULCommFns;
 
 // Specified amount (specamt) is carefully distinguished from benefit
@@ -60,11 +59,11 @@
     ,virtual private obstruct_slicing<Irc7702>
 {
     friend class FindSpecAmt;
+    friend class gpt_specamt;
 
   public:
     Irc7702
-        (BasicValues         const& a_Values
-        ,mcenum_defn_life_ins       a_Test7702
+        (mcenum_defn_life_ins       a_Test7702
         ,int                        a_IssueAge
         ,int                        a_EndtAge
         ,std::vector<double> const& a_Qc
@@ -141,15 +140,6 @@
         ,double                     a_SpecAmt
         ,double                     a_LeastBftAmtEver
         ) const;
-    double CalculateGLPSpecAmt
-        (int                        a_Duration
-        ,double                     a_Premium
-        ,mcenum_dbopt_7702          a_DBOpt
-        ) const;
-    double CalculateGSPSpecAmt
-        (int                        a_Duration
-        ,double                     a_Premium
-        ) const;
     void Initialize7702
         (double                     a_SpecAmt
         ) const;
@@ -180,21 +170,10 @@
         ,double                     a_NetPmtFactorTgt
         ,double                     a_NetPmtFactorExc
         ) const;
-    // Return value is both specamt and bftamt; we name it 'specamt'
-    // because it is typically used to set an input parameter, and
-    // specamt is such a parameter whereas DB is not.
-    double CalculateSpecAmt
-        (EIOBasis const&            a_EIOBasis
-        ,int                        a_Duration
-        ,double                     a_Premium
-        ,double                     a_NetPmtFactorTgt
-        ,double                     a_NetPmtFactorExc
-        ) const;
-    EIOBasis Get4PctBasis
+    static EIOBasis Get4PctBasis
         (mcenum_dbopt_7702          a_DBOpt
-        ) const;
+        );
 
-    BasicValues const&         Values;     // needed for target premium 
callback
     mcenum_defn_life_ins const Test7702;   // 7702 test: CVAT or GPT
     int const                  IssueAge;   // Issue age
     int const                  EndtAge;    // Endowment age

Modified: lmi/trunk/objects.make
===================================================================
--- lmi/trunk/objects.make      2011-11-30 09:59:13 UTC (rev 5319)
+++ lmi/trunk/objects.make      2011-12-01 03:52:14 UTC (rev 5320)
@@ -272,6 +272,7 @@
   authenticity.o \
   commutation_functions.o \
   fund_data.o \
+  gpt_specamt.o \
   ihs_acctval.o \
   ihs_avdebug.o \
   ihs_avmly.o \
@@ -391,6 +392,7 @@
   fenv_lmi.o \
   fund_data.o \
   global_settings.o \
+  gpt_specamt.o \
   ihs_basicval.o \
   ihs_mortal.o \
   input.o \




reply via email to

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