[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] valyuta/004 87f1e13 7/9: Split a unit-test TU in twa
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] valyuta/004 87f1e13 7/9: Split a unit-test TU in twain |
Date: |
Tue, 29 Dec 2020 14:46:03 -0500 (EST) |
branch: valyuta/004
commit 87f1e132e89a4bb90f63bd79704eb083a255f339
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Split a unit-test TU in twain
Commutation functions are an coherent abstraction that is independent
of 7702. In the past, testing 7702 tables in the commutation-functions
unit test was a harmless expedient that introduced no new dependency
(CSO tables were already used to test commutation functions, and 7702
tables used them and a (formerly) hardcoded 7702 interest rate). Now,
however, 7702 tables depend on a 7702 interest rate that must soon
vary according to external circumstances that are not relevant to a
unit test for commutation functions.
---
Makefile.am | 10 +-
commutation_functions_test.cpp | 573 +--------------------------------------
irc7702_tables_test.cpp | 601 +++++++++++++++++++++++++++++++++++++++++
objects.make | 9 +-
4 files changed, 622 insertions(+), 571 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 24f9dc7..9877ec0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -119,6 +119,7 @@ TESTS = \
test_input_seq \
test_input \
test_interpolate_string \
+ test_irc7702_tables \
test_irc7702a \
test_istream_to_string \
test_ledger \
@@ -670,7 +671,6 @@ test_commutation_functions_SOURCES = \
commutation_functions.cpp \
commutation_functions_test.cpp \
cso_table.cpp \
- irc7702_tables.cpp \
timer.cpp
test_commutation_functions_CXXFLAGS = $(AM_CXXFLAGS)
@@ -862,6 +862,14 @@ test_interpolate_string_SOURCES = \
interpolate_string_test.cpp
test_interpolate_string_CXXFLAGS = $(AM_CXXFLAGS)
+test_irc7702_tables_SOURCES = \
+ $(common_test_objects) \
+ commutation_functions.cpp \
+ cso_table.cpp \
+ irc7702_tables.cpp \
+ irc7702_tables_test.cpp
+test_irc7702_tables_CXXFLAGS = $(AM_CXXFLAGS)
+
test_irc7702a_SOURCES = \
$(common_test_objects) \
calendar_date.cpp \
diff --git a/commutation_functions_test.cpp b/commutation_functions_test.cpp
index 63b6689..3910cdf 100644
--- a/commutation_functions_test.cpp
+++ b/commutation_functions_test.cpp
@@ -25,16 +25,13 @@
#include "cso_table.hpp"
#include "et_vector.hpp"
-#include "irc7702_tables.hpp"
-#include "materially_equal.hpp"
#include "math_functions.hpp"
#include "ssize_lmi.hpp"
#include "test_tools.hpp"
-#include "timer.hpp"
+#include "timer.hpp" // TimeAnAliquot()
-#include <algorithm>
-#include <cfloat> // DBL_EPSILON
-#include <cmath> // fabs(), log()
+#include <algorithm> // max()
+#include <cmath> // fabs()
#include <functional> // bind()
#include <iomanip> // setw() etc.
#include <ios> // ios_base::fixed()
@@ -581,7 +578,7 @@ void OLCommFnsTest()
///
/// Calculate year-by-year option B account value for a no-load UL
/// contract; compare to results imported from a spreadsheet, with
-/// a comparison tolerance of 1.0e-13 (see 'materially_equal.hpp').
+/// a comparison tolerance of 1.0e-13 (cf. 'materially_equal.hpp').
///
/// This example calculates and uses a premium to endow for ten times
/// the specified amount. It is worth pointing out that the 7702
@@ -712,567 +709,6 @@ void Test_1980_CSO_Male_ANB()
;
}
-// These two arrays are pasted from the "corridor mult" and "7Pt"
-// columns of 'validate_2001cso', after loading that spreadsheet
-// in 'gnumeric' and formatting those columns to twenty decimals.
-// They use UL commutation functions. See:
-// https://lists.nongnu.org/archive/html/lmi/2015-07/msg00004.html
-
-static double const ss_ul_corr[100] =
-{16.05428685334679173025
-,15.58833599045649087600
-,15.08131070200895074152
-,14.56342500447235721595
-,14.04800434985640045227
-,13.54397833171609022429
-,13.05507387234714933300
-,12.58409661481673680328
-,12.13030984655223143420
-,11.69174091577074925397
-,11.26914166185736476677
-,10.86078105527353621085
-,10.47029884268147448267
-,10.09843359081480329564
-, 9.74294658529263379876
-, 9.40759852219825454256
-, 9.09057733647785148889
-, 8.79027993284445763322
-, 8.50397918973384925323
-, 8.22818279387080941945
-, 7.96118932260834633041
-, 7.70160265863622406357
-, 7.44976553796342688685
-, 7.20499258154732391546
-, 6.96714059909527883008
-, 6.73646229302490073820
-, 6.51311660413237181189
-, 6.29752334665072410758
-, 6.08868484174302349032
-, 5.88548788700455993705
-, 5.68759233818214315903
-, 5.49522616091999260846
-, 5.30831030469870679411
-, 5.12719475896684162564
-, 4.95191511278486373726
-, 4.78246091867951061971
-, 4.61878315488500756913
-, 4.46095911393538724354
-, 4.30885324846834905088
-, 4.16231281496283944676
-, 4.02117206738939625410
-, 3.88525584688570946312
-, 3.75459497560775545821
-, 3.62916166404261142375
-, 3.50888104609130779821
-, 3.39355762372614266908
-, 3.28298850929638108553
-, 3.17689558846831987537
-, 3.07468880549077061559
-, 2.97599858560200258850
-, 2.88084470780052326333
-, 2.78925893311157580001
-, 2.70137019361723274002
-, 2.61714709838817194409
-, 2.53660248632115825629
-, 2.45973786190931420492
-, 2.38640466067929235550
-, 2.31641149864538897774
-, 2.24933351623363186889
-, 2.18485859704871998588
-, 2.12298548776600348731
-, 2.06377060631972986116
-, 2.00732734016649461140
-, 1.95364688011445042370
-, 1.90257560558083449465
-, 1.85390645085427285821
-, 1.80741123662186708998
-, 1.76283474569483433747
-, 1.72002394995400198496
-, 1.67882810972211782286
-, 1.63921097550600691761
-, 1.60120703518178442160
-, 1.56497463008854764688
-, 1.53056280828563395779
-, 1.49778239342608299189
-, 1.46651641824560186045
-, 1.43669325356442145747
-, 1.40828569180480034362
-, 1.38135623671030072224
-, 1.35595612880361837682
-, 1.33205157176719568568
-, 1.30966078753973991233
-, 1.28874851143154445232
-, 1.26913015525378947146
-, 1.25071057910177563244
-, 1.23349050718607222699
-, 1.21741784864651991782
-, 1.20250900968492024923
-, 1.18879112389207719502
-, 1.17616396084234375863
-, 1.16443752080775975166
-, 1.15305360309844973088
-, 1.14154811660101529469
-, 1.12990850456893321407
-, 1.11805918549405669538
-, 1.10585007755591901990
-, 1.09272887195287826678
-, 1.07768889207696427768
-, 1.05889467902677236744
-, 1.03392745267212093907
-};
-
-static double const ss_ul_7pp[100] =
-{0.00999062440751989980
-,0.01028589716601673552
-,0.01062994889232243140
-,0.01100709650196978612
-,0.01141070148832002557
-,0.01183541561717901119
-,0.01227894262614234906
-,0.01273890281958302631
-,0.01321604446917592178
-,0.01371289447070540846
-,0.01422886804024923145
-,0.01476663382430560070
-,0.01532082243677517636
-,0.01588896142650659399
-,0.01647329371041960158
-,0.01706468830702987174
-,0.01766329128405109278
-,0.01826920380439612038
-,0.01888577215846250559
-,0.01951980733786566266
-,0.02017525559338708904
-,0.02085633674231307522
-,0.02156255487066226217
-,0.02229655784475696040
-,0.02305946770995651388
-,0.02385084039099466188
-,0.02467017211649025557
-,0.02551531634397709650
-,0.02639053264687007266
-,0.02730200324593424696
-,0.02825306412357134547
-,0.02924406198100011275
-,0.03027703373115286228
-,0.03135091541809587046
-,0.03246623554060621558
-,0.03362359115588391123
-,0.03482374166899589174
-,0.03606599422970604291
-,0.03735138265340059993
-,0.03868112554395738284
-,0.04005664955242391884
-,0.04147956289034327587
-,0.04294811241142196950
-,0.04446025296529201171
-,0.04601393073756083335
-,0.04760879558840754727
-,0.04924490987244876244
-,0.05092435295618532448
-,0.05265819337044034404
-,0.05445592655778288410
-,0.05631857051817811682
-,0.05824605305494993251
-,0.06023316553704032711
-,0.06227739915724234826
-,0.06437337655335158282
-,0.06651452375385756566
-,0.06870008885031553270
-,0.07093229090910557755
-,0.07322803247632281298
-,0.07560364239280463472
-,0.07805934610230855220
-,0.08058864677483222605
-,0.08317610640496489460
-,0.08580967539473746686
-,0.08848738367896104295
-,0.09121467879909027354
-,0.09400583834207149048
-,0.09688672842792392381
-,0.09987797601076543741
-,0.10300586867342216568
-,0.10628627958701071521
-,0.10972561873411729172
-,0.11330637125813265709
-,0.11702343505126171219
-,0.12092139119378841894
-,0.12504454546357654521
-,0.12943750862444663996
-,0.13413592524308720622
-,0.13914635982676987203
-,0.14447036818012279347
-,0.15013201659901123652
-,0.15613245573059561511
-,0.16249080594919776410
-,0.16930561735046611993
-,0.17664266810670117835
-,0.18447808708057295002
-,0.19278062434737353037
-,0.20145103153300336629
-,0.21034011597622215284
-,0.21938905920499771063
-,0.22862636208321829301
-,0.23858323922962185182
-,0.24981209741923118828
-,0.26220186143911550225
-,0.28642313285880155460
-,0.31717670783614265728
-,0.35965728769722676850
-,0.42686340219691948361
-,0.56031960772985123231
-,0.96718584791956385693
-};
-
-static double const ss_ol_corr[100] =
-{16.03069515721970
-,15.56545542916450
-,15.05919070490880
-,14.54207568908480
-,14.02741865395940
-,13.52413778894550
-,13.03595534928800
-,12.56567351181010
-,12.11255664606990
-,11.67463475724690
-,11.25265884919660
-,10.84490022682110
-,10.45499411648920
-,10.08367827587890
-, 9.72871697105366
-, 9.39386625032253
-, 9.07731649360929
-, 8.77746677844702
-, 8.49159356632208
-, 8.21620906614680
-, 7.94961408895666
-, 7.69041434829488
-, 7.43895222208455
-, 7.19454325862477
-, 6.95704451334878
-, 6.72670844298237
-, 6.50369386229784
-, 6.28842014111261
-, 6.07989090207194
-, 5.87699437244831
-, 5.67939087980040
-, 5.48730816704992
-, 5.30066733657544
-, 5.11981801243330
-, 4.94479580197072
-, 4.77559033227269
-, 4.61215270269525
-, 4.45456017660894
-, 4.30267743185537
-, 4.15635196932867
-, 4.01541830136802
-, 3.87970153695790
-, 3.74923252419573
-, 3.62398356964482
-, 3.50387995898405
-, 3.38872648535844
-, 3.27832055910429
-, 3.17238444761715
-, 3.07032882594890
-, 2.97178458990226
-, 2.87677154683430
-, 2.78532147558464
-, 2.69756322259474
-, 2.61346549280934
-, 2.53304117542039
-, 2.45629184138028
-, 2.38306915684781
-, 2.31318201343135
-, 2.24620607000211
-, 2.18182960005580
-, 2.12005141288773
-, 2.06092793502465
-, 2.00457251268315
-, 1.95097642680359
-, 1.89998629486328
-, 1.85139534102519
-, 1.80497569334546
-, 1.76047246308625
-, 1.71773284834008
-, 1.67660633172185
-, 1.63705678130120
-, 1.59911874599313
-, 1.56295053110245
-, 1.52860126016288
-, 1.49588204901423
-, 1.46467616317511
-, 1.43491217369859
-, 1.40656304375306
-, 1.37969137924250
-, 1.35434853909332
-, 1.33050092572148
-, 1.30816690878090
-, 1.28731141765329
-, 1.26775022859716
-, 1.24938847835256
-, 1.23222703314812
-, 1.21621399207302
-, 1.20136578942719
-, 1.18770946309554
-, 1.17514487873005
-, 1.16348237607749
-, 1.15216547131899
-, 1.14073189550427
-, 1.12916922360185
-, 1.11740178851122
-, 1.10527880649853
-, 1.09224812150223
-, 1.07730439700387
-, 1.05861825755067
-, 1.03377932830447
-};
-
-static double const ss_ol_7pp[100] =
-{0.010005327186958
-,0.010301016999909
-,0.010645562907928
-,0.011023256091546
-,0.011427447066149
-,0.011852778725528
-,0.012296950914868
-,0.012757579901923
-,0.013235415035928
-,0.013732987171806
-,0.014249710382439
-,0.014788257479081
-,0.015343250090949
-,0.015912211536579
-,0.016497388214910
-,0.017089634046416
-,0.017689095179996
-,0.018295872789306
-,0.018913318467641
-,0.019548254138137
-,0.020204632276942
-,0.020886679342528
-,0.021593898359639
-,0.022328941267110
-,0.023092931684899
-,0.023885424544973
-,0.024705914983204
-,0.025552252675176
-,0.026428703850223
-,0.027341460483306
-,0.028293863627333
-,0.029286260140180
-,0.030320689819902
-,0.031396086507395
-,0.032512979072804
-,0.033671965026394
-,0.034873804442084
-,0.036117802719780
-,0.037404994687573
-,0.038736600205397
-,0.040114047455165
-,0.041538946413990
-,0.043009540227530
-,0.044523779574169
-,0.046079606410946
-,0.047676669074214
-,0.049315028941757
-,0.050996767549288
-,0.052732969936346
-,0.054533145156035
-,0.056398310810159
-,0.058328392333208
-,0.060318170371727
-,0.062365129728319
-,0.064463881836038
-,0.066607839381289
-,0.068796246114121
-,0.071031321069015
-,0.073329989610741
-,0.075708601646018
-,0.078167377428823
-,0.080699804001149
-,0.083290412982767
-,0.085927129777381
-,0.088607974722984
-,0.091338396338728
-,0.094132685084862
-,0.097016735479080
-,0.100011192647016
-,0.103142368320708
-,0.106426141130087
-,0.109868909420875
-,0.113453108667038
-,0.117173603120152
-,0.121075007777516
-,0.125201654498742
-,0.129598172492744
-,0.134300204399513
-,0.139314266113466
-,0.144641852159782
-,0.150306989508367
-,0.156310753283924
-,0.162672203024568
-,0.169489903915145
-,0.176829591075732
-,0.184667243191684
-,0.192971446212092
-,0.201642732430611
-,0.210531675161746
-,0.219579312738766
-,0.228814049726310
-,0.238767148018836
-,0.249990843980925
-,0.262373528220005
-,0.286591643152315
-,0.317340642829014
-,0.359815590009435
-,0.427015751779345
-,0.560465915779944
-,0.967324430485689
-};
-
-/// Test CVAT corridor and seven-pay premium.
-
-void Test_Corridor_and_7PP()
-{
- std::vector<double> const naar_discount
- (100
- ,i_upper_12_over_12_from_i<double>()(0.04)
- );
- irc7702_tables z
- (mce_2001cso
- ,oe_orthodox
- ,oe_age_last_birthday
- ,mce_unisex
- ,mce_unismoke
- ,naar_discount
- ,1.0 / 12.0
- ,0
- ,100
- );
- std::vector<double> const& ul_corr = z.ul_corr();
- std::vector<double> const& ul_7pp = z.ul_7pp ();
- std::vector<double> const& ol_corr = z.ol_corr();
- std::vector<double> const& ol_7pp = z.ol_7pp ();
-
- // In the last year, the OL formula reduces to:
- // NSP[omega-1] = vq * (i/delta) + vp
- // (0.30285 / 1.04) * (0.04 / ln(1.04)) + (1 - 0.30285) / 1.04
- BOOST_TEST(materially_equal(0.30285, z.q_[99], 0.0));
- double ol_nsp99 =
- ( z.q_[99] / 1.04) * (0.04 / std::log(1.04))
- + (1.0 - z.q_[99]) / 1.04
- ;
- BOOST_TEST(materially_equal(ol_corr[99], 1.0 / ol_nsp99, DBL_EPSILON));
-
- for(int j = 0; j < lmi::ssize(ol_corr); ++j)
- {
- // Values calculated here must match spreadsheet values to
- // within a minuscule tolerance.
- BOOST_TEST(materially_equal(ss_ul_corr[j], ul_corr[j]));
- BOOST_TEST(materially_equal(ss_ul_7pp [j], ul_7pp [j]));
- BOOST_TEST(materially_equal(ss_ol_corr[j], ol_corr[j]));
- BOOST_TEST(materially_equal(ss_ol_7pp [j], ol_7pp [j]));
- // The 0.0015 tolerance was found experimentally, not by any
- // sort of mathematical law. It represents the inherent
- // discrepancy between the UL method on the one hand, and the
- // OL method (with the i/delta approximation) on the other.
- BOOST_TEST(materially_equal( ol_corr[j], ul_corr[j], 0.0015));
- BOOST_TEST(materially_equal( ol_7pp [j], ul_7pp [j], 0.0015));
- }
-
- // At least for now, display plenty of detail.
-
- std::cout << std::endl;
-
- std::cout
- << ol_corr[99] << " OL corr[omega-1]\n"
- << 1.0 / ol_nsp99 << " vq * (i/delta) + vp\n"
- << std::endl
- ;
-
- std::cout << "q, UL corr, UL 7pp, OL corr, OL 7pp\n";
- for(int j = 0; j < lmi::ssize(ol_corr); ++j)
- {
- std::cout
- << j
- << '\t' << z.q_[j]
- << '\t' << ul_corr[j]
- << '\t' << ul_7pp[j]
- << '\t' << ol_corr[j]
- << '\t' << ol_7pp[j]
- << '\n';
- }
- std::cout << std::endl;
-
- std::vector<double> q12(lmi::ssize(ol_corr));
- assign(q12, apply_binary(coi_rate_from_q<double>(), z.q_, 1.0 / 12.0));
- std::cout << "q, q upper (12), UL corr, UL 7pp\n";
- for(int j = 0; j < lmi::ssize(ul_corr); ++j)
- {
- std::cout
- << j
- << '\t' << z.q_[j]
- << '\t' << q12[j]
- << '\t' << ul_corr[j]
- << '\t' << ul_7pp[j]
- << '\n';
- }
- std::cout << std::endl;
-
- std::cout << "UL corr, OL corr, relative error\n";
- for(int j = 0; j < lmi::ssize(ul_corr); ++j)
- {
- std::cout
- << j
- << '\t' << ul_corr[j]
- << '\t' << ol_corr[j]
- << '\t' << (ol_corr[j] - ul_corr[j]) / ul_corr[j]
- << '\n';
- }
- std::cout << std::endl;
-
- std::cout << "UL 7pp, OL 7pp, relative error\n";
- for(int j = 0; j < lmi::ssize(ul_corr); ++j)
- {
- std::cout
- << j
- << '\t' << ul_7pp[j]
- << '\t' << ol_7pp[j]
- << '\t' << (ol_7pp[j] - ul_7pp[j]) / ul_7pp[j]
- << '\n';
- }
- std::cout << std::endl;
-
- std::cout << "UL corr, 7pp: {calculated, spreadsheet, relative error}\n";
- for(int j = 0; j < lmi::ssize(ss_ul_corr); ++j)
- {
- std::cout
- << j
- << '\t' << ul_corr[j]
- << '\t' << ss_ul_corr[j]
- << '\t' << (ss_ul_corr[j] - ul_corr[j]) / ul_corr[j]
- << '\t' << ul_7pp[j]
- << '\t' << ss_ul_7pp[j]
- << '\t' << (ss_ul_7pp[j] - ul_7pp[j]) / ul_7pp[j]
- << '\n';
- }
- std::cout << std::endl;
-
- std::cout << "OL corr, 7pp: {calculated, spreadsheet, relative error}\n";
- for(int j = 0; j < lmi::ssize(ss_ul_corr); ++j)
- {
- std::cout
- << j
- << '\t' << ol_corr[j]
- << '\t' << ss_ol_corr[j]
- << '\t' << (ss_ol_corr[j] - ol_corr[j]) / ol_corr[j]
- << '\t' << ol_7pp[j]
- << '\t' << ss_ol_7pp[j]
- << '\t' << (ss_ol_7pp[j] - ol_7pp[j]) / ol_7pp[j]
- << '\n';
- }
-}
-
/// Test UL commutation functions in extreme cases.
///
/// For example, ic and ig can both be zero, and qc may round to zero
@@ -1291,7 +727,6 @@ int test_main(int, char*[])
ULCommFnsTest();
OLCommFnsTest();
Test_1980_CSO_Male_ANB();
- Test_Corridor_and_7PP();
TestLimits();
return EXIT_SUCCESS;
diff --git a/irc7702_tables_test.cpp b/irc7702_tables_test.cpp
new file mode 100644
index 0000000..97f198b
--- /dev/null
+++ b/irc7702_tables_test.cpp
@@ -0,0 +1,601 @@
+// 7PP and CVAT corridor from first principles--unit test.
+//
+// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013,
2014, 2015, 2016, 2017, 2018, 2019, 2020 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
+//
+// https://savannah.nongnu.org/projects/lmi
+// email: <gchicares@sbcglobal.net>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+#include "pchfile.hpp"
+
+#include "irc7702_tables.hpp"
+
+#include "materially_equal.hpp"
+#include "math_functions.hpp"
+#include "ssize_lmi.hpp"
+#include "test_tools.hpp"
+
+#include <cfloat> // DBL_EPSILON
+#include <cmath> // log()
+#include <vector>
+
+// These two arrays are pasted from the "corridor mult" and "7Pt"
+// columns of 'validate_2001cso', after loading that spreadsheet
+// in 'gnumeric' and formatting those columns to twenty decimals.
+// They use UL commutation functions. See:
+// https://lists.nongnu.org/archive/html/lmi/2015-07/msg00004.html
+
+static double const ss_ul_corr[100] =
+{16.05428685334679173025
+,15.58833599045649087600
+,15.08131070200895074152
+,14.56342500447235721595
+,14.04800434985640045227
+,13.54397833171609022429
+,13.05507387234714933300
+,12.58409661481673680328
+,12.13030984655223143420
+,11.69174091577074925397
+,11.26914166185736476677
+,10.86078105527353621085
+,10.47029884268147448267
+,10.09843359081480329564
+, 9.74294658529263379876
+, 9.40759852219825454256
+, 9.09057733647785148889
+, 8.79027993284445763322
+, 8.50397918973384925323
+, 8.22818279387080941945
+, 7.96118932260834633041
+, 7.70160265863622406357
+, 7.44976553796342688685
+, 7.20499258154732391546
+, 6.96714059909527883008
+, 6.73646229302490073820
+, 6.51311660413237181189
+, 6.29752334665072410758
+, 6.08868484174302349032
+, 5.88548788700455993705
+, 5.68759233818214315903
+, 5.49522616091999260846
+, 5.30831030469870679411
+, 5.12719475896684162564
+, 4.95191511278486373726
+, 4.78246091867951061971
+, 4.61878315488500756913
+, 4.46095911393538724354
+, 4.30885324846834905088
+, 4.16231281496283944676
+, 4.02117206738939625410
+, 3.88525584688570946312
+, 3.75459497560775545821
+, 3.62916166404261142375
+, 3.50888104609130779821
+, 3.39355762372614266908
+, 3.28298850929638108553
+, 3.17689558846831987537
+, 3.07468880549077061559
+, 2.97599858560200258850
+, 2.88084470780052326333
+, 2.78925893311157580001
+, 2.70137019361723274002
+, 2.61714709838817194409
+, 2.53660248632115825629
+, 2.45973786190931420492
+, 2.38640466067929235550
+, 2.31641149864538897774
+, 2.24933351623363186889
+, 2.18485859704871998588
+, 2.12298548776600348731
+, 2.06377060631972986116
+, 2.00732734016649461140
+, 1.95364688011445042370
+, 1.90257560558083449465
+, 1.85390645085427285821
+, 1.80741123662186708998
+, 1.76283474569483433747
+, 1.72002394995400198496
+, 1.67882810972211782286
+, 1.63921097550600691761
+, 1.60120703518178442160
+, 1.56497463008854764688
+, 1.53056280828563395779
+, 1.49778239342608299189
+, 1.46651641824560186045
+, 1.43669325356442145747
+, 1.40828569180480034362
+, 1.38135623671030072224
+, 1.35595612880361837682
+, 1.33205157176719568568
+, 1.30966078753973991233
+, 1.28874851143154445232
+, 1.26913015525378947146
+, 1.25071057910177563244
+, 1.23349050718607222699
+, 1.21741784864651991782
+, 1.20250900968492024923
+, 1.18879112389207719502
+, 1.17616396084234375863
+, 1.16443752080775975166
+, 1.15305360309844973088
+, 1.14154811660101529469
+, 1.12990850456893321407
+, 1.11805918549405669538
+, 1.10585007755591901990
+, 1.09272887195287826678
+, 1.07768889207696427768
+, 1.05889467902677236744
+, 1.03392745267212093907
+};
+
+static double const ss_ul_7pp[100] =
+{0.00999062440751989980
+,0.01028589716601673552
+,0.01062994889232243140
+,0.01100709650196978612
+,0.01141070148832002557
+,0.01183541561717901119
+,0.01227894262614234906
+,0.01273890281958302631
+,0.01321604446917592178
+,0.01371289447070540846
+,0.01422886804024923145
+,0.01476663382430560070
+,0.01532082243677517636
+,0.01588896142650659399
+,0.01647329371041960158
+,0.01706468830702987174
+,0.01766329128405109278
+,0.01826920380439612038
+,0.01888577215846250559
+,0.01951980733786566266
+,0.02017525559338708904
+,0.02085633674231307522
+,0.02156255487066226217
+,0.02229655784475696040
+,0.02305946770995651388
+,0.02385084039099466188
+,0.02467017211649025557
+,0.02551531634397709650
+,0.02639053264687007266
+,0.02730200324593424696
+,0.02825306412357134547
+,0.02924406198100011275
+,0.03027703373115286228
+,0.03135091541809587046
+,0.03246623554060621558
+,0.03362359115588391123
+,0.03482374166899589174
+,0.03606599422970604291
+,0.03735138265340059993
+,0.03868112554395738284
+,0.04005664955242391884
+,0.04147956289034327587
+,0.04294811241142196950
+,0.04446025296529201171
+,0.04601393073756083335
+,0.04760879558840754727
+,0.04924490987244876244
+,0.05092435295618532448
+,0.05265819337044034404
+,0.05445592655778288410
+,0.05631857051817811682
+,0.05824605305494993251
+,0.06023316553704032711
+,0.06227739915724234826
+,0.06437337655335158282
+,0.06651452375385756566
+,0.06870008885031553270
+,0.07093229090910557755
+,0.07322803247632281298
+,0.07560364239280463472
+,0.07805934610230855220
+,0.08058864677483222605
+,0.08317610640496489460
+,0.08580967539473746686
+,0.08848738367896104295
+,0.09121467879909027354
+,0.09400583834207149048
+,0.09688672842792392381
+,0.09987797601076543741
+,0.10300586867342216568
+,0.10628627958701071521
+,0.10972561873411729172
+,0.11330637125813265709
+,0.11702343505126171219
+,0.12092139119378841894
+,0.12504454546357654521
+,0.12943750862444663996
+,0.13413592524308720622
+,0.13914635982676987203
+,0.14447036818012279347
+,0.15013201659901123652
+,0.15613245573059561511
+,0.16249080594919776410
+,0.16930561735046611993
+,0.17664266810670117835
+,0.18447808708057295002
+,0.19278062434737353037
+,0.20145103153300336629
+,0.21034011597622215284
+,0.21938905920499771063
+,0.22862636208321829301
+,0.23858323922962185182
+,0.24981209741923118828
+,0.26220186143911550225
+,0.28642313285880155460
+,0.31717670783614265728
+,0.35965728769722676850
+,0.42686340219691948361
+,0.56031960772985123231
+,0.96718584791956385693
+};
+
+static double const ss_ol_corr[100] =
+{16.03069515721970
+,15.56545542916450
+,15.05919070490880
+,14.54207568908480
+,14.02741865395940
+,13.52413778894550
+,13.03595534928800
+,12.56567351181010
+,12.11255664606990
+,11.67463475724690
+,11.25265884919660
+,10.84490022682110
+,10.45499411648920
+,10.08367827587890
+, 9.72871697105366
+, 9.39386625032253
+, 9.07731649360929
+, 8.77746677844702
+, 8.49159356632208
+, 8.21620906614680
+, 7.94961408895666
+, 7.69041434829488
+, 7.43895222208455
+, 7.19454325862477
+, 6.95704451334878
+, 6.72670844298237
+, 6.50369386229784
+, 6.28842014111261
+, 6.07989090207194
+, 5.87699437244831
+, 5.67939087980040
+, 5.48730816704992
+, 5.30066733657544
+, 5.11981801243330
+, 4.94479580197072
+, 4.77559033227269
+, 4.61215270269525
+, 4.45456017660894
+, 4.30267743185537
+, 4.15635196932867
+, 4.01541830136802
+, 3.87970153695790
+, 3.74923252419573
+, 3.62398356964482
+, 3.50387995898405
+, 3.38872648535844
+, 3.27832055910429
+, 3.17238444761715
+, 3.07032882594890
+, 2.97178458990226
+, 2.87677154683430
+, 2.78532147558464
+, 2.69756322259474
+, 2.61346549280934
+, 2.53304117542039
+, 2.45629184138028
+, 2.38306915684781
+, 2.31318201343135
+, 2.24620607000211
+, 2.18182960005580
+, 2.12005141288773
+, 2.06092793502465
+, 2.00457251268315
+, 1.95097642680359
+, 1.89998629486328
+, 1.85139534102519
+, 1.80497569334546
+, 1.76047246308625
+, 1.71773284834008
+, 1.67660633172185
+, 1.63705678130120
+, 1.59911874599313
+, 1.56295053110245
+, 1.52860126016288
+, 1.49588204901423
+, 1.46467616317511
+, 1.43491217369859
+, 1.40656304375306
+, 1.37969137924250
+, 1.35434853909332
+, 1.33050092572148
+, 1.30816690878090
+, 1.28731141765329
+, 1.26775022859716
+, 1.24938847835256
+, 1.23222703314812
+, 1.21621399207302
+, 1.20136578942719
+, 1.18770946309554
+, 1.17514487873005
+, 1.16348237607749
+, 1.15216547131899
+, 1.14073189550427
+, 1.12916922360185
+, 1.11740178851122
+, 1.10527880649853
+, 1.09224812150223
+, 1.07730439700387
+, 1.05861825755067
+, 1.03377932830447
+};
+
+static double const ss_ol_7pp[100] =
+{0.010005327186958
+,0.010301016999909
+,0.010645562907928
+,0.011023256091546
+,0.011427447066149
+,0.011852778725528
+,0.012296950914868
+,0.012757579901923
+,0.013235415035928
+,0.013732987171806
+,0.014249710382439
+,0.014788257479081
+,0.015343250090949
+,0.015912211536579
+,0.016497388214910
+,0.017089634046416
+,0.017689095179996
+,0.018295872789306
+,0.018913318467641
+,0.019548254138137
+,0.020204632276942
+,0.020886679342528
+,0.021593898359639
+,0.022328941267110
+,0.023092931684899
+,0.023885424544973
+,0.024705914983204
+,0.025552252675176
+,0.026428703850223
+,0.027341460483306
+,0.028293863627333
+,0.029286260140180
+,0.030320689819902
+,0.031396086507395
+,0.032512979072804
+,0.033671965026394
+,0.034873804442084
+,0.036117802719780
+,0.037404994687573
+,0.038736600205397
+,0.040114047455165
+,0.041538946413990
+,0.043009540227530
+,0.044523779574169
+,0.046079606410946
+,0.047676669074214
+,0.049315028941757
+,0.050996767549288
+,0.052732969936346
+,0.054533145156035
+,0.056398310810159
+,0.058328392333208
+,0.060318170371727
+,0.062365129728319
+,0.064463881836038
+,0.066607839381289
+,0.068796246114121
+,0.071031321069015
+,0.073329989610741
+,0.075708601646018
+,0.078167377428823
+,0.080699804001149
+,0.083290412982767
+,0.085927129777381
+,0.088607974722984
+,0.091338396338728
+,0.094132685084862
+,0.097016735479080
+,0.100011192647016
+,0.103142368320708
+,0.106426141130087
+,0.109868909420875
+,0.113453108667038
+,0.117173603120152
+,0.121075007777516
+,0.125201654498742
+,0.129598172492744
+,0.134300204399513
+,0.139314266113466
+,0.144641852159782
+,0.150306989508367
+,0.156310753283924
+,0.162672203024568
+,0.169489903915145
+,0.176829591075732
+,0.184667243191684
+,0.192971446212092
+,0.201642732430611
+,0.210531675161746
+,0.219579312738766
+,0.228814049726310
+,0.238767148018836
+,0.249990843980925
+,0.262373528220005
+,0.286591643152315
+,0.317340642829014
+,0.359815590009435
+,0.427015751779345
+,0.560465915779944
+,0.967324430485689
+};
+
+/// Test CVAT corridor and seven-pay premium.
+
+void Test_Corridor_and_7PP()
+{
+ std::vector<double> const naar_discount
+ (100
+ ,i_upper_12_over_12_from_i<double>()(0.04)
+ );
+ irc7702_tables z
+ (mce_2001cso
+ ,oe_orthodox
+ ,oe_age_last_birthday
+ ,mce_unisex
+ ,mce_unismoke
+ ,naar_discount
+ ,1.0 / 12.0
+ ,0
+ ,100
+ );
+ std::vector<double> const& ul_corr = z.ul_corr();
+ std::vector<double> const& ul_7pp = z.ul_7pp ();
+ std::vector<double> const& ol_corr = z.ol_corr();
+ std::vector<double> const& ol_7pp = z.ol_7pp ();
+
+ // In the last year, the OL formula reduces to:
+ // NSP[omega-1] = vq * (i/delta) + vp
+ // (0.30285 / 1.04) * (0.04 / ln(1.04)) + (1 - 0.30285) / 1.04
+ BOOST_TEST(materially_equal(0.30285, z.q_[99], 0.0));
+ double ol_nsp99 =
+ ( z.q_[99] / 1.04) * (0.04 / std::log(1.04))
+ + (1.0 - z.q_[99]) / 1.04
+ ;
+ BOOST_TEST(materially_equal(ol_corr[99], 1.0 / ol_nsp99, DBL_EPSILON));
+
+ for(int j = 0; j < lmi::ssize(ol_corr); ++j)
+ {
+ // Values calculated here must match spreadsheet values to
+ // within a minuscule tolerance.
+ BOOST_TEST(materially_equal(ss_ul_corr[j], ul_corr[j]));
+ BOOST_TEST(materially_equal(ss_ul_7pp [j], ul_7pp [j]));
+ BOOST_TEST(materially_equal(ss_ol_corr[j], ol_corr[j]));
+ BOOST_TEST(materially_equal(ss_ol_7pp [j], ol_7pp [j]));
+ // The 0.0015 tolerance was found experimentally, not by any
+ // sort of mathematical law. It represents the inherent
+ // discrepancy between the UL method on the one hand, and the
+ // OL method (with the i/delta approximation) on the other.
+ BOOST_TEST(materially_equal( ol_corr[j], ul_corr[j], 0.0015));
+ BOOST_TEST(materially_equal( ol_7pp [j], ul_7pp [j], 0.0015));
+ }
+
+ // At least for now, display plenty of detail.
+
+ std::cout << std::endl;
+
+ std::cout
+ << ol_corr[99] << " OL corr[omega-1]\n"
+ << 1.0 / ol_nsp99 << " vq * (i/delta) + vp\n"
+ << std::endl
+ ;
+
+ std::cout << "q, UL corr, UL 7pp, OL corr, OL 7pp\n";
+ for(int j = 0; j < lmi::ssize(ol_corr); ++j)
+ {
+ std::cout
+ << j
+ << '\t' << z.q_[j]
+ << '\t' << ul_corr[j]
+ << '\t' << ul_7pp[j]
+ << '\t' << ol_corr[j]
+ << '\t' << ol_7pp[j]
+ << '\n';
+ }
+ std::cout << std::endl;
+
+ std::vector<double> q12(lmi::ssize(ol_corr));
+ assign(q12, apply_binary(coi_rate_from_q<double>(), z.q_, 1.0 / 12.0));
+ std::cout << "q, q upper (12), UL corr, UL 7pp\n";
+ for(int j = 0; j < lmi::ssize(ul_corr); ++j)
+ {
+ std::cout
+ << j
+ << '\t' << z.q_[j]
+ << '\t' << q12[j]
+ << '\t' << ul_corr[j]
+ << '\t' << ul_7pp[j]
+ << '\n';
+ }
+ std::cout << std::endl;
+
+ std::cout << "UL corr, OL corr, relative error\n";
+ for(int j = 0; j < lmi::ssize(ul_corr); ++j)
+ {
+ std::cout
+ << j
+ << '\t' << ul_corr[j]
+ << '\t' << ol_corr[j]
+ << '\t' << (ol_corr[j] - ul_corr[j]) / ul_corr[j]
+ << '\n';
+ }
+ std::cout << std::endl;
+
+ std::cout << "UL 7pp, OL 7pp, relative error\n";
+ for(int j = 0; j < lmi::ssize(ul_corr); ++j)
+ {
+ std::cout
+ << j
+ << '\t' << ul_7pp[j]
+ << '\t' << ol_7pp[j]
+ << '\t' << (ol_7pp[j] - ul_7pp[j]) / ul_7pp[j]
+ << '\n';
+ }
+ std::cout << std::endl;
+
+ std::cout << "UL corr, 7pp: {calculated, spreadsheet, relative error}\n";
+ for(int j = 0; j < lmi::ssize(ss_ul_corr); ++j)
+ {
+ std::cout
+ << j
+ << '\t' << ul_corr[j]
+ << '\t' << ss_ul_corr[j]
+ << '\t' << (ss_ul_corr[j] - ul_corr[j]) / ul_corr[j]
+ << '\t' << ul_7pp[j]
+ << '\t' << ss_ul_7pp[j]
+ << '\t' << (ss_ul_7pp[j] - ul_7pp[j]) / ul_7pp[j]
+ << '\n';
+ }
+ std::cout << std::endl;
+
+ std::cout << "OL corr, 7pp: {calculated, spreadsheet, relative error}\n";
+ for(int j = 0; j < lmi::ssize(ss_ul_corr); ++j)
+ {
+ std::cout
+ << j
+ << '\t' << ol_corr[j]
+ << '\t' << ss_ol_corr[j]
+ << '\t' << (ss_ol_corr[j] - ol_corr[j]) / ol_corr[j]
+ << '\t' << ol_7pp[j]
+ << '\t' << ss_ol_7pp[j]
+ << '\t' << (ss_ol_7pp[j] - ol_7pp[j]) / ol_7pp[j]
+ << '\n';
+ }
+}
+
+int test_main(int, char*[])
+{
+ Test_Corridor_and_7PP();
+
+ return EXIT_SUCCESS;
+}
diff --git a/objects.make b/objects.make
index bebf2c7..f896566 100644
--- a/objects.make
+++ b/objects.make
@@ -431,6 +431,7 @@ unit_test_targets := \
input_sequence_test \
input_test \
interpolate_string_test \
+ irc7702_tables_test \
irc7702a_test \
istream_to_string_test \
ledger_test \
@@ -573,7 +574,6 @@ commutation_functions_test$(EXEEXT): \
commutation_functions.o \
commutation_functions_test.o \
cso_table.o \
- irc7702_tables.o \
timer.o \
configurable_settings_test$(EXEEXT): \
@@ -740,6 +740,13 @@ interpolate_string_test$(EXEEXT): \
interpolate_string.o \
interpolate_string_test.o \
+irc7702_tables_test$(EXEEXT): \
+ $(common_test_objects) \
+ commutation_functions.o \
+ cso_table.o \
+ irc7702_tables.o \
+ irc7702_tables_test.o \
+
irc7702a_test$(EXEEXT): \
$(boost_filesystem_objects) \
$(common_test_objects) \
- [lmi-commits] [lmi] valyuta/004 updated (cf62b44 -> 506051a), Greg Chicares, 2020/12/29
- [lmi-commits] [lmi] valyuta/004 260857d 2/9: Read product data files earlier, Greg Chicares, 2020/12/29
- [lmi-commits] [lmi] valyuta/004 296ee07 5/9: Set 7702 and 7702A interest rates OAOO, Greg Chicares, 2020/12/29
- [lmi-commits] [lmi] valyuta/004 288c26f 8/9: Refactor to avoid a header-only implementation, Greg Chicares, 2020/12/29
- [lmi-commits] [lmi] valyuta/004 4a1687e 1/9: Expunge a defect marker [324], Greg Chicares, 2020/12/29
- [lmi-commits] [lmi] valyuta/004 50ed405 3/9: Prefer explicit to implicit currency rounding, Greg Chicares, 2020/12/29
- [lmi-commits] [lmi] valyuta/004 9e6c7e1 4/9: Abjure converting currency ctors, Greg Chicares, 2020/12/29
- [lmi-commits] [lmi] valyuta/004 806f2fd 6/9: fixup, Greg Chicares, 2020/12/29
- [lmi-commits] [lmi] valyuta/004 87f1e13 7/9: Split a unit-test TU in twain,
Greg Chicares <=
- [lmi-commits] [lmi] valyuta/004 506051a 9/9: Conditionally use H.R. 6800's 7702 transitional rates, Greg Chicares, 2020/12/29