Growth Rate Conventions#
This page documents the anniversary-based growth convention used throughout Lactuca
for all actuarial functions that accept a gr (growth rate) parameter:
Single-life:
äx,ax,AxNamed joint-life shortcuts (2 and 3 lives):
äxy,axy,äxyz,axyz,Axy,AxyzGeneric N-life variants:
äjoint,ajoint,Afirst
Pure endowments (nEx, nExy, nExyz) do not accept gr=.
Anniversary index definition#
For a payment stream with frequency \(m\) (payments per year) starting at time \(d\) (deferment), the \(j\)-th payment (\(j = 0, 1, 2, \ldots\)) receives the growth factor:
where \(\lfloor j / m \rfloor\) is the annual anniversary index — the number of
complete years of payments that have elapsed before payment \(j\). This formula is
for the default geometric growth type (growth_type='g'). For arithmetic
growth (growth_type='a'), the factor is \(F(j) = 1 + g \cdot \lfloor j / m \rfloor\);
the anniversary index \(\lfloor j / m \rfloor\) is the same in both types.
Note
This formula assumes the default apply_from_first=False: the first payment has
factor 1 and growth starts from the second anniversary onward. With
apply_from_first=True the exponent becomes \(\lfloor j/m \rfloor + 1\), so the
first payment already carries the full first-year growth. See Growth Rates
for the apply_from_first parameter.
The absolute payment time for an annuity-immediate (ax) is:
The deferment \(d\) shifts payment times but does not affect the anniversary index. The growth exponent always counts full-year anniversaries from the first payment of the stream, regardless of \(d\).
Full formula (growing temporary life annuity-due)#
Full formula (growing temporary life annuity-immediate)#
For the deferred version with deferment \(d\):
Both äx and ax apply the same growth rule: the \(k\)-th payment (counting from 1)
carries factor \((1+g)^{\lfloor (k-1)/m \rfloor}\), so growth steps once per complete
policy year regardless of payment frequency. The index conventions differ only to
keep each sum naturally aligned with its payment times (\(j = 0\) to \(mn-1\) for
annuity-due, \(j = 1\) to \(mn\) for annuity-immediate).
Continuous calculation modes#
In continuous_precision mode the payment index \(j\) is replaced by continuous
time. The growth factor applied at time \(t\) with deferment \(d\) is
\(F(\lfloor t - d \rfloor)\): growth steps at each full-year anniversary of the
payment stream, regardless of payment density.
continuous_simplified uses an integer-grid approximation. Both modes apply the
same anniversary convention when \(d = 0\) (the most common case). For \(d > 0\),
the fractional terminal period in continuous_simplified uses \(\lfloor t \rfloor\)
rather than \(\lfloor t - d \rfloor\).
Net effective interest rate#
When a benefit grows at rate \(g\) and is discounted at rate \(i\), a useful single-rate equivalent is the net effective interest rate:
When \(i > g > 0\): \(0 < i^* < i\) — payments grow but discounting dominates. When \(i = g\): \(i^* = 0\) — growth and interest cancel; for a purely financial annuity-due of term \(n\) this gives \(\ddot{a}_{\overline{n}|}^{(g,i)} = n\). When \(g > i\): \(i^* < 0\) — growth exceeds discounting and the present value of later payments exceeds that of earlier ones.
Lactuca does not use \(i^*\) internally: all calculations operate directly on the full sum with rate \(i\) and growth factor \((1+g)^k\) per term. The net-rate identity is therefore a useful consistency check or mental shorthand, not an implementation detail. For growing annuities with mortality, the independence of survival probabilities from \(i^*\) means no further simplification arises beyond the annuity formula itself.
Bibliographic reference#
This convention is the standard in international actuarial literature:
Bowers, N.L., Gerber, H.U., Hickman, J.C., Jones, D.A., Nesbitt, C.J. Actuarial Mathematics, 2nd ed. Society of Actuaries, 1997. §5.
Dickson, D.C.M., Hardy, M.R., Waters, H.R. Actuarial Mathematics for Life Contingent Risks, 3rd ed. Cambridge University Press, 2020. §5.11.
Piecewise growth rates and fractional ts#
GrowthRate supports piecewise schedules of the form rates=[r_0, r_1, r_2, ...]
with associated terms. For geometric growth (growth_type='g', the default),
when every segment has a one-year term (terms=[1, 1, ...]), the growth factor at
anniversary \(k\) simplifies to:
For multi-year segments (terms=[T_0, T_1, ...]), the same rate applies for \(T_i\)
consecutive anniversary years: within the segment that contains \(k\), the factor
grows as \((1+r_s)^{k - C_s}\) where \(C_s = \sum_{i<s} T_i\) is the cumulative start
of that segment. Arithmetic piecewise (growth_type='a') is analogous, replacing
compound multiplication with linear accumulation. See lactuca.GrowthRate for
the full specification and Growth Rates for worked examples of both types.
When a temporal shift ts is applied (e.g. ax(x=60, ts=2.5)), the engine calls
GrowthRate.shifted(ts) to discard the first int(ts) anniversary years of the
schedule before dispatching. This flooring is actuarially correct: benefit
revaluation (CPI indexation, salary scales, guaranteed annual increases) always
operates on complete policy years, not fractional ones.
Example — piecewise schedule with fractional ts#
from lactuca import LifeTable, GrowthRate
gr = GrowthRate(rates=[0.01, 0.02, 0.05, 0.08], terms=[1, 1, 1])
# shifted(2.5) consumes years 0 and 1 (int(2.5) = 2)
print(gr.shifted(2.5)) # GrowthRate(rates=[0.05, 0.08], terms=[1], growth_type='g')
# At ts=2.5 the effective schedule starts at 0.05:
# F(0)=1, F(1)=1.05, F(2)=1.05×1.08, ...
lt = LifeTable("PASEM2020_Rel_1o", "m")
# A UserWarning is emitted because a GrowthRate is active with a fractional ts.
val = lt.ax(x=60, ts=2.5, m=12, ir=0.03, gr=gr)
print(round(val, 4))
Policy on fractional ts#
The UserWarning emitted on fractional ts fires only when a GrowthRate is
active (gr != None). Without a growth rate, fractional ts is silently accepted
regardless of config.force_integer_ts. This distinction is growth-specific: the
warning is meaningful only for escalating-benefit schedules where whole-year
anniversary indices matter.
For the full force_integer_ts reference — including the behaviour table and
interaction with d — see Prospective Reserves and the ts Parameter.