Beispiel #1
0
 def testSubtraction(self):
     Z = self.Z
     f = uniutil.polynomial(enumerate(range(1, 6)), Z)
     # sf bug # 1937925
     f2 = uniutil.polynomial([(1, 2), (2, 3), (3, 4), (4, 5)], Z)
     self.assertEqual(f2, f - 1)
     self.assertEqual(-f2, 1 - f)
Beispiel #2
0
 def _small_irriducible(char, degree):
     """
     Return an irreducible polynomial of self.degree with a small
     number of non-zero coefficients.
     """
     cardinality = char**degree
     basefield = FinitePrimeField.getInstance(char)
     top = uniutil.polynomial({degree: 1}, coeffring=basefield)
     for seed in range(degree - 1):
         for const in range(1, char):
             coeffs = [const] + arith1.expand(seed, 2)
             cand = uniutil.polynomial(enumerate(coeffs),
                                       coeffring=basefield) + top
             if cand.isirreducible():
                 _log.debug(cand.order.format(cand))
                 return cand
     for subdeg in range(degree):
         subseedbound = char**subdeg
         for subseed in range(subseedbound + 1, char * subseedbound):
             if not subseed % char:
                 continue
             seed = subseed + cardinality
             cand = uniutil.polynomial(enumerate(
                 arith1.expand(seed, cardinality)),
                                       coeffring=basefield)
             if cand.isirreducible():
                 return cand
Beispiel #3
0
 def testDivPoly(self):
     E = elliptic.EC([3, 4], 101)
     F101 = finitefield.FinitePrimeField.getInstance(E.ch)
     D = ({-1:uniutil.polynomial({0:-1}, F101),
         0:uniutil.polynomial({}, F101),
         1:uniutil.polynomial({0:1}, F101),
         2:uniutil.polynomial({0:2}, F101),
         3:uniutil.polynomial({0:92, 1:48, 2:18, 4:3}, F101),
         4:uniutil.polynomial({0:188, 1:10, 2:22, 3:118, 4:60, 6:4}, F101),
         5:uniutil.polynomial({0:48, 1:58, 2:53, 3:60, 4:28, 5:93, 6:79,
                               7:52, 8:65, 9:5, 10:85, 12:5}, F101),
         6:uniutil.polynomial({0:18, 1:24, 2:88, 3:32, 4:128, 5:44, 6:152,
                               7:56, 8:84, 9:192, 10:174, 12:114, 13:124,
                               14:28, 16:6}, F101),
         7:uniutil.polynomial({0:94, 1:77, 2:87, 3:65, 4:97, 5:45, 6:80,
                               7:22, 8:44, 9:76, 10:5, 11:49, 12:49, 13:74,
                               14:76, 15:53, 16:69, 17:47, 18:63, 19:70,
                               20:78, 21:20, 22:15, 24:7}, F101),
         8:uniutil.polynomial({0:32, 1:100, 2:58, 3:20, 4:124, 5:160, 6:82,
                               7:132, 8:158, 9:96, 10:154, 11:106, 12:134,
                               13:140, 14:10, 15:36, 16:72, 17:56, 18:116,
                               19:190, 20:134, 21:182, 22:74, 23:186, 24:50,
                               25:186, 26:122, 27:68, 28:136, 30:8}, F101)},
        [2, 3, 5, 7])
     self.assertEqual(D, E.divPoly([]))
Beispiel #4
0
    def _primitive_polynomial(char, degree):
        """
        Return a primitive polynomial of self.degree.

        REF: Lidl & Niederreiter, Introduction to finite fields and
             their applications.
        """
        cardinality = char**degree
        basefield = FinitePrimeField.getInstance(char)
        const = basefield.primitive_element()
        if degree & 1:
            const = -const
        cand = uniutil.polynomial({0: const, degree: basefield.one}, basefield)
        maxorder = factor_misc.FactoredInteger((cardinality - 1) // (char - 1))
        var = uniutil.polynomial({1: basefield.one}, basefield)
        while not (cand.isirreducible() and all(
                pow(var,
                    int(maxorder) // p, cand).degree() > 0
                for p in maxorder.prime_divisors())):
            # randomly modify the polynomial
            deg = bigrandom.randrange(1, degree)
            coeff = basefield.random_element(1, char)
            cand += uniutil.polynomial({deg: coeff}, basefield)
        _log.debug(cand.order.format(cand))
        return cand
Beispiel #5
0
    def setUp(self):
        """
	define a class using DivisionProvider
	"""
        R = rational.Rational
        Q = rational.theRationalField
        self.up1 = up1 = uniutil.polynomial([(1, R(1))], coeffring=Q)
        self.u = uniutil.polynomial([(0, up1), (3, up1)], up1.getRing())
        self.v = uniutil.polynomial([(0, -up1)], up1.getRing())
Beispiel #6
0
 def testShortSeq(self):
     """
     sequence has less dimension
     """
     F5 = finitefield.FinitePrimeField.getInstance(5)
     f5 = F5.createElement
     ann = uniutil.polynomial({1: 1}, F5)
     self.assertEqual(ann, linrec.minpoly(map(f5, [3, 0, 0, 0, 0, 0])))
     ann = uniutil.polynomial({2: 1}, F5)
     self.assertEqual(ann, linrec.minpoly(map(f5, [3, 1, 0, 0, 0, 0])))
Beispiel #7
0
 def testAddition(self):
     Z = self.Z
     f = uniutil.polynomial(enumerate(range(1, 6)), Z)
     g = uniutil.polynomial(enumerate(range(7, 10)), Z)
     h = uniutil.polynomial(enumerate([8, 10, 12, 4, 5]), Z)
     self.assertEqual(h, f + g)
     self.assertTrue(isinstance(f + g, uniutil.IntegerPolynomial))
     # sf bug # 1937925
     f2 = uniutil.polynomial(enumerate([2, 2, 3, 4, 5]), Z)
     self.assertEqual(f2, f + 1)
     self.assertEqual(f2, 1 + f)
Beispiel #8
0
 def testResultant(self):
     Z = rational.theIntegerRing
     I = rational.Integer
     f = uniutil.polynomial(enumerate(map(I, range(5))), coeffring=Z)
     g = uniutil.polynomial(enumerate(map(I, range(7, 10))), coeffring=Z)
     self.assertEqual(0, f.resultant(f * g))
     h1 = uniutil.polynomial(enumerate(map(I, [-2, 0, 0, 1])), coeffring=Z)
     h2 = uniutil.polynomial(enumerate([Z.zero, Z.one]), coeffring=Z)
     self.assertEqual(2, h1.resultant(h2))
     t = uniutil.polynomial(enumerate(map(I, range(7, 0, -1))), coeffring=Z)
     self.assertEqual(2**16 * 7**4, t.resultant(t.differentiate()))
Beispiel #9
0
    def setUp(self):
        """
	set up some polynomials
	"""
        self.f1 = uniutil.polynomial(enumerate([3, 6, 81, 1]), Z)
        self.f2 = uniutil.polynomial(enumerate([1, 81, 6, 3]), Z)
        self.f3 = uniutil.polynomial(enumerate([37, 6, 18, 1]), Z)
        self.f4 = uniutil.polynomial(enumerate([91, 7, 14, 1]), Z)
        # f5 = (x - 6)(x - 5)...x(x + 1)(x + 2) - 1
        self.f5 = uniutil.polynomial(
            enumerate([1439, -1368, -1324, 1638, -231, -252, 114, -18, 1]), Z)
    def testNonPrimitive(self):
        f1 = uniutil.polynomial(enumerate([3, 6]), Z)
        f2 = uniutil.polynomial(enumerate([5, 4, 1]), Z)
        f3 = uniutil.polynomial(enumerate([-1, 3]), Z)
        f = f1**3 * f2**2 * f3

        r = zassenhaus.integerpolynomialfactorization(f)
        self.assertTrue(isinstance(r, list))
        self.assertEqual(4, len(r), r)
        self.assertTrue(isinstance(r[0][0], uniutil.IntegerPolynomial))
        self.assertTrue(isinstance(r[1][0], uniutil.IntegerPolynomial))
        self.assertTrue(isinstance(r[2][0], uniutil.IntegerPolynomial))
        self.assertTrue(isinstance(r[3][0], uniutil.IntegerPolynomial))
        self.assertEqual(f, r[0][0]**r[0][1] * r[1][0]**r[1][1] * r[2][0]**r[2][1] * r[3][0]**r[3][1])
Beispiel #11
0
    def setUp(self):
        """
	define a class using DivisionProvider
	"""
        Polynomial = multiutil.UniqueFactorizationDomainPolynomial
        R = rational.Rational
        Q = rational.theRationalField
        self.f1 = f1 = Polynomial([((3, 1), R(1)), ((0, 1), R(1))], coeffring=Q)
        f2 = Polynomial([((0, 1), R(-1))], coeffring=Q)
        self.fn = uniutil.polynomial([(0, f1), (3, f2)], coeffring=f1.getRing())
        self.fz = Polynomial([((0, 3, 1), R(1)), ((3, 0, 1), R(-1)), ((0, 0, 1), R(1))], coeffring=Q)
        u1 = uniutil.polynomial([(1, R(1))], coeffring=Q)
        u2 = uniutil.polynomial([(1, R(1))], coeffring=Q)
        self.u = uniutil.polynomial([(0, u1), (3, u2)], u1.getRing())
Beispiel #12
0
    def testWeilPairing(self):
        # this example was refered to Washington.
        e = elliptic.EC([0, 2], 7)
        P = [5, 1]
        Q = [0, 3]
        R = e.WeilPairing(3, P, Q)
        self.assertEqual(finitefield.FinitePrimeFieldElement(2, 7), R)

        # test case of extension field, characteristic 7
        p = 7
        r = 11
        F = finitefield.FinitePrimeField(p)
        PX = uniutil.polynomial({0:3,1:3,2:2,3:1,4:4,5:1,6:1,10:1},F)
        Fx = finitefield.FiniteExtendedField(p,PX)

        E = elliptic.EC([F.one,-F.one],F)
        Ex = elliptic.EC([Fx.one,-Fx.one],Fx)

        P = [3,6]
        assert E.whetherOn(P)
        assert Ex.whetherOn(P)
        assert E.mul(11,P) == E.infpoint
        Qxcoord = Fx.createElement(6*7**9+7**8+7**6+6*7**3+6*7**2+7+6)
        Qycoord = Fx.createElement(3*7**9+6*7**8+4*7**7+2*7**6+5*7**4+5*7**3+7**2+7+3)
        Q = [Qxcoord,Qycoord]
        assert Ex.whetherOn(Q)
        assert Ex.mul(11,Q) == Ex.infpoint

        w = Ex.WeilPairing(11, P, Q)
        Wp = Fx.createElement(7**9 + 5*7**8 + 4*7**7 + 2*7**5 + 7**4 + 6*7**2)
        assert w == Wp
Beispiel #13
0
def Dedekind(minpoly_coeff, p, e):
    """
    Return (finished or not, an order)

    the Dedekind criterion

    Arguments:
    - minpoly_coeff: (integer) list of the minimal polynomial of theta.
    - p, e: p**e divides the discriminant of the minimal polynomial.
    """
    n = len(minpoly_coeff) - 1  # degree of the minimal polynomial

    m, uniq = _factor_minpoly_modp(minpoly_coeff, p)
    omega = _default_omega(n)

    if m == 0:
        return True, omega

    minpoly = uniutil.polynomial(enumerate(minpoly_coeff), Z)
    v = [_coeff_list(uniq, n)]
    shift = uniq
    for i in range(1, m):
        shift = shift.upshift_degree(1).pseudo_mod(minpoly)
        v.append(_coeff_list(shift, n))
    updater = ModuleWithDenominator(v, p)

    return (m + 1 > e), updater + omega
Beispiel #14
0
 def testDiscriminant(self):
     Q = rational.theRationalField
     rat = rational.Rational
     a, b, c = rat(2, 7), rat(5, 14), rat(1, 7)
     q1 = uniutil.polynomial(enumerate([c, b, a]), Q)
     d = b**2 - 4 * a * c
     self.assertEqual(d, q1.discriminant())
 def testIrreducible(self):
     f = uniutil.polynomial(enumerate([12, 6, 1]), Z)
     r = zassenhaus.zassenhaus(f)
     self.assertTrue(isinstance(r, list), r)
     self.assertEqual(1, len(r))
     self.assertTrue(isinstance(r[0], uniutil.UniqueFactorizationDomainPolynomial))
     self.assertEqual(f, r[0])
Beispiel #16
0
def padic_factorization(f):
    """
    padic_factorization(f) -> p, factors

    Return a prime p and a p-adic factorization of given integer
    coefficient squarefree polynomial f. The result factors have
    integer coefficients, injected from F_p to its minimum absolute
    representation. The prime is chosen to be 1) f is still squarefree
    mod p, 2) the number of factors is not greater than with the
    successive prime.
    """
    num_factors = f.degree()
    stock = None
    for p in prime.generator():
        fmodp = uniutil.polynomial(f.terms(),
                                   finitefield.FinitePrimeField.getInstance(p))
        if f.degree() > fmodp.degree():
            continue
        g = fmodp.getRing().gcd(fmodp, fmodp.differentiate())
        if g.degree() == 0:
            fp_factors = fmodp.factor()
            if (not stock) or num_factors > len(fp_factors):
                stock = (p, fp_factors)
                if len(fp_factors) == 1:
                    return stock
                num_factors = len(fp_factors)
            else:
                break
    p = stock[0]
    fp_factors = []
    for (fp_factor, m) in stock[1]:
        assert m == 1  # since squarefree
        fp_factors.append(minimum_absolute_injection(fp_factor))
    return (p, fp_factors)
Beispiel #17
0
def qpoly(coeffs):
    """
    Return a rational coefficient polynomial constructed from given
    coeffs.  The coeffs is a list of coefficients in ascending order.
    """
    terms = [(i, rational.Rational(c)) for (i, c) in enumerate(coeffs)]
    return uniutil.polynomial(terms, rational.theRationalField)
Beispiel #18
0
def Dedekind(minpoly_coeff, p, e):
    """
    Return (finished or not, an order)

    the Dedekind criterion

    Arguments:
    - minpoly_coeff: (integer) list of the minimal polynomial of theta.
    - p, e: p**e divides the discriminant of the minimal polynomial.
    """
    n = len(minpoly_coeff) - 1  # degree of the minimal polynomial

    m, uniq = _factor_minpoly_modp(minpoly_coeff, p)
    omega = _default_omega(n)

    if m == 0:
        return True, omega

    minpoly = uniutil.polynomial(enumerate(minpoly_coeff), Z)
    v = [_coeff_list(uniq, n)]
    shift = uniq
    for i in range(1, m):
        shift = shift.upshift_degree(1).pseudo_mod(minpoly)
        v.append(_coeff_list(shift, n))
    updater = ModuleWithDenominator(v, p)

    return (m + 1 > e), updater + omega
Beispiel #19
0
def fppoly(coeffs, p):
    """
    Return a Z_p coefficient polynomial constructed from given
    coeffs.  The coeffs is a list of coefficients in ascending order.
    """
    return uniutil.polynomial(enumerate(coeffs),
                              finitefield.FinitePrimeField(p))
Beispiel #20
0
def qpoly(coeffs):
    """
    Return a rational coefficient polynomial constructed from given
    coeffs.  The coeffs is a list of coefficients in ascending order.
    """
    terms = [(i, rational.Rational(c)) for (i, c) in enumerate(coeffs)]
    return uniutil.polynomial(terms, rational.theRationalField)
Beispiel #21
0
def _mod_p(poly, p):
    """
    Return modulo p reduction of given integer coefficient polynomial.
    """
    coeff = {}
    for d, c in poly:
        coeff[d] = finitefield.FinitePrimeFieldElement(c, p)
    return uniutil.polynomial(poly, finitefield.FinitePrimeField.getInstance(p))
Beispiel #22
0
    def testAtti(self):
        """
	This test case is taken from the paper of Atti et al.
	"""
        Q = rational.theRationalField
        rat = rational.Rational
        ann = uniutil.polynomial(enumerate([0, 1, 1, 1]), Q)
        self.assertEqual(ann, linrec.minpoly(map(rat, [1, 2, 7, -9, 2, 7])))
Beispiel #23
0
def _mod_p(poly, p):
    """
    Return modulo p reduction of given integer coefficient polynomial.
    """
    coeff = {}
    for d, c in poly:
        coeff[d] = finitefield.FinitePrimeFieldElement(c, p)
    return uniutil.polynomial(poly, finitefield.FinitePrimeField.getInstance(p))
 def testRegular(self):
     f = uniutil.polynomial(enumerate([12, 7, 1]), Z)
     r = zassenhaus.padic_factorization(f)
     self.assertTrue(isinstance(r, tuple))
     self.assertEqual(2, len(r))
     self.assertTrue(prime.primeq(r[0]))
     self.assertTrue(isinstance(r[1], list))
     self.assertEqual(2, len(r[1]))
Beispiel #25
0
 def setUp(self):
     self.f = ratfunc.RationalFunction(uniutil.polynomial({
         3: 1,
         0: 1
     }, Z), uniutil.polynomial({
         2: 1,
         0: -2
     }, Z))
     self.f2 = self.f
     self.f3 = ratfunc.RationalFunction(
         uniutil.polynomial({
             4: 1,
             1: 1
         }, Z), uniutil.polynomial({
             3: 1,
             1: -2
         }, Z))
 def testRegular(self):
     f = uniutil.polynomial(enumerate([12, 7, 1]), Z)
     r = zassenhaus.zassenhaus(f)
     self.assertTrue(isinstance(r, list))
     self.assertEqual(2, len(r), r)
     self.assertTrue(isinstance(r[0], uniutil.UniqueFactorizationDomainPolynomial))
     self.assertTrue(isinstance(r[1], uniutil.UniqueFactorizationDomainPolynomial))
     self.assertEqual(f, r[0] * r[1])
Beispiel #27
0
    def testAtti_19(self):
        """
	testAtti on F19
	"""
        F19 = finitefield.FinitePrimeField.getInstance(19)
        f19 = F19.createElement
        ann = uniutil.polynomial(enumerate([0, 1, 1, 1]), F19)
        self.assertEqual(ann, linrec.minpoly(map(f19, [1, 2, 7, -9, 2, 7])))
Beispiel #28
0
def _min_abs_poly(poly_p):
    """
    Return minimal absolute mapping of given F_p coefficient polynomial.
    """
    coeff = {}
    p = poly_p.getCoefficientRing().char
    for d, c in poly_p:
        coeff[d] = _pull_back(c, p)
    return uniutil.polynomial(coeff, Z)
Beispiel #29
0
def _min_abs_poly(poly_p):
    """
    Return minimal absolute mapping of given F_p coefficient polynomial.
    """
    coeff = {}
    p = poly_p.getCoefficientRing().char
    for d, c in poly_p:
        coeff[d] = _pull_back(c, p)
    return uniutil.polynomial(coeff, Z)
Beispiel #30
0
def minpoly(firstterms):
    """
    Return the minimal polynomial having at most degree n of of the
    linearly recurrent sequence whose first 2n terms are given.
    """
    field = ring.getRing(firstterms[0])
    r_0 = uniutil.polynomial({len(firstterms): field.one}, field)
    r_1 = uniutil.polynomial(enumerate(reversed(firstterms)), field)
    poly_ring = r_0.getRing()
    v_0 = poly_ring.zero
    v_1 = poly_ring.one
    n = len(firstterms) // 2

    while n <= r_1.degree():
        q, r = divmod(r_0, r_1)
        v_0, v_1 = v_1, v_0 - q * v_1
        r_0, r_1 = r_1, r
    return v_1.scalar_mul(v_1.leading_coefficient().inverse())
Beispiel #31
0
 def getCharPoly(self):
     """
     Return the characteristic polynomial of self 
     by compute products of (x-self^{(i)}).
     """
     if not hasattr(self, "charpoly"):
         Conj = self.getApprox()
         P = uniutil.polynomial({0:-Conj[0], 1:1}, ring.getRing(Conj[0]))
         for i in range(1, self.degree):
             P *= uniutil.polynomial({0:-Conj[i], 1:1}, 
                 ring.getRing(Conj[i]))
         charcoeff = []
         for i in range(self.degree + 1):
             if hasattr(P[i], "real"):
                 charcoeff.append(int(math.floor(P[i].real + 0.5)))
             else:
                 charcoeff.append(int(math.floor(P[i] + 0.5)))
         self.charpoly = charcoeff
     return self.charpoly
Beispiel #32
0
 def getCharPoly(self):
     """
     Return the characteristic polynomial of self
     by compute products of (x-self^{(i)}).
     """
     if not hasattr(self, "charpoly"):
         Conj = self.getApprox()
         P = uniutil.polynomial({0:-Conj[0], 1:1}, ring.getRing(Conj[0]))
         for i in range(1, self.degree):
             P *= uniutil.polynomial({0:-Conj[i], 1:1},
                 ring.getRing(Conj[i]))
         charcoeff = []
         for i in range(self.degree + 1):
             if hasattr(P[i], "real"):
                 charcoeff.append(int(math.floor(P[i].real + 0.5)))
             else:
                 charcoeff.append(int(math.floor(P[i] + 0.5)))
         self.charpoly = charcoeff
     return self.charpoly
Beispiel #33
0
 def _zero_polynomial(self):
     """
     Return the zero polynomial in the polynomial ring.
     """
     if self.number_of_variables == 1:
         import nzmath.poly.uniutil as uniutil
         return uniutil.polynomial((), self._coefficient_ring)
     else:
         import nzmath.poly.multiutil as multiutil
         return multiutil.polynomial((), coeffring=self._coefficient_ring, number_of_variables=self.number_of_variables)
Beispiel #34
0
    def testReduceEuclideanPolynomial(self):
        whole = poly_ring.PolynomialIdeal(-1, self.zx)
        f = uniutil.polynomial([(0, 3), (1, 2)], self.Z)
        f_ideal = poly_ring.PolynomialIdeal(f, self.zx)
        self.assertFalse(whole.reduce(f))
        self.assertTrue(f_ideal.reduce(self.Z.one))

        two_generators = poly_ring.PolynomialIdeal([f, self.zx.createElement(5)], self.zx)
        self.assertFalse(two_generators.reduce(f))
        self.assertTrue(two_generators.reduce(self.Z.one))
Beispiel #35
0
 def _prepared_polynomial(self, preparation):
     """
     Return a polynomial from given preparation, which is suited
     for the first argument of uni-/multi-variable polynomials.
     """
     if self.number_of_variables == 1:
         import nzmath.poly.uniutil as uniutil
         return uniutil.polynomial(preparation, self._coefficient_ring)
     else:
         import nzmath.poly.multiutil as multiutil
         return multiutil.polynomial(preparation, self._coefficient_ring)
    def testSeptic(self):
        """
	Test an example: X^7 + 2X^6 + ... + 7X + 8
	"""
        poly_disc = uniutil.polynomial(enumerate(self.septic),
                                       self.Z).discriminant()
        self.assertEqual(-2**16 * 3**12, poly_disc)
        result = round2.round2(self.septic)
        self.assertTrue(result)
        self.assertEqual(2, len(result))
        self.assertEqual(-2**12 * 3**10, result[1], result)
Beispiel #37
0
 def _constant_polynomial(self, seed):
     """
     Return a constant polynomial made from a constant seed.
     seed should not be zero.
     """
     if self.number_of_variables == 1:
         import nzmath.poly.uniutil as uniutil
         return uniutil.polynomial({0: seed}, self._coefficient_ring)
     else:
         import nzmath.poly.multiutil as multiutil
         const = (0,) * self.number_of_variables
         return multiutil.polynomial({const: seed}, self._coefficient_ring)
Beispiel #38
0
def _factor_minpoly_modp(minpoly_coeff, p):
    """
    Factor theminpoly modulo p, and return two values in a tuple.
    We call gcd(square factors mod p, difference of minpoly and its modp) Z.
    1) degree of Z
    2) (minpoly mod p) / Z
    """
    Fp = finitefield.FinitePrimeField.getInstance(p)
    theminpoly_p = uniutil.polynomial([(d, Fp.createElement(c)) for (d, c) in enumerate(minpoly_coeff)], Fp)
    modpfactors = theminpoly_p.factor()
    mini_p = arith1.product([t for (t, e) in modpfactors])
    quot_p = theminpoly_p.exact_division(mini_p)
    mini = _min_abs_poly(mini_p)
    quot = _min_abs_poly(quot_p)
    minpoly = uniutil.polynomial(enumerate(minpoly_coeff), Z)
    f_p = _mod_p((mini * quot - minpoly).scalar_exact_division(p), p)
    gcd = f_p.getRing().gcd
    common_p = gcd(gcd(mini_p, quot_p), f_p) # called Z
    uniq_p = theminpoly_p // common_p
    uniq = _min_abs_poly(uniq_p)

    return common_p.degree(), uniq
Beispiel #39
0
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.
    """
    zpz = intresidue.IntegerResidueClassRing.getInstance(p)
    f_zpz = uniutil.polynomial(f, zpz)
    g_zpz = uniutil.polynomial(g, zpz)
    zero, one = f_zpz.getRing().zero, f_zpz.getRing().one
    u, v, w, x, y, z = one, zero, f_zpz, zero, one, g_zpz
    while z:
        q = w // z
        u, v, w, x, y, z = x, y, z, u - q*x, v - q*y, w - q*z
    if w.degree() == 0 and w[0] != zpz.one:
        u = u.scalar_exact_division(w[0]) # u / w
        v = v.scalar_exact_division(w[0]) # v / w
        w = w.getRing().one # w / w
    u = minimum_absolute_injection(u)
    v = minimum_absolute_injection(v)
    w = minimum_absolute_injection(w)
    return u, v, w
Beispiel #40
0
    def _primitive_polynomial(char, degree):
        """
        Return a primitive polynomial of self.degree.

        REF: Lidl & Niederreiter, Introduction to finite fields and
             their applications.
        """
        cardinality = char ** degree
        basefield = FinitePrimeField.getInstance(char)
        const = basefield.primitive_element()
        if degree % 2:
            const = -const
        cand = uniutil.polynomial({0:const, degree:basefield.one}, basefield)
        maxorder = factor_misc.FactoredInteger((cardinality - 1) // (char - 1))
        var = uniutil.polynomial({1:basefield.one}, basefield)
        while not (cand.isirreducible() and
                   all(pow(var, int(maxorder) // p, cand).degree() > 0 for p in maxorder.prime_divisors())):
            # randomly modify the polynomial
            deg = bigrandom.randrange(1, degree)
            coeff = basefield.random_element(1, char)
            cand += uniutil.polynomial({deg:coeff}, basefield)
        _log.debug(cand.order.format(cand))
        return cand
Beispiel #41
0
 def _small_irriducible(char, degree):
     """
     Return an irreducible polynomial of self.degree with a small
     number of non-zero coefficients.
     """
     cardinality = char ** degree
     basefield = FinitePrimeField.getInstance(char)
     top = uniutil.polynomial({degree: 1}, coeffring=basefield)
     for seed in range(degree - 1):
         for const in range(1, char):
             coeffs = [const] + arith1.expand(seed, 2)
             cand = uniutil.polynomial(enumerate(coeffs), coeffring=basefield) + top
             if cand.isirreducible():
                 _log.debug(cand.order.format(cand))
                 return cand
     for subdeg in range(degree):
         subseedbound = char ** subdeg
         for subseed in range(subseedbound + 1, char * subseedbound):
             if not subseed % char:
                 continue
             seed = subseed + cardinality
             cand = uniutil.polynomial(enumerate(arith1.expand(seed, cardinality)), coeffring=basefield)
             if cand.isirreducible():
                 return cand
Beispiel #42
0
 def nest(self, outer, coeffring):
     """
     Nest the polynomial by extracting outer variable at the given
     position.
     """
     combined = {}
     if self.number_of_variables == 2:
         itercoeff = lambda coeff: [(i[0], c) for (i, c) in coeff]
         poly = uniutil.polynomial
         polyring = poly_ring.PolynomialRing.getInstance(coeffring)
     elif self.number_of_variables >= 3:
         itercoeff = lambda coeff: coeff
         poly = self.__class__
         polyring = poly_ring.PolynomialRing.getInstance(coeffring, self.number_of_variables - 1)
     else:
         raise TypeError("number of variable is not multiple")
     for index, coeff in self.combine_similar_terms(outer):
         combined[index] = poly(itercoeff(coeff), coeffring=coeffring)
     return uniutil.polynomial(combined, coeffring=polyring)
Beispiel #43
0
def _SimMethod(g, initials=None, newtoninitial=None, repeat=250):
    """
    Return zeros of a polynomial given as a list.

    - g is the list of the polynomial coefficient in ascending order.
    - initial (optional) is a list of initial approximations of zeros.
    - newtoninitial (optional) is an initial value for Newton method to
      obtain an initial approximations of zeros if 'initial' is not given.
    - repeat (optional) is the number of iteration. The default is 250.
    """
    if initials is None:
        if newtoninitial:
            z = _initialize(g, newtoninitial)
        else:
            z = _initialize(g)
    else:
        z = initials

    f = uniutil.polynomial(enumerate(g), imaginary.theComplexField)
    deg = f.degree()
    df = f.differentiate()

    value_list = [f(z[i]) for i in range(deg)]
    for loop in range(repeat):
        sigma_list = [0] * deg
        for i in range(deg):
            if not value_list[i]:
                continue
            sigma = 0
            for j in range(i):
                sigma += 1 / (z[i] - z[j])
            for j in range(i+1, deg):
                sigma += 1 / (z[i] - z[j])
            sigma_list[i] = sigma

        for i in range(deg):
            if not value_list[i]:
                continue
            ratio = value_list[i] / df(z[i])
            z[i] -= ratio / (1 - ratio*sigma_list[i])
            value_list[i] = f(z[i])

    return z
Beispiel #44
0
def _p_maximal(p, e, minpoly_coeff):
    """
    Return p-maximal basis with some related informations.

    The arguments:
      p: the prime
      e: the exponent
      minpoly_coeff: (intefer) list of coefficients of the minimal
        polynomial of theta
    """
    # Apply the Dedekind criterion
    finished, omega = Dedekind(minpoly_coeff, p, e)
    if finished:
        _log.info("Dedekind(%d)" % p)
        return omega

    # main loop to construct p-maximal order
    minpoly = uniutil.polynomial(enumerate(minpoly_coeff), Z)
    theminpoly = minpoly.to_field_polynomial()
    n = theminpoly.degree()
    q = p ** (arith1.log(n, p) + 1)
    while True:
        # Ip: radical of pO
        # Ip = <alpha>, l = dim Ip/pO (essential part of Ip)
        alpha, l = _p_radical(omega, p, q, minpoly, n)

        # instead of step 9 big matrix,
        # Kida's LN section 2.2
        # Up = {x in Ip | xIp \subset pIp} = <zeta> + p<omega>
        zeta = _p_module(alpha, l, p, theminpoly)
        if zeta.rank == 0:
            # no new basis is found
            break

        # new order
        # 1/p Up = 1/p<zeta> + <omega>
        omega2 = zeta / p + omega
        if all(o1 == o2 for o1, o2 in zip(omega.basis, omega2.basis)):
            break
        omega = omega2

    # now <omega> is p-maximal.
    return omega
Beispiel #45
0
def round2(minpoly_coeff):
    """
    Return integral basis of the ring of integers of a field with its
    discriminant.  The field is given by a list of integers, which is
    a polynomial of generating element theta.  The polynomial ought to
    be monic, in other word, the generating element ought to be an
    algebraic integer.

    The integral basis will be given as a list of rational vectors
    with respect to theta.  (In other functions, bases are returned in
    the same fashion.)
    """
    minpoly_int = uniutil.polynomial(enumerate(minpoly_coeff), Z)
    d = minpoly_int.discriminant()
    squarefactors = _prepare_squarefactors(d)
    omega = _default_omega(minpoly_int.degree())
    for p, e in squarefactors:
        _log.debug("p = %d" % p)
        omega = omega + _p_maximal(p, e, minpoly_coeff)

    G = omega.determinant()
    return omega.get_rationals(), d * G**2
Beispiel #46
0
def _kernel_of_qpow(omega, q, p, minpoly, n):
    """
    Return the kernel of q-th powering, which is a linear map over Fp.
    q is a power of p which exceeds n.

    (omega_j^q (mod theminpoly) = \sum a_i_j omega_i   a_i_j in Fp)
    """
    omega_poly = omega.get_polynomials()
    denom = omega.denominator
    theminpoly = minpoly.to_field_polynomial()
    field_p = finitefield.FinitePrimeField.getInstance(p)
    zero = field_p.zero
    qpow = matrix.zeroMatrix(n, n, field_p) # Fp matrix
    for j in range(n):
        a_j = [zero] * n
        omega_poly_j = uniutil.polynomial(enumerate(omega.basis[j]), Z)
        omega_j_qpow = pow(omega_poly_j, q, minpoly)
        redundancy = gcd.gcd(omega_j_qpow.content(), denom ** q)
        omega_j_qpow = omega_j_qpow.coefficients_map(lambda c: c // redundancy)
        essential = denom ** q // redundancy
        while omega_j_qpow:
            i = omega_j_qpow.degree()
            a_ji = int(omega_j_qpow[i] / (omega_poly[i][i] * essential))
            omega_j_qpow -= a_ji * (omega_poly[i] * essential)
            if omega_j_qpow.degree() < i:
                a_j[i] = field_p.createElement(a_ji)
            else:
                _log.debug("%s / %d" % (str(omega_j_qpow), essential))
                _log.debug("j = %d, a_ji = %s" % (j, a_ji))
                raise ValueError("omega is not a basis")
        qpow.setColumn(j + 1, a_j)

    result = qpow.kernel()
    if result is None:
        _log.debug("(_k_q): trivial kernel")
        return matrix.zeroMatrix(n, 1, field_p)
    else:
        return result
Beispiel #47
0
def minimum_absolute_injection(f):
    """
    minimum_absolute_injection(f) -> F

    Return an integer coefficient polynomial F by injection of a Z/pZ
    coefficient polynomial f with sending each coefficient to minimum
    absolute representatives.
    """
    coefficientRing = f.getCoefficientRing()
    if isinstance(coefficientRing, intresidue.IntegerResidueClassRing):
        p = coefficientRing.m
    elif isinstance(coefficientRing, finitefield.FinitePrimeField):
        p = coefficientRing.getCharacteristic()
    else:
        raise TypeError("unknown ring (%s)" % repr(coefficientRing))
    half = p // 2
    g = {}
    for i, c in f.iterterms():
        if c.n > half:
            g[i] = c.n - p
        else:
            g[i] = c.n
    return uniutil.polynomial(g, rational.theIntegerRing)
Beispiel #48
0
def padic_factorization(f):
    """
    padic_factorization(f) -> p, factors

    Return a prime p and a p-adic factorization of given integer
    coefficient squarefree polynomial f. The result factors have
    integer coefficients, injected from F_p to its minimum absolute
    representation. The prime is chosen to be 1) f is still squarefree
    mod p, 2) the number of factors is not greater than with the
    successive prime.
    """
    num_factors = f.degree()
    stock = None
    for p in prime.generator():
        fmodp = uniutil.polynomial(
            f.terms(),
            finitefield.FinitePrimeField.getInstance(p))
        if f.degree() > fmodp.degree():
            continue
        g = fmodp.getRing().gcd(fmodp,
                                fmodp.differentiate())
        if g.degree() == 0:
            fp_factors = fmodp.factor()
            if not stock or num_factors > len(fp_factors):
                stock = (p, fp_factors)
                if len(fp_factors) == 1:
                    return stock
                num_factors = len(fp_factors)
            else:
                break
    p = stock[0]
    fp_factors = []
    for (fp_factor, m) in stock[1]:
        assert m == 1 # since squarefree
        fp_factors.append(minimum_absolute_injection(fp_factor))
    return (p, fp_factors)
Beispiel #49
0
def fppoly(coeffs, p):
    """
    Return a Z_p coefficient polynomial constructed from given
    coeffs.  The coeffs is a list of coefficients in ascending order.
    """
    return uniutil.polynomial(enumerate(coeffs), finitefield.FinitePrimeField(p))
Beispiel #50
0
except ValueError, e:
    print e.message
print

m = matrix.Matrix(2, 2, [1, 0, 1, 0], f2)
print m
print
v = matrix.Matrix(2, 1, [1, 1], f2)
print v
print
print m.inverseImage(v)
print

f2 = finitefield.FinitePrimeField(2)
P = polyring.PolynomialRing(f2)
x = P.createElement(polynomial([(1, 1)], f2))

def T(A, j):
    p = A.coeff_ring.getCharacteristic()
    phi = lambda A: (x * A + matrix.unitMatrix(A.row, A.coeff_ring)).determinant()
    return phi(A)[p**j]
    
A = matrix.Matrix(2, 2, [1, 0, 1, 0], f2)
print T(A, 1)
print

#A = matrix.Matrix(4, 4, [2, 1, 1, 1, 2, 1, 2, 1, 3, 2, 2, 1, 0, 1, 2, 1], R)
A = random_matrix(8, 3, f2)
print "Rank", A.rank()
try:
    (L, U, P) = A.LUPDecomposition()
Beispiel #51
0
def _rational_polynomial(coeffs):
    """
    Return rational polynomial with given coefficients in ascending
    order.
    """
    return uniutil.polynomial(enumerate(coeffs), Q)
Beispiel #52
0
def zpoly(coeffs):
    """
    Return an integer coefficient polynomial constructed from given
    coeffs.  The coeffs is a list of coefficients in ascending order.
    """
    return uniutil.polynomial(enumerate(coeffs), rational.theIntegerRing)
Beispiel #53
0
def affine_multiple_method(lhs, field):
    """
    Find and return a root of the equation lhs = 0 by brute force
    search in the given field.  If there is no root in the field,
    ValueError is raised.

    The first argument lhs is a univariate polynomial with
    coefficients in a finite field.  The second argument field is
    an extension field of the field of coefficients of lhs.

    Affine multiple A(X) is $\sum_{i=0}^{n} a_i X^{q^i} - a$ for some
    a_i's and a in the coefficient field of lhs, which is a multiple
    of the lhs.
    """
    polynomial_ring = lhs.getRing()
    coeff_field = lhs.getCoefficientRing()
    q = card(coeff_field)
    n = lhs.degree()

    # residues = [x, x^q, x^{q^2}, ..., x^{q^{n-1}}]
    residues = [lhs.mod(polynomial_ring.one.term_mul((1, 1)))] # x
    for i in range(1, n):
        residues.append(pow(residues[-1], q, lhs)) # x^{q^i}

    # find a linear relation among residues and a constant
    coeff_matrix = matrix.createMatrix(n, n, [coeff_field.zero] * (n**2), coeff_field)
    for j, residue in enumerate(residues):
        for i in range(residue.degree() + 1):
            coeff_matrix[i + 1, j + 1] = residue[i]
    constant_components = [coeff_field.one] + [coeff_field.zero] * (n - 1)
    constant_vector = vector.Vector(constant_components)
    try:
        relation_vector, kernel = coeff_matrix.solve(constant_vector)
        for j in range(n, 0, -1):
            if relation_vector[j]:
                constant = relation_vector[j].inverse()
                relation = [constant * c for c in relation_vector]
                break
    except matrix.NoInverseImage:
        kernel_matrix = coeff_matrix.kernel()
        relation_vector = kernel_matrix[1]
        assert type(relation_vector) is vector.Vector
        for j in range(n, 0, -1):
            if relation_vector[j]:
                normalizer = relation_vector[j].inverse()
                relation = [normalizer * c for c in relation_vector]
                constant = coeff_field.zero
                break

    # define L(X) = A(X) + constant
    coeffs = {}
    for i, relation_i in enumerate(relation):
        coeffs[q**i] = relation_i
    linearized = uniutil.polynomial(coeffs, coeff_field)

    # Fq basis [1, X, ..., X^{s-1}]
    qbasis = [1]
    root = field.createElement(field.char)
    s = arith1.log(card(field), q)
    qbasis += [root**i for i in range(1, s)]
    # represent L as Matrix
    lmat = matrix.createMatrix(s, s, field.basefield)
    for j, base in enumerate(qbasis):
        imagei = linearized(base)
        if imagei.getRing() == field.basefield:
            lmat[1, j + 1] = imagei
        else:
            for i, coeff in imagei.rep.iterterms():
                if coeff:
                    lmat[i + 1, j + 1] = coeff
    # solve L(X) = the constant
    constant_components = [constant] + [coeff_field.zero] * (s - 1)
    constant_vector = vector.Vector(constant_components)
    solution, kernel = lmat.solve(constant_vector)
    assert lmat * solution == constant_vector
    solutions = [solution]
    for v in kernel:
        for i in range(card(field.basefield)):
            solutions.append(solution + i * v)

    # roots of A(X) contains the solutions of lhs = 0
    for t in bigrange.multirange([(card(field.basefield),)] * len(kernel)):
        affine_root_vector = solution
        for i, ti in enumerate(t):
            affine_root_vector += ti * kernel[i]
        affine_root = field.zero
        for i, ai in enumerate(affine_root_vector):
            affine_root += ai * qbasis[i]
        if not lhs(affine_root):
            return affine_root

    raise ValueError("no root found")