Path: blob/master/src/sage/schemes/elliptic_curves/ell_modular_symbols.py
8820 views
# -*- coding: utf-8 -*-1r"""2Modular symbols34To an elliptic curves `E` over the rational numbers one can associate5a space - or better two spaces - of modular symbols of level `N`,6equal to the conductor of `E`; because `E` is known to be modular.78There are two implementations of modular symbols, one within ``sage``9and the other as part of Cremona's ``eclib``. One can choose here which10one is used.1112The normalisation of our modular symbols attached to `E` can be chosen, too.13For instance one can make it depended on `E` rather than on its14isogeny class. This is useful for `p`-adic L-functions.1516For more details on modular symbols consult the following1718REFERENCES:1920- [MTT] B. Mazur, J. Tate, and J. Teitelbaum,21On `p`-adic analogues of the conjectures of Birch and22Swinnerton-Dyer, Inventiones mathematicae 84, (1986), 1-48.2324- [Cre] John Cremona, Algorithms for modular elliptic curves,25Cambridge University Press, 1997.2627- [SW] William Stein and Christian Wuthrich, Computations About Tate-Shafarevich Groups28using Iwasawa theory, preprint 2009.2930AUTHORS:3132- William Stein (2007): first version3334- Chris Wuthrich (2008): add scaling and reference to eclib3536"""3738#*****************************************************************************39# Copyright (C) 2007 William Stein <[email protected]>40#41# Distributed under the terms of the GNU General Public License (GPL)42#43# This code is distributed in the hope that it will be useful,44# but WITHOUT ANY WARRANTY; without even the implied warranty of45# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU46# General Public License for more details.47#48# The full text of the GPL is available at:49#50# http://www.gnu.org/licenses/51#*****************************************************************************5253from sage.structure.sage_object import SageObject54from sage.modular.modsym.all import ModularSymbols55from sage.libs.cremona.newforms import ECModularSymbol56from sage.databases.cremona import parse_cremona_label5758from sage.rings.arith import next_prime, kronecker_symbol, prime_divisors, valuation59from sage.rings.infinity import unsigned_infinity as infinity60from sage.rings.integer import Integer61from sage.modular.cusps import Cusps62from sage.rings.integer_ring import ZZ63from sage.rings.rational_field import QQ64from sage.misc.all import verbose6566from sage.schemes.elliptic_curves.constructor import EllipticCurve6768oo = Cusps(infinity)69zero = Integer(0)7071def modular_symbol_space(E, sign, base_ring, bound=None):72r"""73Creates the space of modular symbols of a given sign over a give base_ring,74attached to the isogeny class of elliptic curves.7576INPUT:7778- ``E`` - an elliptic curve over `\QQ`79- ``sign`` - integer, -1, 0, or 180- ``base_ring`` - ring81- ``bound`` - (default: None) maximum number of Hecke operators to82use to cut out modular symbols factor. If None, use83enough to provably get the correct answer.8485OUTPUT: a space of modular symbols8687EXAMPLES::8889sage: import sage.schemes.elliptic_curves.ell_modular_symbols90sage: E=EllipticCurve('11a1')91sage: M=sage.schemes.elliptic_curves.ell_modular_symbols.modular_symbol_space(E,-1,GF(37))92sage: M93Modular Symbols space of dimension 1 for Gamma_0(11) of weight 2 with sign -1 over Finite Field of size 379495"""96_sign = int(sign)97if _sign != sign:98raise TypeError, 'sign must be an integer'99if not (_sign in [-1,0,1]):100raise TypeError, 'sign must -1, 0, or 1'101N = E.conductor()102M = ModularSymbols(N, sign=sign, base_ring=base_ring)103if bound is None:104bound = M.hecke_bound() + 10105V = M106p = 2107while p <= bound and V.dimension() > 1:108t = V.T(p)109ap = E.ap(p)110V = (t - ap).kernel()111p = next_prime(p)112113return V114115class ModularSymbol(SageObject):116r"""117A modular symbol attached to an elliptic curve, which is the map118`\QQ\to \QQ` obtained by sending `r` to the normalized119symmetrized (or anti-symmetrized) integral from `r` to `\infty`.120121This is as defined in [MTT], but normalized122to depend on the curve and not only its isogeny class as in [SW].123124See the documentation of ``E.modular_symbol()`` in125Elliptic curves over the rational numbers126for help.127128REFERENCES:129130- [MTT] B. Mazur, J. Tate, and J. Teitelbaum,131On `p`-adic analogues of the conjectures of Birch and132Swinnerton-Dyer, Inventiones mathematicae 84, (1986), 1-48.133134- [SW] William Stein and Christian Wuthrich, Computations About Tate-Shafarevich Groups135using Iwasawa theory, preprint 2009.136137"""138139def sign(self):140r"""141Return the sign of this elliptic curve modular symbol.142143EXAMPLES::144145sage: m = EllipticCurve('11a1').modular_symbol()146sage: m.sign()1471148sage: m = EllipticCurve('11a1').modular_symbol(sign=-1)149sage: m.sign()150-1151"""152153return self._sign154155def elliptic_curve(self):156r"""157Return the elliptic curve of this modular symbol.158159EXAMPLES::160161sage: m = EllipticCurve('11a1').modular_symbol()162sage: m.elliptic_curve()163Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field164165"""166return self._E167168def base_ring(self):169r"""170Return the base ring for this modular symbol.171172EXAMPLES::173174sage: m = EllipticCurve('11a1').modular_symbol()175sage: m.base_ring()176Rational Field177"""178return self._base_ring179180def _repr_(self):181r"""182String representation of modular symbols.183184EXAMPLES::185186sage: m = EllipticCurve('11a1').modular_symbol(use_eclib=True)187sage: m188Modular symbol with sign 1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field189sage: m = EllipticCurve('43a1').modular_symbol(sign=-1)190sage: m191Modular symbol with sign -1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 + x^2 over Rational Field192"""193return "Modular symbol with sign %s over %s attached to %s"%(194self._sign, self._base_ring, self._E)195196def _find_scaling_L_ratio(self):197r"""198This function is use to set ``_scaling``, the factor used to adjust the199scalar multiple of the modular symbol.200If `[0]`, the modular symbol evaluated at 0, is non-zero, we can just scale201it with respect to the approximation of the L-value. It is known that202the quotient is a rational number with small denominator.203Otherwise we try to scale using quadratic twists.204205``_scaling`` will be set to a rational non-zero multiple if we succeed and to 1 otherwise.206Even if we fail we scale at least to make up the difference between the periods207of the `X_0`-optimal curve and our given curve `E` in the isogeny class.208209EXAMPLES::210211sage : m = EllipticCurve('11a1').modular_symbol(use_eclib=True)212sage : m._scaling2131214sage: m = EllipticCurve('11a2').modular_symbol(use_eclib=True)215sage: m._scaling2165/2217sage: m = EllipticCurve('11a3').modular_symbol(use_eclib=True)218sage: m._scaling2191/10220sage: m = EllipticCurve('11a1').modular_symbol(use_eclib=False)221sage: m._scaling2221/5223sage: m = EllipticCurve('11a2').modular_symbol(use_eclib=False)224sage: m._scaling2251226sage: m = EllipticCurve('11a3').modular_symbol(use_eclib=False)227sage: m._scaling2281/25229sage: m = EllipticCurve('37a1').modular_symbol(use_eclib=False)230sage: m._scaling2311232sage: m = EllipticCurve('37a1').modular_symbol(use_eclib=True)233sage: m._scaling234-1235sage: m = EllipticCurve('389a1').modular_symbol(use_eclib=True)236sage: m._scaling237-1/2238sage: m = EllipticCurve('389a1').modular_symbol(use_eclib=False)239sage: m._scaling2402241sage: m = EllipticCurve('196a1').modular_symbol(use_eclib=False)242sage: m._scaling2431/2244245Some harder cases fail::246247sage: m = EllipticCurve('121b1').modular_symbol(use_eclib=False)248Warning : Could not normalize the modular symbols, maybe all further results will be multiplied by -1, 2 or -2.249sage: m._scaling2501251252TESTS::253254sage: rk0 = ['11a1', '11a2', '15a1', '27a1', '37b1']255sage: for la in rk0: # long time (3s on sage.math, 2011)256... E = EllipticCurve(la)257... me = E.modular_symbol(use_eclib = True)258... ms = E.modular_symbol(use_eclib = False)259... print E.lseries().L_ratio()*E.real_components(), me(0), ms(0)2601/5 1/5 1/52611 1 12621/4 1/4 1/42631/3 1/3 1/32642/3 2/3 2/3265266sage: rk1 = ['37a1','43a1','53a1', '91b1','91b2','91b3']267sage: [EllipticCurve(la).modular_symbol(use_eclib=True)(0) for la in rk1] # long time (1s on sage.math, 2011)268[0, 0, 0, 0, 0, 0]269sage: for la in rk1: # long time (8s on sage.math, 2011)270... E = EllipticCurve(la)271... m = E.modular_symbol(use_eclib = True)272... lp = E.padic_lseries(5)273... for D in [5,17,12,8]:274... ED = E.quadratic_twist(D)275... md = sum([kronecker(D,u)*m(ZZ(u)/D) for u in range(D)])276... etaa = lp._quotient_of_periods_to_twist(D)277... assert ED.lseries().L_ratio()*ED.real_components()*etaa == md278279"""280E = self._E281self._scaling = 1 # by now.282self._failed_to_scale = False283284if self._sign == 1 :285at0 = self(0)286# print 'modular symbol evaluates to ',at0,' at 0'287if at0 != 0 :288l1 = self.__lalg__(1)289if at0 != l1:290verbose('scale modular symbols by %s'%(l1/at0))291self._scaling = l1/at0292else :293# if [0] = 0, we can still hope to scale it correctly by considering twists of E294Dlist = [5,8,12,13,17,21,24,28,29, 33, 37, 40, 41, 44, 53, 56, 57, 60, 61, 65, 69, 73, 76, 77, 85, 88, 89, 92, 93, 97] # a list of positive fundamental discriminants295j = 0296at0 = 0297# computes [0]+ for the twist of E by D until one value is non-zero298while j < 30 and at0 == 0 :299D = Dlist[j]300# the following line checks if the twist of the newform of E by D is a newform301# this is to avoid that we 'twist back'302if all( valuation(E.conductor(),ell)<= valuation(D,ell) for ell in prime_divisors(D) ) :303at0 = sum([kronecker_symbol(D,u) * self(ZZ(u)/D) for u in range(1,abs(D))])304j += 1305if j == 30 and at0 == 0: # curves like "121b1", "225a1", "225e1", "256a1", "256b1", "289a1", "361a1", "400a1", "400c1", "400h1", "441b1", "441c1", "441d1", "441f1 .. will arrive here306self._failed_to_scale = True307self.__scale_by_periods_only__()308else :309l1 = self.__lalg__(D)310if at0 != l1:311verbose('scale modular symbols by %s found at D=%s '%(l1/at0,D), level=2)312self._scaling = l1/at0313314else : # that is when sign = -1315Dlist = [-3,-4,-7,-8,-11,-15,-19,-20,-23,-24, -31, -35, -39, -40, -43, -47, -51, -52, -55, -56, -59, -67, -68, -71, -79, -83, -84, -87, -88, -91] # a list of negative fundamental discriminants316j = 0317at0 = 0318while j < 30 and at0 == 0 :319# computes [0]+ for the twist of E by D until one value is non-zero320D = Dlist[j]321if all( valuation(E.conductor(),ell)<= valuation(D,ell) for ell in prime_divisors(D) ) :322at0 = - sum([kronecker_symbol(D,u) * self(ZZ(u)/D) for u in range(1,abs(D))])323j += 1324if j == 30 and at0 == 0: # no more hope for a normalization325# we do at least a scaling with the quotient of the periods326self._failed_to_scale = True327self.__scale_by_periods_only__()328else :329l1 = self.__lalg__(D)330if at0 != l1:331verbose('scale modular symbols by %s'%(l1/at0))332self._scaling = l1/at0333334335def __lalg__(self,D):336r"""337For positive `D`, this function evaluates the quotient338`L(E_D,1)\cdot \sqrt(D)/\Omega_E` where `E_D` is the twist of339`E` by `D`, `\Omega_E` is the least positive period of `E`.340For negative `E`, it is the quotient341`L(E_D,1)\cdot \sqrt(-D)/\Omega^{-}_E`342where `\Omega^{-}_E` is the least positive imaginary part of a343non-real period of `E`.344345EXMAPLES::346347sage: E = EllipticCurve('11a1')348sage: m = E.modular_symbol(sign=+1)349sage: m.__lalg__(1)3501/5351sage: m.__lalg__(3)3525/2353354"""355from sage.functions.all import sqrt356# the computation of the L-value could take a lot of time,357# but then the conductor is so large358# that the computation of modular symbols for E took even longer359360E = self._E361ED = E.quadratic_twist(D)362lv = ED.lseries().L_ratio() # this is L(ED,1) divided by the Neron period omD of ED363lv *= ED.real_components()364omD = ED.period_lattice().basis()[0]365if D > 0 :366om = E.period_lattice().basis()[0]367q = sqrt(D)*omD/om * 8368else :369om = E.period_lattice().basis()[1].imag()370q = sqrt(-D)*omD/om*8371372# see padic_lseries.pAdicLeries._quotient_of_periods_to_twist373# for the explanation of the second factor374verbose('real approximation is %s'%q)375return lv/8 * QQ(int(round(q)))376377def __scale_by_periods_only__(self):378r"""379If we fail to scale with ``_find_scaling_L_ratio``, we drop here380to try and find the scaling by the quotient of the381periods to the `X_0`-optimal curve. The resulting ``_scaling``382is not guaranteed to be correct, but could well be.383384EXAMPLES::385386sage: E = EllipticCurve('11a1')387sage: m = E.modular_symbol(sign=+1)388sage: m.__scale_by_periods_only__()389Warning : Could not normalize the modular symbols, maybe all further results will be multiplied by -1, 2 or -2.390sage: m._scaling3911392393sage: E = EllipticCurve('11a3')394sage: m = E.modular_symbol(sign=+1, use_eclib=True)395sage: m.__scale_by_periods_only__()396Warning : Could not normalize the modular symbols, maybe all further results will be multiplied by -1, 2 or -2.397sage: m._scaling3981/5399400"""401# we only do this inside the cremona-tables.402try :403crla = parse_cremona_label(self._E.label())404except RuntimeError: # raised when curve is outside of the table405print "Warning : Could not normalize the modular symbols, maybe all further results will be multiplied by a rational number."406self._scaling = 1407else :408print "Warning : Could not normalize the modular symbols, maybe all further results will be multiplied by -1, 2 or -2."409cr0 = Integer(crla[0]).str() + crla[1] + '1'410E0 = EllipticCurve(cr0)411q = E0.period_lattice().basis()[0]/self._E.period_lattice().basis()[0]412q = QQ(int(round(q*200)))/200413verbose('scale modular symbols by %s'%q)414self._scaling = q415416417class ModularSymbolECLIB(ModularSymbol):418def __init__(self, E, sign, normalize="L_ratio"):419r"""420Modular symbols attached to `E` using ``eclib``.421422INPUT:423424- ``E`` - an elliptic curve425- ``sign`` - an integer, -1 or 1426- ``normalize`` - either 'L_ratio' (default) or 'none';427For 'L_ratio', the modular symbol is correctly normalized428by comparing it to the quotient of `L(E,1)` by the least429positive period for the curve and some small twists.430For 'none', the modular symbol is almost certainly431not correctly normalized, i.e. all values will be a432fixed scalar multiple of what they should be.433434EXAMPLES::435436sage: import sage.schemes.elliptic_curves.ell_modular_symbols437sage: E=EllipticCurve('11a1')438sage: M=sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolECLIB(E,+1)439sage: M440Modular symbol with sign 1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field441sage: M(0)4421/5443sage: E=EllipticCurve('11a2')444sage: M=sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolECLIB(E,+1)445sage: M(0)4461447448This is a rank 1 case with vanishing positive twists.449The modular symbol can not be adjusted::450451sage: E=EllipticCurve('121b1')452sage: M=sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolECLIB(E,+1)453Warning : Could not normalize the modular symbols, maybe all further results will be multiplied by -1, 2 or -2.454sage: M(0)4550456sage: M(1/7)457-2458459sage: M = EllipticCurve('121d1').modular_symbol(use_eclib=True)460sage: M(0)4612462sage: M = EllipticCurve('121d1').modular_symbol(use_eclib=True,normalize='none')463sage: M(0)4648465466sage: E = EllipticCurve('15a1')467sage: [C.modular_symbol(use_eclib=True,normalize='L_ratio')(0) for C in E.isogeny_class()]468[1/4, 1/8, 1/4, 1/2, 1/8, 1/16, 1/2, 1]469sage: [C.modular_symbol(use_eclib=True,normalize='none')(0) for C in E.isogeny_class()]470[1/4, 1/4, 1/4, 1/4, 1/4, 1/4, 1/4, 1/4]471472Currently, the interface for negative modular symbols in eclib is not yet written::473474sage: E.modular_symbol(use_eclib=True,sign=-1)475Traceback (most recent call last):476...477NotImplementedError: Despite that eclib has now -1 modular symbols the interface to them is not yet written.478479TESTS (for trac 10236)::480481sage: E = EllipticCurve('11a1')482sage: m = E.modular_symbol(use_eclib=True)483sage: m(1/7)4847/10485sage: m(0)4861/5487"""488self._sign = ZZ(sign)489if self._sign != sign:490raise TypeError, 'sign must be an integer'491if self._sign != -1 and self._sign != 1:492raise TypeError, 'sign must -1 or 1'493if self._sign == -1:494raise NotImplementedError, "Despite that eclib has now -1 modular symbols the interface to them is not yet written."495self._E = E496self._use_eclib = True497self._base_ring = QQ498self._normalize = normalize499self._modsym = ECModularSymbol(E)500p = ZZ(2)501while not E.is_good(p):502p = p.next_prime()503# this computes {0,oo} using the Hecke-operator at p504self._atzero = sum([self._modsym(ZZ(a)/p) for a in range(p)])/E.Np(p)505506if normalize == "L_ratio":507self._find_scaling_L_ratio()508elif normalize == "none":509self._scaling = ZZ(1)510else :511raise ValueError, "no normalization '%s' known for modular symbols using John Cremona's eclib"%normalize512513514def _call_with_caching(self, r):515r"""516Evaluates the modular symbol at `r`, caching the computed value.517518EXAMPLES::519520sage: m = EllipticCurve('11a1').modular_symbol(use_eclib=True)521sage: m._call_with_caching(0)5221/5523"""524try:525return self.__cache[r]526except AttributeError:527self.__cache = {}528except KeyError:529pass530c = (self._atzero - self._modsym(r))*self._scaling531self.__cache[r] = c532return c533534def __call__(self, r):535r"""536Evaluates the modular symbol at `r`.537538EXAMPLES::539540sage: m = EllipticCurve('11a1').modular_symbol(use_eclib=True)541sage: m(0)5421/5543544"""545# this computes {0,oo} - {0,r} = {r,oo}546from sage.rings.rational import Rational547if r != oo:548r = Rational(r)549r = r.numer() % r.denom() / r.denom()550return (self._atzero - self._modsym(r))*self._scaling551552553class ModularSymbolSage(ModularSymbol):554def __init__(self, E, sign, normalize="L_ratio"):555"""556Modular symbols attached to `E` using ``sage``.557558INPUT:559560- ``E`` -- an elliptic curve561- ``sign`` -- an integer, -1 or 1562- ``normalize`` -- either 'L_ratio' (default), 'period', or 'none';563For 'L_ratio', the modular symbol is correctly normalized564by comparing it to the quotient of `L(E,1)` by the least565positive period for the curve and some small twists.566The normalization 'period' uses the integral_period_map567for modular symbols and is known to be equal to the above568normalization up to the sign and a possible power of 2.569For 'none', the modular symbol is almost certainly570not correctly normalized, i.e. all values will be a571fixed scalar multiple of what they should be. But572the initial computation of the modular symbol is573much faster, though evaluation of574it after computing it won't be any faster.575576EXAMPLES::577578sage: E=EllipticCurve('11a1')579sage: import sage.schemes.elliptic_curves.ell_modular_symbols580sage: M=sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolSage(E,+1)581sage: M582Modular symbol with sign 1 over Rational Field attached to Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field583sage: M(0)5841/5585sage: E=EllipticCurve('11a2')586sage: M=sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolSage(E,+1)587sage: M(0)5881589sage: M=sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolSage(E,-1)590sage: M(1/3)5911592593This is a rank 1 case with vanishing positive twists.594The modular symbol is adjusted by -2::595596sage: E=EllipticCurve('121b1')597sage: M=sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolSage(E,-1,normalize='L_ratio')598sage: M(1/3)5992600sage: M._scaling601-2602603sage: M = EllipticCurve('121d1').modular_symbol(use_eclib=False)604sage: M(0)6052606sage: M = EllipticCurve('121d1').modular_symbol(use_eclib=False,normalize='none')607sage: M(0)6081609610sage: E = EllipticCurve('15a1')611sage: [C.modular_symbol(use_eclib=False, normalize='L_ratio')(0) for C in E.isogeny_class()]612[1/4, 1/8, 1/4, 1/2, 1/8, 1/16, 1/2, 1]613sage: [C.modular_symbol(use_eclib=False, normalize='period')(0) for C in E.isogeny_class()]614[1/8, 1/16, 1/8, 1/4, 1/16, 1/32, 1/4, 1/2]615sage: [C.modular_symbol(use_eclib=False, normalize='none')(0) for C in E.isogeny_class()]616[1, 1, 1, 1, 1, 1, 1, 1]617618"""619self._sign = ZZ(sign)620if self._sign != sign:621raise TypeError, 'sign must be an integer'622if self._sign != -1 and self._sign != 1:623raise TypeError, 'sign must -1 or 1'624self._E = E625self._use_eclib = False626self._normalize = normalize627self._modsym = E.modular_symbol_space(sign=self._sign)628self._base_ring = self._modsym.base_ring()629self._ambient_modsym = self._modsym.ambient_module()630631if normalize == "L_ratio":632self._e = self._modsym.dual_eigenvector()633self._find_scaling_L_ratio()634if self._failed_to_scale:635self._find_scaling_period() # will reset _e and _scaling636else:637self._e *= self._scaling638elif normalize == "period" :639self._find_scaling_period() # this will set _e and _scaling640elif normalize == "none":641self._scaling = 1642self._e = self._modsym.dual_eigenvector()643else :644raise ValueError, "no normalization %s known for modular symbols"%normalize645646647def _find_scaling_period(self):648r"""649Uses the integral period map of the modular symbol implementation in sage650in order to determine the scaling. The resulting modular symbol is correct651only for the `X_0`-optimal curve, at least up to a possible factor +-1 or +-2.652653EXAMPLES::654655sage: E = EllipticCurve('11a1')656sage: m = sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolSage(E,+1,normalize='period')657sage: m._e658(1/5, 1)659sage: E = EllipticCurve('11a2')660sage: m = sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolSage(E,+1,normalize='period')661sage: m._e662(1, 5)663sage: E = EllipticCurve('121b2')664sage: m = sage.schemes.elliptic_curves.ell_modular_symbols.ModularSymbolSage(E,+1,normalize='period')665sage: m._e666(0, 11/2, 0, 11/2, 11/2, 0, 0, -3, 2, 1/2, -1, 3/2)667668"""669670P = self._modsym.integral_period_mapping()671self._e = P.matrix().transpose().row(0)672self._e /= 2673E = self._E674try :675crla = parse_cremona_label(E.label())676except RuntimeError: # raised when curve is outside of the table677self._scaling = 1678else :679cr0 = Integer(crla[0]).str() + crla[1] + '1'680E0 = EllipticCurve(cr0)681q = E0.period_lattice().basis()[0]/E.period_lattice().basis()[0]682q = QQ(int(round(q*200)))/200683verbose('scale modular symbols by %s'%q)684self._scaling = q685self._e *= self._scaling686687def _call_with_caching(self, r):688r"""689Evaluates the modular symbol at `r`, caching the computed value.690691EXAMPLES::692693sage: m = EllipticCurve('11a1').modular_symbol(use_eclib=False)694sage: m._call_with_caching(0)6951/5696"""697try:698return self.__cache[r]699except AttributeError:700self.__cache = {}701except KeyError:702pass703w = self._ambient_modsym([oo,r]).element()704c = (self._e).dot_product(w)705self.__cache[r] = c706return c707708def __call__(self, r):709r"""710Evaluates the modular symbol at `r`.711712EXAMPLES::713714sage: m = EllipticCurve('11a1').modular_symbol(use_eclib=False)715sage: m(0)7161/5717718"""719# this next line takes most of the time720w = self._ambient_modsym.modular_symbol([zero, oo, Cusps(r)], check=False)721722return (self._e).dot_product(w.element())723724725