Commutation

Creates an Association containing values for the six standard commutation functions used in actuarial mathematics.

ResourceFunction["Commutation"][l,v]

computes values for the six standard commutation functions (“D”,”N”,”S”,”C”,”M”,”R”) as a function of ℓ, a list containing the fraction of the initial population surviving at the start of each time unit, and v, a discount rate generally between 0 and 1, showing the value of money received one year from now.

Details and Options

Commutation functions can be used to compute a number of quantities of interest in actuarial mathematics, such as the value of an annuity or death benefit.
The “ReturnForm” option directs the form in which the data is returned: permissible option values are as follows:
"FunctionAssociation" returns an Association in which the commutation function names are the keys and the values are the values of each function at each successive unit of time; "TimeAssociation" returns a nested Association in which the outer keys are the successive units of time and the values are Associations in which the keys are the names of the commutation functions and the values are the value of that function at the specified unit of time.“FunctionValues” returns a nested list in which each outer list represents the values of a commutation function at a successive unit of time. The lists are ordered as “D”,”N”,”S”,”C”,”M”,”R”. For example, the fourth element of the returned values contains a list of the values for the “C” commutation function.“TimeValues” returns a nested list in which each outer list represents a unit of time. Each inner list contains six values, one for each of the six commutation functions and in the order “D”,”N”,”S”,”C”,”M”,”R”.
The “InitialTime” option can (and probably should) be used when the mortality table begins at an age other than 0.
Although commutation functions and tables displaying them are used less frequently than in times when computation was less accessible, they are still a useful tool in swiftly computing quanities of interest in actuarial mathematics.

Examples

Basic Examples

Compute the commutation functions for a mortality table that goes from 1 to 0 in 5 periods and a discount rate of 0.9:

In[1]:=
ResourceFunction[
 "https://www.wolframcloud.com/obj/user-b295538f-24b3-45c5-932c-\
3ab748075099/DeployedResources/Function/Commutation"][{1, 0.9, 0.8, 0.2, 0.1, 0}, 0.9]
Out[1]=

Do the same computation as immediately above but return the values as a nested Association in which the outer keys represent years; the result is converted into a Dataset to aid visualization:

In[2]:=
ResourceFunction[
  "https://www.wolframcloud.com/obj/user-b295538f-24b3-45c5-932c-\
3ab748075099/DeployedResources/Function/Commutation"][{1, 0.9, 0.8, 0.2, 0.1, 0}, 0.9, "ReturnForm" -> "TimeAssociation"] // Dataset
Out[2]=

Do the same computation as immediately above, but assume the starting age for the mortality vector is age 20:

In[3]:=
ResourceFunction[
  "https://www.wolframcloud.com/obj/user-b295538f-24b3-45c5-932c-\
3ab748075099/DeployedResources/Function/Commutation"][{1, 0.9, 0.8, 0.2, 0.1, 0}, 0.9, "ReturnForm" -> "TimeAssociation", "InitialTime" -> 20] // Dataset
Out[3]=

Scope

Exact values will be provided where rational numbers are used for the inputs :

In[4]:=
ResourceFunction[
 "https://www.wolframcloud.com/obj/user-b295538f-24b3-45c5-932c-\
3ab748075099/DeployedResources/Function/Commutation"][{1, 9/10, 8/10, 2/10, 1/10, 0}, 9/10, "ReturnForm" -> "FunctionValues"]
Out[4]=

The function works on symbolic arguments:

In[5]:=
ResourceFunction[
 "https://www.wolframcloud.com/obj/user-b295538f-24b3-45c5-932c-\
3ab748075099/DeployedResources/Function/Commutation"][Array[l, 5, 0],
  v]
Out[5]=

By adjusting the discount rate, the function can be used for mortality tables that go by time units other than a year ; compute the commutation functions of a mortality table that goes by 10 year periods when the annual discount rate is 0.95:

In[6]:=
ResourceFunction[
 "https://www.wolframcloud.com/obj/user-b295538f-24b3-45c5-932c-\
3ab748075099/DeployedResources/Function/Commutation"][{1, 0.9846173379875812`, 0.9639606131621938`, 0.9325133217994516`, 0.8639769154117698`, 0.7361732007375918`, 0.5120752978556353`, 0.18294306933939167`, 0}, 0.95^10]
Out[6]=

Options

Changing the "ReturnForm" option changes the form of the output :

In[7]:=
Table[ResourceFunction[
  "https://www.wolframcloud.com/obj/user-b295538f-24b3-45c5-932c-\
3ab748075099/DeployedResources/Function/Commutation"][{1, 0.9, 0.8, 0.2, 0.1, 0}, 0.9, "ReturnForm" -> form], {form, {"FunctionAssociation", "TimeAssociation", "FunctionValues", "TimeValues"}}]
Out[7]=

Changing the “InitialTime” option changes the keys of the TimeAssociation return form; the values of each Association remain the same:

In[8]:=
Table[ResourceFunction[
  "https://www.wolframcloud.com/obj/user-b295538f-24b3-45c5-932c-\
3ab748075099/DeployedResources/Function/Commutation"][{1, 0.9, 0.8, 0.2, 0.1, 0}, 0.9, "ReturnForm" -> "TimeAssociation", "InitialTime" -> x], {x, {0, 20, 40}}]
Out[8]=

Applications

Get the commutation functions for males based on “U.S. Historical Population Mortality Rates 2000-2017 for 2017” and a discount rate of 0.95:

In[9]:=
(maleMortality = 100000 ResourceFunction["MortalityConvert"][
     ReplacePart[CompressedData["
1:eJw9UnssFAAc1jq5XNKDyKs5rc0rvTwW9cnRJJ07r8q5w53DPEPOqyONxJJ3
Wh4zCVlh4rTU6dwk5Cqi2OlQ8lrMvNsklfXHt+/3z/f4bZ8uO8yZu0VOTo6+
geOrfoWavS7IW9rmdc/RDXrG+U16Re6o5+jtqp2+iL0+4l5D7mUYU7SmR808
8CK2mhJ6k4GjElmyDcETrwihQ90uTPjmZD+tq2QipyvRvoXPxPybAzusllkQ
rbtvWHlju2YJS7/LG6q3HaYIJ3xAMxtTnI3wQaD6aXKFLfs/u4mqyqnWHBRJ
Z2kqExzMBXy91bjiC7+X6p1pPC4skg1M40u5OKU8IxkM8YepvvwQqycAXgqS
/fTBoM38EBS4U0Z1zoch4tchFfLwlU3/CDBbvM2DGVexOF9BVn3N2/wzGqT4
wZHajjhE8Y5ZOLD4m72v41KVabclNQn71Ouf90XegMaDKFfTM8mQ7qaSWAsp
mNzJ9lcsTsUSiScW2KWhrIBu1NSQju9dpLpMagaIj7U8fC0zUfWIG8TPzoL8
vwOZD5WZNFkOhIHcVpPFXHT5x+pIi/NRvCCca/S/C4VrCeq6Vvfha70Ut9xe
CO2OMZTLSuDoGqYUnF8KW3qp07dzZbCXciYpauX40UxekTlUIFnJqTaPW4UZ
YqW8yc9qtG3trPAceQLKOkHNMLAOKV5T4xfs6rF2xCamIbwB0k9JkWfzBJBp
fDYQjT5DFpW5avSuGcPzYuLIByHSearOCc4ijGtXTtgfFiN1RI/tcLANDGIE
rdWxHZROp2r+yU6sMzruZFi/RU1J7hdzoQSC+bWPMZPv4RjuNhBt1wN+jYCd
ONCLkEhOXOuePsj/mY12Pwh/hf34DZ6gLtg=
"], -1 -> 1], "Hazard" -> "Survival"]) // Short
Out[9]=
In[10]:=
males2017 = ResourceFunction[
   "https://www.wolframcloud.com/obj/user-b295538f-24b3-45c5-932c-\
3ab748075099/DeployedResources/Function/Commutation"][maleMortality, 0.95, "ReturnForm" -> "TimeAssociation", "InitialTime" -> 20] // Dataset
Out[10]=

Use the commutation dataset to compute the value of an “increasing annuity” issues to a 60 year old that pays $1 its first year, $2 its second year, and one additional dollar each year thereafter:

In[11]:=
Query[Key@(60 + 1), #S &][males2017]/Query[Key@60, #D &][males2017]
Out[11]=

Compute for a person aged 33, the net single premium for a 20 - year term insurance payable at the end of the year of death, where $1 is paid if the death occurs in the first year, $2 is paid is the death occurs in the second year, $3 is paid if the death occurs in the third year and so on:

In[12]:=
(Query[Key@33, #R &][males2017] - Query[Key@(33 + 20), #R &][males2017] - Query[Key@53, 20*#M &][males2017])/Query[Key@33, #D &][males2017]
Out[12]=

Use the commutation dataset to plot the level annual premium for a term life insurance policy of 20 years as a function of the issue age of the insured:

In[13]:=
With[{m = Normal@Query[All, #M &][males2017], n = Normal@Query[All, #N &][males2017]},
 ListLinePlot[
  Table[(m[[Key@x]] - m[[Key@(x + 20)]])/(
   n[[Key@(x + 1)]] - n[[Key@(x + 20 + 1)]]), {x, 20, 78}], Sequence[
  DataRange -> {20, 78}, Frame -> True, FrameLabel -> {"issue age", "premium"}, "PlotLabel" -> "Annual net level premiums by issue age\nfor 20 \
year term policy"]]]
Out[13]=

Use the commutation dataset to compute the annual level premium (paid at the beginning of the year) per $1 of whole life coverage for a purchaser with “issue age” of 25 :

In[14]:=
premiumMale25 = Query[Key@25, #M/#N &][males2017]
Out[14]=

Use the same dataset to Plot the retrospective reserve on this policy according to the attained age of the insured:

In[15]:=
retrospectiveReserve = Query[(Key /@ Range[25, 100]) /* ListLinePlot, (#M/#D - premiumMale25*#N/#D &) /* Chop][males2017]
Out[15]=

Compute the net single premium needed to fund a life insurance policy of $1,000,000 on a 61 year old for 10 years, with death benefits paid at the end of the year of death :

In[16]:=
1000000*(Query[Key@61, #M &][males2017] - Query[Key@(61 + 10), #M &][males2017])/
 Query[Key@61, #D &][males2017]
Out[16]=

Do the same computation using the commutation dataset but make the notation more transparent :

In[17]:=
With[{\[ScriptCapitalM] = Normal[males2017[All, "M"]], \[ScriptCapitalD] = Normal[males2017[All, "D"]]}, 1000000 (\[ScriptCapitalM][61] - \[ScriptCapitalM][
    61 + 10])/\[ScriptCapitalD][61]]
Out[17]=

Properties and Relations

The Resource Function “MortalityConvert” permits use of mortality data provided as a hazard or probability instead of as survival:

In[18]:=
ResourceFunction[
 "https://www.wolframcloud.com/obj/user-b295538f-24b3-45c5-932c-\
3ab748075099/DeployedResources/Function/Commutation"][ResourceFunction[
ResourceObject[
Association[
    "Name" -> "MortalityConvert", "ShortName" -> "MortalityConvert", "UUID" -> "d6a8caca-d1fc-4ed8-95d8-053c0bd6fc6a", "ResourceType" -> "Function", "Version" -> "1.0.0", "Description" -> "Converts vector descriptions of mortality into \
another representation", "RepositoryLocation" -> URL[
      "https://www.wolframcloud.com/objects/resourcesystem/api/1.0"], "SymbolName" -> "FunctionRepository`$\
9e9dbb22d85b4c1baf0bac6c35e980ed`MortalityConvert", "FunctionLocation" -> CloudObject[
      "https://www.wolframcloud.com/obj/75ed37b9-dd11-4f80-832e-\
c2f10fed7e8b"]], ResourceSystemBase -> "https://www.wolframcloud.com/objects/\
resourcesystem/api/1.0"]][{0.1, 0.2, 0.3, 0.4, 1}, "Hazard" -> "Survival"], 0.9]
Out[18]=

Neat Examples

Determine the amount an insurer would be willing to pay to rid itself of a $1,000,000 insurance policy issued to a 25 year old priced under the mortality table contained in “U.S. Historical Population Mortality Rates 2000-2017 for 2017” when the insurer becomes aware that the insured’s hazards are 80% greater than contained in the table:

In[19]:=
insuredMortality = 100000 ResourceFunction["MortalityConvert"][
   ReplacePart[1.8*CompressedData["
1:eJw9UnssFAAc1jq5XNKDyKs5rc0rvTwW9cnRJJ07r8q5w53DPEPOqyONxJJ3
Wh4zCVlh4rTU6dwk5Cqi2OlQ8lrMvNsklfXHt+/3z/f4bZ8uO8yZu0VOTo6+
geOrfoWavS7IW9rmdc/RDXrG+U16Re6o5+jtqp2+iL0+4l5D7mUYU7SmR808
8CK2mhJ6k4GjElmyDcETrwihQ90uTPjmZD+tq2QipyvRvoXPxPybAzusllkQ
rbtvWHlju2YJS7/LG6q3HaYIJ3xAMxtTnI3wQaD6aXKFLfs/u4mqyqnWHBRJ
Z2kqExzMBXy91bjiC7+X6p1pPC4skg1M40u5OKU8IxkM8YepvvwQqycAXgqS
/fTBoM38EBS4U0Z1zoch4tchFfLwlU3/CDBbvM2DGVexOF9BVn3N2/wzGqT4
wZHajjhE8Y5ZOLD4m72v41KVabclNQn71Ouf90XegMaDKFfTM8mQ7qaSWAsp
mNzJ9lcsTsUSiScW2KWhrIBu1NSQju9dpLpMagaIj7U8fC0zUfWIG8TPzoL8
vwOZD5WZNFkOhIHcVpPFXHT5x+pIi/NRvCCca/S/C4VrCeq6Vvfha70Ut9xe
CO2OMZTLSuDoGqYUnF8KW3qp07dzZbCXciYpauX40UxekTlUIFnJqTaPW4UZ
YqW8yc9qtG3trPAceQLKOkHNMLAOKV5T4xfs6rF2xCamIbwB0k9JkWfzBJBp
fDYQjT5DFpW5avSuGcPzYuLIByHSearOCc4ijGtXTtgfFiN1RI/tcLANDGIE
rdWxHZROp2r+yU6sMzruZFi/RU1J7hdzoQSC+bWPMZPv4RjuNhBt1wN+jYCd
ONCLkEhOXOuePsj/mY12Pwh/hf34DZ6gLtg=
"], -1 -> 1], "Hazard" -> "Survival"]
Out[19]=
In[20]:=
insuredCommutation = ResourceFunction[
   "https://www.wolframcloud.com/obj/user-b295538f-24b3-45c5-932c-\
3ab748075099/DeployedResources/Function/Commutation"][
   insuredMortality, 0.95, "ReturnForm" -> "TimeAssociation", "InitialTime" -> 20] // Dataset
Out[20]=
In[21]:=
Legended[Show[retrospectiveReserve, Query[(Key /@ Range[25, 100]) /* (ListLinePlot[#, PlotStyle -> Red] &), (#M/#D - premiumMale25*#N/#D &) /* Chop][insuredCommutation], Sequence[
  Frame -> True, FrameLabel -> {"attained age", "$"}, GridLines -> Automatic]], LineLegend[{
ColorData[1][1], Red}, {
  "with assumed mortality", "with 180% assumed mortality"}]]
Out[21]=

Source Metadata

Publisher Information