Я хочу быстро умножить два полинома в python. Поскольку мои многочлены довольно большие (> 100000) элементов, и я должен умножить их много. Ниже вы найдете мой подход,
from numpy.random import seed, randint
from numpy import polymul, pad
from numpy.fft import fft, ifft
from timeit import default_timer as timer
length=100
def test_mul(arr_a,arr_b): #inbuilt python multiplication
c=polymul(arr_a,arr_b)
return c
def sb_mul(arr_a,arr_b): #my schoolbook multiplication
c=[0]*(len(arr_a) + len(arr_b) - 1 )
for i in range( len(arr_a) ):
for j in range( len(arr_b) ):
k=i+j
c[k]=c[k]+arr_a[i]*arr_b[j]
return c
def fft_test(arr_a,arr_b): #fft based polynomial multuplication
arr_a1=pad(arr_a,(0,length),'constant')
arr_b1=pad(arr_b,(0,length),'constant')
a_f=fft(arr_a1)
b_f=fft(arr_b1)
c_f=[0]*(2*length)
for i in range( len(a_f) ):
c_f[i]=a_f[i]*b_f[i]
return c_f
if __name__ == '__main__':
seed(int(timer()))
random=1
if(random==1):
x=randint(1,1000,length)
y=randint(1,1000,length)
else:
x=[1]*length
y=[1]*length
start=timer()
res=test_mul(x,y)
end=timer()
print("time for built in pol_mul", end-start)
start=timer()
res1=sb_mul(x,y)
end=timer()
print("time for schoolbook mult", end-start)
res2=fft_test(x,y)
print(res2)
#########check############
if( len(res)!=len(res1) ):
print("ERROR");
for i in range( len(res) ):
if( res[i]!=res1[i] ):
print("ERROR at pos ",i,"res[i]:",res[i],"res1[i]:",res1[i])
Теперь, вот мой подход в деталях,
1. Сначала я попробовал себя в наивной реализации Schoolbook со сложностью O (n ^ 2). Но, как вы можете ожидать, это оказалось очень медленно.
Во-вторых, я узнал polymul
в библиотеке Numpy. Эта функция намного быстрее, чем предыдущая. Но я понял, что это тоже сложность O (n ^ 2). Вы можете видеть, что при увеличении длины k время увеличивается в k ^ 2 раза.
Мой третий подход заключается в том, чтобы попробовать умножение на основе БПФ с использованием встроенных функций БПФ. Я следовал хорошо известному подходу, также описанному здесь , но я не смог заставить его работать.
Теперь мои вопросы,
Где я ошибаюсь в подходе, основанном на БПФ? Подскажите, пожалуйста, как мне это исправить?
Является ли моё наблюдение, что функция polymul
имеет сложность O (n ^ 2)?
Пожалуйста, дайте мне знать, если у вас есть какие-либо вопросы.
Заранее спасибо.