def _height(P,check=True): if check: assert P.curve() == self._E, "the point P must lie on the curve from which the height function was created" Q = n * P cQ = denominator(Q[0]) uQ = self.lift(Q,prec = prec) si = self.__padic_sigma_square(uQ, prec=prec) nn = self._q.valuation() qEu = self._q/p**nn return -(log(si*self._Csquare()/cQ) + log(uQ)**2/log(qEu)) / n**2
def newton_sqrt(self,f,x0, prec): r""" Takes the square root of the power series `f` by Newton's method NOTE: this function should eventually be moved to `p`-adic power series ring INPUT: - f power series wtih coefficients in `\QQ_p` or an extension - x0 seeds the Newton iteration - prec precision OUTPUT: the square root of `f` EXAMPLES:: sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x) sage: Q = H(0,0) sage: u,v = H.local_coord(Q,prec=100) sage: K = Qp(11,5) sage: HK = H.change_ring(K) sage: L.<a> = K.extension(x^20-11) sage: HL = H.change_ring(L) sage: S = HL(u(a),v(a)) sage: f = H.hyperelliptic_polynomials()[0] sage: y = HK.newton_sqrt( f(u(a)^11), a^11,5) sage: y^2 - f(u(a)^11) O(a^122) AUTHOR: - Jennifer Balakrishnan """ z = x0 try: x = f.parent().variable_name() if x!='a' : #this is to distinguish between extensions of Qp that are finite vs. not S = f.base_ring()[[x]] x = S.gen() except ValueError: pass z = x0 loop_prec = (log(RR(prec))/log(RR(2))).ceil() for i in range(loop_prec): z = (z+f/z)/2 try: return z + O(x**prec) except (NameError,ArithmeticError,TypeError): return z
def L_invariant(self, prec=20): r""" Returns the *mysterious* `\mathcal{L}`-invariant associated to an elliptic curve with split multiplicative reduction. One instance where this constant appears is in the exceptional case of the `p`-adic Birch and Swinnerton-Dyer conjecture as formulated in [MTT]_. See [Col]_ for a detailed discussion. INPUT: - ``prec`` - the `p`-adic precision, default is 20. REFERENCES: [MTT]_ .. [Col] Pierre Colmez, Invariant `\mathcal{L}` et derivees de valeurs propres de Frobenius, preprint, 2004. EXAMPLES:: sage: eq = EllipticCurve('130a1').tate_curve(5) sage: eq.L_invariant(prec=10) 5^3 + 4*5^4 + 2*5^5 + 2*5^6 + 2*5^7 + 3*5^8 + 5^9 + O(5^10) """ if not self.is_split(): raise RuntimeError("The curve must have split multiplicative " "reduction") qE = self.parameter(prec=prec) n = qE.valuation() u = qE / self._p**n # the p-adic logarithm of Iwasawa normalised by log(p) = 0 return log(u) / n
def L_invariant(self,prec=20): r""" Returns the *mysterious* `\mathcal{L}`-invariant associated to an elliptic curve with split multiplicative reduction. One instance where this constant appears is in the exceptional case of the `p`-adic Birch and Swinnerton-Dyer conjecture as formulated in [MTT]. See [Col] for a detailed discussion. INPUT: - ``prec`` - the `p`-adic precision, default is 20. REFERENCES: - [MTT] B. Mazur, J. Tate, and J. Teitelbaum, On `p`-adic analogues of the conjectures of Birch and Swinnerton-Dyer, Inventiones mathematicae 84, (1986), 1-48. - [Col] Pierre Colmez, Invariant `\mathcal{L}` et derivees de valeurs propores de Frobenius, preprint, 2004. EXAMPLES:: sage: eq = EllipticCurve('130a1').tate_curve(5) sage: eq.L_invariant(prec=10) 5^3 + 4*5^4 + 2*5^5 + 2*5^6 + 2*5^7 + 3*5^8 + 5^9 + O(5^10) """ if not self.is_split(): raise RuntimeError("The curve must have split multiplicative reduction") qE = self.parameter(prec=prec) n = qE.valuation() u = qE/self._p**n # the p-adic logarithm of Iwasawa normalised by log(p) = 0 return log(u)/n
def entropy(x, q=2): """ Compute the entropy at `x` on the `q`-ary symmetric channel. INPUT: - ``x`` - real number in the interval `[0, 1]`. - ``q`` - (default: 2) integer greater than 1. This is the base of the logarithm. EXAMPLES:: sage: codes.bounds.entropy(0, 2) 0 sage: codes.bounds.entropy(1/5,4).factor() # optional - sage.symbolic 1/10*(log(3) - 4*log(4/5) - log(1/5))/log(2) sage: codes.bounds.entropy(1, 3) # optional - sage.symbolic log(2)/log(3) Check that values not within the limits are properly handled:: sage: codes.bounds.entropy(1.1, 2) Traceback (most recent call last): ... ValueError: The entropy function is defined only for x in the interval [0, 1] sage: codes.bounds.entropy(1, 1) Traceback (most recent call last): ... ValueError: The value q must be an integer greater than 1 """ if x < 0 or x > 1: raise ValueError("The entropy function is defined only for x in the" " interval [0, 1]") q = ZZ(q) # This will error out if q is not an integer if q < 2: # Here we check that q is actually at least 2 raise ValueError("The value q must be an integer greater than 1") if x == 0: return 0 if x == 1: return log(q - 1, q) H = x * log(q - 1, q) - x * log(x, q) - (1 - x) * log(1 - x, q) return H
def from_sparse6(G, g6_string): r""" Fill ``G`` with the data of a sparse6 string. INPUT: - ``G`` -- a graph - ``g6_string`` -- a sparse6 string EXAMPLE:: sage: from sage.graphs.graph_input import from_sparse6 sage: g = Graph() sage: from_sparse6(g, ':I`ES@obGkqegW~') sage: g.is_isomorphic(graphs.PetersenGraph()) True """ from .generic_graph_pyx import length_and_string_from_graph6, int_to_binary_string from math import ceil, floor from sage.misc.functional import log n = g6_string.find('\n') if n == -1: n = len(g6_string) s = g6_string[:n] n, s = length_and_string_from_graph6(s[1:]) if n == 0: edges = [] else: k = int(ceil(log(n, 2))) ords = [ord(i) for i in s] if any(o > 126 or o < 63 for o in ords): raise RuntimeError( "The string seems corrupt: valid characters are \n" + ''.join([chr(i) for i in range(63, 127)])) bits = ''.join([int_to_binary_string(o - 63).zfill(6) for o in ords]) b = [] x = [] for i in range(int(floor(len(bits) / (k + 1)))): b.append(int(bits[(k + 1) * i:(k + 1) * i + 1], 2)) x.append(int(bits[(k + 1) * i + 1:(k + 1) * i + k + 1], 2)) v = 0 edges = [] for i in range(len(b)): if b[i] == 1: v += 1 if x[i] > v: v = x[i] else: if v < n: edges.append((x[i], v)) G.add_vertices(range(n)) G.add_edges(edges)
def from_sparse6(G, g6_string): r""" Fill ``G`` with the data of a sparse6 string. INPUT: - ``G`` -- a graph - ``g6_string`` -- a sparse6 string EXAMPLE:: sage: from sage.graphs.graph_input import from_sparse6 sage: g = Graph() sage: from_sparse6(g, ':I`ES@obGkqegW~') sage: g.is_isomorphic(graphs.PetersenGraph()) True """ from generic_graph_pyx import length_and_string_from_graph6, int_to_binary_string from math import ceil, floor from sage.misc.functional import log n = g6_string.find('\n') if n == -1: n = len(g6_string) s = g6_string[:n] n, s = length_and_string_from_graph6(s[1:]) if n == 0: edges = [] else: k = int(ceil(log(n,2))) ords = [ord(i) for i in s] if any(o > 126 or o < 63 for o in ords): raise RuntimeError("The string seems corrupt: valid characters are \n" + ''.join([chr(i) for i in xrange(63,127)])) bits = ''.join([int_to_binary_string(o-63).zfill(6) for o in ords]) b = [] x = [] for i in xrange(int(floor(len(bits)/(k+1)))): b.append(int(bits[(k+1)*i:(k+1)*i+1],2)) x.append(int(bits[(k+1)*i+1:(k+1)*i+k+1],2)) v = 0 edges = [] for i in xrange(len(b)): if b[i] == 1: v += 1 if x[i] > v: v = x[i] else: if v < n: edges.append((x[i],v)) G.add_vertices(range(n)) G.add_edges(edges)
def gv_info_rate(n, delta, q): r""" The Gilbert-Varshamov lower bound for information rate. The Gilbert-Varshamov lower bound for information rate of a `q`-ary code of length `n` and minimum distance `n\delta`. EXAMPLES:: sage: RDF(codes.bounds.gv_info_rate(100,1/4,3)) # abs tol 1e-15 0.36704992608261894 """ q = ZZ(q) return log(gilbert_lower_bound(n, q, int(n * delta)), q) / n
def an_padic(self, p, prec=0, use_twists=True): r""" Returns the conjectural order of `Sha(E/\QQ)`, according to the `p`-adic analogue of the Birch and Swinnerton-Dyer conjecture as formulated in [MTT]_ and [BP]_. REFERENCES: .. [MTT] B. Mazur, J. Tate, and J. Teitelbaum, On `p`-adic analogues of the conjectures of Birch and Swinnerton-Dyer, Inventiones mathematicae 84, (1986), 1-48. .. [BP] Dominique Bernardi and Bernadette Perrin-Riou, Variante `p`-adique de la conjecture de Birch et Swinnerton-Dyer (le cas supersingulier), C. R. Acad. Sci. Paris, Ser I. Math, 317 (1993), no 3, 227-232. .. [SW] William Stein and Christian Wuthrich, Computations About Tate-Shafarevich Groups using Iwasawa theory, preprint 2009. INPUT: - ``p`` - a prime > 3 - ``prec`` (optional) - the precision used in the computation of the `p`-adic L-Series - ``use_twists`` (default = ``True``) - If ``True`` the algorithm may change to a quadratic twist with minimal conductor to do the modular symbol computations rather than using the modular symbols of the curve itself. If ``False`` it forces the computation using the modular symbols of the curve itself. OUTPUT: `p`-adic number - that conjecturally equals `\# Sha(E/\QQ)`. If ``prec`` is set to zero (default) then the precision is set so that at least the first `p`-adic digit of conjectural `\# Sha(E/\QQ)` is determined. EXAMPLES: Good ordinary examples:: sage: EllipticCurve('11a1').sha().an_padic(5) # rank 0 1 + O(5^2) sage: EllipticCurve('43a1').sha().an_padic(5) # rank 1 1 + O(5) sage: EllipticCurve('389a1').sha().an_padic(5,4) # rank 2, long time (2s on sage.math, 2011) 1 + O(5^3) sage: EllipticCurve('858k2').sha().an_padic(7) # rank 0, non trivial sha, long time (10s on sage.math, 2011) Traceback (most recent call last): # 32-bit (see ticket :trac: `112111`) ... # 32-bit OverflowError: Python int too large to convert to C long # 32-bit 7^2 + O(7^6) # 64-bit sage: EllipticCurve('300b2').sha().an_padic(3) # 9 elements in sha, long time (2s on sage.math, 2011) 3^2 + O(3^6) sage: EllipticCurve('300b2').sha().an_padic(7, prec=6) # long time 2 + 7 + O(7^8) Exceptional cases:: sage: EllipticCurve('11a1').sha().an_padic(11) # rank 0 1 + O(11^2) sage: EllipticCurve('130a1').sha().an_padic(5) # rank 1 1 + O(5) Non-split, but rank 0 case (:trac:`7331`):: sage: EllipticCurve('270b1').sha().an_padic(5) # rank 0, long time (2s on sage.math, 2011) 1 + O(5^2) The output has the correct sign:: sage: EllipticCurve('123a1').sha().an_padic(41) # rank 1, long time (3s on sage.math, 2011) 1 + O(41) Supersingular cases:: sage: EllipticCurve('34a1').sha().an_padic(5) # rank 0 1 + O(5^2) sage: EllipticCurve('53a1').sha().an_padic(5) # rank 1, long time (11s on sage.math, 2011) 1 + O(5) Cases that use a twist to a lower conductor:: sage: EllipticCurve('99a1').sha().an_padic(5) 1 + O(5) sage: EllipticCurve('240d3').sha().an_padic(5) # sha has 4 elements here 4 + O(5) sage: EllipticCurve('448c5').sha().an_padic(7,prec=4, use_twists=False) # long time (2s on sage.math, 2011) 2 + 7 + O(7^6) sage: EllipticCurve([-19,34]).sha().an_padic(5) # see :trac: `6455`, long time (4s on sage.math, 2011) 1 + O(5) """ try: return self.__an_padic[(p,prec)] except AttributeError: self.__an_padic = {} except KeyError: pass E = self.Emin tam = E.tamagawa_product() tors = E.torsion_order()**2 reg = E.padic_regulator(p) # todo : here we should cache the rank computation r = E.rank() if use_twists and p > 2: Et, D = E.minimal_quadratic_twist() # trac 6455 : we have to assure that the twist back is allowed D = ZZ(D) if D % p == 0: D = D/p for ell in D.prime_divisors(): if ell % 2 == 1: if Et.conductor() % ell**2 == 0: D = D/ell ve = valuation(D,2) de = (D/2**ve).abs() if de % 4 == 3: de = -de Et = E.quadratic_twist(de) # now check individually if we can twist by -1 or 2 or -2 Nmin = Et.conductor() Dmax = de for DD in [-4*de,8*de,-8*de]: Et = E.quadratic_twist(DD) if Et.conductor() < Nmin and valuation(Et.conductor(),2) <= valuation(DD,2): Nmin = Et.conductor() Dmax = DD D = Dmax Et = E.quadratic_twist(D) lp = Et.padic_lseries(p) else : lp = E.padic_lseries(p) D = 1 if r == 0 and D == 1: # short cut for rank 0 curves, we do not # to compute the p-adic L-function, the leading # term will be the L-value divided by the Neron # period. ms = E.modular_symbol(sign=+1, normalize='L_ratio') lstar = ms(0)/E.real_components() bsd = tam/tors if prec == 0: prec = valuation(lstar/bsd, p) shan = Qp(p,prec=prec+2)(lstar/bsd) elif E.is_ordinary(p): K = reg.parent() lg = log(K(1+p)) if (E.is_good(p) or E.ap(p) == -1): if not E.is_good(p): eps = 2 else: eps = (1-arith.kronecker_symbol(D,p)/lp.alpha())**2 # according to the p-adic BSD this should be equal to the leading term of the p-adic L-series divided by sha: bsdp = tam * reg * eps/tors/lg**r else: r += 1 # exceptional zero eq = E.tate_curve(p) Li = eq.L_invariant() # according to the p-adic BSD (Mazur-Tate-Teitelbaum) # this should be equal to the leading term of the p-adic L-series divided by sha: bsdp = tam * reg * Li/tors/lg**r v = bsdp.valuation() if v > 0: verbose("the prime is irregular.") # determine how much prec we need to prove at least the triviality of # the p-primary part of Sha if prec == 0: n = max(v,2) bounds = lp._prec_bounds(n,r+1) while bounds[r] <= v: n += 1 bounds = lp._prec_bounds(n,r+1) verbose("set precision to %s"%n) else: n = max(2,prec) not_yet_enough_prec = True while not_yet_enough_prec: lps = lp.series(n,quadratic_twist=D,prec=r+1) lstar = lps[r] if (lstar != 0) or (prec != 0): not_yet_enough_prec = False else: n += 1 verbose("increased precision to %s"%n) shan = lstar/bsdp elif E.is_supersingular(p): K = reg[0].parent() lg = log(K(1+p)) # according to the p-adic BSD this should be equal to the leading term of the D_p - valued # L-series : bsdp = tam /tors/lg**r * reg # note this is an element in Q_p^2 verbose("the algebraic leading terms : %s"%bsdp) v = [bsdp[0].valuation(),bsdp[1].valuation()] if prec == 0: n = max(min(v)+2,3) else: n = max(3,prec) verbose("...computing the p-adic L-series") not_yet_enough_prec = True while not_yet_enough_prec: lps = lp.Dp_valued_series(n,quadratic_twist=D,prec=r+1) lstar = [lps[0][r],lps[1][r]] verbose("the leading terms : %s"%lstar) if (lstar[0] != 0 or lstar[1] != 0) or ( prec != 0): not_yet_enough_prec = False else: n += 1 verbose("increased precision to %s"%n) verbose("...putting things together") if bsdp[0] != 0: shan0 = lstar[0]/bsdp[0] else: shan0 = 0 # this should actually never happen if bsdp[1] != 0: shan1 = lstar[1]/bsdp[1] else: shan1 = 0 # this should conjecturally only happen when the rank is 0 verbose("the two values for Sha : %s"%[shan0,shan1]) # check consistency (the first two are only here to avoid a bug in the p-adic L-series # (namely the coefficients of zero-relative precision are treated as zero) if shan0 != 0 and shan1 != 0 and shan0 - shan1 != 0: raise RuntimeError("There must be a bug in the supersingular routines for the p-adic BSD.") #take the better if shan1 == 0 or shan0.precision_relative() > shan1.precision_relative(): shan = shan0 else: shan = shan1 else: raise ValueError("The curve has to have semi-stable reduction at p.") self.__an_padic[(p,prec)] = shan return shan
def attack(m, q, r=4, sigma=3.0, subfield_only=False): K = CyclotomicField(m, 'z') z = K.gen() OK = K.ring_of_integers() G = K.galois_group() n = euler_phi(m) mprime = m / r nprime = euler_phi(mprime) Gprime = [tau for tau in G if tau(z**r) == z**r] R = PolynomialRing(IntegerRing(), 'a') a = R.gen() phim = a**n + 1 D = DiscreteGaussianDistributionIntegerSampler(sigma) print "sampling f,g" while True: f = sum([D() * z**i for i in range(n)]) fx = sum([f[i] * a**i for i in range(n)]) res = inverse(fx, phim, q) if res[0]: f_inv = sum([res[1][i] * z**i for i in range(n)]) print "f_inv * f = %s (mod %d)" % ((f * f_inv).mod(q), q) break g = sum([D() * z**i for i in range(n)]) print "done sampling f, g" #h = [g*f^{-1)]_q h = (g * f_inv).mod(q) lognorm_f = log(f.vector().norm(), 2) lognorm_g = log(g.vector().norm(), 2) print "f*h - g = %s" % (f * h - g).mod(q) print "log q = ", log(q, 2).n(precision) print "log |f| = %s, log |g| = %s" % (lognorm_f.n(precision), lognorm_g.n(precision)) print "log |(f,g)| = ", log( sqrt(f.vector().norm()**2 + g.vector().norm()**2), 2).n(precision) print "begin computing N(f), N(g), N(h), Tr(h), fbar" fprime = norm(f, Gprime) gprime = norm(g, Gprime) hprime = norm(h, Gprime).mod(q) htr = trace(h, Gprime) fbar = prod([tau(f) for tau in Gprime[1:]]) print "end computing N(f), N(g), N(h), Tr(h), fbar" lognorm_fp = log(fprime.vector().norm(), 2) lognorm_gp = log(gprime.vector().norm(), 2) print "%d * log |f| - log |f'| = %s" % (r, r * lognorm_f.n(precision) - lognorm_fp.n(precision)) print "log |(f', g')| = ", log( sqrt(fprime.vector().norm()**2 + gprime.vector().norm()**2), 2).n(precision) print "log |N(f), Tr(g fbar)| = ", log( sqrt(fprime.vector().norm()**2 + trace(g * fbar, Gprime).vector().norm()**2), 2).n(precision) #(fprime, gprime) lies in the lattice \Lambda_hprime^q print "f'*h' - g' = %s " % (hprime * fprime - gprime).mod(q) print "N(f) Tr(h) - Tr(g fbar) = %s" % (htr * fprime - trace(g * fbar, Gprime)).mod(q) if not subfield_only: ntru_full = NTRU(h, K, q) full_sv = ntru_full.shortest_vector() print "log |v| = %s" % log(full_sv.norm(), 2).n(precision) ntru_subfield = NTRU_subfield(hprime, q, nprime, r) ntru_trace_subfield = NTRU_subfield(htr, q, nprime, r) print "begin computing Shortest Vector of subfield lattice" norm_sv = ntru_subfield.shortest_vector() tr_sv = ntru_trace_subfield.shortest_vector() print "end computing Shortest Vector of subfield lattice" norm_xp = sum( [coerce(Integer, norm_sv[i]) * z**(r * i) for i in range(nprime)]) tr_xp = sum( [coerce(Integer, tr_sv[i]) * z**(r * i) for i in range(nprime)]) print "Norm map: log |(x',y')| = ", log(norm_sv.norm(), 2).n(precision) print "Trace map: log |(x', y')| = ", log(tr_sv.norm(), 2).n(precision) #test if xprime belongs to <fprime> mat = [] for i in range(nprime): coordinate = (fprime * z**(r * i)).vector().list() mat.append([coordinate[r * j] for j in range(nprime)]) FL = IntegerLattice(mat) print norm_sv[:nprime] in FL print tr_sv[:nprime] in FL norm_x = norm_xp norm_y = mod_q(norm_x * h, q) tr_x = tr_xp tr_y = mod_q(tr_x * h, q) print "Norm map: log |(x,y)| = ", log( sqrt(norm_x.vector().norm()**2 + norm_y.vector().norm()**2), 2).n(precision) print "Trace map: log |(x,y)| = ", log( sqrt(tr_x.vector().norm()**2 + tr_y.vector().norm()**2), 2).n(precision)
def neg_xlog2x(p): if p == 0: return 0 else: return -p * log(p, 2)
def an_padic(self, p, prec=0, use_twists=True): r""" Returns the conjectural order of `Sha(E/\QQ)`, according to the `p`-adic analogue of the Birch and Swinnerton-Dyer conjecture as formulated in [MTT]_ and [BP]_. REFERENCES: .. [MTT] \B. Mazur, J. Tate, and J. Teitelbaum, On `p`-adic analogues of the conjectures of Birch and Swinnerton-Dyer, Inventiones mathematicae 84, (1986), 1-48. .. [BP] Dominique Bernardi and Bernadette Perrin-Riou, Variante `p`-adique de la conjecture de Birch et Swinnerton-Dyer (le cas supersingulier), C. R. Acad. Sci. Paris, Sér I. Math., 317 (1993), no. 3, 227-232. INPUT: - ``p`` - a prime > 3 - ``prec`` (optional) - the precision used in the computation of the `p`-adic L-Series - ``use_twists`` (default = ``True``) - If ``True`` the algorithm may change to a quadratic twist with minimal conductor to do the modular symbol computations rather than using the modular symbols of the curve itself. If ``False`` it forces the computation using the modular symbols of the curve itself. OUTPUT: `p`-adic number - that conjecturally equals `\# Sha(E/\QQ)`. If ``prec`` is set to zero (default) then the precision is set so that at least the first `p`-adic digit of conjectural `\# Sha(E/\QQ)` is determined. EXAMPLES: Good ordinary examples:: sage: EllipticCurve('11a1').sha().an_padic(5) # rank 0 1 + O(5^22) sage: EllipticCurve('43a1').sha().an_padic(5) # rank 1 1 + O(5) sage: EllipticCurve('389a1').sha().an_padic(5,4) # rank 2, long time (2s on sage.math, 2011) 1 + O(5^3) sage: EllipticCurve('858k2').sha().an_padic(7) # rank 0, non trivial sha, long time (10s on sage.math, 2011) 7^2 + O(7^24) sage: EllipticCurve('300b2').sha().an_padic(3) # 9 elements in sha, long time (2s on sage.math, 2011) 3^2 + O(3^24) sage: EllipticCurve('300b2').sha().an_padic(7, prec=6) # long time 2 + 7 + O(7^8) Exceptional cases:: sage: EllipticCurve('11a1').sha().an_padic(11) # rank 0 1 + O(11^22) sage: EllipticCurve('130a1').sha().an_padic(5) # rank 1 1 + O(5) Non-split, but rank 0 case (:trac:`7331`):: sage: EllipticCurve('270b1').sha().an_padic(5) # rank 0, long time (2s on sage.math, 2011) 1 + O(5^22) The output has the correct sign:: sage: EllipticCurve('123a1').sha().an_padic(41) # rank 1, long time (3s on sage.math, 2011) 1 + O(41) Supersingular cases:: sage: EllipticCurve('34a1').sha().an_padic(5) # rank 0 1 + O(5^22) sage: EllipticCurve('53a1').sha().an_padic(5) # rank 1, long time (11s on sage.math, 2011) 1 + O(5) Cases that use a twist to a lower conductor:: sage: EllipticCurve('99a1').sha().an_padic(5) 1 + O(5) sage: EllipticCurve('240d3').sha().an_padic(5) # sha has 4 elements here 4 + O(5) sage: EllipticCurve('448c5').sha().an_padic(7,prec=4, use_twists=False) # long time (2s on sage.math, 2011) 2 + 7 + O(7^6) sage: EllipticCurve([-19,34]).sha().an_padic(5) # see trac #6455, long time (4s on sage.math, 2011) 1 + O(5) Test for :trac:`15737`:: sage: E = EllipticCurve([-100,0]) sage: s = E.sha() sage: s.an_padic(13) 1 + O(13^20) """ try: return self.__an_padic[(p,prec)] except AttributeError: self.__an_padic = {} except KeyError: pass E = self.Emin tam = E.tamagawa_product() tors = E.torsion_order()**2 r = E.rank() if r > 0 : reg = E.padic_regulator(p) else: if E.is_supersingular(p): reg = vector([ Qp(p,20)(1), 0 ]) else: reg = Qp(p,20)(1) if use_twists and p > 2: Et, D = E.minimal_quadratic_twist() # trac 6455 : we have to assure that the twist back is allowed D = ZZ(D) if D % p == 0: D = ZZ(D/p) for ell in D.prime_divisors(): if ell % 2 == 1: if Et.conductor() % ell**2 == 0: D = ZZ(D/ell) ve = valuation(D,2) de = ZZ( (D/2**ve).abs() ) if de % 4 == 3: de = -de Et = E.quadratic_twist(de) # now check individually if we can twist by -1 or 2 or -2 Nmin = Et.conductor() Dmax = de for DD in [-4*de,8*de,-8*de]: Et = E.quadratic_twist(DD) if Et.conductor() < Nmin and valuation(Et.conductor(),2) <= valuation(DD,2): Nmin = Et.conductor() Dmax = DD D = Dmax Et = E.quadratic_twist(D) lp = Et.padic_lseries(p) else : lp = E.padic_lseries(p) D = 1 if r == 0 and D == 1: # short cut for rank 0 curves, we do not # to compute the p-adic L-function, the leading # term will be the L-value divided by the Neron # period. ms = E.modular_symbol(sign=+1, normalize='L_ratio') lstar = ms(0)/E.real_components() bsd = tam/tors if prec == 0: #prec = valuation(lstar/bsd, p) prec = 20 shan = Qp(p,prec=prec+2)(lstar/bsd) elif E.is_ordinary(p): K = reg.parent() lg = log(K(1+p)) if (E.is_good(p) or E.ap(p) == -1): if not E.is_good(p): eps = 2 else: eps = (1-arith.kronecker_symbol(D,p)/lp.alpha())**2 # according to the p-adic BSD this should be equal to the leading term of the p-adic L-series divided by sha: bsdp = tam * reg * eps/tors/lg**r else: r += 1 # exceptional zero eq = E.tate_curve(p) Li = eq.L_invariant() # according to the p-adic BSD (Mazur-Tate-Teitelbaum) # this should be equal to the leading term of the p-adic L-series divided by sha: bsdp = tam * reg * Li/tors/lg**r v = bsdp.valuation() if v > 0: verbose("the prime is irregular for this curve.") # determine how much prec we need to prove at least the # triviality of the p-primary part of Sha if prec == 0: n = max(v,2) bounds = lp._prec_bounds(n,r+1) while bounds[r] <= v: n += 1 bounds = lp._prec_bounds(n,r+1) verbose("set precision to %s"%n) else: n = max(2,prec) not_yet_enough_prec = True while not_yet_enough_prec: lps = lp.series(n,quadratic_twist=D,prec=r+1) lstar = lps[r] if (lstar != 0) or (prec != 0): not_yet_enough_prec = False else: n += 1 verbose("increased precision to %s"%n) shan = lstar/bsdp elif E.is_supersingular(p): K = reg[0].parent() lg = log(K(1+p)) # according to the p-adic BSD this should be equal to the leading term of the D_p - valued # L-series : bsdp = tam /tors/lg**r * reg # note this is an element in Q_p^2 verbose("the algebraic leading terms : %s"%bsdp) v = [bsdp[0].valuation(),bsdp[1].valuation()] if prec == 0: n = max(min(v)+2,3) else: n = max(3,prec) verbose("...computing the p-adic L-series") not_yet_enough_prec = True while not_yet_enough_prec: lps = lp.Dp_valued_series(n,quadratic_twist=D,prec=r+1) lstar = [lps[0][r],lps[1][r]] verbose("the leading terms : %s"%lstar) if (lstar[0] != 0 or lstar[1] != 0) or ( prec != 0): not_yet_enough_prec = False else: n += 1 verbose("increased precision to %s"%n) verbose("...putting things together") if bsdp[0] != 0: shan0 = lstar[0]/bsdp[0] else: shan0 = 0 # this should actually never happen if bsdp[1] != 0: shan1 = lstar[1]/bsdp[1] else: shan1 = 0 # this should conjecturally only happen when the rank is 0 verbose("the two values for Sha : %s"%[shan0,shan1]) # check consistency (the first two are only here to avoid a bug in the p-adic L-series # (namely the coefficients of zero-relative precision are treated as zero) if shan0 != 0 and shan1 != 0 and shan0 - shan1 != 0: raise RuntimeError("There must be a bug in the supersingular routines for the p-adic BSD.") #take the better if shan1 == 0 or shan0.precision_relative() > shan1.precision_relative(): shan = shan0 else: shan = shan1 else: raise ValueError("The curve has to have semi-stable reduction at p.") self.__an_padic[(p,prec)] = shan return shan
def _name_maker(self, names): r""" Helper function to create names of elements of algebraic structures. INPUT: Identical to the input for :class:`OperationTable` and :meth:`change_names`, so look there for details. OUTPUT: - ``width`` - an integer giving the maximum width of the strings describing the elements. This is used for formatting the ASCII version of the table. - ``name_list`` - a list of strings naming the elements, in the same order as given by the :meth:`list` method. - ``name_dict`` - a dictionary giving the correspondence between the strings and the actual elements. So the keys are the strings and the values are the elements of the structure. EXAMPLES: This routine is tested extensively in the :class:`OperationTable` and :meth:`change_names` methods. So we just demonstrate the nature of the output here. :: sage: from sage.matrix.operation_table import OperationTable sage: G=SymmetricGroup(3) sage: T=OperationTable(G, operator.mul) sage: w, l, d = T._name_maker('letters') sage: w 1 sage: l[0] 'a' sage: d['a'] () TESTS: We test the error conditions here, rather than as part of the doctests for the :class:`OperationTable` and :meth:`change_names` methods that rely on this one. :: sage: from sage.matrix.operation_table import OperationTable sage: G=AlternatingGroup(3) sage: T=OperationTable(G, operator.mul) sage: T._name_maker(['x']) Traceback (most recent call last): ... ValueError: list of element names must be the same size as the set, 1 != 3 sage: T._name_maker(['x', 'y', 4]) Traceback (most recent call last): ... ValueError: list of element names must only contain strings, not 4 sage: T._name_maker('blatzo') Traceback (most recent call last): ... ValueError: element names must be a list, or one of the keywords: 'letters', 'digits', 'elements' """ from sage.misc.functional import log name_list = [] if names == 'digits': if self._n == 0 or self._n == 1: width = 1 else: width = int(log(self._n-1,10))+1 for i in range(self._n): name_list.append('{0:0{1}d}'.format(i,width)) elif names == 'letters': from string import ascii_lowercase as letters from sage.rings.integer import Integer base = len(letters) if self._n == 0 or self._n == 1: width = 1 else: width = int(log(self._n-1,base))+1 for i in range(self._n): places = Integer(i).digits(base=base, digits=letters, padto=width) places.reverse() name_list.append(''.join(places)) elif names == 'elements': width = 0 for e in self._elts: estr = repr(e) if len(estr) > width: width = len(estr) name_list.append(estr) elif isinstance(names, list): if len(names) != self._n: raise ValueError('list of element names must be the same size as the set, %s != %s'%(len(names), self._n)) width = 0 for name in names: if not isinstance(name, str): raise ValueError('list of element names must only contain strings, not %s' % name) if len(name) > width: width = len(name) name_list.append(name) else: raise ValueError("element names must be a list, or one of the keywords: 'letters', 'digits', 'elements'") name_dict = {} for i in range(self._n): name_dict[name_list[i]]=self._elts[i] return width, name_list, name_dict
def neg_xlog2x(p): if p == 0: return 0 else: return -p*log(p,2)
def field_to_bytes(alpha, q): if q & 0x1 == 1: t = ceil(log(q, 2)) l = ceil(t / 8) return Integer_to_bytes(alpha.lift(), l)