积分可能根据小数位有所不同

时间:2015-04-12 15:28:37

标签: r

我正在尝试将牛顿公式应用于长度为n = 500的反向采样方法。 (u统一随机数,Fphi_x我们根据分布,fphi_x是我们的密度)。 然后牛顿公式:找到x,使得Fphi_x(x)-u = 0

`u=runif(500)
xnewton=rep(1e-30,500)
fphi_x=function(x){return(0.307/(x^{5/12}*(x+1)))} 
Fphi_x=function(u){k=integrate(fphi_x,0,u)$value
               return(k)}
 for(i in 1:500)
{
  while(abs(Fphi_x(xnewton[i])-u[i])>0.0000001){
  xnewton[i]=xnewton[i]-(Fphi_x(xnewton[i])-u[i])/fphi_x(xnewton[i])
  }
 }`

代码正确。但是我得到了错误代码: Error in integrate(fphi_x, 0, u) : the integral is probably divergent. 我发现了:

Fphi_x(1e15)=1.197390096030634e-05 但如果我有小数位;例如 Fphi_x(10000000000.000000)我收到错误消息。 根据我的发行版,我会默默地获得高数字,例如小数位数,例如431232.132131。怎么解决? 最好的问候

1 个答案:

答案 0 :(得分:0)

这个问题似乎与你的被积函数在其下界无限的事实有关;

> fphi_x(0)
[1] Inf

显然integrate可以处理较小的上限而不是较大的上限。我尝试了几种方法。似乎有用的一个是改变积分

中的变量
      y = 1/x

保持被积函数有限,但明确地使上界无限。然后,您可以使用quadinf包中的积分函数pracma,它允许积分上的无限边界。
为了比较两个集成例程的结果,使用了set.seed(100)来修复为u返回的随机值。使用u的这些值,integrate函数将处理u的前126个值,而quadinf将计算所有500个值。每个的前126个值都相同 两者的代码如下:

set.seed(100)
  u=runif(500)
  xnewton=rep(1e-30,500)
  fphi_x=function(x){return(0.307/(x^{5/12}*(x+1)))} 
  Fphi_x=function(u){ k=integrate(fphi_x,0,u)$value
                      return(k)}
  for(i in 1:126)
  {
    while(abs(Fphi_x(xnewton[i])-u[i])>0.0000001){
      xnewton[i]=xnewton[i]-(Fphi_x(xnewton[i])-u[i])/fphi_x(xnewton[i])
    }
  }
  xnewton_x <- xnewton
 #
 #  using change of variable y = 1/x and quadinf function
 #
  library(pracma)
  xnewton=rep(1e-30,500)
  fphi_y <- function(y) .307*y^(5/12-1)/(1+y)
  Fphi_y <- function(u) quadinf(fphi_y, 1/u, Inf)$Q

  for(i in 1:500)
   {
     while(abs(Fphi_y(xnewton[i])-u[i])>0.0000001){
       xnewton[i] <- xnewton[i]- (Fphi_y(xnewton[i]) - u[i])/fphi_x(xnewton[i])
    }
   }
   xnewton_y <- xnewton  

quadinf似乎需要比integrate更长的时间来运行,但至少似乎会在integrate失败的情况下返回结果。