python精度+;快速傅里叶变换
我一直在学习fft,特别是用于竞争性编码竞赛。在谷歌搜索之后,我提出了一个python实现。为了测试它,我还为多项式乘法创建了一个简单的实现 代码如下:python精度+;快速傅里叶变换,python,fft,precision,Python,Fft,Precision,我一直在学习fft,特别是用于竞争性编码竞赛。在谷歌搜索之后,我提出了一个python实现。为了测试它,我还为多项式乘法创建了一个简单的实现 代码如下: from cmath import pi, cos, sin mod = 100003 def fft(x, inv): n = len(x) j = 0 for i in xrange(1, n): b = n >> 1 while j >= b:
from cmath import pi, cos, sin
mod = 100003
def fft(x, inv):
n = len(x)
j = 0
for i in xrange(1, n):
b = n >> 1
while j >= b:
j -= b
b >>= 1
j += b
if j > i:
x[i], x[j] = x[j], x[i]
trans_size = 2
while trans_size <= n:
w = 1
ang = [-2 * pi / trans_size, 2 * pi / trans_size][inv]
wn = complex(cos(ang), sin(ang))
for t in xrange(trans_size >> 1):
for trans in xrange(n / trans_size):
i = trans * trans_size + t
j = i + (trans_size >> 1)
a = x[i]
b = x[j] * w
x[i] = a + b
x[j] = a - b
w *= wn
trans_size <<= 1
def polymul(x, y):
lx = len(x)
ly = len(y)
lz = 1 << (lx + ly - 1).bit_length()
x += [0] * (lz - lx)
y += [0] * (lz - ly)
fft(x, 0)
fft(y, 0)
z = []
for i in xrange(lz):
z.append(x[i] * y[i])
fft(z, 1)
for i in xrange(lx + ly - 1):
z[i] = int(z[i].real/lz + 0.5) % mod
return z[:lx + ly - 1]
def naive_polymul(x, y):
lx = len(x)
ly = len(y)
z = [0 for i in xrange(lx + ly - 1)]
for i in xrange(lx):
for j in xrange(ly):
z[i + j] += x[i] * y[j]
for i in xrange(lx + ly - 1):
z[i] %= mod
return z
from random import randint
N = input()
A = [randint(1, 100000) for i in xrange(N)]
B = [randint(1, 100000) for i in xrange(N)]
C = naive_polymul(A, B)
D = polymul(A, B)
assert(C == D)
从cmath导入pi、cos、sin
国防部=100003
def fft(x,inv):
n=len(x)
j=0
对于x范围内的i(1,n):
b=n>>1
当j>=b时:
j-=b
b>>=1
j+=b
如果j>i:
x[i],x[j]=x[j],x[i]
trans_size=2
当trans_大小>1时):
对于X范围内的变速箱(n/trans_尺寸):
i=变速箱*变速箱尺寸+t
j=i+(变速箱尺寸>>1)
a=x[i]
b=x[j]*w
x[i]=a+b
x[j]=a-b
w*=wn
传输大小==================================================重新启动================================
>>>
4000
>>>=================================================重新启动================================
>>>
5000
回溯(最近一次呼叫最后一次):
文件“fft.py”,第75行,在
断言(C==D)
断言错误
我对代码进行了一些研究,我很确定问题在于浮点值导致的精度错误,系数的值总是偏离1。我知道提高精度的唯一方法是十进制,但它显著降低了代码的速度,这与我在这里要讲的恰恰相反
因为这个问题,我正在测试我的代码(),在较大的测试用例中给了我错误的答案,而C++的提交(来自其他用户)使用标准的长双。
我错过了什么?如果有人能为我指出解决此问题的正确方向,我将不胜感激
谢谢 你不能用吗?就像我说的,这是为了竞争性的编码比赛。除默认库外,不允许使用其他库。
>>> ================================ RESTART ================================
>>>
4000
>>> ================================ RESTART ================================
>>>
5000
Traceback (most recent call last):
File "fft.py", line 75, in <module>
assert(C == D)
AssertionError