The following simple code can be used to find roots of functions (based on the secant algorithm),
secant=function(fun, x0, x1, tolerence=1e-07, niter=500){ for ( i in 1:niter ) { x2 <- x1-fun(x1)*(x1-x0)/(fun(x1)-fun(x0)) if (abs(fun(x2)) < tolerence) return(x2) x0 <- x1 x1 <- x2 }}
It can be interesting in actuarial science, e.g. to find the actuarial rate so that to present values are equal. For instance, consider the following capital, given only if the insured is still alive (this example was initially considered here). We would like to find the rate so that the probable discounted value is 600,
> Lx=read.table("https://perso.univ-rennes1.fr/arthur.charpentier/TV8890.csv", + header=TRUE,sep=";") > capital=c(100,100,125,125,150,150) > n=length(capital) > x=0.035 > X=45 > f=function(x){ + capital.act=capital*(1/(1+x))^(1:n) + PROBA=Lx[((Lx[,1]>X)*(Lx[,1]<=(X+n)))==1,2]/Lx[(Lx[,1]==X)==1,2] + return(sum(capital.act*PROBA))} > > f1=function(x){f(x)-600} > secant(f1,0,0.1) [1] 0.06022313 > f(0.06022313) [1] 600
OpenEdition suggests that you cite this post as follows:
Arthur Charpentier (December 7, 2010). Finding roots of functions in actuarial science. Freakonometrics. Retrieved January 14, 2025 from https://doi.org/10.58079/ouft
I recoiled when I read the title where you had to make the algorithm specific to actuarial science, it’s as if one were to discover a way to compute an integral in biology/diabetes research. Oh wait somebody did just that: http://goo.gl/ytDqK 🙂
Igor.
ANSWER: 🙂 Good point ! My post was simply to mention how important this algorithm was in actuarial science. So I just put it here… and actually, I got an extremely interesting comment by Franck about multiple roots ! Stupid post can lead to interesting comments… so finally I am proud of writing useless things !
Thank you for this interesting post. I gives me the opportunity to have your impact on a related question.
The internal rate of return is a very convenient tool, but I have a major difficulty with it : its non uniqueness.
For instance, with your example, f(-1,69844) works as well. I understand that this is not a good solution, since the IRR has to be positive.
Is there a way to define the IRR in a non ambiguous way ?
For instance, which IRR should I choose in the following case :
flux<-c(75.76,-174.24,100)
1/polyroot(flux)-1
# +10 % or +20% ?
ANSWER: this is a good question… give me a few days to think about it ! (or if anyone has a response to that, please leave a comment)