Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
 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))
Ejemplo n.º 4
0
          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
Ejemplo n.º 5
0
 def setUp(self):
     Z = rational.theIntegerRing
     self.zx = poly_ring.PolynomialRing(Z)
Ejemplo n.º 6
0
 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)