Ticket #11890: 11890_try_nffactor.patch

File 11890_try_nffactor.patch, 5.2 KB (added by jdemeyer, 9 years ago)
  • sage/rings/number_field/number_field.py

    # HG changeset patch
    # User Jeroen Demeyer <jdemeyer@cage.ugent.be>
    # Date 1317840257 -7200
    # Node ID e1d69aec3c4b6048e81c978658a045c2a99f61bd
    # Parent  1d259d9af60357f5d2e89554ee4981e37d044d15
    Try nffactor() with the defining polynomial if nfinit() fails with RuntimeError
    
    diff --git a/sage/rings/number_field/number_field.py b/sage/rings/number_field/number_field.py
    a b  
    40744074            elif not important:
    40754075                # Trial divide the discriminant
    40764076                m = self.pari_polynomial().poldisc().abs().factor(limit=0)
    4077                 # Since we only need a *squarefree* factorization, we need
    4078                 # trial division up to D^(1/3) instead of D^(1/2).
    4079                 trialdivlimit = pari(pari._primelimit()**3)
    4080                 if all([ p < trialdivlimit or p.isprime() for p in m[0] ]):
     4077                # Since we only need a *squarefree* factorization for
     4078                # primes with exponent 1, we need trial division up to D^(1/3)
     4079                # instead of D^(1/2).
     4080                trialdivlimit2 = pari(pari._primelimit()**2)
     4081                trialdivlimit3 = pari(pari._primelimit()**3)
     4082                if all([ p < trialdivlimit2 or (e == 1 and p < trialdivlimit3) or p.isprime() for p,e in zip(m[0],m[1]) ]):
    40814083                    B = f.nfbasis(fa = m)
    40824084                else:
    40834085                    raise RuntimeError, "Unable to factor discriminant with trial division"
  • sage/rings/polynomial/polynomial_element.pyx

    diff --git a/sage/rings/polynomial/polynomial_element.pyx b/sage/rings/polynomial/polynomial_element.pyx
    a b  
    27192719            x^5 * (x^5 + (4/7*a - 6/7)*x^4 + (9/49*a^2 - 3/7*a + 15/49)*x^3 + (8/343*a^3 - 32/343*a^2 + 40/343*a - 20/343)*x^2 + (5/2401*a^4 - 20/2401*a^3 + 40/2401*a^2 - 5/343*a + 15/2401)*x - 6/16807*a^4 + 12/16807*a^3 - 18/16807*a^2 + 12/16807*a - 6/16807)
    27202720
    27212721        Factoring over a number field over which we cannot factor the
    2722         discriminant::
     2722        discriminant by trial division::
     2723
     2724            sage: x = polygen(QQ)
     2725            sage: K.<a> = NumberField(x^16 - x - 6)
     2726            sage: R.<x> = PolynomialRing(K)
     2727            sage: f = (x+a)^50 - (a-1)^50
     2728            sage: len(factor(f))
     2729            6
     2730            sage: factor(K.discriminant())
     2731            -1 * 3^15 * 23 * 887 * 12583 * 6335047 * 371692813
     2732
     2733        Factoring over a number field over which we cannot factor the
     2734        discriminant and over which `nffactor()` fails::
    27232735
    27242736            sage: p = next_prime(10^50); q = next_prime(10^51); n = p*q;
    27252737            sage: K.<a> = QuadraticField(p*q)
    27262738            sage: R.<x> = PolynomialRing(K)
     2739            sage: K.pari_polynomial('a').nffactor("x^2+1")
     2740            Traceback (most recent call last):
     2741            ...
     2742            PariError: precision too low (10)
    27272743            sage: factor(x^2 + 1)
    27282744            x^2 + 1
    27292745            sage: factor( (x - a) * (x + 2*a) )
     
    27962812            g = M['x']([to_M(x) for x in self.list()])
    27972813            F = g.factor()
    27982814            S = self.parent()
    2799             v = [(S([from_M(x) for x in f.list()]), e) for f, e in g.factor()]
     2815            v = [(S([from_M(x) for x in f.list()]), e) for f, e in F]
    28002816            return Factorization(v, from_M(F.unit()))
    28012817
    28022818        elif is_FiniteField(R):
     
    28302846            v = [ c._pari_("a") for c in self.list() ]
    28312847            f = pari(v).Polrev()
    28322848            try:
    2833                 # Try to compute the PARI nf structure with important=False.
    2834                 # This will raise RuntimeError if the computation is too
    2835                 # difficult.  It will raise TypeError if the defining
    2836                 # polynomial is not integral.
    2837                 Rpari = R.pari_nf(important=False).nf_subst("'a")
    2838                 # Factor using nffactor()
     2849                try:
     2850                    # Try to compute the PARI nf structure with important=False.
     2851                    # This will raise RuntimeError if the computation is too
     2852                    # difficult.  It will raise TypeError if the defining
     2853                    # polynomial is not integral.
     2854                    Rpari = R.pari_nf(important=False).nf_subst("'a")
     2855                except RuntimeError:
     2856                    # Cannot easily compute the nf structure, use the defining
     2857                    # polynomial instead.
     2858                    Rpari = R.pari_polynomial("a")
     2859                # nffactor() can fail with PariError "precision too low"
    28392860                G = list(Rpari.nffactor(f))
    2840             except (RuntimeError, TypeError):
    2841                 # Use factornf() which only needs the defining polynomial
    2842                 # and which does not require an integral polynomial.
     2861            except (PariError, TypeError):
     2862                # Use factornf() which only needs the defining polynomial,
     2863                # which does not require an integral polynomial and which
     2864                # has no problems with floating-point precision.
    28432865                G = list(f.factornf(R.pari_polynomial("a")))
    28442866            # PARI's nffactor() ignores the unit, _factor_pari_helper()
    28452867            # adds back the unit of the factorization.