[GRASS-user] r.mapcalc: columns()/modulo - rounding issue, possible bugfeature ?

Hi,

I stumbled over this "funny" behavior of the col() function of r.mapcalc (GRASS6.2 and GRASS6.4, both on Linux).

According to The Book, col() "returns current col of moving window".

I assume that for each row of a given raster layer col() should provide the values 1,2,3,4,5, etc. as it travels through the row.

To produce a map of repeating value sequences (for example the numbers 1 2 3 4 ) the module operator can be used on the col()-function:

col() operator result
1 mod 4 = 1
2 mod 4 = 2
3 mod 4 = 3
4 mod 4 = 0
5 mod 4 = 1
6 mod 4 = 2
etc

this approach was put into mapcalc. The "1 + " makes sure that the sequence runs from 1-4 not 0 - 3:

r.mapcalc modulo="(1 + ( col() % 4 ) )"

A map was produced in a Spearfish location (col() should operate independently from the projection).

Here it comes:
For some (strange ?)reason, there are "ripples" in the "1 - 4" sequence.

Instead of going 1234 1234 1234 ad infinitum once in a while a number is omitted: 1234 1234 234 1234 134 etc.

Has anybody come across this behavior before ?
Is this a feature/good-thing ?

The phenomenon can be reproduced by using the above mentioned r.mapcalc command, displaying the result as a cell values layer.

1234, 1234, ...,
Peter
--
Dr. Peter Löwe
<peter.loewe@gmx.de>

Jetzt 1 Monat kostenlos! GMX FreeDSL - Telefonanschluss + DSL
für nur 17,95 Euro/mtl.!* http://dsl.gmx.de/?ac=OM.AD.PD003K11308T4569a

On 16/02/09 15:31, peter.loewe@gmx.de wrote:

Hi,

I stumbled over this "funny" behavior of the col() function of
r.mapcalc (GRASS6.2 and GRASS6.4, both on Linux).

According to The Book, col() "returns current col of moving window".

I assume that for each row of a given raster layer col() should
provide the values 1,2,3,4,5, etc. as it travels through the row.

To produce a map of repeating value sequences (for example the
numbers 1 2 3 4 ) the module operator can be used on the
col()-function:

col() operator result 1 mod 4 = 1 2 mod 4 = 2 3
mod 4 = 3 4 mod 4 = 0 5 mod 4 = 1 6 mod 4
= 2 etc

this approach was put into mapcalc. The "1 + " makes sure that the
sequence runs from 1-4 not 0 - 3:

r.mapcalc modulo="(1 + ( col() % 4 ) )"

A map was produced in a Spearfish location (col() should operate
independently from the projection).

Here it comes: For some (strange ?)reason, there are "ripples" in the
"1 - 4" sequence.

Instead of going 1234 1234 1234 ad infinitum once in a while a number
is omitted: 1234 1234 234 1234 134 etc.

Has anybody come across this behavior before ? Is this a
feature/good-thing ?

After a little testing I come to the (preliminary) conclusion that this depends on whether the number of cols is divisable by 4, i.e. cols % 4 = 0. If this is not the case, then you don't get the complete sequence. So, it depends on your region setting.

Moritz

peter.loewe@gmx.de wrote:

I stumbled over this "funny" behavior of the col() function of
r.mapcalc (GRASS6.2 and GRASS6.4, both on Linux).

According to The Book, col() "returns current col of moving window".

I assume that for each row of a given raster layer col() should
provide the values 1,2,3,4,5, etc. as it travels through the row.

To produce a map of repeating value sequences (for example the numbers
1 2 3 4 ) the module operator can be used on the col()-function:

col() operator result
1 mod 4 = 1
2 mod 4 = 2
3 mod 4 = 3
4 mod 4 = 0
5 mod 4 = 1
6 mod 4 = 2
etc

this approach was put into mapcalc. The "1 + " makes sure that the
sequence runs from 1-4 not 0 - 3:

r.mapcalc modulo="(1 + ( col() % 4 ) )"

A map was produced in a Spearfish location (col() should operate
independently from the projection).

Here it comes:
For some (strange ?)reason, there are "ripples" in the "1 - 4" sequence.

Instead of going 1234 1234 1234 ad infinitum once in a while a number
is omitted: 1234 1234 234 1234 134 etc.

Has anybody come across this behavior before ?
Is this a feature/good-thing ?

The phenomenon can be reproduced by using the above mentioned
r.mapcalc command, displaying the result as a cell values layer.

Please be more precise regarding the "displaying" part.

If I run:

  r.mapcalc "modulo = (1 + ( col() % 4 ) )"
  r.out.ascii modulo | head

I see what I expect, not what you describe.

OTOH, if you replace r.out.ascii with e.g. d.rast, the data will then
be resampled again according to the "screen" dimensions.

If you run d.rast from the command line, the default screen dimensions
are 640 x 480. With the default region for Spearfish of 634 x 477, the
resampling will be ever so slightly greater than 1:1, resulting in
occasional duplicates.

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

peter.loewe wrote:

I stumbled over this "funny" behavior of the col() function of
r.mapcalc (GRASS6.2 and GRASS6.4, both on Linux).

According to The Book, col() "returns current col of moving window".

I assume that for each row of a given raster layer col()
should provide the values 1,2,3,4,5, etc. as it travels
through the row.

To produce a map of repeating value sequences (for example
the numbers 1 2 3 4 ) the module operator can be used on the
col()-function:

col() operator result
1 mod 4 = 1
2 mod 4 = 2
3 mod 4 = 3
4 mod 4 = 0
5 mod 4 = 1
6 mod 4 = 2
etc

this approach was put into mapcalc. The "1 + "
makes sure that the sequence runs from 1-4 not 0 - 3:

r.mapcalc modulo="(1 + ( col() % 4 ) )"

A map was produced in a Spearfish location (col() should
operate independently from the projection).

Here it comes:
For some (strange ?)reason, there are "ripples"
in the "1 - 4" sequence.

Instead of going 1234 1234 1234 ad infinitum once in a
while a number is omitted: 1234 1234 234 1234 134 etc.

Has anybody come across this behavior before ?
Is this a feature/good-thing ?

For the the xmon looks ok to me,

#spearfish + grass 6.4rc
g.region -d
  #rows: 477
  #cols: 634
r.mapcalc modulo="(1 + ( col() % 4 ) )"

r.stats modulo -c # count number of cells
100%
1 75366
2 75843
3 75843
4 75366

# 75843 - 75366 = 477 = number of rows.
# zooming way in and looking with d.what.rast I see the left-most
# column (western edge) is 2s and the right-most column (eastern edge)
# is 3s.

r.univar modulo
sum: 756045

#rows: 477
#cols: 634

634 % 4 = 2
634 / 4 = 158 (truncated to int)

( 1*158 + 2*159 + 3*159 + 4*158 ) * 477 = 756045
which is the same as r.univar reports.

so only thing I see is that the "col()%4 +1" doesn't need the +1 as
col() starts at 1 not 0. For the missing value mid-stream I would guess
slight sampling/aliasing error?? try running "g.region rast=modulo" first
and see if you get the same result.

Hamish