From 64c254bc4375174186bb072bac2f3e8e1cffc33a Mon Sep 17 00:00:00 2001 From: arnaucube Date: Sun, 20 Feb 2022 12:44:39 +0100 Subject: [PATCH] Add fast polynomial multiplication using FFT --- fft.sage | 20 ++++++++++++++++++++ fft_test.sage | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/fft.sage b/fft.sage index af779dc..6f7bbdd 100644 --- a/fft.sage +++ b/fft.sage @@ -40,3 +40,23 @@ def fft(F, n): ft_inv = ft^-1 return w, ft, ft_inv + +# Fast polynomial multiplicaton using FFT +def poly_mul(fa, fb, F, n): + w, ft, ft_inv = fft(F, n) + + # compute evaluation points from polynomials fa & fb at the roots of unity + a_evals = [] + b_evals = [] + for i in range(n): + a_evals.append(fa(w[i])) + b_evals.append(fb(w[i])) + + # multiply elements in a_evals by b_evals + c_evals = map(operator.mul, a_evals, b_evals) + c_evals = vector(c_evals) + + # using FFT, convert the c_evals into fc(x) + fc_coef = c_evals*ft_inv + fc2=P(fc_coef.list()) + return fc2, c_evals diff --git a/fft_test.sage b/fft_test.sage index 9136845..f2a1cf3 100644 --- a/fft_test.sage +++ b/fft_test.sage @@ -57,3 +57,23 @@ for i in range(len(a)): assert fa(w[i]) == a[i] + +# Fast polynomial multiplicaton using FFT +print("\n---------") +print("---Fast polynomial multiplication using FFT") + +n = 8 +# q needs to be a prime, s.t. q-1 is divisible by n +assert (q-1)%n==0 +print("q =", q, "n = ", n) + +fa=P([1,2,3,4]) +fb=P([1,2,3,4]) +fc_expected = fa*fb +print("fc expected result:", fc_expected) # expected result +print("fc expected coef", fc_expected.coefficients()) + +fc, c_evals = poly_mul(fa, fb, F, n) +print("c_evals=(a_evals*b_evals)=", c_evals) +print("fc:", fc) +assert fc_expected == fc