def DirichletCharacterGaloisReps(N): global DCGR_cache if not N in DCGR_cache: Chars = [ch[0] for ch in DG(N).galois_orbits()] vv = [[[DC.multiplicative_order(chi)] + character_traces(DC.sage_character(chi)), i] for i, chi in enumerate(Chars)] vv.sort() DCGR_cache[N] = [Chars[v[1]] for v in vv] return DCGR_cache[N]
class WebChar(WebObject, CachedRepresentation): r""" Class which should/might be replaced with WebDirichletCharcter once this is ok. """ _key = ['modulus', 'number', 'version'] _file_key = ['modulus', 'number', 'version'] _collection_name = 'webchar' def __init__(self, modulus=1, number=1, update_from_db=True, compute_values=False, init_dynamic_properties=True): r""" Init self. """ emf_logger.debug("In WebChar {0}".format( (modulus, number, update_from_db, compute_values))) if isinstance(modulus, basestring): try: m, n = modulus.split('.') modulus = int(m) number = int(n) except: raise ValueError, "{0} does not correspond to the label of a WebChar".format( modulus) if not gcd(number, modulus) == 1: raise ValueError, "Character number {0} of modulus {1} does not exist!".format( number, modulus) if number > modulus: number = number % modulus self._properties = WebProperties( WebInt('conductor'), WebInt('modulus', value=modulus), WebInt('number', value=number), WebInt('modulus_euler_phi'), WebInt('order'), WebStr('latex_name'), WebStr('label', value="{0}.{1}".format(modulus, number)), WebNoStoreObject('sage_character', type(trivial_character(1))), WebDict('_values_algebraic'), WebDict('_values_float'), WebDict('_embeddings'), WebFloat('version', value=float(emf_version))) emf_logger.debug('Set properties in WebChar!') super(WebChar, self).__init__(update_from_db=update_from_db, init_dynamic_properties=init_dynamic_properties) #if not self.has_updated_from_db(): # self.init_dynamic_properties() # this was not done if we exited early # compute = True if compute_values: self.compute_values() #emf_logger.debug('In WebChar, self.__dict__ = {0}'.format(self.__dict__)) emf_logger.debug('In WebChar, self.number = {0}'.format(self.number)) def compute_values(self, save=False): emf_logger.debug( 'in compute_values for WebChar number {0} of modulus {1}'.format( self.number, self.modulus)) if self._values_algebraic == {} or self._values_float == {}: changed = True for i in range(self.modulus): self.value(i, value_format='float') self.value(i, value_format='algebraic') if changed and save: self.save_to_db() else: emf_logger.debug('Not saving.') def init_dynamic_properties(self, embeddings=False): if self.number is not None: emf_logger.debug('number: {0}'.format(self.number)) self.character = DirichletCharacter_conrey( DirichletGroup_conrey(self.modulus), self.number) if not self.number == 1: self.sage_character = self.character.sage_character() else: self.sage_character = trivial_character(self.modulus) self.name = "Character nr. {0} of modulus {1}".format( self.number, self.modulus) if embeddings: from lmfdb.modular_forms.elliptic_modular_forms.backend.emf_utils import dirichlet_character_conrey_galois_orbit_embeddings emb = dirichlet_character_conrey_galois_orbit_embeddings( self.modulus, self.number) self.set_embeddings(emb) c = self.character if self.conductor == 0: self.conductor = c.conductor() if self.order == 0: self.order = c.multiplicative_order() if self.modulus_euler_phi == 0: self.modulus_euler_phi = euler_phi(self.modulus) if self.latex_name == '': self.latex_name = "\chi_{" + str(self.modulus) + "}(" + str( self.number) + ", \cdot)" def is_trivial(self): r""" Check if self is trivial. """ return self.character.is_trivial() def embeddings(self): r""" Returns a dictionary that maps the Conrey numbers of the Dirichlet characters in the Galois orbit of ```self``` to the powers of $\zeta_{\phi(N)}$ so that the corresponding embeddings map the labels. Let $\zeta_{\phi(N)}$ be the generator of the cyclotomic field of $N$-th roots of unity which is the base field for the coefficients of a modular form contained in the database. Considering the space $S_k(N,\chi)$, where $\chi = \chi_N(m, \cdot)$, if embeddings()[m] = n, then $\zeta_{\phi(N)}$ is mapped to $\mathrm{exp}(2\pi i n /\phi(N))$. """ return self._embeddings def set_embeddings(self, d): self._embeddings = d def embedding(self): r""" Let $\zeta_{\phi(N)}$ be the generator of the cyclotomic field of $N$-th roots of unity which is the base field for the coefficients of a modular form contained in the database. If ```self``` is given as $\chi = \chi_N(m, \cdot)$ in the Conrey naming scheme, then we have to apply the map \[ \zeta_{\phi(N)} \mapsto \mathrm{exp}(2\pi i n /\phi(N)) \] to the coefficients of normalized newforms in $S_k(N,\chi)$ as in the database in order to obtain the coefficients corresponding to ```self``` (that is to elements in $S_k(N,\chi)$). """ return self._embeddings[self.number] def __repr__(self): r""" Return the string representation of the character of self. """ return self.name def value(self, x, value_format='algebraic'): r""" Return the value of self as an algebraic integer or float. """ x = int(x) if value_format == 'algebraic': if self._values_algebraic is None: self._values_algebraic = {} y = self._values_algebraic.get(x) if y is None: y = self._values_algebraic[x] = self.sage_character(x) else: self._values_algebraic[x] = y return self._values_algebraic[x] elif value_format == 'float': ## floating point if self._values_float is None: self._values_float = {} y = self._values_float.get(x) if y is None: y = self._values_float[x] = self.character(x) else: self._values_float[x] = y return self._values_float[x] else: raise ValueError, "Format {0} is not known!".format(value_format) def url(self): r""" Return the url of self. """ if not hasattr(self, '_url') or self._url is None: self._url = url_for('characters.render_Dirichletwebpage', modulus=self.modulus, number=self.number) return self._url
class WebChar(WebObject, CachedRepresentation): r""" Class which should/might be replaced with WebDirichletCharcter once this is ok. """ _key = ['modulus', 'number','version'] _file_key = ['modulus', 'number','version'] _collection_name = 'webchar' def __init__(self, modulus=1, number=1, update_from_db=True, compute_values=False, init_dynamic_properties=True): r""" Init self. """ emf_logger.debug("In WebChar {0}".format((modulus,number,update_from_db,compute_values))) if isinstance(modulus,basestring): try: m,n=modulus.split('.') modulus = int(m); number=int(n) except: raise ValueError,"{0} does not correspond to the label of a WebChar".format(modulus) if not gcd(number,modulus)==1: raise ValueError,"Character number {0} of modulus {1} does not exist!".format(number,modulus) if number > modulus: number = number % modulus self._properties = WebProperties( WebInt('conductor'), WebInt('modulus', value=modulus), WebInt('number', value=number), WebInt('modulus_euler_phi'), WebInt('order'), WebStr('latex_name'), WebStr('label',value="{0}.{1}".format(modulus,number)), WebNoStoreObject('sage_character', type(trivial_character(1))), WebDict('_values_algebraic'), WebDict('_values_float'), WebDict('_embeddings'), WebFloat('version', value=float(emf_version)) ) emf_logger.debug('Set properties in WebChar!') super(WebChar, self).__init__( update_from_db=update_from_db, init_dynamic_properties=init_dynamic_properties ) #if not self.has_updated_from_db(): # self.init_dynamic_properties() # this was not done if we exited early # compute = True if compute_values: self.compute_values() #emf_logger.debug('In WebChar, self.__dict__ = {0}'.format(self.__dict__)) emf_logger.debug('In WebChar, self.number = {0}'.format(self.number)) def compute_values(self, save=False): emf_logger.debug('in compute_values for WebChar number {0} of modulus {1}'.format(self.number, self.modulus)) if self._values_algebraic == {} or self._values_float == {}: changed = True for i in range(self.modulus): self.value(i,value_format='float') self.value(i,value_format='algebraic') if changed and save: self.save_to_db() else: emf_logger.debug('Not saving.') def init_dynamic_properties(self, embeddings=False): if self.number is not None: emf_logger.debug('number: {0}'.format(self.number)) self.character = DirichletCharacter_conrey(DirichletGroup_conrey(self.modulus),self.number) if not self.number == 1: self.sage_character = self.character.sage_character() else: self.sage_character = trivial_character(self.modulus) self.name = "Character nr. {0} of modulus {1}".format(self.number,self.modulus) if embeddings: from lmfdb.modular_forms.elliptic_modular_forms.backend.emf_utils import dirichlet_character_conrey_galois_orbit_embeddings emb = dirichlet_character_conrey_galois_orbit_embeddings(self.modulus,self.number) self.set_embeddings(emb) c = self.character if self.conductor == 0: self.conductor = c.conductor() if self.order == 0: self.order = c.multiplicative_order() if self.modulus_euler_phi == 0: self.modulus_euler_phi = euler_phi(self.modulus) if self.latex_name == '': self.latex_name = "\chi_{" + str(self.modulus) + "}(" + str(self.number) + ", \cdot)" def is_trivial(self): r""" Check if self is trivial. """ return self.character.is_trivial() def embeddings(self): r""" Returns a dictionary that maps the Conrey numbers of the Dirichlet characters in the Galois orbit of ```self``` to the powers of $\zeta_{\phi(N)}$ so that the corresponding embeddings map the labels. Let $\zeta_{\phi(N)}$ be the generator of the cyclotomic field of $N$-th roots of unity which is the base field for the coefficients of a modular form contained in the database. Considering the space $S_k(N,\chi)$, where $\chi = \chi_N(m, \cdot)$, if embeddings()[m] = n, then $\zeta_{\phi(N)}$ is mapped to $\mathrm{exp}(2\pi i n /\phi(N))$. """ return self._embeddings def set_embeddings(self, d): self._embeddings = d def embedding(self): r""" Let $\zeta_{\phi(N)}$ be the generator of the cyclotomic field of $N$-th roots of unity which is the base field for the coefficients of a modular form contained in the database. If ```self``` is given as $\chi = \chi_N(m, \cdot)$ in the Conrey naming scheme, then we have to apply the map \[ \zeta_{\phi(N)} \mapsto \mathrm{exp}(2\pi i n /\phi(N)) \] to the coefficients of normalized newforms in $S_k(N,\chi)$ as in the database in order to obtain the coefficients corresponding to ```self``` (that is to elements in $S_k(N,\chi)$). """ return self._embeddings[self.number] def __repr__(self): r""" Return the string representation of the character of self. """ return self.name def value(self, x, value_format='algebraic'): r""" Return the value of self as an algebraic integer or float. """ x = int(x) if value_format =='algebraic': if self._values_algebraic is None: self._values_algebraic = {} y = self._values_algebraic.get(x) if y is None: y = self._values_algebraic[x]=self.sage_character(x) else: self._values_algebraic[x]=y return self._values_algebraic[x] elif value_format=='float': ## floating point if self._values_float is None: self._values_float = {} y = self._values_float.get(x) if y is None: y = self._values_float[x]=self.character(x) else: self._values_float[x]=y return self._values_float[x] else: raise ValueError,"Format {0} is not known!".format(value_format) def url(self): r""" Return the url of self. """ if not hasattr(self, '_url') or self._url is None: self._url = url_for('characters.render_Dirichletwebpage',modulus=self.modulus, number=self.number) return self._url