Chris Butcher - 1 year ago 73

Ruby Question

I would like to create a random number generator, that generates a random decimal number:

- Greater than 0.0
- Less than 15.0
- Where the probability of that number being close to 2.0 is relatively high
- The probability of it being near 15.0 or very close to zero is very low

I'm terrifically poor at mathematics but my research seems to tell me I want to pull a random number from a Cumulative Distribution Function resembling a Fisherâ€“Snedecor (F) pattern, a bit like this one:

http://cdn.app.compendium.com/uploads/user/458939f4-fe08-4dbc-b271-efca0f5a2682/742d7708-efd3-492c-abff-6044d78e3bbd/Image/6303a2314437d8fcf2f72d9a56b1293a/f_distribution_probability.png

I am using a Ruby gem called Distribution (https://github.com/sciruby/distribution) to try and achieve this. It looks like the right tool, but I'm having a terrible time trying to understand how to use it to achieve the desired outcome :( Any help please.

Answer Source

I'll take it back, there is no `rng`

call for `F`

. So, if you want to use `Distribution`

gem, what I would propose is to use Chi^{2} with 4 degrees of freedom.

Mode for Chi^{2} with `k`

degress of freedom is equal to `k-2`

, so for 4 d.f. you'll get mode at 2, see here. My Ruby is rusty, bear with me

```
require 'distribution'
normal = Distribution::Normal.rng(0)
g1 = normal.call
g2 = normal.call
g3 = normal.call
g4 = normal.call
chi2 = g1*g1 + g2*g2 + g3*g3 + g4*g4
```

UPDATE

You have to truncate it at 15, so if generated chi2 is greater than 15 just reject it and generate another one. Though I would say you won't see a lot of value above 15, check graphs for PDF/CDF.

UPDATE II

And if you want to get samples from `F`

, make generic Chi^{2} generator for `d`

degrees of freedom from code above, and just sample ratio of chi2, check here

```
chi2_d1 = DChi2(d1)
chi2_d2 = DChi2(d2)
f = (chi2_d1.call / d1) / (chi2_d2.call / d2)
```

UPDATE III

And, frankly, I don't see how you could get `F`

distribution working for you. It is ok at `0`

, but mode is equal to `(d1-2)/d1 * d2/(d2 + 2)`

, and it is hard to see it equal to 2. Graph you provided has mode at about 1/3.