jared simpson | 18 Nov 05:20 2013
Picon

Incorrect behavior in Data.Complex ?

Prelude Data.Complex> 0**2
0.0
Prelude Data.Complex> 0**2 :: Complex Double
NaN :+ NaN
Prelude Data.Complex> exp $ 2 * log 0 :: Complex Double
NaN :+ NaN
Prelude Data.Complex> log 0 :: Complex Double
(-Infinity) :+ 0.0
Prelude Data.Complex> 2 * it :: Complex Double
(-Infinity) :+ NaN
Prelude Data.Complex> exp it :: Complex Double
NaN :+ NaN

So Complex uses the default implementation of **. Then when 2*(-inf :+ 0) is evaluated. We do (2 * -inf - 0*0) :+ (2*0 + -inf*0). Which because of -inf*0 sets the imaginary part to NaN. 

Then exp (-inf :+ NaN) = exp x cos y :+ exp x sin y which becomes 0 * cos NaN :+ 0 * sin NaN. So we end up with NaN :+ NaN.

So is there a library I should be using, or is this a bug?
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
Ross Paterson | 18 Nov 09:24 2013
Picon

Re: Incorrect behavior in Data.Complex ?

On Sun, Nov 17, 2013 at 08:20:21PM -0800, jared simpson wrote:
> Prelude Data.Complex> 0**2
> 0.0
> Prelude Data.Complex> 0**2 :: Complex Double
> NaN :+ NaN
> [...]
> 
> So Complex uses the default implementation of **. Then when 2*(-inf :+ 0) is
> evaluated. We do (2 * -inf - 0*0) :+ (2*0 + -inf*0). Which because of -inf*0
> sets the imaginary part to NaN. 
> 
> Then exp (-inf :+ NaN) = exp x cos y :+ exp x sin y which becomes 0 * cos NaN
> :+ 0 * sin NaN. So we end up with NaN :+ NaN.
> 
> So is there a library I should be using, or is this a bug?

I would say the default implementation of (**) is wrong: to match the
Float/Double instances it should be

         x ** y  =  if x == 0 then 0 else exp (log x * y)
jared simpson | 18 Nov 22:54 2013
Picon

Re: Incorrect behavior in Data.Complex ?

On Mon, Nov 18, 2013 at 3:24 AM, Ross Paterson <R.Paterson <at> city.ac.uk> wrote:
On Sun, Nov 17, 2013 at 08:20:21PM -0800, jared simpson wrote:
> Prelude Data.Complex> 0**2
> 0.0
> Prelude Data.Complex> 0**2 :: Complex Double
> NaN :+ NaN
> [...]
>
> So Complex uses the default implementation of **. Then when 2*(-inf :+ 0) is
> evaluated. We do (2 * -inf - 0*0) :+ (2*0 + -inf*0). Which because of -inf*0
> sets the imaginary part to NaN.
>
> Then exp (-inf :+ NaN) = exp x cos y :+ exp x sin y which becomes 0 * cos NaN
> :+ 0 * sin NaN. So we end up with NaN :+ NaN.
>
> So is there a library I should be using, or is this a bug?

I would say the default implementation of (**) is wrong: to match the
Float/Double instances it should be

         x ** y  =  if x == 0 then 0 else exp (log x * y)
_______________________________________________

Bug filed thanks.
 
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe <at> haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Gmane