vendredi 26 mai 2017

Generating random numbers from a distribution specified in R

I'm trying to generate random values from a given distribution given by the following function in R with the inverse cdf method found here described after the function

sigma=function(x){

  rc=0.5

  y=(x/rc) ; 

  C=(1/rc) ;

  Fun = log(1+C)-( C/(1+C) ) ; 

##### terms  

  a = 1/( y^2 - 1) ; b = 2/( sqrt(y^2 + 1 ) ) ;  c = atan( sqrt((y - 1)/y+1) ) ; 

  ff = a*(1 - b*c) ; 

##### My function   

  cst=2*pi

  sigma1 = (ff)/(cst*(rc^2)*Fun) ## function to generate random values

  # return(sigma1)

}

######## inverse CDF method from "found here" link

den<-sigma

#calculates the cdf by numerical integration
cdf<-function(x) integrate(den,-Inf,x)[[1]]

#inverts the cdf
inverse.cdf<-function(x,cdf,starting.value=0){
 lower.found<-FALSE
 lower<-starting.value
 while(!lower.found){
  if(cdf(lower)>=(x-.000001))
   lower<-lower-(lower-starting.value)^2-1
  else
   lower.found<-TRUE
 }
 upper.found<-FALSE
 upper<-starting.value
 while(!upper.found){
  if(cdf(upper)<=(x+.000001))
   upper<-upper+(upper-starting.value)^2+1
  else
   upper.found<-TRUE
 }
 uniroot(function(y) cdf(y)-x,c(lower,upper))$root
}

#generates 1000 random variables of distribution 'den'
vars<-apply(matrix(runif(1000)),1,function(x) inverse.cdf(x,cdf))
hist(vars)

And then the following error appears :

Error in integrate(den, -Inf, x) : the integral is probably divergent
Called from: integrate(den, -Inf, x)

Unfortunally I can't understand where is the problem in my function. However I tried another approach as follow: (which can be found here)

library(distr)
p <- sigma  # probability density function
dist <-AbscontDistribution(d=p)  # signature for a dist with pdf ~ p
rdist <- r(dist)                 # function to create random variates from p

set.seed(1)                      # for reproduceable example
X <- rdist(1000)                 # sample from X ~ p
x <- seq(-10,10, .01)
hist(X, freq=F, breaks=50, xlim=c(-5,5))
lines(x,p(x),lty=2, col="red")

And when I run the line dist <-AbscontDistribution(d=p), the following error is shown:

Error in seq.default(from = low1, to = upp1, length = ngrid) : 
  'from' cannot be NA, NaN or infinite
Além disso: Warning message:
In sqrt((y - 1)/y + 1) : NaNs produzidos

I'd like to know if someone can help me with this problem pointing me to some possible method that really works ?

I apologize for any error in my question.

If I was not very clear in my doubt, what I'm trying to do is something similar to what was done in this link, but with my function.

Again, thanks in advanced




Aucun commentaire:

Enregistrer un commentaire