def _load(self, path, filename): print filename i = 0 while filename[i].isalpha(): i += 1 j = len(filename) - 1 while filename[j].isalpha() or filename[j] in [".", "_"]: j -= 1 S = [eval(z) for z in filename[i:j + 1].split("-")] S.sort() data = open(path + "/" + filename).read() data = data.replace("^", "**") x = PolynomialRing(RationalField(), 'x').gen() v = eval(data) s = tuple(S) if self.root.has_key(s): self.root[s] += v self.root[s].sort() else: self.root[s] = v
def _load(self, path, filename): print(filename) i = 0 while filename[i].isalpha(): i += 1 j = len(filename) - 1 while filename[j].isalpha() or filename[j] in [".", "_"]: j -= 1 S = sorted([eval(z) for z in filename[i:j + 1].split("-")]) with open(path + "/" + filename) as f: data = f.read() data = data.replace("^", "**") x = PolynomialRing(RationalField(), 'x').gen() # used next line v = eval(data) s = tuple(S) if s in self.root: self.root[s] += v self.root[s].sort() else: self.root[s] = v
def _init(self, path): """ Create the database from scratch from the PARI files on John Jones's web page, downloaded (e.g., via wget) to a local directory, which is specified as path above. INPUT: - ``path`` - (default works on William Stein install.) path must be the path to Jones's Number_Fields directory http://hobbes.la.asu.edu/Number_Fields These files should have been downloaded using wget. EXAMPLES: This is how to create the database from scratch, assuming that the number fields are in the default directory above: From a cold start of Sage:: sage: J = JonesDatabase() sage: J._init() # not tested ... This takes about 5 seconds. """ from sage.misc.misc import sage_makedirs n = 0 x = PolynomialRing(RationalField(), 'x').gen() self.root = {} self.root[tuple([])] = [x - 1] if not os.path.exists(path): raise IOError("Path %s does not exist." % path) for X in os.listdir(path): if X[-4:] == "solo": Z = path + "/" + X print(X) for Y in os.listdir(Z): if Y[-3:] == ".gp": self._load(Z, Y) sage_makedirs(JONESDATA) save(self.root, JONESDATA + "/jones.sobj")
def ExponentialCycleIndexSeries(R=RationalField()): r""" Return the cycle index series of the species `E` of sets. This cycle index satisfies .. MATH:: Z_{E} = \sum_{n \geq 0} \sum_{\lambda \vdash n} \frac{p_{\lambda}}{z_{\lambda}}. EXAMPLES:: sage: from sage.combinat.species.generating_series import ExponentialCycleIndexSeries sage: ExponentialCycleIndexSeries().coefficients(5) [p[], p[1], 1/2*p[1, 1] + 1/2*p[2], 1/6*p[1, 1, 1] + 1/2*p[2, 1] + 1/3*p[3], 1/24*p[1, 1, 1, 1] + 1/4*p[2, 1, 1] + 1/8*p[2, 2] + 1/3*p[3, 1] + 1/4*p[4]] """ CIS = CycleIndexSeriesRing(R) return CIS(_exp_gen(R))
def __init__(self, g, weights=None, field=None, phantom_edge=None, no_symmetry=False): if g.oriented and g.is_degenerate: raise NotImplementedError( "degenerate oriented graphs not supported.") self._graph = copy(g) self._flag_cls = type(g) if weights is None: self._weights = None else: if len(weights) != g.n: raise ValueError self._weights = weights if field is None: self._field = RationalField() else: self._field = field if not phantom_edge is None: # check edge is valid; will get an Exception if not. h = copy(g) h.add_edge(phantom_edge) self._phantom_edge = phantom_edge # Only make use of symmetry when all the conditions are right... self._use_symmetry = False if field is None and weights is None and phantom_edge is None: if g.n > 4 and not no_symmetry: # Should probably allow OrientedGraphFlag if type(g) is GraphFlag or type(g) is OrientedGraphFlag: self._use_symmetry = True
def twist_values(self, s, dmin, dmax): r""" Return values of `L(E, s, \chi_d)` for each quadratic character `\chi_d` for `d_{\min} \leq d \leq d_{\max}`. .. note:: The L-series is normalized so that the center of the critical strip is 1. INPUT: - ``s`` -- complex numbers - ``dmin`` -- integer - ``dmax`` -- integer OUTPUT: - list of pairs `(d, L(E, s, \chi_d))` EXAMPLES:: sage: E = EllipticCurve('37a') sage: vals = E.lseries().twist_values(1, -12, -4) sage: vals # abs tol 1e-17 [(-11, 1.47824342), (-8, 8.9590946e-18), (-7, 1.85307619), (-4, 2.45138938)] sage: F = E.quadratic_twist(-8) sage: F.rank() 1 sage: F = E.quadratic_twist(-7) sage: F.rank() 0 """ from sage.lfunctions.lcalc import lcalc return lcalc.twist_values(s - RationalField()('1/2'), dmin, dmax, L=self.__E)
def _cl_term(n, R = RationalField()): r""" Compute the order-n term of the cycle index series of the virtual species `\Omega`, the compositional inverse of the species `E^{+}` of nonempty sets. EXAMPLES:: sage: from sage.combinat.species.generating_series import _cl_term sage: [_cl_term(i) for i in range(4)] [0, p[1], -1/2*p[1, 1] - 1/2*p[2], 1/3*p[1, 1, 1] - 1/3*p[3]] """ n = Integer(n) # check that n is an integer p = SymmetricFunctions(R).power() res = p.zero() if n == 1: res = p([1]) elif n > 1: res = 1/n * ((-1)**(n-1) * p([1])**n - sum(d * p([n // d]).plethysm(_cl_term(d, R)) for d in divisors(n)[:-1])) return res
def _change_basis(self,x): v = x.parts() tmp = self._changebasismatrix * Matrix(RationalField(),2,1,v) return tmp[0,0],tmp[1,0]
def L_ratio(self): r""" Returns the ratio `L(E,1)/\Omega` as an exact rational number. The result is \emph{provably} correct if the Manin constant of the associated optimal quotient is `\leq 2`. This hypothesis on the Manin constant is true for all semistable curves (i.e., squarefree conductor), by a theorem of Mazur from his \emph{Rational Isogenies of Prime Degree} paper. EXAMPLES:: sage: E = EllipticCurve([0, -1, 1, -10, -20]) # 11A = X_0(11) sage: E.lseries().L_ratio() 1/5 sage: E = EllipticCurve([0, -1, 1, 0, 0]) # X_1(11) sage: E.lseries().L_ratio() 1/25 sage: E = EllipticCurve([0, 0, 1, -1, 0]) # 37A (rank 1) sage: E.lseries().L_ratio() 0 sage: E = EllipticCurve([0, 1, 1, -2, 0]) # 389A (rank 2) sage: E.lseries().L_ratio() 0 sage: E = EllipticCurve([0, 0, 1, -38, 90]) # 361A (CM curve)) sage: E.lseries().L_ratio() 0 sage: E = EllipticCurve([0,-1,1,-2,-1]) # 141C (13-isogeny) sage: E.lseries().L_ratio() 1 sage: E = EllipticCurve(RationalField(), [1, 0, 0, 1/24624, 1/886464]) sage: E.lseries().L_ratio() 2 See :trac:`3651` and :trac:`15299`:: sage: EllipticCurve([0,0,0,-193^2,0]).sha().an() 4 sage: EllipticCurve([1, 0, 1, -131, 558]).sha().an() # long time 1.00000000000000 ALGORITHM: Compute the root number. If it is -1 then L(E,s) vanishes to odd order at 1, hence vanishes. If it is +1, use a result about modular symbols and Mazur's "Rational Isogenies" paper to determine a provably correct bound (assuming Manin constant is <= 2) so that we can determine whether L(E,1) = 0. AUTHOR: William Stein, 2005-04-20. """ try: return self.__lratio except AttributeError: pass if not self.__E.is_minimal(): self.__lratio = self.__E.minimal_model().lseries().L_ratio() return self.__lratio QQ = RationalField() if self.__E.root_number() == -1: self.__lratio = QQ.zero() return self.__lratio # Even root number. Decide if L(E,1) = 0. If E is a modular # *OPTIMAL* quotient of J_0(N) elliptic curve, we know that T * # L(E,1)/omega is an integer n, where T is the order of the # image of the rational torsion point (0)-(oo) in E(Q), and # omega is the least real Neron period. (This is proved in my # Ph.D. thesis, but is probably well known.) We can easily # compute omega to very high precision using AGM. So to prove # that L(E,1) = 0 we compute T/omega * L(E,1) to sufficient # precision to determine it as an integer. If eps is the # error in computation of L(E,1), then the error in computing # the product is (2T/Omega_E) * eps, and we need this to be # less than 0.5, i.e., # (2T/Omega_E) * eps < 0.5, # so # eps < 0.5 * Omega_E / (2T) = Omega_E / (4*T). # # Since in general E need not be optimal, we have to choose # eps = Omega_E/(8*t*B), where t is the exponent of E(Q)_tor, # and is a multiple of the degree of an isogeny between E # and the optimal curve. # # NOTES: We *do* have to worry about the Manin constant, since # we are using the Neron model to compute omega, not the # newform. My theorem replaces the omega above by omega/c, # where c is the Manin constant, and the bound must be # correspondingly smaller. If the level is square free, then # the Manin constant is 1 or 2, so there's no problem (since # we took 8 instead of 4 in the denominator). If the level # is divisible by a square, then the Manin constant could # be a divisible by an arbitrary power of that prime, except # that Edixhoven claims the primes that appear are <= 7. t = self.__E.torsion_subgroup().order() omega = self.__E.period_lattice().basis()[0] d = self.__E._multiple_of_degree_of_isogeny_to_optimal_curve() C = 8*d*t eps = omega / C sqrtN = 2*int(sqrt(self.__E.conductor())) k = sqrtN + 10 while True: L1, error_bound = self.at1(k) if error_bound < eps: n = int(round(L1*C/omega)) quo = QQ((n,C)) self.__lratio = quo / self.__E.real_components() return self.__lratio k += sqrtN misc.verbose("Increasing precision to %s terms."%k)
def sage(self, var="x", base_field=RationalField()): from sage.rings.all import PolynomialRing, QQ, Integer PP = PolynomialRing(QQ, var) return PP([Integer(val) for val in self])
def sage(self, var="x", base_field=RationalField()): from sage.rings.all import PolynomialRing, QQ PP = PolynomialRing(QQ, var) return PP(self)
def __init__(self): self._field = RationalField() self._flag_cls = None
def __init__(self, variant=False): self._variant = variant self._field = RationalField() self._flag_cls = ThreeGraphFlag
def coleman_integrals_on_basis(self, P, Q, algorithm=None): r""" Computes the Coleman integrals `\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}` INPUT: - P point on self - Q point on self - algorithm (optional) = None (uses Frobenius) or teichmuller (uses Teichmuller points) OUTPUT: the Coleman integrals `\{\int_P^Q x^i dx/2y \}_{i=0}^{2g-1}` EXAMPLES:: sage: K = pAdicField(11, 5) sage: x = polygen(K) sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16) sage: P = C.lift_x(2) sage: Q = C.lift_x(3) sage: C.coleman_integrals_on_basis(P, Q) (10*11 + 6*11^3 + 2*11^4 + O(11^5), 11 + 9*11^2 + 7*11^3 + 9*11^4 + O(11^5), 3 + 10*11 + 5*11^2 + 9*11^3 + 4*11^4 + O(11^5), 3 + 11 + 5*11^2 + 4*11^4 + O(11^5)) sage: C.coleman_integrals_on_basis(P, Q, algorithm='teichmuller') (10*11 + 6*11^3 + 2*11^4 + O(11^5), 11 + 9*11^2 + 7*11^3 + 9*11^4 + O(11^5), 3 + 10*11 + 5*11^2 + 9*11^3 + 4*11^4 + O(11^5), 3 + 11 + 5*11^2 + 4*11^4 + O(11^5)) :: sage: K = pAdicField(11,5) sage: x = polygen(K) sage: C = HyperellipticCurve(x^5 + 33/16*x^4 + 3/4*x^3 + 3/8*x^2 - 1/4*x + 1/16) sage: P = C.lift_x(11^(-2)) sage: Q = C.lift_x(3*11^(-2)) sage: C.coleman_integrals_on_basis(P, Q) (3*11^3 + 7*11^4 + 4*11^5 + 7*11^6 + 5*11^7 + O(11^8), 3*11 + 10*11^2 + 8*11^3 + 9*11^4 + 7*11^5 + O(11^6), 4*11^-1 + 2 + 6*11 + 6*11^2 + 7*11^3 + O(11^4), 11^-3 + 6*11^-2 + 2*11^-1 + 2 + O(11^2)) :: sage: R = C(0,1/4) sage: a = C.coleman_integrals_on_basis(P,R) # long time (7s on sage.math, 2011) sage: b = C.coleman_integrals_on_basis(R,Q) # long time (9s on sage.math, 2011) sage: c = C.coleman_integrals_on_basis(P,Q) # long time sage: a+b == c # long time True :: sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^3-10*x+9) sage: K = Qp(5,8) sage: HK = H.change_ring(K) sage: S = HK(1,0) sage: P = HK(0,3) sage: T = HK(0,1,0) sage: Q = HK.lift_x(5^-2) sage: R = HK.lift_x(4*5^-2) sage: HK.coleman_integrals_on_basis(S,P) (2*5^2 + 5^4 + 5^5 + 3*5^6 + 3*5^7 + 2*5^8 + O(5^9), 5 + 2*5^2 + 4*5^3 + 2*5^4 + 3*5^6 + 4*5^7 + 2*5^8 + O(5^9)) sage: HK.coleman_integrals_on_basis(T,P) (2*5^2 + 5^4 + 5^5 + 3*5^6 + 3*5^7 + 2*5^8 + O(5^9), 5 + 2*5^2 + 4*5^3 + 2*5^4 + 3*5^6 + 4*5^7 + 2*5^8 + O(5^9)) sage: HK.coleman_integrals_on_basis(P,S) == -HK.coleman_integrals_on_basis(S,P) True sage: HK.coleman_integrals_on_basis(S,Q) (4*5 + 4*5^2 + 4*5^3 + O(5^4), 5^-1 + O(5^3)) sage: HK.coleman_integrals_on_basis(Q,R) (4*5 + 2*5^2 + 2*5^3 + 2*5^4 + 5^5 + 5^6 + 5^7 + 3*5^8 + O(5^9), 2*5^-1 + 4 + 4*5 + 4*5^2 + 4*5^3 + 2*5^4 + 3*5^5 + 2*5^6 + O(5^7)) sage: HK.coleman_integrals_on_basis(S,R) == HK.coleman_integrals_on_basis(S,Q) + HK.coleman_integrals_on_basis(Q,R) True sage: HK.coleman_integrals_on_basis(T,T) (0, 0) sage: HK.coleman_integrals_on_basis(S,T) (0, 0) AUTHORS: - Robert Bradshaw (2007-03): non-Weierstrass points - Jennifer Balakrishnan and Robert Bradshaw (2010-02): Weierstrass points """ import sage.schemes.hyperelliptic_curves.monsky_washnitzer as monsky_washnitzer from sage.misc.profiler import Profiler prof = Profiler() prof("setup") K = self.base_ring() p = K.prime() prec = K.precision_cap() g = self.genus() dim = 2 * g V = VectorSpace(K, dim) #if P or Q is Weierstrass, use the Frobenius algorithm if self.is_weierstrass(P): if self.is_weierstrass(Q): return V(0) else: PP = None QQ = Q TP = None TQ = self.frobenius(Q) elif self.is_weierstrass(Q): PP = P QQ = None TQ = None TP = self.frobenius(P) elif self.is_same_disc(P, Q): return self.tiny_integrals_on_basis(P, Q) elif algorithm == 'teichmuller': prof("teichmuller") PP = TP = self.teichmuller(P) QQ = TQ = self.teichmuller(Q) evalP, evalQ = TP, TQ else: prof("frobPQ") TP = self.frobenius(P) TQ = self.frobenius(Q) PP, QQ = P, Q prof("tiny integrals") if TP is None: P_to_TP = V(0) else: if TP is not None: TPv = (TP[0]**g / TP[1]).valuation() xTPv = TP[0].valuation() else: xTPv = TPv = +Infinity if TQ is not None: TQv = (TQ[0]**g / TQ[1]).valuation() xTQv = TQ[0].valuation() else: xTQv = TQv = +Infinity offset = (2 * g - 1) * max(TPv, TQv) if offset == +Infinity: offset = (2 * g - 1) * min(TPv, TQv) if (offset > prec and (xTPv < 0 or xTQv < 0) and (self.residue_disc(P) == self.change_ring(GF(p))(0, 1, 0) or self.residue_disc(Q) == self.change_ring(GF(p))(0, 1, 0))): newprec = offset + prec K = pAdicField(p, newprec) A = PolynomialRing(RationalField(), 'x') f = A(self.hyperelliptic_polynomials()[0]) from sage.schemes.hyperelliptic_curves.constructor import HyperellipticCurve self = HyperellipticCurve(f).change_ring(K) xP = P[0] xPv = xP.valuation() xPnew = K( sum(c * p**(xPv + i) for i, c in enumerate(xP.expansion()))) PP = P = self.lift_x(xPnew) TP = self.frobenius(P) xQ = Q[0] xQv = xQ.valuation() xQnew = K( sum(c * p**(xQv + i) for i, c in enumerate(xQ.expansion()))) QQ = Q = self.lift_x(xQnew) TQ = self.frobenius(Q) V = VectorSpace(K, dim) P_to_TP = V(self.tiny_integrals_on_basis(P, TP)) if TQ is None: TQ_to_Q = V(0) else: TQ_to_Q = V(self.tiny_integrals_on_basis(TQ, Q)) prof("mw calc") try: M_frob, forms = self._frob_calc except AttributeError: M_frob, forms = self._frob_calc = monsky_washnitzer.matrix_of_frobenius_hyperelliptic( self) prof("eval f") R = forms[0].base_ring() try: prof("eval f %s" % R) if PP is None: L = [-f(R(QQ[0]), R(QQ[1])) for f in forms] ##changed elif QQ is None: L = [f(R(PP[0]), R(PP[1])) for f in forms] else: L = [ f(R(PP[0]), R(PP[1])) - f(R(QQ[0]), R(QQ[1])) for f in forms ] except ValueError: prof("changing rings") forms = [f.change_ring(self.base_ring()) for f in forms] prof("eval f %s" % self.base_ring()) if PP is None: L = [-f(QQ[0], QQ[1]) for f in forms] ##changed elif QQ is None: L = [f(PP[0], PP[1]) for f in forms] else: L = [f(PP[0], PP[1]) - f(QQ[0], QQ[1]) for f in forms] b = V(L) if PP is None: b -= TQ_to_Q elif QQ is None: b -= P_to_TP elif algorithm != 'teichmuller': b -= P_to_TP + TQ_to_Q prof("lin alg") M_sys = matrix(K, M_frob).transpose() - 1 TP_to_TQ = M_sys**(-1) * b prof("done") # print prof if algorithm == 'teichmuller': return P_to_TP + TP_to_TQ + TQ_to_Q else: return TP_to_TQ
def __init__(self, E, algorithm=None): r""" Initialization function for EllipticCurveTorsionSubgroup class INPUT: - ``E`` - An elliptic curve defined over a number field (including `\Q`) - ``algorithm`` - (string, default None): If not None, must be one of 'PARI', 'doud', 'lutz_nagell'. For curves defined over `\QQ`, PARI is then used with the appropriate flag passed to PARI's ``elltors()`` function; this parameter is ignored for curves whose base field is not `\QQ`. EXAMPLES:: sage: from sage.schemes.elliptic_curves.ell_torsion import EllipticCurveTorsionSubgroup sage: E=EllipticCurve('11a1') sage: K.<i>=NumberField(x^2+1) sage: EK=E.change_ring(K) sage: EllipticCurveTorsionSubgroup(EK) Torsion Subgroup isomorphic to Z/5 associated to the Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Number Field in i with defining polynomial x^2 + 1 Note: this class is normally constructed indirectly as follows:: sage: T = EK.torsion_subgroup(); T Torsion Subgroup isomorphic to Z/5 associated to the Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Number Field in i with defining polynomial x^2 + 1 sage: type(T) <class 'sage.schemes.elliptic_curves.ell_torsion.EllipticCurveTorsionSubgroup_with_category'> sage: T == loads(dumps(T)) # optional - pickling http://trac.sagemath.org/sage_trac/ticket/11599 True """ self.__E = E self.__K = E.base_field() pari_torsion_algorithms = ["pari", "doud", "lutz_nagell"] if self.__K is RationalField( ) and algorithm in pari_torsion_algorithms: flag = pari_torsion_algorithms.index(algorithm) G = None loop = 0 while G is None and loop < 3: loop += 1 try: G = self.__E.pari_curve(prec=400).elltors( flag ) # pari_curve will return the curve of maximum known precision except RuntimeError: self.__E.pari_curve( factor=2) # caches a curve of twice the precision if G is not None: order = G[0].python() structure = G[1].python() gens = G[2].python() self.__torsion_gens = [self.__E(P) for P in gens] from sage.groups.additive_abelian.additive_abelian_group import cover_and_relations_from_invariants groups.AdditiveAbelianGroupWrapper.__init__( self, self.__E(0).parent(), self.__torsion_gens, structure) return T1 = E(0) # these will be the two generators T2 = E(0) k1 = 1 # with their order k2 = 1 # find a multiple of the order of the torsion group bound = E._torsion_bound(number_of_places=20) # now do prime by prime for p, e in bound.factor(): ptor = E._p_primary_torsion_basis(p, e) # print p,'-primary part is ',ptor if len(ptor) > 0: T1 += ptor[0][0] k1 *= p**(ptor[0][1]) if len(ptor) > 1: T2 += ptor[1][0] k2 *= p**(ptor[1][1]) order = k1 * k2 if k1 == 1: structure = [] gens = [] elif k2 == 1: structure = [k1] gens = [T1] else: structure = [k1, k2] gens = [T1, T2] #self.__torsion_gens = gens self._structure = structure groups.AdditiveAbelianGroupWrapper.__init__(self, T1.parent(), [T1, T2], structure)
def L_ratio(self): r""" Returns the ratio `L(E,1)/\Omega` as an exact rational number. The result is *provably* correct if the Manin constant of the associated optimal quotient is `\leq 2`. This hypothesis on the Manin constant is true for all semistable curves (i.e., squarefree conductor), by a theorem of Mazur from his *Rational Isogenies of Prime Degree* paper. EXAMPLES:: sage: E = EllipticCurve([0, -1, 1, -10, -20]) # 11A = X_0(11) sage: E.lseries().L_ratio() 1/5 sage: E = EllipticCurve([0, -1, 1, 0, 0]) # X_1(11) sage: E.lseries().L_ratio() 1/25 sage: E = EllipticCurve([0, 0, 1, -1, 0]) # 37A (rank 1) sage: E.lseries().L_ratio() 0 sage: E = EllipticCurve([0, 1, 1, -2, 0]) # 389A (rank 2) sage: E.lseries().L_ratio() 0 sage: E = EllipticCurve([0, 0, 1, -38, 90]) # 361A (CM curve)) sage: E.lseries().L_ratio() 0 sage: E = EllipticCurve([0,-1,1,-2,-1]) # 141C (13-isogeny) sage: E.lseries().L_ratio() 1 sage: E = EllipticCurve(RationalField(), [1, 0, 0, 1/24624, 1/886464]) sage: E.lseries().L_ratio() 2 See :trac:`3651` and :trac:`15299`:: sage: EllipticCurve([0,0,0,-193^2,0]).sha().an() 4 sage: EllipticCurve([1, 0, 1, -131, 558]).sha().an() # long time 1.00000000000000 ALGORITHM: Compute the root number. If it is -1 then `L(E,s)` vanishes to odd order at 1, hence vanishes. If it is +1, use a result about modular symbols and Mazur's *Rational Isogenies* paper to determine a provably correct bound (assuming Manin constant is <= 2) so that we can determine whether `L(E,1) = 0`. AUTHOR: William Stein, 2005-04-20. """ try: return self.__lratio except AttributeError: pass if not self.__E.is_minimal(): self.__lratio = self.__E.minimal_model().lseries().L_ratio() return self.__lratio QQ = RationalField() if self.__E.root_number() == -1: self.__lratio = QQ.zero() return self.__lratio # Even root number. Decide if L(E,1) = 0. If E is a modular # *OPTIMAL* quotient of J_0(N) elliptic curve, we know that T * # L(E,1)/omega is an integer n, where T is the order of the # image of the rational torsion point (0)-(oo) in E(Q), and # omega is the least real Neron period. (This is proved in my # Ph.D. thesis, but is probably well known.) We can easily # compute omega to very high precision using AGM. So to prove # that L(E,1) = 0 we compute T/omega * L(E,1) to sufficient # precision to determine it as an integer. If eps is the # error in computation of L(E,1), then the error in computing # the product is (2T/Omega_E) * eps, and we need this to be # less than 0.5, i.e., # (2T/Omega_E) * eps < 0.5, # so # eps < 0.5 * Omega_E / (2T) = Omega_E / (4*T). # # Since in general E need not be optimal, we have to choose # eps = Omega_E/(8*t*B), where t is the exponent of E(Q)_tor, # and is a multiple of the degree of an isogeny between E # and the optimal curve. # # NOTES: We *do* have to worry about the Manin constant, since # we are using the Neron model to compute omega, not the # newform. My theorem replaces the omega above by omega/c, # where c is the Manin constant, and the bound must be # correspondingly smaller. If the level is square free, then # the Manin constant is 1 or 2, so there's no problem (since # we took 8 instead of 4 in the denominator). If the level # is divisible by a square, then the Manin constant could # be a divisible by an arbitrary power of that prime, except # that Edixhoven claims the primes that appear are <= 7. t = self.__E.torsion_subgroup().order() omega = self.__E.period_lattice().basis()[0] d = self.__E._multiple_of_degree_of_isogeny_to_optimal_curve() C = 8 * d * t eps = omega / C sqrtN = 2 * int(sqrt(self.__E.conductor())) k = sqrtN + 10 while True: L1, error_bound = self.at1(k) if error_bound < eps: n = int(round(L1 * C / omega)) quo = QQ((n, C)) self.__lratio = quo / self.__E.real_components() return self.__lratio k += sqrtN misc.verbose("Increasing precision to %s terms." % k)
def __init__(self): self._field = RationalField() self._flag_cls = ThreeGraphFlag
from sage.structure.sage_object import SageObject from sage.rings.all import ( Integer, RealField, RationalField, RIF, ZZ) from sage.misc.functional import log from math import sqrt from sage.misc.all import verbose import sage.rings.arith as arith from sage.rings.padics.factory import Qp factor = arith.factor valuation = arith.valuation Q = RationalField() class Sha(SageObject): r""" The Tate-Shafarevich group associated to an elliptic curve. If `E` is an elliptic curve over a global field `K`, the Tate-Shafarevich group is the subgroup of elements in `H^1(K,E)` which map to zero under every global-to-local restriction map `H^1(K,E) \to H^1(K_v,E)`, one for each place `v` of `K`. EXAMPLES:: sage: E = EllipticCurve('571a1') sage: E._set_gens([]) sage: S = E.sha()
def __init__(self, E): r""" Initialization function for EllipticCurveTorsionSubgroup class INPUT: - ``E`` - An elliptic curve defined over a number field (including `\Q`) EXAMPLES:: sage: from sage.schemes.elliptic_curves.ell_torsion import EllipticCurveTorsionSubgroup sage: E = EllipticCurve('11a1') sage: K.<i> = NumberField(x^2+1) sage: EK = E.change_ring(K) sage: EllipticCurveTorsionSubgroup(EK) Torsion Subgroup isomorphic to Z/5 associated to the Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Number Field in i with defining polynomial x^2 + 1 Note: this class is normally constructed indirectly as follows:: sage: T = EK.torsion_subgroup(); T Torsion Subgroup isomorphic to Z/5 associated to the Elliptic Curve defined by y^2 + y = x^3 + (-1)*x^2 + (-10)*x + (-20) over Number Field in i with defining polynomial x^2 + 1 sage: type(T) <class 'sage.schemes.elliptic_curves.ell_torsion.EllipticCurveTorsionSubgroup_with_category'> sage: T == loads(dumps(T)) # known bug, see http://trac.sagemath.org/sage_trac/ticket/11599#comment:7 True """ self.__E = E self.__K = E.base_field() if self.__K is RationalField(): G = self.__E.pari_curve().elltors() structure = G[1].sage() gens = G[2].sage() self.__torsion_gens = [self.__E(P) for P in gens] groups.AdditiveAbelianGroupWrapper.__init__( self, self.__E(0).parent(), self.__torsion_gens, structure) return T1 = E(0) # these will be the two generators T2 = E(0) k1 = 1 # with their order k2 = 1 # find a multiple of the order of the torsion group bound = torsion_bound(E, number_of_places=20) # now do prime by prime for p, e in bound.factor(): ptor = E._p_primary_torsion_basis(p, e) if ptor: T1 += ptor[0][0] k1 *= p**(ptor[0][1]) if len(ptor) > 1: T2 += ptor[1][0] k2 *= p**(ptor[1][1]) if k1 == 1: structure = [] gens = [] elif k2 == 1: structure = [k1] gens = [T1] else: structure = [k1, k2] gens = [T1, T2] #self.__torsion_gens = gens self._structure = structure groups.AdditiveAbelianGroupWrapper.__init__(self, T1.parent(), [T1, T2], structure)
def torsion_bound(E, number_of_places=20): r""" Return an upper bound on the order of the torsion subgroup. INPUT: - ``E`` -- an elliptic curve over `\QQ` or a number field - ``number_of_places`` (positive integer, default = 20) -- the number of places that will be used to find the bound OUTPUT: (integer) An upper bound on the torsion order. ALGORITHM: An upper bound on the order of the torsion group of the elliptic curve is obtained by counting points modulo several primes of good reduction. Note that the upper bound returned by this function is a multiple of the order of the torsion group, and in general will be greater than the order. To avoid nontrivial arithmetic in the base field (in particular, to avoid having to compute the maximal order) we only use prime `P` above rational primes `p` which do not divide the discriminant of the equation order. EXAMPLES:: sage: CDB = CremonaDatabase() sage: from sage.schemes.elliptic_curves.ell_torsion import torsion_bound sage: [torsion_bound(E) for E in CDB.iter([14])] [6, 6, 6, 6, 6, 6] sage: [E.torsion_order() for E in CDB.iter([14])] [6, 6, 2, 6, 2, 6] An example over a relative number field (see :trac:`16011`):: sage: R.<x> = QQ[] sage: F.<a> = QuadraticField(5) sage: K.<b> = F.extension(x^2-3) sage: E = EllipticCurve(K,[0,0,0,b,1]) sage: E.torsion_subgroup().order() 1 An example of a base-change curve from `\QQ` to a degree 16 field:: sage: from sage.schemes.elliptic_curves.ell_torsion import torsion_bound sage: f = PolynomialRing(QQ,'x')([5643417737593488384,0, ....: -11114515801179776,0,-455989850911004,0,379781901872, ....: 0,14339154953,0,-1564048,0,-194542,0,-32,0,1]) sage: K = NumberField(f,'a') sage: E = EllipticCurve(K, [1, -1, 1, 824579, 245512517]) sage: torsion_bound(E) 16 sage: E.torsion_subgroup().invariants() (4, 4) """ from sage.rings.all import ZZ, GF from sage.schemes.elliptic_curves.constructor import EllipticCurve K = E.base_field() # Special case K = QQ if K is RationalField(): bound = ZZ.zero() k = 0 p = ZZ(2) # so we start with 3 E = E.integral_model() disc_E = E.discriminant() while k < number_of_places: p = p.next_prime() if p.divides(disc_E): continue k += 1 Fp = GF(p) new_bound = E.reduction(p).cardinality() bound = bound.gcd(new_bound) if bound == 1: return bound return bound # In case K is a relative extension we absolutize: absK = K.absolute_field('a_') f = absK.defining_polynomial() abs_map = absK.structure()[1] # Ensure f is monic and in ZZ[x] f = f.monic() den = f.denominator() if den != 1: x = f.parent().gen() n = f.degree() f = den**n * f(x / den) disc_f = f.discriminant() d = K.absolute_degree() # Now f is monic in ZZ[x] of degree d and defines the extension K = Q(a) # Make sure that we have a model for E with coefficients in ZZ[a] E = E.integral_model() disc_E = E.discriminant().norm() ainvs = [abs_map(c) for c in E.a_invariants()] bound = ZZ.zero() k = 0 p = ZZ(2) # so we start with 3 try: # special case, useful for base-changes from QQ ainvs = [ZZ(ai) for ai in ainvs] while k < number_of_places: p = p.next_prime() if p.divides(disc_E) or p.divides(disc_f): continue k += 1 for fi, ei in f.factor_mod(p): di = fi.degree() Fp = GF(p) new_bound = EllipticCurve( Fp, ainvs).cardinality(extension_degree=di) bound = bound.gcd(new_bound) if bound == 1: return bound return bound except (ValueError, TypeError): pass # General case while k < number_of_places: p = p.next_prime() if p.divides(disc_E) or p.divides(disc_f): continue k += 1 for fi, ei in f.factor_mod(p): di = fi.degree() Fq = GF(p**di) ai = fi.roots(Fq, multiplicities=False)[0] def red(c): return Fq.sum(Fq(c[j]) * ai**j for j in range(d)) new_bound = EllipticCurve([red(c) for c in ainvs]).cardinality() bound = bound.gcd(new_bound) if bound == 1: return bound return bound
def _change_basis(self,x): v=x.parts() tmp=self._changebasismatrix*Matrix(RationalField(),_sage_const_2 ,_sage_const_1 ,v) return tmp[_sage_const_0 ,_sage_const_0 ],tmp[_sage_const_1 ,_sage_const_0 ]