# HW5

## Due Date: Mar 11, before midnight (11:59:59PM)

This assignment comprises both written questions and implementation-based lab.

## HW5

Answer the following questions from the DPV book i) Q2.27-a,b,c, ii) Q2.32-a,b,c iii) Show the output at each recursive step of the FFT algorithm in Fig 2.9, for the input $A = [2,5,4,2,0,0,0,0]$, and $\omega = \frac{1}{\sqrt{2}}(1 + i)$.

## Lab5: Multiplying Large Polynomials

Basic Algorithm: Implement the basic quadratic time algorithm (Alg1 in Lecture11-PDF), which is a simplified version of the description at the beginning of sec 2.6 in the book (before sec 2.6.1).

Your code must take as input the "maximum degree" $d$ for the polynomial $A$, and you must generate $d$ random coefficients in the range 1--10, which will denote the coefficients $[a_0, a_1, a_2, ..., a_{d-1}]$, so in fact the degree of the polynomial will be $d-1$. Likewise, generate $d$ random coefficients for the polynomial $B$, to make up the coefficients $[b_0, b_1, b_2, ..., b_{d-1}]$.

You code must output the coefficients for the polynomial $C = A\cdot B$, and also the time it takes.

FFT-Based Algorithm: Implement the FFT algorithm in Fig 2.9. Use the python cmath library to deal with complex numbers. Now, use the following pseudo-code to multiply the two polynomials $A$, $B$:

n = power of 2 equal to or larger than 2d-1
angle = 2. * cmath.pi/n  # primitive root's angle
w = cmath.cos(angle) + cmath.sin(angle) * 1j #primitive n-th root of unity
A = [a_0, a_1, a_2, ...., a_{d-1}, 0, 0, ..., 0] #zero-pad to length n
B = [b_0, b_1, b_2, ...., b_{d-1}, 0, 0, ..., 0] #zero-pad to length n

# Evaluation
fft_A = FFT(A, w)
fft_B = FFT(B, w)

# Multiplication
fft_C = fft_A * fft_B # elementwise multiplication

# Interpolation
C = 1/n * FFT(fft_C, w**-1)


You code must output the coefficients for the polynomial $C = A\cdot B$, and also the time it takes. When implementing the FFT, you'll find it useful to check whether $\omega = 1$ by using the cmath.isclose() function, since it may not be exactly 1.

Bonus: Implement the recursive divide-and-conquer algorithm, Alg2, for polynomial multiplication that we discussed in Lecture11-PDF (using the two-way split and using three subproblems). Compare the output with the basic method for correctness, and report the running time. Is it faster or slower than the basic method?

You must compare the output of the two algorithms to check for correctness of your implementation of the FFT-based approach. You should compare the running time for the two approaches for the following values of $d=100, 1000, 10000$. You can also try larger values.
In the PDF include the output of the two algorithms for only $d=100$. But you must include your running time for all the values of $d$. Include the time for both the basic and FFT-based method, and the divide-and-conquer method if you implement that.