Naive Approach
# input: A and B are the coefficients of two polynomials of degree m and n
# output: the (m+n-1) coefficients of the product of A and B
# time: O(m*n) (or O(n^2) if m=n)
# space: O(m+n)
def multiply(A, B, m, n):
prod = [0] * (m + n - 1);
for i in range(m): # A polynomial
for j in range(n): # B polynomial
prod[i + j] += A[i] * B[j]; # Add A[i]*B[j] to the (i+j)th coefficient
return prod;
Karatsuba Algorithm for Polynomials
# input: p and q are the coefficients of two polynomials
# output: the coefficients of the product of p and q
# time: O(n^log2(3))
# space: O(n)
def karatsuba_poly_mult(p, q):
# Base case: if either polynomial is empty, return an empty list
if not p or not q:
return []
# Base case: if either polynomial is a constant, perform scalar multiplication
if len(p) == 1:
return [p[0] * qi for qi in q]
if len(q) == 1:
return [q[0] * pi for pi in p]
# Determine the size for splitting the polynomials
m = min(len(p), len(q)) // 2
# Split the polynomials into lower and higher degree parts
p_low = p[:m]
p_high = p[m:]
q_low = q[:m]
q_high = q[m:]
# Recursively compute the three products
z0 = karatsuba_poly_mult(p_low, q_low)
z2 = karatsuba_poly_mult(p_high, q_high)
p_sum = [p_low[i] + p_high[i] for i in range(len(p_low))]
q_sum = [q_low[i] + q_high[i] for i in range(len(q_low))]
z1 = karatsuba_poly_mult(p_sum, q_sum)
# Combine the results to get the final product
result = [0] * (len(p) + len(q) - 1)
for i in range(len(z0)):
result[i] += z0[i]
for i in range(len(z1)):
result[i + m] += z1[i] - z0[i] - z2[i]
for i in range(len(z2)):
result[i + 2 * m] += z2[i]
return result
Fast Polynomial Multiplication using FFT
Lagrange Polynomial
- (Interpolation theorem) For every set of distinct points such that :
- There is a unique polynomial of degree (at most) such that for all
- is said to interpolate the set , and it is called the Lagrange interpolation polynomial of the set
- (The points are called the interpolation points or data points, and are the interpolation nodes)
- The Lagrange interpolation polynomial can be computed in time
- There is a unique polynomial of degree (at most) such that for all
Naive Algorithm for Polynomial Mul. u/ Lagrange Interpolation
- Algorithm:
- Input: Two polynomials and of degree at most
- Let be the smallest power of such that
- Choose distinct points in
- Find the Lagrange interpolation polynomial of the set
In this approach, the multiplication operation () is easily performed in linear time, but the interpolation step is done in time, which of course is not efficient compared to the previous approaches. However, we will see that by selecting the points carefully, we can achieve a more efficient divide-and-conquer algorithm that is efficient for both evaluation and interpolation steps. The smart choice of points will be in the complex plane, so the algorithm will be for polynomials in
Polynomial Multiplication u/ FFT
- Input:
- Two polynomials with degree less than for some integer
- A primitive th root of unity
- Two polynomials with degree less than for some integer
- (Calculate the DFT of and using FFT)
- is an th primitive root of unity,
- (Pointwise multiplication)
- (Calculate the IDFT of using FFT)