[GRASS-dev] [bug #4998] (grass) r.mapcalc rand (a, b): b-1 is used instead of b

Glynn Clements glynn at gclements.plus.com
Wed Aug 16 04:54:02 EDT 2006


Maciej Sieczka wrote:

> > Using partitions which are closed at both ends results in overlapping
> > partitions (i.e. the boundary points belong to both), while partitions
> > which are open at both ends result in gaps (i.e. the boundary points
> > belong to neither).
> 
> Right. I haven't thought of it.
> 
> On the other hand, if one needs an FP random number from a closed range
> eg. <1,100> (I mean - including the max value) given how rand is
> currently implemented in r.mapcalc this cannot be achieved. He will get
> all values <1,100), ie. all but 100 itself.
> 
> Thanks to your explanations I understand now this problem should be
> rather considered as a wish. Would it be hard to implement both closed
> and open ranges, as well as their combinations, in r.mapcalc's rand?

For integers, getting a closed range is trivial; just add one to the
upper bound, i.e. rand(1,101) will give {x : 1 <= x <= 100}.

For floating point values, a closed range would require a FP PRNG
which provides a closed range, which we would have to write ourselves;
drand48() and erand48() both return values in the range [0,1), and
there aren't any other standard functions we could use.

You can fudge it with e.g. "rand(10000,1000001) / 1e4", although that
will produce artifacts which might be signficant for some
applications.

[We already do essentially this if drand48() isn't available, although
it currently results in an end-closed range (dividing by RAND_MAX
rather than RAND_MAX+1).]

Ultimately, for FP, the difference is largely theoretical. With a
53-bit mantissa, the chances of actually getting the end value would
be 1 in 2^53, which is negligible.

One of the things which makes writing a real FP PRNG tricky is that
every FP value within the target range should be possible, but the
probability of any given value occurring needs to be weighted
according to the exponent (i.e. if you want values between 1 and 4,
the number of values between 2 and 4 should be double the number
between 1 and 2).

FWIW, the current FP rand() implementation doesn't actually meet the
first criterion unless the bounds are 0 and 2^N, for some N. Again,
this can't be fixed without writing our own FP PRNG. It should be
close enough for most case though (and there will always be cases
where a given PRNG falls down due to the deterministic nature of
pseudo-random numbers; the only way to avoid that is to use truly
random numbers derived from e.g. quantum noise).

-- 
Glynn Clements <glynn at gclements.plus.com>




More information about the grass-dev mailing list