[R] Different values for double integral
Andreas Wittmann
andreas_wittmann at gmx.de
Sat Jan 24 15:10:48 CET 2009
Thank you all, for the very helpful advice.
i want to estimate the parameters omega and beta of the gamma-nhpp-model
with numerical integration.
so one step in order to do this is to compute the normalizing constant,
but as you see below i get different values
## some reliability data, theses are times between events like a
failures during software test.
`s` <-
c(8100, 4800, 900, 450, 450, 6000, 2400, 2100, 2100,
1260, 1200, 300, 9000, 600, 2400, 600, 15060, 120, 360,
1200, 300, 1200, 1200, 3300, 19800, 3000, 600, 9600,
8400, 8100, 15600, 1800, 5400, 3900, 2400, 1200, 79500,
9000, 48900)
## likelihood function of the NHPP-gamma reliability model
`likelihood` <- function(s, omega, beta, alpha=1)
{
me<-length(s)-1
te<-cumsum(s)[length(s)] ## endpoint of observation
omega^me*prod(dgamma(cumsum(s)[-length(s)], shape=alpha, rate=beta)) *
exp(-omega*pgamma(te, shape=alpha, rate=beta))
}
## normalizing constant first integrating omega then beta
`normConst1` <- function(s, alpha=1, lowBeta=-Inf, uppBeta=Inf,
lowOmega=-Inf, uppOmega=Inf)
{
"g" <- function(beta, ...)
{
integrate(function(omega) {likelihood(s=s, omega, beta,
alpha=alpha)}, lowOmega, uppOmega)$value
}
val <- integrate(Vectorize(function(beta) {g(beta, lowOmega=lowOmega,
uppOmega=uppOmega, s=s,
alpha=alpha)}), lowBeta,
uppBeta)$value
return(val)
}
## normalizing constant first integrating beta then omega
`normConst2` <- function(s, x, alpha=1, lowBeta=-Inf, uppBeta=Inf,
lowOmega=-Inf, uppOmega=Inf)
{
"g" <- function(omega, ...)
{
integrate(function(beta) {likelihood(s=s, omega, beta,
alpha=alpha)}, lowBeta, uppBeta)$value
}
val <- integrate(Vectorize(function(omega) {g(omega, lowBeta=lowBeta,
uppBeta=uppBeta, s=s,
alpha=alpha)}), lowOmega,
uppOmega)$value
return(val)
}
## integration limits were choosen by taking the quantiles of beta and
omega
## of a mcmc run
normConst1(s=s, lowBeta=2.8e-06, uppBeta=2.8e-05,
lowOmega=12.5, uppOmega=90)
[1] 5.131021e-162
normConst2(s=s, lowBeta=2.8e-06, uppBeta=2.8e-05,
lowOmega=12.5, uppOmega=90)
[1] 5.246008e-158
## i get normalizing constants with different values
best regards and many thanks
Andreas
Prof Brian Ripley wrote:
> More generally, if you want to do a two-dimensional integral, you will
> do better to us a 2D integration algorithm, such as those in package
> 'adapt'.
>
> Also, these routines are somewhat sensitive to scaling, so if the
> correct answer is around 5e-9, you ought to rescale. You seem to be
> in the far right tail of your gamma distribution (but as you are not
> integrating over z, pgamma is not appropriate).
>
> More specifically, cumsum(z)[-length(z)] is constant ( c(80,100, 140)
> ) are can be done once. But without knowing the intention of f1, it
> is impossible to show you better code.
>
> On Sat, 24 Jan 2009, Duncan Murdoch wrote:
>
>> On 24/01/2009 5:23 AM, Andreas Wittmann wrote:
>>> Dear R useRs,
>>>
>>> i have the function f1(x, y, z) which i want to integrate for x and
>>> y. On the one hand i do this by first integrating for x and then for
>>> y, on the other hand i do this the other way round and i wondering
>>> why i doesn't get the same result each way?
>>>
>>> z <- c(80, 20, 40, 30)
>>>
>>> "f1" <- function(x, y, z) {dgamma(cumsum(z)[-length(z)], shape=x,
>>> rate=y)}
>>>
>>> "g1" <- function(y, z) {integrate(function(x) {f1(x=x, y=y, z=z)},
>>> 0.1, 0.5)$value}
>>> "g2" <- function(x, z) {integrate(function(y) {f1(x=x, y=y, z=z)},
>>> 0.1, 0.5)$value}
>>>
>>> integrate(Vectorize(function(y) {g1(y=y, z=z)}), 0.1, 0.5)$value
>>> [1] 5.909943e-09
>>> integrate(Vectorize(function(x) {g2(x=x, z=z)}), 0.1, 0.5)$value
>>> [1] 5.978334e-09
>>>
>>> If you have any advice what is wrong here, i would be very thankful.
>>
>> It looks as though your f1 returns a vector result whose length will
>> be the max of length(z)-1, length(x), and length(y): that's not
>> good, when you don't have control over the lengths of x and y. I'd
>> guess that's your problem. I don't know what your intention was, but
>> if the lengths of x and y were 1, I think it should return a length 1
>> result.
>>
>> More geneally, integrate() does approximate integration, and it may
>> be that you won't get identical results from switching the order even
>> if you fix the problems above.
>>
>> Finally, if this is the real problem you're working on, you can use
>> the pgamma function to do your inner integral: it will be faster and
>> more accurate than integrate.
>>
>> Duncan Murdoch
>>
>> ______________________________________________
>> R-help at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> PLEASE do read the posting guide
>> http://www.R-project.org/posting-guide.html
>> and provide commented, minimal, self-contained, reproducible code.
>>
>
More information about the R-help
mailing list