Triple integral in R (how to specifying the domain)

痴心易碎 提交于 2019-12-11 12:38:32

问题


I would like to compute the triple integral of a function of three variables f(x,y,z) in R. I'm using the package cubature and the function adaptIntegrate(). The integrand is equal to 1 only in a certain domain (x<y<z, 0 otherwise) which I don't know how to specify. I'm trying 2 different implementations of the function, but none of them work:

#First implementation
fxyz <- function(w) {
x <- w[1]
y <- w[2]
z <- w[3]
x*y*z*(x < y)&(y < z)
}

#Second implementation
fxyz <- function(w) {
x <- w[1]
y <- w[2]
z <- w[3]
if(x<y&y<z)
    out<-1
else
    out<-0
out
}

#Computation of integral
library(cubature)
lower <- rep(0,3)
upper <- rep(1, 3)
adaptIntegrate(f=fxyz, lowerLimit=lower, upperLimit=upper, fDim = 3)

Any idea on how to specify the domain correctly?


回答1:


In your first function the return value is wrong. It should be as.numeric(x<=y)*as.numeric(y<=z). In your second function you should also use <= instead of <, otherwise `adapIntegrate won't work correctly. You also need to specify a maximum number of evaluations. Try this

library(cubature)
lower <- rep(0,3)
upper <- rep(1,3)

# First implementation (modified)
fxyz <- function(w) {
    x <- w[1]
    y <- w[2]
    z <- w[3]
    as.numeric(x <= y)*as.numeric(y <= z)
}

adaptIntegrate(f=fxyz,lowerLimit=lower,upperLimit=upper,doChecking=TRUE,
          maxEval=2000000,absError=10e-5,tol=1e-5)
#$integral
#[1] 0.1664146
#$error
#[1] 0.0001851699
#$functionEvaluations
#[1] 2000031
#$returnCode
#[1] 0



回答2:


I don't know about the cubature package, but you can do this by repeated application of base R's integrate function for one-dimensional integration.

f.xyz <- function(x, y, z) ifelse(x < y & y < z, 1, 0)
f.yz <- Vectorize(function(y, z) integrate(f.xyz, 0, 1, y=y, z=z)$value,
                  vectorize.args="y")
f.z <- Vectorize(function(z) integrate(f.yz, 0, 1, z=z)$value,
                 vectorize.args="z")

integrate(f.z, 0, 1)
# 0.1666632 with absolute error < 9.7e-05

You'll probably want to play with the control arguments to set the numeric tolerances; small errors in the inner integration can turn into big ones on the outside.




回答3:


The domain 0 <= x <= y <= z <= 1 is the "canonical" simplex. To integrate over a simplex, use the SimplicialCubature package.

library(SimplicialCubature)
f <- function(x) 1
S <- CanonicalSimplex(3)

> adaptIntegrateSimplex(function(x) 1, S)
$integral
[1] 0.1666667

$estAbsError
[1] 1.666667e-13

$functionEvaluations
[1] 55

$returnCode
[1] 0

$message
[1] "OK"

Note that integrating the constant function f(x)=1 over the simplex simply gives the volume of the simplex, which is 1/6. The integration is useless for this example.

> SimplexVolume(S)
[1] 0.1666667


来源:https://stackoverflow.com/questions/29448144/triple-integral-in-r-how-to-specifying-the-domain

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!