# [racket] Neil: Is there a sensible way to sample from the naturals? EOM

On 02/19/2014 03:33 PM, Sam Tobin-Hochstadt wrote:
>* On Wed, Feb 19, 2014 at 5:02 PM, Neil Toronto <neil.toronto at gmail.com> wrote:
*>>*
*>>* (: random-natural/no-mean (-> Real Natural))
*>>* (define (random-natural/no-mean prob-zero)
*>>* (define n (exact-floor (sample (geometric-dist prob-zero))))
*>>* (define m1 (assert (expt 2 n) integer?))
*>>* (define m0 (quotient m1 2))
*>>* (max 0 (random-integer m0 m1)))
*>>*
*>>* The "max 0" keeps TR from complaining that `random-integer' returns an
*>>* Integer.
*>*
*>* These both look like places where `math` could do better here with types.
*>*
*>* Specifically, `geometric-dist` should probably say that it produces
*>* non-negative floats. That would fix the need for the `assert`.
*
Ah, of course.
>* Second, `random-integer` could have the type: (case-> (Natural Natural
*>* -> Natural) (Integer Integer -> Integer)). That would fix the need
*>* for `max`.
*
I hadn't thought of doing that.
When I wrote that function, the math library was taking 45% of the total
compilation time, so I had stopped considering case-> types that weren't
strictly necessary. I know TR has gotten faster in the meantime, so it
might be time to revisit making some of the types more precise.
Uh, after I finish writing my dissertation. :) I'm so close...
>* Finally, I don't understand why `geometric-dist` returns floats and
*>* not integers, anyway.
*
The inverse CDF of any geometric distribution evaluated at 1 should be
infinity, as here:
> (inv-cdf (geometric-dist 0.5) 1)
+inf.0
My original reasoning was that I didn't want to deal with types like (U
Natural +inf.0) or ask users to deal with them. But now I realize that
it should be (U Natural Positive-Infinity):
> (inv-cdf (geometric-dist 0.5) 1)
+inf
i.e. the answer should be exact, not inexact.
Neil ⊥