【问题标题】:Best way to solve an integral including a nonparametric density and distribution求解积分的最佳方法,包括非参数密度和分布
【发布时间】:2018-02-16 18:58:57
【问题描述】:

假设我想求解一个包含两个积分的函数(这是一个例子,实际函数更丑)

其中 a 和 b 是边界,c 和 d 是已知参数,f(x) 和 F(x) 是随机变量 x 的密度和分布。在我的问题中,f(x) 和 F(x) 是非参数化的,所以我只知道 x 的某些特定值的值。你会如何设置积分?

我做到了:

# Create the data
val <- runif(300, min=1, max = 10) #use the uniform distribution
CDF <- (val - 1)/(10 - 1)
pdf <- 1 / (10 - 1)
data <- data.frame(val = val, CDF = CDF, pdf = pdf)

c = 2
d = 1

# Inner integral
integrand1 <- function(x) {
  i <- which.min(abs(x - data$val))
  FF <- data$CDF[i]
  ff <- data$pdf[i]
  (1 - FF)^(c/d) * ff
}

# Vectorize the inner integral
Integrand1 <- Vectorize(integrand1)

# Outer integral
integrand2 <- function(x){
  i <- which.min(abs(x - data$val))
  FF <- data$CDF[i]
  ff <- data$pdf[i]
  (quadgk(Integrand1, x, 10) / FF) * c * ff
}

# Vectorize the outer integral
Integrand2 <- Vectorize(integrand2)

# Solve
require(pracma)
quadgk(Integrand2, 1, 10)

积分非常慢。有没有更好的方法来解决这个问题?谢谢。

---------编辑---------

在我的问题中,pdf 和 CDF 是根据值向量 v 计算得出的,如下所示:

# Create the original data
v <- runif(300, min = 1, max = 10)
require(np)

# Compute the CDF and pdf
v.CDF.bw <- npudistbw(dat = v, bandwidth.compute = TRUE, ckertype = "gaussian")
v.pdf.bw <- npudensbw(dat = v, bandwidth.compute = TRUE, ckertype = "gaussian")

# Extend v on a grid (I add this step because the v vector in my data
# is not very large. In this way I approximate the estimated pdf and CDF
# on a grid)
val <- seq(from = min(v), to = max(v), length.out = 1000)
data <- data.frame(val)
CDF <- npudist(bws = v.CDF.bw, newdata = data$val, edat = data )
pdf <- npudens(bws = v.pdf.bw, newdata = data$val, edat = data )
data$CDF <- CDF$dist
data$pdf <- pdf$dens

【问题讨论】:

    标签: r integration numerical-methods


    【解决方案1】:

    您是否考虑过使用approxfun

    它采用向量 x 和 y 并为您提供一个在它们之间进行线性插值的函数。因此,例如,尝试

    x <- runif(1000)+runif(1000)+2*(runif(1000)^2)
    dx <- density(x)
    fa <- approxfun(dx$x,dx$y)
    curve(fa,0,2)
    fa(0.4) 
    

    您应该能够使用网格化评估来调用它。它可能比你正在做的更快(也更准确)

    (编辑:是的,正如你所说,splinefun 应该没问题,如果它足够快满足你的需要)

    【讨论】:

    • 嗨@Glen_b,不幸的是这只是一个玩具例子,可能真正的积分更丑陋。我的主要问题是关于我在集成 1 和集成 2 函数中创建 CDF 和 pdf 的方式(例如,FF &lt;- data$CDF[i]ff &lt;- data$pdf[i])。我认为正是这种搜索算法减慢了计算速度。有没有更好的方法来做到这一点?
    • 老实说,我不太理解你在那里尝试做的事情;你只是说 cdf 是最接近已知值的 cdf 吗? ...和pdf一样吗? (那么两者会做出不一致的假设)也许对您尝试在那里做的事情进行更多详细说明的解释会有所帮助。 cdf和pdf的非参数计算是怎么做的?如果那里的情况更清楚,可能会做一些巧妙的事情。
    • 这比我想的要简单,但是你考虑过使用approxfun吗?
    • 它采用向量 x 和 y 并为您提供一个在它们之间进行线性插值的函数。例如,尝试x=runif(1000)+runif(1000)+2*(runif(1000)^2); dx=density(x); fa=approxfun(dx$x,dx$y); curve(fa,0,2); fa(0.4) .... 您应该可以使用网格评估来调用它。它可能比你正在做的更快(也更准确)
    • 如果这太慢了,您也许可以通过自己处理设置部分并直接调用C_ApproxTest(它的倒数第二行)或通过执行类似的操作来避免approxfun 中的开销.
    猜你喜欢
    • 1970-01-01
    • 2016-10-07
    • 1970-01-01
    • 1970-01-01
    • 2014-04-21
    • 2016-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多