Page 1 of 1

possible bug -fx ^ vs pow

Posted: 2010-10-17T16:52:43-07:00
by fmw42
IM 6.6.5.0 Q16 HDRI Mac OSX Tiger

Create gradient:

convert -size 1x256 gradient: -rotate 90 grad1.png

This does not work to make an gaussian:

convert grad1.png -fx "exp(-(u)^2)" grad1_gauss_a.png
identify -verbose grad1_gauss_a.png
Format: PNG (Portable Network Graphics)
Class: PseudoClass
Geometry: 256x1+0+0
Resolution: 72x72
Print size: 3.55556x0.0138889
Units: Undefined
Type: Bilevel
Base type: Bilevel
Endianess: Undefined
Colorspace: Gray
Depth: 16-bit
Channel depth:
gray: 1-bit
Channel statistics:
Gray:
min: 65535 (1)
max: 65535 (1)
mean: 65535 (1)



But this works fine:

convert grad1.png -fx "exp(-pow(u,2))" grad1_gauss_b.png
identify -verbose grad1_gauss_b.png
Format: PNG (Portable Network Graphics)
Class: PseudoClass
Geometry: 256x1+0+0
Resolution: 72x72
Print size: 3.55556x0.0138889
Units: Undefined
Type: Grayscale
Base type: Grayscale
Endianess: Undefined
Colorspace: Gray
Depth: 16-bit
Channel depth:
gray: 16-bit
Channel statistics:
Gray:
min: 24109 (0.36788)
max: 65535 (1)
mean: 48927 (0.746578)

Re: possible bug -fx ^ vs pow

Posted: 2010-10-17T17:18:57-07:00
by magick
Try this:
  • convert grad1.png -fx "exp(-(u^2))" grad1_gauss_a.png
In the mean-time we'll investigate why -(u)^2 does not return a correct result.

Re: possible bug -fx ^ vs pow

Posted: 2010-10-17T18:45:59-07:00
by fmw42
Now this seems to work.


sig=0.5
convert grad1.png -fx "exp(-((u/$sig)^2))" grad1_gauss_a.png
identify -verbose grad1_gauss_a.png
...

Channel statistics:
Gray:
min: 1200 (0.0183108)
max: 65535 (1)
mean: 28921 (0.441307)


So perhaps I was looking at the wrong result?


But now this is not working (with a radial gradient):

convert -size 256x256 radial-gradient: -negate radgrad256.png

sig=0.5
convert radgrad256.png -fx "exp(-(u/$sig)^2)" radgrad256_gauss_b.png
identify -verbose radgrad256_gauss_b.png
...
Channel statistics:
Gray:
min: 65535 (1)
max: 65535 (1)
mean: 65535 (1)



But this still works:

sig=0.5
convert radgrad256.png -fx "exp(-pow((u/$sig),2))" radgrad256_gauss_a.png
identify -verbose radgrad256_gauss_a.png
...
Channel statistics:
Gray:
min: 1200 (0.0183108)
max: 65527 (0.999878)
mean: 12798.4 (0.195292)




So I am not sure if I am doing something wrong or there is some intermittent issue or what?

Re: possible bug -fx ^ vs pow

Posted: 2010-10-18T04:49:13-07:00
by anthony
Looks like a parenthesis handling issue in FX. It really needs a proper parser (lex? yacc? bison?), even if a FX compiler is not yet on the cards.

Re: possible bug -fx ^ vs pow

Posted: 2010-10-19T18:54:18-07:00
by magick
Perhaps its not a bug afterall. Take a look at http://www.calculateforfree.com/sci.html. It returns the same results as -fx as follows:
  • -(0.5)^2 = 0.25
    -(0.5^2) = -0.25
Which suggests the results of exp(-(u)^2) is expected to be different from exp(-(u^2)). Instead exp(-(u^2)) is equivalent to exp(-pow(u,2)).

Re: possible bug -fx ^ vs pow

Posted: 2010-10-19T20:01:32-07:00
by fmw42
magick wrote:Perhaps its not a bug afterall. Take a look at http://www.calculateforfree.com/sci.html. It returns the same results as -fx as follows:
  • -(0.5)^2 = 0.25
    -(0.5^2) = -0.25
Which suggests the results of exp(-(u)^2) is expected to be different from exp(-(u^2)). Instead exp(-(u^2)) is equivalent to exp(-pow(u,2)).

Thanks. Strange that the parens don't seem to take precedence in -(0.5)^2 = 0.25 and behaves like (-0.5)^2 = 0.25

Not sure I am using your link correctly, but I get from it:

-(0.5)^2 = NaN

Re: possible bug -fx ^ vs pow

Posted: 2010-10-20T00:45:56-07:00
by anthony
It isn't the parenthesis precedence, but the precendence between unary minus '-' and '^' The uneray minus should be lower precedence (performed AFTER ^) just as normal + and - operators.

The problem is few languages defined this precedence in relation to other operators.
See http://en.wikipedia.org/wiki/Order_of_o ... _languages
for example which does not list 'power-of' though talks about it in the sections above.


Note the parenthesis in -(0.5)^2 should be equivalent to -0.5^2 if precedence rules are being obeyed correctly.
however whether that results in (-0.5)^2 or -(0.5^2) is a matter for the order of the precedence.

Re: possible bug -fx ^ vs pow

Posted: 2010-10-20T09:19:43-07:00
by fmw42
magick wrote:Under normal left-to-right associativity, -(0.5)^2 is 0.25, however, in Fortran its interpretted as -0.25. We'll investigate supporting the later interpretation in the next few days.

It is not urgent or really needed as long it is explained somewhere.

Re: possible bug -fx ^ vs pow

Posted: 2010-10-23T15:01:46-07:00
by magick
We can reproduce the problem you posted and have a patch in ImageMagick 6.6.5-4 Beta available by sometime tomorrow. Thanks.

Re: possible bug -fx ^ vs pow

Posted: 2010-10-24T17:34:07-07:00
by anthony
It has been updated, however i would like to point out that "Debug()" seems to give a indication of how the unary minus is being handled.
convert null: -channel R -fx 'debug(-(0.5)^2)' null:
[0,0].red: -1.0*(0.5)^2=-0.25
convert null: -channel R -fx 'debug(-0.5^2)' null:
[0,0].red: -1.0*0.5^2=-0.25
As such the parenthesis around the single element no-longer matters, which is as it should be.
Note how the unary minus now expands to be "-1.0" multiplier. And that by precedence ^ is now higher than multiply.

Continuing this, using parenthesis to modify the precedence...
convert null: -channel R -fx 'debug(-(0.5^2))' null:
[0,0].red: -1.0*(0.5^2)=-0.25
convert null: -channel R -fx 'debug((-0.5)^2)' null:
[0,0].red: (-1.0*0.5)^2=0.25
Which shows parenthesis is doing as it should.

If you are not certain of the order - apply parenthesis, including the operation you want to take precedence.

However the FX page does not list "-(unary)" in its precedence list. (same level as multiply).