def __init__(self, **args): # Check for compulsory arguments if not ('weight' in args.keys() and 'level' in args.keys()): raise KeyError("You have to supply weight and level for an elliptic modular form L-function") logger.debug(str(args)) self.addToLink = '' # This is to take care of the case where character and/or label is not given # Initialize default values if not args['character']: args['character'] = 0 # Trivial character is default self.addToLink = '/0' if not args['label']: args['label'] = 'a' # No label, is OK If space is one-dimensional self.addToLink += '/a' if not args['number']: args['number'] = 0 # Default choice of embedding of the coefficients self.addToLink += '/0' modform_translation_limit = 101 # Put the arguments into the object dictionary self.__dict__.update(args) # logger.debug(str(self.character)+str(self.label)+str(self.number)) self.weight = int(self.weight) self.motivic_weight = 1 self.level = int(self.level) self.character = int(self.character) # if self.character > 0: # raise KeyError, "The L-function of a modular form with non-trivial # character has not been implemented yet." self.number = int(self.number) # Create the modular form try: self.MF = WebNewForm(self.weight, self.level, self.character, self.label, verbose=1) except: raise KeyError("No data available yet for this modular form, so" + " not able to compute it's L-function") # Extract the L-function information from the elliptic modular form self.automorphyexp = float(self.weight - 1) / float(2) self.Q_fe = float(sqrt(self.level) / (2 * math.pi)) # logger.debug("ALeigen: " + str(self.MF.atkin_lehner_eigenvalues())) self.kappa_fe = [1] self.lambda_fe = [self.automorphyexp] self.mu_fe = [] self.nu_fe = [Rational(str(self.weight - 1) + '/2')] self.selfdual = True self.langlands = True self.primitive = True self.degree = 2 self.poles = [] self.residues = [] self.numcoeff = 20 + int(5 * math.ceil( self.weight * sqrt(self.level))) # just testing NB: Need to learn how to use more coefficients self.algebraic_coefficients = [] # Get the data for the corresponding elliptic curve if possible if self.level <= modform_translation_limit and self.weight == 2: self.ellipticcurve = EC_from_modform(self.level, self.label) self.nr_of_curves_in_class = nr_of_EC_in_isogeny_class(self.ellipticcurve) else: self.ellipticcurve = False # Appending list of Dirichlet coefficients GaloisDegree = self.MF.degree() # number of forms in the Galois orbit # logger.debug("Galois degree: " + str(GaloisDegree)) if GaloisDegree == 1: self.algebraic_coefficients = self.MF.q_expansion_embeddings( self.numcoeff + 1)[1:self.numcoeff + 1] # when coeffs are rational, q_expansion_embedding() # is the list of Fourier coefficients self.coefficient_type = 2 # In this case, the L-function also comes from an elliptic curve. We tell that to lcalc, even if the coefficients are not produced using the elliptic curve else: # logger.debug("Start computing coefficients.") embeddings = self.MF.q_expansion_embeddings(self.numcoeff + 1) for n in range(1, self.numcoeff + 1): self.algebraic_coefficients.append(embeddings[n][self.number]) self.coefficient_type = 0 # In this case the coefficients are neither periodic nor coming from an elliptic curve # logger.debug("Done computing coefficients.") self.dirichlet_coefficients = [] for n in range(1, len(self.algebraic_coefficients) + 1): self.dirichlet_coefficients.append( self.algebraic_coefficients[n - 1] / float(n ** self.automorphyexp)) if self.level == 1: # For level 1, the sign is always plus self.sign = 1 else: # for level not 1, calculate sign from Fricke involution and weight if self.character > 0: self.sign = signOfEmfLfunction(self.level, self.weight, self.algebraic_coefficients) else: self.sign = self.MF.atkin_lehner_eigenvalues()[self.level] * (-1) ** (float(self.weight / 2)) # logger.debug("Sign: " + str(self.sign)) self.coefficient_period = 0 self.quasidegree = 1 self.checkselfdual() self.texname = "L(s,f)" self.texnamecompleteds = "\\Lambda(s,f)" if self.selfdual: self.texnamecompleted1ms = "\\Lambda(1-s,f)" else: self.texnamecompleted1ms = "\\Lambda(1-s,\\overline{f})" if self.character != 0: characterName = " character \(%s\)" % (self.MF.conrey_character_name()) else: characterName = " trivial character" self.title = "$L(s,f)$, where $f$ is a holomorphic cusp form with weight %s, level %s, and %s" % ( self.weight, self.level, characterName) self.citation = '' self.credit = '' self.generateSageLfunction() constructor_logger(self, args)
def __init__(self, **args): # Check for compulsory arguments if not 'label' in args.keys(): raise Exception("You have to supply a label for an elliptic curve L-function") # Initialize default values max_height = 30 modform_translation_limit = 101 # Put the arguments into the object dictionary self.__dict__.update(args) # Remove the ending number (if given) in the label to only get isogeny class while self.label[len(self.label) - 1].isdigit(): self.label = self.label[0:len(self.label) - 1] # Compute the # of curves in the isogeny class self.nr_of_curves_in_class = nr_of_EC_in_isogeny_class(self.label) # Create the elliptic curve curves = base.getDBConnection().elliptic_curves.curves Edata = curves.find_one({'lmfdb_label': self.label + '1'}) if Edata is None: raise KeyError('No elliptic curve with label %s exists in the database' % self.label) else: self.E = EllipticCurve([int(a) for a in Edata['ainvs']]) # Extract the L-function information from the elliptic curve self.quasidegree = 1 self.level = self.E.conductor() self.Q_fe = float(sqrt(self.level) / (2 * math.pi)) self.sign = self.E.lseries().dokchitser().eps self.kappa_fe = [1] self.lambda_fe = [0.5] self.numcoeff = round(self.Q_fe * 220 + 10) # logger.debug("numcoeff: {0}".format(self.numcoeff)) self.mu_fe = [] self.nu_fe = [Rational('1/2')] self.langlands = True self.degree = 2 self.motivic_weight = 1 # Get the data for the corresponding modular form if possible if self.level <= modform_translation_limit: self.modform = modform_from_EC(self.label) else: self.modform = False self.dirichlet_coefficients = self.E.anlist(self.numcoeff)[1:] # remove a0 self.dirichlet_coefficients_unnormalized = self.dirichlet_coefficients[:] self.normalize_by = Rational('1/2') # Renormalize the coefficients for n in range(0, len(self.dirichlet_coefficients) - 1): an = self.dirichlet_coefficients[n] self.dirichlet_coefficients[n] = float(an) / float(sqrt(n + 1)) self.poles = [] self.residues = [] self.coefficient_period = 0 self.selfdual = True self.primitive = True self.coefficient_type = 2 self.texname = "L(s,E)" self.texnamecompleteds = "\\Lambda(s,E)" self.texnamecompleted1ms = "\\Lambda(1-s,E)" self.title = "L-function $L(s,E)$ for the Elliptic Curve Isogeny Class " + self.label self.properties = [('Degree ', '%s' % self.degree)] self.properties.append(('Level', '%s' % self.level)) self.credit = 'Sage' self.citation = '' self.sageLfunction = lc.Lfunction_from_elliptic_curve(self.E, int(self.numcoeff)) # logger.info("I am now proud to have ", str(self.__dict__)) constructor_logger(self, args)