用Python计算Unity的第n个根

时间:2013-03-15 03:58:16

标签: python fft complex-numbers dft

所以,我试图编写一个算法croot(k,n),它返回n的第k个根,n == n。我得到了大部分正确的答案,但它给了我一些奇怪的陈述,这些陈述对于某些数字来说似乎是错误的。这是一个例子。

import cmath

def croot(k, n):
    if n<=0:
        return None
    return cmath.exp((2 * cmath.pi * 1j * k) / n)


for k in range(8):
    print croot(k, 8)

输出是:

(1+0j)
(0.70710...+0.70710...j)
(6.12323399574e-17+1j)
哇哇哇哇哇所以k = 2和n = 8时的根是错误的,因为它应该只是i,它将表示为1j,或j或1.00000j等。有人可以帮助我吗?我之所以这样做,是因为我试图编写FFT算法。我对复杂数字和Python不是很有经验,所以我很可能犯了一个简单的错误。

谢谢,

如果你们需要任何其他信息,请询问。

3 个答案:

答案 0 :(得分:5)

看看这个号码

(6.12303176911e-17+1j)

6.12303176911e-17 = 0.0000000000000000612303176911这个非常小(接近于零)。您所看到的是由于浮点数的有限表示而导致舍入错误

该误差相当于测量到太阳的距离在10微米左右。如果您对来自现实世界的数据运行FFT,则测量误差通常远大于此。

答案 1 :(得分:5)

这是立方体的统一根和第4根用作示例。输入数组应解释为多项式系数。

>>> import numpy as np
>>> np.roots([1, 0, 0, -1])
array([-0.5+0.8660254j, -0.5-0.8660254j,  1.0+0.j       ])
>>> np.roots([1, 0, 0, 0, -1])
array([ -1.00000000e+00+0.j,   5.55111512e-17+1.j,   5.55111512e-17-1.j,
         1.00000000e+00+0.j])

编辑: 多项式系数在输入数组pnp.roots(p)中按以下顺序给出:

p[0] * x**n + p[1] * x**(n-1) + ... + p[n-1]*x + p[n]

因此,举例来说,要返回n统一的根,这是等式1 * x**n - 1 == 0的解,你将使用像p = [1] + [0] * (n - 1) + [-1]这样的输入。

答案 2 :(得分:0)

使用Python 3.5.2时,当我试图确定第1,200个统一根时,numpy.roots内存不足并导致我的Chromebook崩溃。当他们为多项式构造伴随矩阵时发生了崩溃,所以我不认为他们使用稀疏表示。来自文档:

  

该算法依赖于计算伴随矩阵的特征值

如果你只需要计算单位的根,那么三角学方法在时间和空间复杂性方面都是渐近的:

def nthRootsOfUnity1(n): # linear space, parallelizable
    from numpy import arange, pi, exp
    return exp(2j * pi / n * arange(n))

如果您愿意放弃并行化,可以使用生成器为每个额外的根实现恒定的空间和恒定的时间,而第一个方法必须在返回之前计算所有n个根:

def nthRootsOfUnity2(n): # constant space, serial
    from cmath import exp, pi
    c = 2j * pi / n
    return (exp(k * c) for k in range(n))

在我的机器上并且没有使用并行化,这些方法在numpy.roots计算第1000个根所需的时间内计算第10,000,000个根:

In [3]: n = 1000

In [4]: %time _ = sum(numpy.roots([1] + [0]*(n - 1) + [-1]))
CPU times: user 40.7 s, sys: 811 ms, total: 41.5 s
Wall time: 10.8 s

In [5]: n = 10000000

In [6]: %time _ = sum(nthRootsOfUnity1(n))
CPU times: user 4.98 s, sys: 256 ms, total: 5.23 s
Wall time: 5.23 s

In [7]: %time _ = sum(nthRootsOfUnity2(n))
CPU times: user 11.6 s, sys: 2 ms, total: 11.6 s
Wall time: 11.6 s