Note that there are some explanatory texts on larger screens.

plurals
  1. POPolynomial multiplication using Finite Field FFT - the selection of nth primitive root of unity
    primarykey
    data
    text
    <p>As a school assignment, I am supposed to create a program in C# that multiplies two polynomials using FFT over a finite field.<br> My finite field of choice would be Z<sub><strong>p</strong></sub> (all operations modulo p, the elements are {<strong>0,...,<b>p</b> - 1</strong>} ). I realized the <strong>p</strong> has to be large enough so that the factors in the resulting polynomial are not changed by the modulo operation.<br> Finding the n<sup>th</sup> primitive root of unity is easy for small n(in a corresponding finite field). However, I needed to find it for n = 2<sup>20</sup>. I practically needed only this one as computing it for all the lower powers of 2 is done by squaring. I tried to write a simple program that would compute it(using the fact that there is 2<sup>r</sup> th root of unity in the finite field Z<sub>c*2<sup>r</sup> + 1</sub>), ran it for a pretty long time and it didn't finish. So I tried to Google something and only found a table of primitive n<sup>th</sup> roots for n = 2<sup>k</sup> for k = 0..30 in the field Z<sub>70383776563201</sub> and used it. Of course when I used longint, it resulted in overflow and therefore, wrong answers. So I started using the <strong>BigInteger</strong> structure from the <strong>System.Numerics</strong> namespace. This is where I am, having a correct algorithm that is extremely slow:</p> <pre><code>private static List&lt;BigInteger&gt; FFT(List&lt;BigInteger&gt; input, BigInteger Omega) { if (input.Count == 1) { return new List&lt;BigInteger&gt;() { input[0] }; } else { List&lt;BigInteger&gt; evenInput = new List&lt;BigInteger&gt;(); for (int i = 0; i &lt; input.Count; i += 2) { evenInput.Add(input[i]); } List&lt;BigInteger&gt; oddInput = new List&lt;BigInteger&gt;(); for (int i = 1; i &lt; input.Count; i += 2) { oddInput.Add(input[i]); } List&lt;BigInteger&gt; even = FFT(evenInput, (Omega * Omega)); List&lt;BigInteger&gt; odd = FFT(oddInput, (Omega * Omega)); BigInteger[] outputArr = new BigInteger[input.Count]; int count = 0; for (int i = 0; i &lt; input.Count / 2; i++) { outputArr[i] = (even[i] + BigInteger.Pow(Omega, i) * odd[i]); outputArr[i + input.Count / 2] = (even[i] - BigInteger.Pow(Omega, i) * odd[i]); count += 2; } List&lt;BigInteger&gt; output = new List&lt;BigInteger&gt;(); for (int i = 0; i &lt; count; i++) { output.Add(outputArr[i] % finiteField); } return output; } } </code></pre> <p>I know that creating all the lists doesn't help the speed, but the main problem is the BigInteger structure of course.(I tried basically the same code with System.Numerics.Complex structure and it was as fast as it should be) The modulo operation takes extremely long, so I know I have to go back to longint. The problem is finding the primitive n<sup>th</sup> root of unity. I don't know if it's even possible to use the 2<sup>20</sup> th primitive root of unity with longint without having to worry about overflow. If not, for which n can I use longint and thus have a fast algorithm?<br> Is there a way of computing the primitive roots for large n faster? Maybe someone knows of a table of precomputed primitive roots in finite fields? Or should I consider using other finite fields? This is the only kind I know of. I have been searching for quite a long time and didn't come across anything useful. I have been told by the teacher that this area is well documented, but it doesn't seem to be the case.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload