From 671e2447dbb5cc1e5617b6f691a5bd707024a108 Mon Sep 17 00:00:00 2001 From: Alec Loudenback Date: Sat, 3 Feb 2024 08:26:30 -0600 Subject: [PATCH] allow fractional issue age if `mortality` is a parametric model --- src/LifeContingencies.jl | 16 ++++++++++++---- test/single_life.jl | 12 ++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/LifeContingencies.jl b/src/LifeContingencies.jl index df65615..af10f60 100644 --- a/src/LifeContingencies.jl +++ b/src/LifeContingencies.jl @@ -61,11 +61,19 @@ Keyword arguments: issue_age = 30 ) """ -struct SingleLife{M,D} <: Life +struct SingleLife{I,M,D} <: Life mortality::M - issue_age::Int + issue_age::I alive::Bool fractional_assump::D + function SingleLife(mortality::M, issue_age::I, alive::Bool=true, fractional_assump::D=mt.Uniform()) where {M<:MortalityTables.ParametricMortality,I<:Real,D<:DeathDistribution} + + return new{I,M,D}(mortality, issue_age, alive, fractional_assump) + end + function SingleLife(mortality::M, issue_age::I, alive::Bool=true, fractional_assump::D=mt.Uniform()) where {M,I<:Integer,D<:DeathDistribution} + + return new{I,M,D}(mortality, issue_age, alive, fractional_assump) + end end function SingleLife(; mortality, issue_age=nothing, alive=true, fractional_assump=mt.Uniform()) @@ -77,9 +85,9 @@ function SingleLife(mortality; issue_age=nothing, alive=true, fractional_assump= issue_age = firstindex(mortality) end - if !(eltype(mortality) <: Real) + if (eltype(mortality) <: AbstractArray) # most likely case is that mortality is an array of vectors - # use issue age to select the right one (assuming indexed with issue age + # use issue age to select the right one (assuming indexed with issue age) return SingleLife(mortality[issue_age], issue_age, alive, fractional_assump) else return SingleLife(mortality, issue_age, alive, fractional_assump) diff --git a/test/single_life.jl b/test/single_life.jl index e9f00d2..193bfaf 100644 --- a/test/single_life.jl +++ b/test/single_life.jl @@ -89,4 +89,16 @@ @test premium_net(ins, 26) ≈ LifeContingencies.A(ins, 26) / LifeContingencies.ä(ins, 26) end + + @testset "issue https://github.com/JuliaActuary/LifeContingencies.jl/issues/78" begin + t = MortalityTables.table("2001 VBT Residual Standard Select and Ultimate - Male Nonsmoker, ANB") + i = 0.05 + @test_throws MethodError LifeContingency(SingleLife(mortality=t.ultimate, issue_age=53.75), i) + + m = MortalityTables.MakehamBeard() + lc1 = LifeContingency(SingleLife(mortality=m, issue_age=53.75), i) + lc2 = LifeContingency(SingleLife(mortality=m, issue_age=54.00), i) + @test l(lc1, 1) > l(lc2, 1) + + end end \ No newline at end of file