Ticket #7931: 7931_fixes.patch

File 7931_fixes.patch, 6.3 KB (added by roed, 9 years ago)

Apply on top of 7931_nth_root.2.patch and 7931_common_superclass.patch

  • sage/rings/finite_rings/element_base.pyx

    # HG changeset patch
    # User David Roe <roed@math.harvard.edu>
    # Date 1285816174 14400
    # Node ID b65e732ec9dd94231437b8a9ce2bdce1117caa40
    # Parent  52506cc26942ad30ab3fd8cb0c794d2d67b84f86
    [mq]: 7931_fixes.patch
    
    diff -r 52506cc26942 -r b65e732ec9dd sage/rings/finite_rings/element_base.pyx
    a b  
    5656                nthroot = g**q1overn
    5757                return [nthroot**a for a in range(gcd)] if all else nthroot
    5858        n = n % (q-1)
    59         gcd, alpha, beta = n.xgcd(q-1) # gcd = alpha*n + beta*(p-1), so 1/n = alpha/gcd (mod p-1)
     59        if n == 0:
     60            if all: return []
     61            else: raise ValueError, "no nth root"
     62        gcd, alpha, beta = n.xgcd(q-1) # gcd = alpha*n + beta*(q-1), so 1/n = alpha/gcd (mod q-1)
    6063        if gcd == 1:
    6164            return [self**alpha] if all else self**alpha
    6265        n = gcd
     66        q1overn = (q-1)//n
     67        if self**q1overn != 1:
     68            if all: return []
     69            else: raise ValueError, "no nth root"
    6370        self = self**alpha
    6471        if cunningham:
    6572            F = n._factor_cunningham()
     
    6774            F = n.factor()
    6875        from sage.groups.generic import discrete_log
    6976        if algorithm is None or algorithm == 'Johnston':
    70             q1overn = (q-1)//n
    71             if self**q1overn != 1:
    72                 if all: return []
    73                 else: raise ValueError, "no nth root"
    7477            g = K.multiplicative_generator()
    7578            for r, v in F:
    7679                k, h = (q-1).val_unit(r)
  • sage/rings/finite_rings/integer_mod.pyx

    diff -r 52506cc26942 -r b65e732ec9dd sage/rings/finite_rings/integer_mod.pyx
    a b  
    10301030
    10311031        TESTS::
    10321032
    1033             sage: for p in [1009,2003,10007,100003]: # long
     1033            sage: for p in [1009,2003,10007,100003]: # long time
    10341034            ...       K = GF(p)
    10351035            ...       for r in (p-1).divisors():
    10361036            ...           if r == 1: continue
     
    11031103                if all:
    11041104                    return [K(a.lift()*p**(pval // n) + p**(k - (pval - pval//n)) * b) for a in mod(upart, p**(k-pval)).nth_root(n, all=True, algorithm=algorithm) for b in range(p**(pval - pval//n))]
    11051105                else:
    1106                     return K(p**(pval // n) * mod(upart.lift(), p**(k-pval)).nth_root(n, algorithm=algorithm).lift())
     1106                    return K(p**(pval // n) * mod(upart, p**(k-pval)).nth_root(n, algorithm=algorithm).lift())
    11071107            from sage.rings.padics.all import ZpFM
     1108            R = ZpFM(p,k,print_mode='digits')
     1109            self_orig = self
    11081110            if p == 2:
     1111                sign = [1]
    11091112                if self % 4 == 3:
    11101113                    if n % 2 == 0:
    11111114                        if all: return []
     
    11141117                        sign = [-1]
    11151118                        self = -self
    11161119                elif n % 2 == 0:
     1120                    if k > 2 and self % 8 == 5:
     1121                        if all: return []
     1122                        else: raise ValueError, "no nth root"
    11171123                    sign = [1, -1]
    1118                 else:
    1119                     sign = [1]
    11201124                if k == 2:
    1121                     if all: return [K(s) for s in sign]
     1125                    if all: return [K(s) for s in sign[:2]]
    11221126                    else: return K(sign[0])
    1123                 if all: modp = [mod(1,2)]
    1124                 else: modp = mod(1,2)
     1127                if all: modp = [mod(self,8)]
     1128                else: modp = mod(self,8)
    11251129            else:
    11261130                sign = [1]
    11271131                modp = self % p
    1128                 self = self / K(ZpFM(p,k).teichmuller(modp))
     1132                self = self / K(R.teichmuller(modp))
    11291133                modp = modp.nth_root(n, all=all, algorithm=algorithm)
    11301134            # now self is congruent to 1 mod 4 or 1 mod p (for odd p), so the power series for p-adic log converges.
    11311135            # Hensel lifting is probably better, but this is easier at the moment.
    1132             R = ZpFM(p,k)
    11331136            plog = R(self).log()
    11341137            nval = n.valuation(p)
    11351138            if nval >= plog.valuation() + (-1 if p == 2 else 0):
    11361139                if self == 1:
    1137                     if all: return [self]
    1138                     else: return self
     1140                    if all:
     1141                        return [s*K(p*k+m.lift()) for k in range(p**(k-(2 if p==2 else 1))) for m in modp for s in sign]
     1142                    else: return self_orig
    11391143                else:
    11401144                    if all: return []
    11411145                    else: raise ValueError, "no nth root"
     
    11461150            else:
    11471151                return sign[0] * K(R.teichmuller(modp) * (plog // n).exp())
    11481152        return self._nth_root_common(n, all, algorithm, cunningham)
     1153
     1154    def _nth_root_naive(self, n):
     1155        """
     1156        Computes all nth roots using brute force, for doc-testing.
     1157
     1158        TESTS::
     1159
     1160            sage: for n in range(2,100): # long time
     1161            ...       K=Integers(n)
     1162            ...       elist = range(1,min(2*n+2,100))
     1163            ...       for e in random_sublist(elist, 5/len(elist)):
     1164            ...           for a in random_sublist(range(1,n), min((n+2)//2,10)/(n-1)):
     1165            ...               b = K(a)
     1166            ...               try:
     1167            ...                   L = b.nth_root(e, all=True)
     1168            ...                   if len(L) > 0:
     1169            ...                       c = b.nth_root(e)
     1170            ...               except:
     1171            ...                   L = [-1]
     1172            ...               M = b._nth_root_naive(e)
     1173            ...               if sorted(L) != M:
     1174            ...                   print "mod(%s, %s).nth_root(%s,all=True), mod(%s, %s)._nth_root_naive(%s)"%(a,n,e,a,n,e)
     1175            ...                   raise ValueError
     1176            ...               if len(L) > 0 and (c not in L):
     1177            ...                   print "mod(%s, %s).nth_root(%s), mod(%s, %s).nth_root(%s,all=True)"%(a,n,e,a,n,e)
     1178            ...                   raise ValueError
     1179        """
     1180        L = []
     1181        for a in self.parent():
     1182            if a**n == self:
     1183                L.append(a)
     1184        return L
    11491185       
    11501186    def _balanced_abs(self):
    11511187        """