Reputation: 99
I dont understand why the below function return NaN even the answer shouldn't be NaN. I have tried to search similar question but most of them in other programming language that i couldn't understand.
Code:
a0 = 1.5; a1 = 0.4; b1 = 0.3; g1= 0.7
nu = rep(0,1)
h.new = rep(0,1)
ddp = rep(0,1)
nu[1]=0
h.new[1] = a0/(1-a1-b1)
ddp[1] = 0.5*log(g1)- g1*h.new[1] +
nu[1]*(log(nu[1])-1) - log(factorial(nu[1]))+(g1)*nu[1]*
(1+log(h.new[1]/nu[1]))
This is the output:
###> ddp
###[1] NaN
Then I do manual calculation, clearly show that ddp is not NaN:
###h.new = 1.5/(1-0.4-0.3) = 5
###ddp
###= 0.5*log(0.7)- (0.7)*(5) +
###(0)*(log(0)-1) - log(0!)+(0.7)*(0)*
###(1+log(5/0))
###= 0.5*log(0.7)- (0.7)*(5)
###= -3.6783
I did know for sum() function, na.rm=TRUE could ommit all the missing value, but in this case, how to modify the code to make it return to the correct answer?
Thanks in advance.
Upvotes: 0
Views: 2528
Reputation: 4537
nu[1]
is 0 and the log of 0 is undefined. R evaluates log(0)
as -Inf
Then you have log(5/0)
- what is 5/0? It's undefined. So you have lots of undefined values which will create an overall undefined result. As noted in Ben's answer, the NaN
is created when you multiply 0 by Inf
or -Inf
However, even if these two elements were to resolve to 0, the code you've written would evaluate to -3.68, not -0.52. So, you're doing something wrong by hand.
Upvotes: 2
Reputation: 226182
In general 0*Inf
gives NaN
in R: the computer doesn't/can't know how you want to take the limit. If you know that you want these limits to be zero, you can specify how your computation works in the special case nu==0
:
term3 <- if (nu==0) 0 else nu*(log(nu)-1)
term5 <- if (nu==0) 0 else g1*nu*(1+log(h.new/nu))
ddp = 0.5*log(g1)-
g1*h.new +
term3 -
log(factorial(nu))+
term5
You could do this slightly more generally with a zprod
function:
zprod <- function(x,y) {
if (x==0) 0 else x*y
}
ddp = 0.5*log(g1)- g1*h.new +
zprod(nu,log(nu)-1) - log(factorial(nu))+
g1*zprod(nu,1+log(h.new/nu))
Upvotes: 2