![]() |
VOOZH | about |
Given two polynomials represented by two arrays, write a function that multiplies the given two polynomials. In this representation, each index of the array corresponds to the exponent of the variable(e.g. x), and the value at that index represents the coefficient of the term. For example, the array A[] = [a, b, c, d] represents the polynomial a + b* x1+ c* x2 + d* x3 and B[] = [a1, b1, c1] represents the polynomial a1 + b1* x1+ c1* x2. The goal is to compute the product of these two polynomials and return the resulting polynomial in the same array-based format.
Example:
Input: A[] = [5, 0, 10, 6]
B[] = [1, 2, 4]
Output: [5, 10, 30, 26, 52, 24]
Explanation:
The first input array represents "5 + 0x1 + 10x2 + 6x3"
The second array represents "1 + 2x1 + 4x2"
after Multiply both them we get "5 + 10x1 + 30x2 + 26x3 + 52x4 + 24x5"
Table of Content
one by one consider every term of the first polynomial and multiply it with every term of the second polynomial. Following is the algorithm of this simple method.
Step by Step Approach:
5 10 30 26 52 24
Time complexity: O(m x n), Where m and n is the size of the array A and B respectively.
Auxiliary Space: O(m + n)
This Algorithm work only when size of both is equal, so to make it work we pad 0 at higher power in the small size array. Then splitting is done at the middle of the polynomial them recursively
Let the two given polynomials be A and B.
- A0β will hold the first half of the coefficients, and A1 will hold the second half.
- Similarly, B0β and B1β hold the respective halves of polynomial B
For simplicity, Let us assume that the given two polynomials are of same degree and have degree in powers of 2, i.e., n = 2i
The polynomial 'A' can be written as A0 + A1*xn/2
The polynomial 'B' can be written as B0 + B1*xn/2
For example 1 + 10x + 6x2 - 4x3 + 5x4 can be
written as (1 + 10x) + (6 - 4x + 5x2)*x2
A * B = (A0 + A1*xn/2) * (B0 + B1*xn/2)
= A0*B0 + A0*B1*xn/2 + A1*B0*xn/2 + A1*B1*xn
= A0*B0 + (A0*B1 + A1*B0)xn/2 + A1*B1*xn
Let us take another example with array inputs
A = [5,0,10,6] becomes A0 = [5,0] and A1 = [10,6]
B = [1,2,4] becomes B = [1, 2, 4, 0] becomes B0 = [1,2] and B1 = [4,0]
So the above divide and conquer approach requires 4 multiplications and O(n) time to add all 4 results. Therefore the time complexity is T(n) = 4T(n/2) + O(n). The solution of the recurrence is O(n2) which is the same as the above simple solution.
The idea is to reduce the number of multiplications to 3 and make the recurrence as T(n) = 3T(n/2) + O(n)
How to reduce the number of multiplications?
This requires a little trick similar to Strassenβs Matrix Multiplication. We do the following 3 multiplications. We recursively Compute the Three Products
The Karatsuba algorithm computes three intermediate products using recursive calls:
In-Depth Explanation
Conventional polynomial multiplication uses 4 coefficient multiplications:
(ax + b)(cx + d) = acx2 + (ad + bc)x + bd
However, notice the following relation:
(a + b)(c + d) = ad + bc + ac + bd
The rest of the two components are exactly the middle coefficient for the product of two polynomials. Therefore, the product can be computed as:
(ax + b)(cx + d) = acx2 + ((a + b)(c + d) - ac - bd )x + bd
Hence, the latter expression has only three multiplications. So the time taken by this algorithm is T(n) = 3T(n/2) + O(n). The solution of the above recurrence is O(nLg3) which is better than O(n2).
5 10 30 26 52 24
Time Complexity: O(n(logβ‘23))βO(n1.585), where n is the size of the input polynomial (or the next power of 2 greater than or equal to the size of the input arrays).
Auxiliary Space: O(n), where n is the size of the input polynomial (or the next power of 2 greater than or equal to the size of the input arrays).
A(x) = a0 β+ a1βx + a2x2 + β― +an-1βxn-1
We assume, without loss of generality, that the number of coefficients n is a power of 2.
If it's not, we can simply pad the polynomial with zeros to make the number of terms a power of 2. That is, for missing terms aixi , we just set ai =0.
The equation xn = 1 has exactly n distinct complex solutions, known as the n-th roots of unity.
Each root is given by:
Οn,k = e2Οi / nβ, for k=0,1,2,β¦,nβ1
These roots lie evenly spaced on the unit circle in the complex plane.
Οnβ=Οn,1β=e2Οi / nβ
Then all the n-th roots of unity can be expressed as powers of βΟn:
Οn,kβ=(Οnβ)k
The Discrete Fourier Transform (DFT) of a polynomial A(x) or equivalently, of the coefficient vector (a0,a1,β¦,anβ1β) is defined as the values of the polynomial evaluated at the n-th roots of unity:
DFT(A) = [A(Οn,0),A(Οn,1),β¦,A(Οn,nβ1)]
In other words, youβre evaluating the polynomial A(x) at each complex point x=Οn,k for k=0 to nβ1.
This transforms the polynomial from its coefficient representation to its value representation β a key step that enables fast multiplication via pointwise product.
Just as the Discrete Fourier Transform (DFT) converts a polynomial from its coefficient form to its value form, the Inverse DFT (IDFT) performs the reverse:
InverseDFT(y0β,y1β,β¦,ynβ1β) = (a0β,a1β,β¦,anβ1β)
Let A(x) and B(x)B be two polynomials. Then:
(Aβ B)(x) = A(x)β B(x)
This implies that if we compute the DFT of both polynomials, the element-wise (pointwise) multiplication of their transformed vectors:
DFT(A).DFT(B) == DFT(Aβ B)
Finally, the product of two polynomials A(x) and B(x) can be recovered by applying the inverse Discrete Fourier Transform to the pointwise product of their DFTs:
Aβ B = InverseDFT(DFT(A)β DFT(B))
5 10 30 26 52 24
Time Complexity: O(n log n), where n is the size of the next power of 2 greater than or equal to the sum of the sizes of the input polynomials.
Auxiliary Space: O(n), where n is the size of the next power of 2 greater than or equal to the sum of the sizes of the input polynomials.