def padic_lift_list(f, factors, p, q): """ padicLift(f, factors, p, q) -> lifted_factors Find a lifted integer coefficient polynomials such that: f = G1*G2*...*Gm (mod q*p), Gi = gi (mod q), from f and gi's of integer coefficient polynomials such that: f = g1*g2*...*gm (mod q), gi's are pairwise coprime with positive integers p dividing q. """ ZpZx = poly_ring.PolynomialRing( intresidue.IntegerResidueClassRing.getInstance(p)) gg = arith1.product(factors) h = ZpZx.createElement([(d, c // q) for (d, c) in (f - gg).iterterms()]) lifted = [] for g in factors: gg = gg.pseudo_floordiv(g) g_mod = ZpZx.createElement(g) if gg.degree() == 0: break u, v, w = extgcdp(g, gg, p) if w.degree() > 0: raise ValueError("factors must be pairwise coprime.") v_mod = ZpZx.createElement(v) t = v_mod * h // g_mod lifted.append(g + minimum_absolute_injection(v_mod * h - g_mod * t) * q) u_mod = ZpZx.createElement(u) gg_mod = ZpZx.createElement(gg) h = u_mod * h + gg_mod * t lifted.append(g + minimum_absolute_injection(h) * q) return lifted
def find_combination(f, d, factors, q): """ find_combination(f, d, factors, q) -> g, list Find a combination of d factors which divides f (or its complement). The returned values are: the product g of the combination and a list consisting of the combination itself. If there is no combination, return (0,[]). """ lf = f.leading_coefficient() ZqZX = poly_ring.PolynomialRing( intresidue.IntegerResidueClassRing.getInstance(q)) if d == 1: for g in factors: product = minimum_absolute_injection(ZqZX.createElement(lf * g)) if divisibility_test(lf * f, product): return (product.primitive_part(), [g]) else: for idx in combinatorial.combinationIndexGenerator(len(factors), d): picked = [factors[i] for i in idx] product = lf * arith1.product(picked) product = minimum_absolute_injection(ZqZX.createElement(product)) if divisibility_test(lf * f, product): return (product.primitive_part(), picked) return 0, [] # nothing found
def testSubring(self): self.assertTrue(self.F17.issubring(self.F17)) self.assertTrue(self.F17.issuperring(self.F17)) # polynomial ring import nzmath.poly.ring as ring F17X = ring.PolynomialRing(self.F17, 1) self.assertTrue(self.F17.issubring(F17X)) self.assertFalse(self.F17.issuperring(F17X)) # rational field self.assertFalse(self.F17.issuperring(theRationalField)) self.assertFalse(self.F17.issubring(theRationalField))
of integer coefficient polynomials If you need lifted factors only once, you may want to use lift_upto function. On the other hand, if you might happen to need another lift, you would directly use one of the lifters and its lift method for consecutive lifts. """ import sys import nzmath.arith1 as arith1 import nzmath.rational as rational import nzmath.poly.ring as polyring # module globals the_ring = polyring.PolynomialRing(rational.theIntegerRing) the_one = the_ring.one the_zero = the_ring.zero def _extgcdp(f, g, p): """ _extgcdp(f,g,p) -> u,v,w Find u,v,w such that f*u + g*v = w = gcd(f,g) mod p. p should be a prime number. This is a private function. """ modp = lambda c: c % p u, v, w, x, y, z = the_one, the_zero, f, the_zero, the_one, g
def setUp(self): Z = rational.theIntegerRing self.zx = poly_ring.PolynomialRing(Z)
def setUp(self): self.Z = rational.theIntegerRing self.Q = rational.theRationalField self.Z2 = poly_ring.PolynomialRing(self.Z, 2) self.Q3 = poly_ring.PolynomialRing(self.Q, 3)