Data.Complex包为-8 + 0i((-8):+ 0)的立方根提供了奇怪的结果

时间:2017-09-18 20:23:56

标签: haskell complex-numbers

我不得不说,数学不是我的强项。我希望通过使用How to find the cube root of a negative integer such that it does not return NaN?包来获得Data.Complex的合适结果,但是当我喜欢的时候

*Main> ((-8):+0) ** (1/3)
1.0 :+ 1.732050807568877

我希望得到类似(-2.0):+0的东西,其中-2是真实部分,0是虚部。然而,结果显示出一个重要的想象部分。我已查看其所声明的(**)类型的RealFloat Complex个实例;

x ** y = case (x,y) of
  (_ , (0:+0))  -> 1 :+ 0
  ((0:+0), (exp_re:+_)) -> case compare exp_re 0 of
             GT -> 0 :+ 0
             LT -> inf :+ 0
             EQ -> nan :+ nan
  ((re:+im), (exp_re:+_))
    | (isInfinite re || isInfinite im) -> case compare exp_re 0 of
             GT -> inf :+ 0
             LT -> 0 :+ 0
             EQ -> nan :+ nan
    | otherwise -> exp (log x * y)
  where
    inf = 1/0
    nan = 0/0

因此,我们必须正常查看exp (log x * y) exp log Complexexp (x:+y) = expx * cos y :+ expx * sin y where expx = exp x log z = log (magnitude z) :+ phase z 实例的部分;

magnitude

然后我转到magnitude :: (RealFloat a) => Complex a -> a magnitude (x:+y) = scaleFloat k (sqrt (sqr (scaleFloat mk x) + sqr (scaleFloat mk y))) where k = max (exponent x) (exponent y) mk = - k sqr z = z * z ,其定义为;

sqrt (realPart z ^ 2 + imagPart z ^ 2)

我被困住了。我只想做createGamePlan_1

我做错了什么..?

1 个答案:

答案 0 :(得分:7)

嗯,你得到的答案是 -8的立方根,正如你可以通过立方体看到的那样:

> let x = ((-8):+0)**(1/3)
> x
1.0 :+ 1.732050807568877
> x^3
(-7.9999999999999964) :+ 2.220446049250313e-15
> x*x*x
(-7.9999999999999964) :+ 2.220446049250313e-15
> 

它不是你想要的立方根。

实际上,有三个立方根--8。您可以通过计算一个的三个立方根来计算它们:

> let j = (-1/2):+sqrt(3)/2   -- a cube root of 1
> let units = [1,j,j*j]       -- that can generate them all

并将它们乘以上面的值:

> map (*x) units  -- the cube roots of -8
[1.0 :+ 1.732050807568877,
 (-1.9999999999999996) :+ 1.1102230246251565e-16,
 0.9999999999999997 :+ (-1.7320508075688767)]
> map (^3) $ map (*x) units  -- prove they cube to -8
[(-7.9999999999999964) :+ 2.220446049250313e-15,
 (-7.999999999999995) :+ 1.3322676295501873e-15,
 (-7.999999999999992) :+ 8.881784197001252e-16]
>

正如您所确定的,((-8):+0)**(1/3)生成的多维数据集根是-8的特定多维数据集根,计算方式为:

> exp(log((-8):+0)*(1/3))
1.0 :+ 1.732050807568877
> 

可能值得注意的是:(1)explogData.Complex的定义虽然看起来很奇怪,但却是这些函数对于复数的标准数学定义; (2)复数的x ** y定义为exp(log(x)*y)在数学上是完全有意义的,并确保x ** y具有您应该期望的所有属性,包括立方{{1}的属性应该给你-8。

至于((-8):+0)**(1/3)的定义(用于magnitude的定义),你的简单定义也适用:

log

但是,> magnitude (-8) 8.0 > sqrt (realPart (-8) ^ 2 + imagPart (-8) ^ 2) 8.0 > magnitude的定义已被选中,以便在涉及的数字非常大的情况下提供正确的答案:

Data.Complex