Reputation: 3
When I run in R
runif(100,max=0.1, min=1e-10)
I get 100 uniformly distributed random variables between 0.1 and 0.0001. So, there is no random value between 0.0001 and the min value (min=1e-10
).
How to generate uniform random variables on the whole interval (between min and max values)?
Upvotes: 0
Views: 1229
Reputation: 145775
(Edited to replace exp(-10)
with 1e-10
)
Given your max of 0.1
and min of 1e-10
, the probability that any given value is less than 1e-4
is given by
(1e-4 - 1e-10) / (0.1 - 1e-10) = 9.99999e-04
The probability that 100 random values from this distribution are all greater than 1e-4
is
(1 - 9.99999e-04) ^ 100 = 0.90479
About 90.5%. So you shouldn't be at all surprised that in a draw of 100 numbers from this distribution, you didn't see any less than 1e-4
. This is expected more than 90.5% of the time theoretically. We can even verify this in simulation:
set.seed(47) # for replicability
# 100,000 times, draw 100 numbers from your uniform distribution
d = replicate(n = 1e5, runif(100, max = 0.1, min = 1e-10))
# what proportion of the 100k draws have no values less than 1e-4?
mean(colSums(d < 1e-4) == 0)
# [1] 0.90557
# 90.56% - very close to our calculated 90.48%
For more precision, we can repeat with even more replications
# same thing, 1 million replications
d2 = replicate(n = 1e6, runif(100, max = 0.1, min = 1e-10))
mean(colSums(d2 < 1e-4) == 0)
# [1] 0.90481
So, with 1MM replications, runif()
is almost exactly meeting expectations. It is off from the expectation by 0.90481 - 0.90479 = 0.00002
. I would say there is absolutely no evidence that runif
is broken.
We can even plot the histograms for some of the replications. Here are the first 20:
par(mfrow = c(4, 5), mar = rep(0.4, 4))
for (i in 1:20) {
hist(d[, i], main = "", xlab = "", axes = F,
col = "gray70", border = "gray40")
}
The histograms are showing 10 bars each, so each bar is about .01
wide (since the total range is about 0.1). The range you are interested in is about 0.0001
wide. To see that in a histogram, we would need to plot 1,000 bars per plot, 100 times as many bars. Using 1,000 bins doesn't make a lot of sense when there are only 100 values. Of course almost all the bins will be empty, and the lowest one, in particular, will be empty about 90% of the time as we calculated above.
To get more very low random values, your two choices are (a) draw more numbers from the uniform or (b) change distributions to one that has more weight closer to 0. You could try an exponential distribution? Or maybe, if you want a hard upper bound as well you could scale a beta distribution? Your other choice is to not use random values at all, maybe you want evenly spaced values and seq
is what you're looking for?
Upvotes: 2
Reputation: 94182
Maybe you aren't generating enough to make it likely enough that you've seen one:
> range(runif(100,max=0.1,min=exp(-10)))
[1] 0.00199544 0.09938462
> range(runif(1000,max=0.1,min=exp(-10)))
[1] 0.0002407759 0.0999674631
> range(runif(10000,max=0.1,min=exp(-10)))
[1] 5.428209e-05 9.998912e-02
How often do they occur?
> sum(runif(10000,max=0.1,min=exp(-10)) < .0001)
[1] 5
5 in that sample of 10000. So the chances of getting one in a sample of 100 is... (Actually you can work this out exactly from the number and the properties of a Uniform distribution).
Upvotes: 3