/// <summary> /// Make recursive FFT /// </summary> /// <param name="a">Polynom. Number of items must be pow of two</param> /// <param name="omega">Proper sqrt of 1</param> /// <returns></returns> public static Polynom RecursiveFFT(Polynom a, Complex omega) { if (ComplexUtils.IsAlmostEqual(omega, 1)) { return(a); } Polynom a_s = new Polynom(); Polynom a_l = new Polynom(); for (int i = 0; i < a.Count / 2; i++) { a_s.Add(a[2 * i]); a_l.Add(a[2 * i + 1]); } Polynom s = RecursiveFFT(a_s, omega * omega); Polynom l = RecursiveFFT(a_l, omega * omega); Complex x = 1; Polynom ret = new Polynom(a.Count); for (int i = 0; i < a.Count / 2; i++) { ret[i] = s[i] + x * l[i]; ret[i + a.Count / 2] = s[i] - x * l[i]; x *= omega; } return(ret); }
/// <summary> /// Multiple a and b by convolution /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static Polynom MulByConvolution(Polynom a, Polynom b) { Polynom ret = new Polynom(); for (int i = 0; i < a.Count + b.Count - 1; i++) //i index of ret { Complex c = 0; for (int ii = 0; ii <= i; ii++) { if (ii >= a.Count) { continue; } if ((i - ii) >= b.Count) { continue; } c += a[ii] * b[i - ii]; } ret.Add(c); } ret.Trim(); return(ret); }
static void TestWithRandomPolynoms(int polynomALength, int polynomBLength, double maxValue) { Random rnd = new Random(); Polynom a = new Polynom(); for (int i = 0; i < polynomALength; i++) { a.Add(new Complex(rnd.NextDouble() * maxValue, rnd.NextDouble() * maxValue)); } Polynom b = new Polynom(); for (int i = 0; i < polynomBLength; i++) { b.Add(new Complex(rnd.NextDouble() * maxValue, rnd.NextDouble() * maxValue)); } Polynom ret1 = a * b; Polynom ret2 = Polynom.MulByConvolution(a, b); if (Polynom.AreAlmostEquival(ret1, ret2, output: false)) // output:true to see what members are not equal { Console.WriteLine("Equival"); } else { Console.WriteLine("Nonequival"); } }
/// <summary> /// Complements polynom with nulls so rank would be pow of 2 /// </summary> /// <returns>New polynom</returns> public Polynom ComplementWithNulls() { Polynom ret = this.Clone(); int l = (int)Math.Ceiling(Math.Log(ret.Count, 2)); while (ret.Count < Math.Pow(2, l)) { ret.Add(0); } return(ret); }