Strange r.mapcalc results

7 messages Options
Embed this post
Permalink
Hermann Peifer

Strange r.mapcalc results

Reply Threaded More More options
Print post
Permalink
Hi,

I am trying to find out if 2 raster layers are exactly identical. I am
not an experienced mapcalc user, so I am wondering, where the 3200204
NULL values come from, in Test1. The result in Test2 is what I expected.

My obviously wrong understanding was that I wouldn't need the special
operator ||| in Test1, as NULL values are already treated specially by
isnull()

Any hint from the experts?

Hermann


Test1

$ r.mapcalc 'result = isnull(mapA) && isnull(mapT) || mapA == mapT ? 1 : 2'

$ r.stats -c result
1 799796
* 3200204

Test2

$ r.mapcalc 'result = isnull(mapA) && isnull(mapT) ||| mapA == mapT ? 1 : 2'

$ r.stats -c result
1 4000000

Test3

$ r.mapcalc 'result = isnull(mapA) && isnull(mapT) ? 1 : mapA == mapT ?
2 : 3'

$ r.stats -c result
1 3200204
2 799796

_______________________________________________
grass-user mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/grass-user
hamish-2

Re: Strange r.mapcalc results

Reply Threaded More More options
Print post
Permalink
Hermann wrote:
> I am trying to find out if 2 raster layers are exactly
> identical.

I usually do

g.region rast=map1,map2

r.univar map1
r.univar map2

and make sure the output is the same.


another way is
r.mapcalc "diffmap = map1 - map2"
r.univar diffmap


see also wish #618
 https://trac.osgeo.org/grass/ticket/618


Hamish




_______________________________________________
grass-user mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/grass-user
Hermann Peifer

Re: Strange r.mapcalc results

Reply Threaded More More options
Print post
Permalink
 > r.univar based comparison:

What if there was a small geometric shift between the 2 maps. Would I
notice if both maps have enough NULLs around the edges?


 > r.mapcalc "diffmap = map1 - map2"

How would I separate NULL,NULL cases from cases where one map has a
value, but the other has NULL?


And after thinking twice about my earlier posted test results, I still
do not understand the logic of the isnull() results:

isnull(mapA) && isnull(mapT) gives NULL (Test1)
isnull(mapA) && isnull(mapT) gives 1    (Test3)

This doesn't make sense to me, which might be my fault, though.

Test1

$ r.mapcalc 'result = isnull(mapA) && isnull(mapT) || mapA == mapT ? 1 : 2'

$ r.stats -c result
1 799796
* 3200204

Test3

$ r.mapcalc 'result = isnull(mapA) && isnull(mapT) ? 1 : mapA == mapT ?
2 : 3'

$ r.stats -c result
1 3200204
2 799796

Hermann



Hamish wrote:

> Hermann wrote:
>> I am trying to find out if 2 raster layers are exactly
>> identical.
>
> I usually do
>
> g.region rast=map1,map2
>
> r.univar map1
> r.univar map2
>
> and make sure the output is the same.
>
>
> another way is
> r.mapcalc "diffmap = map1 - map2"
> r.univar diffmap
>
>
> see also wish #618
>  https://trac.osgeo.org/grass/ticket/618
>
>
> Hamish
>
>
>
>      
> _______________________________________________
> grass-user mailing list
> [hidden email]
> http://lists.osgeo.org/mailman/listinfo/grass-user
>

_______________________________________________
grass-user mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/grass-user
Glynn Clements

Re: Strange r.mapcalc results

Reply Threaded More More options
Print post
Permalink
In reply to this post by Hermann Peifer

Hermann Peifer wrote:

> I am trying to find out if 2 raster layers are exactly identical. I am
> not an experienced mapcalc user, so I am wondering, where the 3200204
> NULL values come from, in Test1. The result in Test2 is what I expected.
>
> My obviously wrong understanding was that I wouldn't need the special
> operator ||| in Test1, as NULL values are already treated specially by
> isnull()

> Any hint from the experts?

> Test1
>
> $ r.mapcalc 'result = isnull(mapA) && isnull(mapT) || mapA == mapT ? 1 : 2'

> Test2
>
> $ r.mapcalc 'result = isnull(mapA) && isnull(mapT) ||| mapA == mapT ? 1 : 2'

If mapA and mapT are both null, then Test 1 reduces to:

        result = isnull(mapA) && isnull(mapT) || mapA == mapT
-> result = isnull(null) && isnull(null) || null == null
-> result = 1 && 1 || null
-> result = 1 || null
-> result = null

while Test2 reduces to:

        result = isnull(mapA) && isnull(mapT) ||| mapA == mapT
-> result = isnull(null) && isnull(null) ||| null == null
-> result = 1 && 1 ||| null
-> result = 1 ||| null
-> result = 1

The || and && operators always propagate nulls (i.e. they return null
if either operand is null), while ||| and &&& return a non-null result
where possible (i.e. ||| returns 1 if either operand is non-zero, &&&
returns 0 if either operand is zero).

--
Glynn Clements <[hidden email]>
_______________________________________________
grass-user mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/grass-user
Hermann Peifer

Re: Strange r.mapcalc results

Reply Threaded More More options
Print post
Permalink
Glynn,

Thanks indeed for the enlightening. I am new to the mapcalc business and
my obviously wrong (AWK-based) thinking was that mapcalc would do a lazy
evaluation of the conditions, i.e.  "1 && 1 || something" would always
be 1, whatever "something" was. Now I know better.

Thanks again, Hermann


Glynn Clements wrote:

> Hermann Peifer wrote:
>
>> I am trying to find out if 2 raster layers are exactly identical. I am
>> not an experienced mapcalc user, so I am wondering, where the 3200204
>> NULL values come from, in Test1. The result in Test2 is what I expected.
>>
>> My obviously wrong understanding was that I wouldn't need the special
>> operator ||| in Test1, as NULL values are already treated specially by
>> isnull()
>
>> Any hint from the experts?
>
>> Test1
>>
>> $ r.mapcalc 'result = isnull(mapA) && isnull(mapT) || mapA == mapT ? 1 : 2'
>
>> Test2
>>
>> $ r.mapcalc 'result = isnull(mapA) && isnull(mapT) ||| mapA == mapT ? 1 : 2'
>
> If mapA and mapT are both null, then Test 1 reduces to:
>
> result = isnull(mapA) && isnull(mapT) || mapA == mapT
> -> result = isnull(null) && isnull(null) || null == null
> -> result = 1 && 1 || null
> -> result = 1 || null
> -> result = null
>
> while Test2 reduces to:
>
> result = isnull(mapA) && isnull(mapT) ||| mapA == mapT
> -> result = isnull(null) && isnull(null) ||| null == null
> -> result = 1 && 1 ||| null
> -> result = 1 ||| null
> -> result = 1
>
> The || and && operators always propagate nulls (i.e. they return null
> if either operand is null), while ||| and &&& return a non-null result
> where possible (i.e. ||| returns 1 if either operand is non-zero, &&&
> returns 0 if either operand is zero).
>

_______________________________________________
grass-user mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/grass-user
Glynn Clements

Re: Re: Strange r.mapcalc results

Reply Threaded More More options
Print post
Permalink

Hermann Peifer wrote:

> Thanks indeed for the enlightening. I am new to the mapcalc business and
> my obviously wrong (AWK-based) thinking was that mapcalc would do a lazy
> evaluation of the conditions, i.e.  "1 && 1 || something" would always
> be 1, whatever "something" was. Now I know better.

r.mapcalc never does "short-circuit" evaluation. This is true for if()
and ?: as well as &&,||,&&&,|||.

&& and || propagate nulls, while &&& and ||| return non-null where
possible. All four operators are symmetric, so e.g. "null() ||| 1" and
"1 ||| null()" both evaluate to 1.

--
Glynn Clements <[hidden email]>
_______________________________________________
grass-user mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/grass-user
Hermann Peifer

Re: Strange r.mapcalc results

Reply Threaded More More options
Print post
Permalink
Glynn Clements wrote:

> Hermann Peifer wrote:
>
>> Thanks indeed for the enlightening. I am new to the mapcalc business and
>> my obviously wrong (AWK-based) thinking was that mapcalc would do a lazy
>> evaluation of the conditions, i.e.  "1 && 1 || something" would always
>> be 1, whatever "something" was. Now I know better.
>
> r.mapcalc never does "short-circuit" evaluation. This is true for if()
> and ?: as well as &&,||,&&&,|||.
>
> && and || propagate nulls, while &&& and ||| return non-null where
> possible. All four operators are symmetric, so e.g. "null() ||| 1" and
> "1 ||| null()" both evaluate to 1.
>

Thanks once again.

It might be worth adding this hint into the r.mapcalc documentation at:
http://grass.itc.it/grass64/manuals/html64_user/r.mapcalc.html

Hermann
_______________________________________________
grass-user mailing list
[hidden email]
http://lists.osgeo.org/mailman/listinfo/grass-user