Reputation: 117
My question is related to my previous one Generate random variables from a distribution function using inverse sampling Now I want to generate random variables from a distribution function using inverse sampling but the sampling should be conditioned. For example, if the inverse of my cdf is :
invcdf <- function(y) a2 * log(a1/y - 1) + a3
I used inverse sampling to generate 10 rv as follows :
invcdf(runif(10))
Now, the problem is that I want the values generated greater or less than a value. How should I introduce this condition in random generator?
When I use this to have value greater than 500 :
invcdf(runif(10,500,1e6))
I get this error message : Warning message: In log((a0/y) - 1) : NaNs produced
I already try to repeat the process until having values satsifying my constraints but it is not efficient!
repeat{
x=invcdf(runif(1))
if(x>100){
break
}
Upvotes: 1
Views: 236
Reputation: 20090
As @spf614 noted, you'd better have checks in your function like
invcdf <- function(y) {
if (a1 > y) {
return( a2 * log(a1/y - 1) + a3 )
}
NaN
}
Then it works for all arguments
Sampling would be
low <- ...
r <- invcdf(runif(low, a1, 1e6))
UPDATE
checking for NaNs in output
nof_nans <- sum(is.nan(r))
if (nof_nans > 0) {
....
Upvotes: 2
Reputation: 52
The reason that you're getting NaNs is that R is trying to take the logarithm of a negative number. Do you want the log term to be log((a1/y)-1)
or log(a1/(y-1))
? You currently have the function written the first way, and when you get a very high value for y, the term a1/y
approaches zero (the speed with which it approaches zero depends on the value of a1
). Thus, subtracting 1 gives you a negative number inside the log function. So if the term is meant to be how you have it written (log(a1/y-1)
), you simply won't be able to calculate that above certain values of y
.
The simple fix is just
invcdf <- function(y){
a2 * log(a1/(y-1)) + a3
}
Upvotes: 1