public BigIntPolynomial Multiply(BigIntPolynomial b) { BigIntPolynomial c = F1.Multiply(b); c = F2.Multiply(c); c.Add(F3.Multiply(b)); return(c); }
/** * Calculates a <code>rho</code> modulo <code>m1*m2</code> from * two resultants whose <code>rho</code>s are modulo <code>m1</code> and <code>m2</code>.<br/> * </code>res</code> is set to <code>null</code>. * * @param modRes1 * @param modRes2 * @return <code>rho</code> modulo <code>modRes1.modulus * modRes2.modulus</code>, and <code>null</code> for </code>res</code>. */ public static ModularResultant CombineRho(ModularResultant modRes1, ModularResultant modRes2) { BigInteger mod1 = modRes1.modulus; BigInteger mod2 = modRes2.modulus; BigInteger prod = mod1.Multiply(mod2); BigIntEuclidean er = BigIntEuclidean.Calculate(mod2, mod1); BigIntPolynomial rho1 = (BigIntPolynomial)modRes1.Rho.Clone(); rho1.Multiply(er.x.Multiply(mod2)); BigIntPolynomial rho2 = (BigIntPolynomial)modRes2.Rho.Clone(); rho2.Multiply(er.y.Multiply(mod1)); rho1.Add(rho2); rho1.Mod(prod); return(new ModularResultant(rho1, null, prod)); }
/** * Karazuba multiplication */ private BigIntPolynomial MultiplyRecursive(BigIntPolynomial poly2) { BigInteger[] a = coeffs; BigInteger[] b = poly2.coeffs; int n = poly2.coeffs.Length; if (n <= 1) { BigInteger[] c = new BigInteger[coeffs.Length]; Array.Copy(coeffs, c, coeffs.Length); for (int i = 0; i < coeffs.Length; i++) { c[i] = c[i].Multiply(poly2.coeffs[0]); } return(new BigIntPolynomial(c)); } else { int n1 = n / 2; // TODO: Double Check Conversion (Don't worry too much, it'll explode if wrong)... It Exploded BigInteger[] a1temp = new BigInteger[n1]; BigInteger[] a2temp = new BigInteger[n - n1]; BigInteger[] b1temp = new BigInteger[n1]; BigInteger[] b2temp = new BigInteger[n - n1]; Array.Copy(a, a1temp, n1); Array.Copy(a, n1, a2temp, 0, n - n1); Array.Copy(b, b1temp, n1); Array.Copy(b, n1, b2temp, 0, n - n1); BigIntPolynomial a1 = new BigIntPolynomial(a1temp); BigIntPolynomial a2 = new BigIntPolynomial(a2temp); BigIntPolynomial b1 = new BigIntPolynomial(b1temp); BigIntPolynomial b2 = new BigIntPolynomial(b2temp); BigIntPolynomial A = (BigIntPolynomial)a1.Clone(); A.Add(a2); BigIntPolynomial B = (BigIntPolynomial)b1.Clone(); B.Add(b2); BigIntPolynomial c1 = a1.MultiplyRecursive(b1); BigIntPolynomial c2 = a2.MultiplyRecursive(b2); BigIntPolynomial c3 = A.MultiplyRecursive(B); c3.Sub(c1); c3.Sub(c2); BigIntPolynomial c = new BigIntPolynomial(2 * n - 1); for (int i = 0; i < c1.coeffs.Length; i++) { c.coeffs[i] = c1.coeffs[i]; } for (int i = 0; i < c3.coeffs.Length; i++) { c.coeffs[n1 + i] = c.coeffs[n1 + i].Add(c3.coeffs[i]); } for (int i = 0; i < c2.coeffs.Length; i++) { c.coeffs[2 * n1 + i] = c.coeffs[2 * n1 + i].Add(c2.coeffs[i]); } return(c); } }