To find values distributed with probability of 1/x
:
The integral of 1/x
is ln x
, and as @dbaupp pointed out, it grows without bound. In fact, the limit of ln x
as x approaches 0 is infinite (negative), and the limit as it grows to positive infinity is infinite (positive).
So we'll have to limit the range of our function to some interval [min, max)
, where min > 0
and both are finite.
The inverse of q = ln x
is x = e^q
, so the quantile function is e^[(ln max - ln min)q + ln(min)]
, where q falls in the interval [0,1)
After a little algebra, that becomes (max/min)^q * min
= (max^q)(min^(1-q))
(I'm not sure which form is more numerically stable)
So, plugging uniformly distributed values ranging from 0 to 1, such as you'd get from nextDouble, into this function will give you values with a pdf = 1/x
and ranging from the given min to max:
public static double reciprocalQuantile(double q, double min, double max) {
return Math.pow(max, q)*Math.pow(min, 1-q);
}
So you could say:
Random rand = new Random();
double value = reciprocalQuantile(rand.nextDouble(), 0.0001, 10000);
I think :-) Please feel free to check my math.
One more point: You could of course set min to Double.MIN_VALUE and max to Double.MAX_VALUE, but I don't know enough about floating point representations to know if that would be problematic, and if it is then I don't know how small/large a number would need to be to become so. It might also not be very useful. A little testing showed a lot of very tiny values and a lot of very large ones --- which isn't surprising, since the integrals of the top and the bottom approach infinity. So to get enough values in the middlish range for a pretty histogram, you'd need a lot of values.