TradLife_A Space Overview#

This notebook tutorial explains the basics of spaces, by taking a closer look at spaces defined in the TradLife_A model in the :mod:~annuallife library as an example.

Click the badge below to run this notebook online on Google Colab. You need a Google account and need to be logged in to it to run this notebook on Google Colab. Run on Google Colab

The next code cell below is relevant only when you run this notebook on Google Colab. It installs lifelib and creates a copy of the library for this notebook.

[1]:
import sys, os

if 'google.colab' in sys.modules:
    lib = 'annuallife'; lib_dir = '/content/' + lib
    if not os.path.exists(lib_dir):
        !pip install lifelib
        import lifelib; lifelib.create(lib, lib_dir)

    %cd $lib_dir

Reading the TradLife_A model#

The TradLife_A model is loaded from disk by modelx’s read_model function. Make sure your working directory contains the TradLife_A model directory and the input.xlsx workbook alongside it.

[2]:
import modelx as mx
model = mx.read_model("TradLife_A")

If you read the same model twice, the previously created model is renamed automatically to avoid name conflict. To get all existing models, get_models modelx API function can be used. get_models returns a dict of all the existing models associated with their names.

[3]:
import modelx as mx
mx.get_models()
[3]:
{'TradLife_A': <Model TradLife_A>}

Access spaces in the model#

In the model, there are child spaces and other objects referenced in the model. spaces property holds pairs of child space names and objects as a dict-like view.

[4]:
model.spaces
[4]:
{'InputData': TradLife_A.InputData, 'Economic': TradLife_A.Economic, 'BaseProj': TradLife_A.BaseProj, 'PV': TradLife_A.PV, 'Projection': TradLife_A.Projection, 'Assumptions': TradLife_A.Assumptions, 'PolicyAttrs': TradLife_A.PolicyAttrs, 'Utilities': TradLife_A.Utilities, 'CommTable': TradLife_A.CommTable, 'Enums': TradLife_A.Enums}

To just get all the names of the spaces, use the idiomatic expression below. To get all the space objects, values method can be used instead of keys.

[5]:
list(model.spaces.keys())
[5]:
['InputData',
 'Economic',
 'BaseProj',
 'PV',
 'Projection',
 'Assumptions',
 'PolicyAttrs',
 'Utilities',
 'CommTable',
 'Enums']

To get a specific space, simply type its name as model’s attribute, or pass the name as a key to spaces property. For example, to get Projection space:

[6]:
model.Projection
[6]:
<UserSpace TradLife_A.Projection>

or

[7]:
model.spaces['Projection']
[7]:
<UserSpace TradLife_A.Projection>

A space can in turn contain other spaces, forming a space tree. To access child spaces of a space, the spaces property and attribute access by name as we used on models can be used. Enums for example contains child spaces representing enum types used by the model.

[8]:
model.Enums.spaces
[8]:
{'ProductID': TradLife_A.Enums.ProductID, 'SexID': TradLife_A.Enums.SexID, 'RateBasisID': TradLife_A.Enums.RateBasisID}
[9]:
model.Enums.ProductID
[9]:
<UserSpace TradLife_A.Enums.ProductID>
[10]:
model.Enums.spaces['ProductID']
[10]:
<UserSpace TradLife_A.Enums.ProductID>

Space overview#

Below is the list of the names of the spaces in the TradLife_A model.

[11]:
list(model.spaces.keys())
[11]:
['InputData',
 'Economic',
 'BaseProj',
 'PV',
 'Projection',
 'Assumptions',
 'PolicyAttrs',
 'Utilities',
 'CommTable',
 'Enums']

Below is a brief explanation of each space directly under the model.

  • InputData: Space holding data read from the input file input.xlsx.

  • Economic: Parametric space whose dynamic child spaces hold economic assumptions for each scenario.

  • BaseProj: Base space of Projection space, which contains cells to carry out projections.

  • PV: Mixin base space of Projection space, which contains cells to calculate present values of cashflows.

  • Projection: Parametric space, whose dynamic child spaces carry out projection for each model point.

  • Assumptions: Space holding assumption parameters and rates used by Projection.

  • PolicyAttrs: Space holding policy attributes and policy values used by Projection.

  • Utilities: Base space of Assumptions and PolicyAttrs, providing helper cells.

  • CommTable: Parametric space providing commutation functions and actuarial notations.

  • Enums: Container space for the enum types used across the model.

Base spaces#

BaseProj and PV are base spaces of Projection, and cells defined in those spaces are inherited by Projection.

[12]:
model.Projection.bases
[12]:
[<UserSpace TradLife_A.BaseProj>, <UserSpace TradLife_A.PV>]

Parametric spaces#

Among the spaces listed above, parametric spaces along with their parameters are listed below.

  • CommTable[Sex, IntRate, Table]

  • Economic[scen_id]

  • Projection[idx, scen_id=1]

To check parameters of a parametric space, call its parameters property.

[13]:
model.CommTable.parameters
[13]:
('Sex', 'IntRate', 'Table')

A space becomes parametric when it has the formula property. By calling the formula property, the source code of the function the formula is created from is printed.

The parameters of a parametric space, and their default values if any, are taken from the signature of its associated function.

[14]:
model.CommTable.formula
[14]:
lambda Sex, IntRate, Table: None

Parameter spaces serve as factories to create their child spaces dynamically.

When a parametric space is called with specific arguments being passed to the parameters, a dynamic child space associated with the arguments is created if it’s not yet created, and returned. This can be achieved either by the call operation () or by subscription [] on the parametric space. If a parameter has its default value, and the arguments to the parameter is omitted, the default value is passed.

[15]:
model.Projection[0]
[15]:
<ItemSpace TradLife_A.Projection[0, 1]>

Space formula#

Space formulas have 2 roles relating to dynamic element spaces.

  • To define the space’s parameters and their default values.

  • To specify arguments used for constructing element spaces.

When the user tries to access the element space of a space, such as model.Projection[0], for the first time, the formula of the space is called in order to pass a dictionary of pairs of parameters and arguments used for constructing and initializing the element space.

The parameters include:

  • bases: a list of base spaces of the element space. If not specified, the space itself becomes the direct base space of the element space.

  • refs: a dictionary of references to be defined in the element space.

Both of the parameters are optional. As we have seen in the above, space formulas are created from function definitions.

[16]:
model.Projection.formula
[16]:
lambda idx, scen_id=1: None

The formula code is executed in the namespace associated with the space. So, names that appear in the formula above are defined in the namespace of model.Projection. The names defined in the namespace consists of child cells, child spaces and references in the space, i.e. the namespace is the union of cells, spaces, refs properties.

dir function on a space lists all the names defined in the namespace associated with the space.

[17]:
dir(model.Projection)
[17]:
['ProductID',
 'RateBasisID',
 'SexID',
 '__builtins__',
 '_model',
 '_self',
 '_space',
 'accum_cf',
 'age',
 'ann_prem_pp',
 'ann_prem_rate',
 'asmp',
 'cash_value_rate',
 'change_rsrv',
 'claims',
 'claims_acc_dth',
 'claims_acc_dth_pp',
 'claims_acc_hosp',
 'claims_acc_hosp_pp',
 'claims_ann',
 'claims_ann_pp',
 'claims_death',
 'claims_death_pp',
 'claims_living',
 'claims_living_pp',
 'claims_mat',
 'claims_mat_pp',
 'claims_other',
 'claims_other_pp',
 'claims_sick_hosp',
 'claims_sick_hosp_pp',
 'claims_surg',
 'claims_surg_pp',
 'claims_surr',
 'claims_surr_pp',
 'comm_table',
 'commissions',
 'disc_rate_mth',
 'expense_acq_pp',
 'expense_maint_pp',
 'expenses',
 'exps_acq',
 'exps_acq_total',
 'exps_comm_init',
 'exps_comm_init_pp',
 'exps_comm_ren',
 'exps_comm_ren_pp',
 'exps_maint',
 'exps_maint_total',
 'exps_other',
 'exps_other_pp',
 'gross_prem_rate',
 'income_total',
 'inflation_factor',
 'insur_if_beg1',
 'insur_if_end',
 'int_accum_cf',
 'interest_net_cf',
 'invst_income',
 'invst_income_pp',
 'lapse_rate',
 'last_mort_age',
 'mort_factor',
 'mort_rate',
 'net_cf',
 'net_prem_rate',
 'np',
 'pd',
 'pol',
 'pols_acc_death',
 'pols_acc_hosp',
 'pols_annuity',
 'pols_death',
 'pols_if',
 'pols_if_aft_mat',
 'pols_if_beg',
 'pols_if_beg1',
 'pols_if_init',
 'pols_lapse',
 'pols_living',
 'pols_maturity',
 'pols_other',
 'pols_renewal',
 'pols_sick_hosp',
 'pols_surg',
 'premium_pp',
 'premiums',
 'profit_bef_tax',
 'proj_len',
 'pv_check',
 'pv_claims',
 'pv_claims_death',
 'pv_claims_mat',
 'pv_claims_surr',
 'pv_commissions',
 'pv_expenses',
 'pv_exps_acq',
 'pv_exps_maint',
 'pv_net_cf',
 'pv_net_cf_for_check',
 'pv_premiums',
 'pv_sum_insur_if',
 'reserve_hosp_rsrv_end',
 'reserve_nlp_rate',
 'reserve_prem_rsrv_aft_mat_pp',
 'reserve_prem_rsrv_end',
 'reserve_prem_rsrv_end_pp',
 'reserve_total_aft_mat_pp',
 'reserve_total_end',
 'reserve_uern_prem_aft_mat_pp',
 'reserve_uern_prem_end',
 'reserve_uern_prem_end_pp',
 'scen',
 'sum_assured',
 'surr_charge']