public static Polynomial Rem(Polynomial firstArg, Polynomial secondArg) { var firstDeg = firstArg.Deg; var secondDeg = secondArg.Deg; var newDeg = firstDeg - secondDeg; var result = new ulong[newDeg + 1]; var reminder = (ulong[])firstArg._coefficients.Clone(); var mod = secondArg._mod; ulong firstLc; ulong secondLc = secondArg[secondDeg]; for (int i = 0; i <= newDeg; i++) { firstLc = reminder[firstDeg - i]; result[newDeg - i] = (firstLc * IntegerMath.Inverse(secondLc, mod)) % mod; for (int j = 0; j <= secondDeg; j++) { reminder[firstDeg - secondDeg + j - i] = (reminder[firstDeg - secondDeg + j - i] + (mod - (result[newDeg - i] * secondArg[j]) % mod)) % mod; } } return(new Polynomial(reminder)); }
static ulong[] SlowInverseFt(ulong[] vector) { var size = vector.Length; var res = new ulong[size]; ulong pow = (ulong)(Power / size); ulong root_n = IntegerMath.ModPow(Root_1, pow, Mod); ulong root_i = 1; for (int i = 0; i < size; i++) { double temp = 0; ulong root_j = 1; for (int j = 0; j < size; j++) { temp = (temp + (vector[j] * root_j) % Mod) % Mod; root_j = (root_j * root_i) % Mod; } res[i] = (ulong)(temp * IntegerMath.Inverse((ulong)size, Mod)) % Mod; root_i = (root_i * root_n) % Mod; } return(res); }
public static Polynomial Inverse(Polynomial polynomial, Polynomial mod, ulong fieldCharacteristic, out Polynomial gcd) { polynomial.SetMod(fieldCharacteristic); mod.SetMod(fieldCharacteristic); polynomial.Reduce(); mod.Reduce(); if (mod.Deg == -1 || polynomial.Deg == -1) { throw new InvalidOperationException("Обратный элемент не определен"); } Polynomial bezoutCoefficient = new Polynomial(new ulong[] { 1 }); Polynomial nextBezoutCoefficient = new Polynomial(); gcd = polynomial % mod; Polynomial reminder = mod; Polynomial temp = new Polynomial(); Polynomial quotient; gcd.SetMod(fieldCharacteristic); gcd.Reduce(); bezoutCoefficient.SetMod(fieldCharacteristic); bezoutCoefficient.Reduce(); nextBezoutCoefficient.SetMod(fieldCharacteristic); nextBezoutCoefficient.Reduce(); while (reminder.Deg != -1) { temp = reminder; quotient = gcd / reminder; quotient.SetMod(fieldCharacteristic); quotient.Reduce(); var qxr = quotient * reminder; qxr.SetMod(fieldCharacteristic); qxr.Reduce(); reminder = gcd - qxr; reminder.SetMod(fieldCharacteristic); reminder.Reduce(); gcd = temp; temp = nextBezoutCoefficient; var qxu = quotient * nextBezoutCoefficient; qxu.SetMod(fieldCharacteristic); qxu.Reduce(); nextBezoutCoefficient = bezoutCoefficient - qxu; nextBezoutCoefficient.SetMod(fieldCharacteristic); nextBezoutCoefficient.Reduce(); bezoutCoefficient = temp; } gcd = gcd % mod; gcd.SetMod(fieldCharacteristic); gcd.Reduce(); var c = gcd[0]; var inverse = IntegerMath.Inverse(c, fieldCharacteristic); if (c != 1) { gcd = inverse * gcd; gcd.SetMod(fieldCharacteristic); gcd.Reduce(); } if (gcd != new Polynomial(new ulong[] { 1 })) { throw new ArgumentException(string.Format("Обратный элемент к {0} не существует!", polynomial)); } var res = (inverse * bezoutCoefficient) % mod; res.SetMod(fieldCharacteristic); res.Reduce(); return(res); }