public Tuple <Polynomial, Polynomial, Polynomial> FindBezoutCoefficients(Polynomial firstArg, Polynomial secondArg) { var polyMath = new PolynomialMath(-1); Polynomial u0 = new Polynomial(new BigInteger[] { 1 }); Polynomial u1 = new Polynomial(new BigInteger[] { 0 }); Polynomial v0 = new Polynomial(new BigInteger[] { 0 }); Polynomial v1 = new Polynomial(new BigInteger[] { 1 }); Polynomial u2, v2, q0, r2; Polynomial r0 = firstArg; Polynomial r1 = secondArg; while (r1.Deg != -1) { q0 = polyMath.Div(r0, r1); u2 = polyMath.Sub(u0, polyMath.Mul(q0, u1)); v2 = polyMath.Sub(v0, polyMath.Mul(q0, v1)); r2 = polyMath.Add(polyMath.Mul(u2, firstArg), polyMath.Mul(v2, secondArg)); r0 = r1; r1 = r2; u0 = u1; u1 = u2; v0 = v1; v1 = v2; } return(new Tuple <Polynomial, Polynomial, Polynomial>(u0, v0, r0)); }
public List <long> FindRoots(Polynomial polynomial, long mod) { if (mod < 100) { var bruteForceMethod = new BruteforceRootFinder(); return(bruteForceMethod.FindRoots(polynomial, mod)); } var result = new List <long>(); var gcd = new PolynomialGcd(); var polyMath = new PolynomialMath(mod); var x = new Polynomial(new BigInteger[] { 0, 1 }); var powX = polyMath.ModPow(x, mod, polynomial); var h = polyMath.Sub(powX, x); var g = gcd.Calculate(polynomial, h, mod); if (g.Value(0) % mod == 0) { result.Add(0); g = polyMath.Div(g, new Polynomial(new BigInteger[] { 0, 1 })); } Roots(g, mod, result); return(result); }
public bool IsIrreducible(Polynomial poly, BigInteger mod) { var factors = new List <int>(); var deg = poly.Deg; if (deg % 2 == 0) { factors.Add(2); } for (int i = 3; i <= deg; i += 2) { if (deg % i == 0) { factors.Add(i); } } var polyMath = new PolynomialMath(mod); var x = new Polynomial(new BigInteger[] { 0, 1 }); var xPow = polyMath.ModPow(x, BigInteger.Pow(mod, deg), poly); var bigPoly = polyMath.Sub(xPow, x); if (bigPoly.Deg != -1) { return(false); } var polynomialGcd = new PolynomialGcd(); foreach (var factor in factors) { xPow = polyMath.ModPow(x, BigInteger.Pow(mod, deg / factor), poly); bigPoly = polyMath.Sub(xPow, x); var gcd = polynomialGcd.Calculate(bigPoly, poly, mod); if (gcd.Deg != 0 || (gcd[0] + mod) % mod != 1) { return(false); } } return(true); }
public PolynomialOverFiniteField Div(PolynomialOverFiniteField firstArg, PolynomialOverFiniteField secondArg) { if (secondArg.Deg == -1) { throw new DivideByZeroException(); } if (firstArg.Deg < secondArg.Deg) { return(new PolynomialOverFiniteField(new Polynomial[] { new Polynomial(new BigInteger[] { 0 }) })); } var firstDeg = firstArg.Deg; var secondDeg = secondArg.Deg; var newDeg = firstDeg - secondDeg; var result = new Polynomial[newDeg + 1]; var reminder = (Polynomial[])firstArg.Coefficients.Clone(); Polynomial firstLc; Polynomial secondLc = secondArg[secondDeg]; var inverse = new PolynomialInverse(); secondLc = inverse.Inverse(secondLc, Mod); for (int i = 0; i <= newDeg; i++) { firstLc = reminder[firstDeg - i]; result[newDeg - i] = _polynomialMath.Mul(firstLc, secondLc); for (int j = 0; j <= secondDeg; j++) { reminder[firstDeg - secondDeg + j - i] = _polynomialMath.Sub(reminder[firstDeg - secondDeg + j - i], (_polynomialMath.Mul(result[newDeg - i], secondArg[j]))); } } return(new PolynomialOverFiniteField(result, Mod, FieldChar)); }