[GRASSLIST:40] Re: r.mapcalc evaluation order
Jan Hartmann
jhart at frw.uva.nl
Thu May 15 11:21:42 EDT 2003
Ok, very clear answer, thanks. Good to know that this is indeed the
bottleneck. I'll write a C function in Grass to do my recategorization.
Shouldn't be much work.
Knowing this, I don't think implementing "lazy" function in Grass itself
is a good idea. It would change Grass's behavior. With r.mapcalc for
example, if two if-expressions overlap, I guess the result now is the
last one, and with lazy evaluation the first. This would without any
doubt cause endless problems with existing applications.
Jan
Glynn Clements wrote:
> Jan Hartmann wrote:
>
>
>>I am running r.mapcalc on the LandScan world population database
>>(www.ornl.gov/gist/projects/LandScan). This is a 4 byte, 43.200*20.800
>>raster, and I use mapcalc to recategorize it to a one byte, 256 valued
>>raster, according to some different categorizing algorithms (essentially
>>variations on histogram equalisation). The category boundaries have been
>>computed separately; the only thing r.mapcalc has to do is to apply them
>>to the input raster. The mapcalc script only consists of a few dozens of
>>"if" rules, but these take a very long time to execute (days). My
>>impression is that r.mapcalc evaluates every rule for every cell. Does
>>anyone know if this is the case, and if so, is there a way to stop
>>evaluation after a match has been found (something like an "else"
>>statement)?
>
>
> The overall evaluation strategy is that r.mapcalc processes one row at
> a time. Each function (e.g. "if") takes a row of cells (i.e. a
> one-dimensional array) as input, and stores the results in a result
> array. For nested expressions, the array which holds the result from
> an inner term is passed as an input to the enclosing term. Once the
> final result has been computed for a row, the row is written out and
> computation starts on the next row.
>
> I suspect that your problem stems from the fact that the "if" function
> is strict; i.e. all of the arguments are computed, passed to the
> function, then one of the arguments is returned. Any time spent
> computing the unused argument is effectively wasted.
>
> This contrasts with general-purpose programming languages, where the
> "if" construct is lazy; i.e. the condition is evaluated first, and
> only one of the alternatives is evaluated.
>
> r.mapcalc doesn't provide a lazy conditional mechanism. For
> general-purpose programming languages, a lazy conditional is
> absolutely necessary in order to be able to define recursive
> functions. As r.mapcalc doesn't allow you to define your own functions
> (recursive or otherwise), this isn't an issue.
>
> For r.mapcalc, a lazy conditional would only be an optimisation; it
> wouldn't extend the set of possible computations, but would just make
> some of them faster.
>
> I appreciate that this particular optimisation might be of substantial
> benefit to you personally, but it would require significant changes to
> r.mapcalc. Currently, *all* functions are strict; the core evaluation
> code would need to be extended to allow for lazy functions generally
> before you could implement any specific lazy function.
>
> Consequently, such an extension isn't likely to be implemented any
> time soon. In the absence of any other options, you could just add
> your categorisation function to r.mapcalc itself. Adding new functions
> is relatively straightforward; I can provide assistance if you wish to
> take that route.
>
More information about the grass-user
mailing list