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?

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)

On Mon, Nov 18, 2013 at 3:24 AM, Ross Paterson
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 :+
On Sun, Nov 17, 2013 at 08:20:21PM -0800, jared simpson wrote: 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.
participants (2)
-
jared simpson
-
Ross Paterson