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

Glynn Clements glynn at gclements.plus.com
Mon Aug 14 22:53:00 EDT 2006


Maciej Sieczka wrote:

> >> $ r.mapcalc 'map=rand(1,100)'
> >> $ r.info -r map
> >> min=1
> >> max=99
> >>     ^
> >>     |
> >>   should be 100!
> 
> > The above is correct, although the documentation should be more
> > explicit. The result of rand() is a pseudo-random value x such that:
> 
> > 	a <= x < b
> 
> > This definition results in consistent behaviour for both the integer
> > and floating-point cases, as well as being consistent with most
> > standard PRNG functions (which usually treat the upper bound as
> > exclusive).
> 
> Is this really necessary?

Well, "necessary" is debatable, but it is The Right Thing, for most
sane values of "right".

> Isn't it counter intuitive?

That depends; whose intuition?

To anyone with a remotely mathematical background, anything other than
the above definition would be completely abnormal (at least for the
float case, and see below about treating integers differently).

It's a throughly established convention that partitions are defined as
start-closed, end-open (i.e. lo <= x < hi). E.g. if you partition the
reals into unit subsets, you would normally do it as:

{..., {x : -2 <= x < -1}, {x : -1 <= x < 0}, {x : 0 <= x < 1}, {x : 1 <= x < 2}, ...}

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).

With integers, you can always replace "... < n" with "... <= n+1";
that won't work with reals, as there isn't a "next" real.

Beyond that, as a general rule, the integers should, wherever possible
be treated as a subset of the reals, rather than as a disjoint set. 
For anything which is defined for both integers and reals, the integer
version should be defined such that it produces the same (or
equivalent) result as applying the real definition to any real which
happens to be an integer.

Also, note that, in the floating-point case, the behaviour of
r.mapcalc's rand() is essentially dictated by that of drand48(). An
end-closed range would require writing our own FP PRNG.

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




More information about the grass-dev mailing list