def make_E(self): coeffs = self.ainvs # list of 5 lists of d strings self.ainvs = [self.field.parse_NFelt(x) for x in coeffs] self.latex_ainvs = web_latex(self.ainvs) from sage.schemes.elliptic_curves.all import EllipticCurve self.E = E = EllipticCurve(self.ainvs) self.equn = web_latex(E) self.numb = str(self.number) # Conductor, discriminant, j-invariant N = E.conductor() self.cond = web_latex(N) self.cond_norm = web_latex(N.norm()) if N.norm()==1: # since the factorization of (1) displays as "1" self.fact_cond = self.cond else: self.fact_cond = web_latex_ideal_fact(N.factor()) self.fact_cond_norm = web_latex(N.norm().factor()) D = self.field.K().ideal(E.discriminant()) self.disc = web_latex(D) self.disc_norm = web_latex(D.norm()) if D.norm()==1: # since the factorization of (1) displays as "1" self.fact_disc = self.disc else: self.fact_disc = web_latex_ideal_fact(D.factor()) self.fact_disc_norm = web_latex(D.norm().factor()) # Minimal model? # # All curves in the database should be given # by models which are globally minimal if possible, else # minimal at all but one prime. But we do not rely on this # here, and the display should be correct if either (1) there # exists a global minimal model but this model is not; or (2) # this model is non-minimal at more than one prime. # self.non_min_primes = non_minimal_primes(E) self.is_minimal = (len(self.non_min_primes)==0) self.has_minimal_model = True if not self.is_minimal: self.non_min_prime = ','.join([web_latex(P) for P in self.non_min_primes]) self.has_minimal_model = has_global_minimal_model(E) if not self.is_minimal: Dmin = minimal_discriminant_ideal(E) self.mindisc = web_latex(Dmin) self.mindisc_norm = web_latex(Dmin.norm()) if Dmin.norm()==1: # since the factorization of (1) displays as "1" self.fact_mindisc = self.mindisc else: self.fact_mindisc = web_latex_ideal_fact(Dmin.factor()) self.fact_mindisc_norm = web_latex(Dmin.norm().factor()) j = E.j_invariant() if j: d = j.denominator() n = d*j # numerator exists for quadratic fields only! g = GCD(list(n)) n1 = n/g self.j = web_latex(n1) if d!=1: if n1>1: #self.j = "("+self.j+")\(/\)"+web_latex(d) self.j = web_latex(r"\frac{%s}{%s}" % (self.j,d)) else: self.j = web_latex(d) if g>1: if n1>1: self.j = web_latex(g) + self.j else: self.j = web_latex(g) self.j = web_latex(j) self.fact_j = None if j.is_zero(): self.fact_j = web_latex(j) else: try: self.fact_j = web_latex(j.factor()) except (ArithmeticError,ValueError): # if not all prime ideal factors principal pass # CM and End(E) self.cm_bool = "no" self.End = "\(\Z\)" if self.cm: self.cm_bool = "yes (\(%s\))" % self.cm if self.cm%4==0: d4 = ZZ(self.cm)//4 self.End = "\(\Z[\sqrt{%s}]\)"%(d4) else: self.End = "\(\Z[(1+\sqrt{%s})/2]\)" % self.cm # Q-curve / Base change self.qc = "no" try: if self.q_curve: self.qc = "yes" except AttributeError: # in case the db entry does not have this field set pass # Torsion self.ntors = web_latex(self.torsion_order) self.tr = len(self.torsion_structure) if self.tr==0: self.tor_struct_pretty = "Trivial" if self.tr==1: self.tor_struct_pretty = "\(\Z/%s\Z\)" % self.torsion_structure[0] if self.tr==2: self.tor_struct_pretty = r"\(\Z/%s\Z\times\Z/%s\Z\)" % tuple(self.torsion_structure) torsion_gens = [E([self.field.parse_NFelt(x) for x in P]) for P in self.torsion_gens] self.torsion_gens = ",".join([web_latex(P) for P in torsion_gens]) # Rank etc try: self.rk = web_latex(self.rank) except AttributeError: self.rk = "not recorded" # if rank in self: # self.r = web_latex(self.rank) # Local data self.local_data = [] for p in N.prime_factors(): self.local_info = E.local_data(p, algorithm="generic") self.local_data.append({'p': web_latex(p), 'norm': web_latex(p.norm().factor()), 'tamagawa_number': self.local_info.tamagawa_number(), 'kodaira_symbol': web_latex(self.local_info.kodaira_symbol()).replace('$', ''), 'reduction_type': self.local_info.bad_reduction_type(), 'ord_den_j': max(0,-E.j_invariant().valuation(p)), 'ord_mindisc': self.local_info.discriminant_valuation() }) # URLs of self and related objects: self.urls = {} self.urls['curve'] = url_for(".show_ecnf", nf = self.field_label, conductor_label=self.conductor_label, class_label = self.iso_label, number = self.number) self.urls['class'] = url_for(".show_ecnf_isoclass", nf = self.field_label, conductor_label=self.conductor_label, class_label = self.iso_label) self.urls['conductor'] = url_for(".show_ecnf_conductor", nf = self.field_label, conductor_label=self.conductor_label) self.urls['field'] = url_for(".show_ecnf1", nf=self.field_label) if self.field.is_real_quadratic(): self.hmf_label = "-".join([self.field.label,self.conductor_label,self.iso_label]) self.urls['hmf'] = url_for('hmf.render_hmf_webpage', field_label=self.field.label, label=self.hmf_label) if self.field.is_imag_quadratic(): self.bmf_label = "-".join([self.field.label,self.conductor_label,self.iso_label]) self.friends = [] self.friends += [('Isogeny class '+self.short_class_label, self.urls['class'])] self.friends += [('Twists',url_for('ecnf.index',field_label=self.field_label,jinv=self.jinv))] if self.field.is_real_quadratic(): self.friends += [('Hilbert Modular Form '+self.hmf_label, self.urls['hmf'])] if self.field.is_imag_quadratic(): self.friends += [('Bianchi Modular Form %s not yet available' % self.bmf_label, '')] self.properties = [ ('Base field', self.field.field_pretty()), ('Label' , self.label)] # Plot if E.base_field().signature()[0]: self.plot = encode_plot(EC_nf_plot(E,self.field.generator_name())) self.plot_link = '<img src="%s" width="200" height="150"/>' % self.plot self.properties += [(None, self.plot_link)] self.properties += [ ('Conductor' , self.cond), ('Conductor norm' , self.cond_norm), ('j-invariant' , self.j), ('CM' , self.cm_bool)] if self.base_change: self.properties += [('base-change', 'yes: %s' % ','.join([str(lab) for lab in self.base_change]))] else: self.base_change = [] # in case it was False instead of [] self.properties += [('Q-curve' , self.qc)] self.properties += [ ('Torsion order' , self.ntors), ('Rank' , self.rk), ] for E0 in self.base_change: self.friends += [('Base-change of %s /\(\Q\)' % E0 , url_for("ec.by_ec_label", label=E0))]
def make_E(self): coeffs = self.ainvs # list of 5 lists of d strings self.ainvs = [self.field.parse_NFelt(x) for x in coeffs] self.latex_ainvs = web_latex(self.ainvs) from sage.schemes.elliptic_curves.all import EllipticCurve self.E = E = EllipticCurve(self.ainvs) self.equn = web_latex(E) self.numb = str(self.number) # Conductor, discriminant, j-invariant N = E.conductor() self.cond = web_latex(N) self.cond_norm = web_latex(N.norm()) if N.norm() == 1: # since the factorization of (1) displays as "1" self.fact_cond = self.cond else: self.fact_cond = web_latex_ideal_fact(N.factor()) self.fact_cond_norm = web_latex(N.norm().factor()) D = self.field.K().ideal(E.discriminant()) self.disc = web_latex(D) self.disc_norm = web_latex(D.norm()) if D.norm() == 1: # since the factorization of (1) displays as "1" self.fact_disc = self.disc else: self.fact_disc = web_latex_ideal_fact(D.factor()) self.fact_disc_norm = web_latex(D.norm().factor()) # Minimal model? # # All curves in the database should be given # by models which are globally minimal if possible, else # minimal at all but one prime. But we do not rely on this # here, and the display should be correct if either (1) there # exists a global minimal model but this model is not; or (2) # this model is non-minimal at more than one prime. # self.non_min_primes = non_minimal_primes(E) self.is_minimal = (len(self.non_min_primes) == 0) self.has_minimal_model = True if not self.is_minimal: self.non_min_prime = ','.join( [web_latex(P) for P in self.non_min_primes]) self.has_minimal_model = has_global_minimal_model(E) if not self.is_minimal: Dmin = minimal_discriminant_ideal(E) self.mindisc = web_latex(Dmin) self.mindisc_norm = web_latex(Dmin.norm()) if Dmin.norm( ) == 1: # since the factorization of (1) displays as "1" self.fact_mindisc = self.mindisc else: self.fact_mindisc = web_latex_ideal_fact(Dmin.factor()) self.fact_mindisc_norm = web_latex(Dmin.norm().factor()) j = E.j_invariant() if j: d = j.denominator() n = d * j # numerator exists for quadratic fields only! g = GCD(list(n)) n1 = n / g self.j = web_latex(n1) if d != 1: if n1 > 1: #self.j = "("+self.j+")\(/\)"+web_latex(d) self.j = web_latex(r"\frac{%s}{%s}" % (self.j, d)) else: self.j = web_latex(d) if g > 1: if n1 > 1: self.j = web_latex(g) + self.j else: self.j = web_latex(g) self.j = web_latex(j) self.fact_j = None if j.is_zero(): self.fact_j = web_latex(j) else: try: self.fact_j = web_latex(j.factor()) except (ArithmeticError, ValueError): # if not all prime ideal factors principal pass # CM and End(E) self.cm_bool = "no" self.End = "\(\Z\)" if self.cm: self.cm_bool = "yes (\(%s\))" % self.cm if self.cm % 4 == 0: d4 = ZZ(self.cm) // 4 self.End = "\(\Z[\sqrt{%s}]\)" % (d4) else: self.End = "\(\Z[(1+\sqrt{%s})/2]\)" % self.cm # Q-curve / Base change self.qc = "no" try: if self.q_curve: self.qc = "yes" except AttributeError: # in case the db entry does not have this field set pass # Torsion self.ntors = web_latex(self.torsion_order) self.tr = len(self.torsion_structure) if self.tr == 0: self.tor_struct_pretty = "Trivial" if self.tr == 1: self.tor_struct_pretty = "\(\Z/%s\Z\)" % self.torsion_structure[0] if self.tr == 2: self.tor_struct_pretty = r"\(\Z/%s\Z\times\Z/%s\Z\)" % tuple( self.torsion_structure) torsion_gens = [ E([self.field.parse_NFelt(x) for x in P]) for P in self.torsion_gens ] self.torsion_gens = ",".join([web_latex(P) for P in torsion_gens]) # Rank etc try: self.rk = web_latex(self.rank) except AttributeError: self.rk = "not recorded" # if rank in self: # self.r = web_latex(self.rank) # Local data self.local_data = [] for p in N.prime_factors(): self.local_info = E.local_data(p, algorithm="generic") self.local_data.append({ 'p': web_latex(p), 'norm': web_latex(p.norm().factor()), 'tamagawa_number': self.local_info.tamagawa_number(), 'kodaira_symbol': web_latex(self.local_info.kodaira_symbol()).replace('$', ''), 'reduction_type': self.local_info.bad_reduction_type(), 'ord_den_j': max(0, E.j_invariant().valuation(p)), 'ord_mindisc': self.local_info.discriminant_valuation() }) # URLs of self and related objects: self.urls = {} self.urls['curve'] = url_for(".show_ecnf", nf=self.field_label, conductor_label=self.conductor_label, class_label=self.iso_label, number=self.number) self.urls['class'] = url_for(".show_ecnf_isoclass", nf=self.field_label, conductor_label=self.conductor_label, class_label=self.iso_label) self.urls['conductor'] = url_for(".show_ecnf_conductor", nf=self.field_label, conductor_label=self.conductor_label) self.urls['field'] = url_for(".show_ecnf1", nf=self.field_label) if self.field.is_real_quadratic(): self.hmf_label = "-".join( [self.field.label, self.conductor_label, self.iso_label]) self.urls['hmf'] = url_for('hmf.render_hmf_webpage', field_label=self.field.label, label=self.hmf_label) if self.field.is_imag_quadratic(): self.bmf_label = "-".join( [self.field.label, self.conductor_label, self.iso_label]) self.friends = [] self.friends += [('Isogeny class ' + self.short_class_label, self.urls['class'])] if self.field.is_real_quadratic(): self.friends += [('Hilbert Modular Form ' + self.hmf_label, self.urls['hmf'])] if self.field.is_imag_quadratic(): self.friends += [ ('Bianchi Modular Form %s not yet available' % self.bmf_label, '') ] self.properties = [('Base field', self.field.field_pretty()), ('Label', self.label)] # Plot n1 = len(E.base_field().embeddings(RR)) if (n1): self.plot = encode_plot(EC_nf_plot(E, self.field.generator_name())) self.plot_link = '<img src="%s" width="200" height="150"/>' % self.plot self.properties += [(None, self.plot_link)] self.properties += [('Conductor', self.cond), ('Conductor norm', self.cond_norm), ('j-invariant', self.j), ('CM', self.cm_bool)] if self.base_change: self.properties += [ ('base-change', 'yes: %s' % ','.join([str(lab) for lab in self.base_change])) ] else: self.base_change = [] # in case it was False instead of [] self.properties += [('Q-curve', self.qc)] self.properties += [ ('Torsion order', self.ntors), ('Rank', self.rk), ] for E0 in self.base_change: self.friends += [('Base-change of %s /\(\Q\)' % E0, url_for("ec.by_ec_label", label=E0))]
def make_E(self): coeffs = self.ainvs # list of 5 lists of d strings self.ainvs = [self.field.parse_NFelt(x) for x in coeffs] self.latex_ainvs = web_latex(self.ainvs) from sage.schemes.elliptic_curves.all import EllipticCurve self.E = E = EllipticCurve(self.ainvs) self.equn = web_latex(E) self.numb = str(self.number) # Conductor, discriminant, j-invariant N = E.conductor() self.cond = web_latex(N) self.cond_norm = web_latex(N.norm()) if N.norm() == 1: # since the factorization of (1) displays as "1" self.fact_cond = self.cond else: self.fact_cond = web_latex_ideal_fact(N.factor()) self.fact_cond_norm = web_latex(N.norm().factor()) D = self.field.K().ideal(E.discriminant()) self.disc = web_latex(D) self.disc_norm = web_latex(D.norm()) if D.norm() == 1: # since the factorization of (1) displays as "1" self.fact_disc = self.disc else: self.fact_disc = web_latex_ideal_fact(D.factor()) self.fact_disc_norm = web_latex(D.norm().factor()) # Minimal model? # # All curves in the database should be given # by models which are globally minimal if possible, else # minimal at all but one prime. But we do not rely on this # here, and the display should be correct if either (1) there # exists a global minimal model but this model is not; or (2) # this model is non-minimal at more than one prime. # self.non_min_primes = non_minimal_primes(E) self.is_minimal = (len(self.non_min_primes) == 0) self.has_minimal_model = True if not self.is_minimal: self.non_min_prime = ','.join([web_latex(P) for P in self.non_min_primes]) self.has_minimal_model = has_global_minimal_model(E) if not self.is_minimal: Dmin = minimal_discriminant_ideal(E) self.mindisc = web_latex(Dmin) self.mindisc_norm = web_latex(Dmin.norm()) if Dmin.norm() == 1: # since the factorization of (1) displays as "1" self.fact_mindisc = self.mindisc else: self.fact_mindisc = web_latex_ideal_fact(Dmin.factor()) self.fact_mindisc_norm = web_latex(Dmin.norm().factor()) j = E.j_invariant() if j: d = j.denominator() n = d * j # numerator exists for quadratic fields only! g = GCD(list(n)) n1 = n / g self.j = web_latex(n1) if d != 1: if n1 > 1: # self.j = "("+self.j+")\(/\)"+web_latex(d) self.j = web_latex(r"\frac{%s}{%s}" % (self.j, d)) else: self.j = web_latex(d) if g > 1: if n1 > 1: self.j = web_latex(g) + self.j else: self.j = web_latex(g) self.j = web_latex(j) self.fact_j = None # See issue 1258: some j factorizations work bu take too long (e.g. EllipticCurve/6.6.371293.1/1.1/a/1) # If these are really wanted, they could be precomputed and stored in the db if j.is_zero(): self.fact_j = web_latex(j) else: if self.field.K().degree() < 3: #j.numerator_ideal().norm()<1000000000000: try: self.fact_j = web_latex(j.factor()) except (ArithmeticError, ValueError): # if not all prime ideal factors principal pass # CM and End(E) self.cm_bool = "no" self.End = "\(\Z\)" if self.cm: self.cm_bool = "yes (\(%s\))" % self.cm if self.cm % 4 == 0: d4 = ZZ(self.cm) // 4 self.End = "\(\Z[\sqrt{%s}]\)" % (d4) else: self.End = "\(\Z[(1+\sqrt{%s})/2]\)" % self.cm # The line below will need to change once we have curves over non-quadratic fields # that contain the Hilbert class field of an imaginary quadratic field if self.signature == [0,1] and ZZ(-self.abs_disc*self.cm).is_square(): self.ST = '<a href="%s">$%s$</a>' % (url_for('st.by_label', label='1.2.U(1)'),'\\mathrm{U}(1)') else: self.ST = '<a href="%s">$%s$</a>' % (url_for('st.by_label', label='1.2.N(U(1))'),'N(\\mathrm{U}(1))') else: self.ST = '<a href="%s">$%s$</a>' % (url_for('st.by_label', label='1.2.SU(2)'),'\\mathrm{SU}(2)') # Q-curve / Base change self.qc = "no" try: if self.q_curve: self.qc = "yes" except AttributeError: # in case the db entry does not have this field set pass # Torsion self.ntors = web_latex(self.torsion_order) self.tr = len(self.torsion_structure) if self.tr == 0: self.tor_struct_pretty = "Trivial" if self.tr == 1: self.tor_struct_pretty = "\(\Z/%s\Z\)" % self.torsion_structure[0] if self.tr == 2: self.tor_struct_pretty = r"\(\Z/%s\Z\times\Z/%s\Z\)" % tuple(self.torsion_structure) torsion_gens = [E([self.field.parse_NFelt(x) for x in P]) for P in self.torsion_gens] self.torsion_gens = ",".join([web_latex(P) for P in torsion_gens]) # Rank or bounds try: self.rk = web_latex(self.rank) except AttributeError: self.rk = "?" try: self.rk_bnds = "%s...%s" % tuple(self.rank_bounds) except AttributeError: self.rank_bounds = [0, Infinity] self.rk_bnds = "not available" # Generators try: gens = [E([self.field.parse_NFelt(x) for x in P]) for P in self.gens] self.gens = ", ".join([web_latex(P) for P in gens]) if self.rk == "?": self.reg = "not available" else: if gens: self.reg = E.regulator_of_points(gens) else: self.reg = 1 # otherwise we only get 1.00000... except AttributeError: self.gens = "not available" self.reg = "not available" try: if self.rank == 0: self.reg = 1 except AttributeError: pass # Local data self.local_data = [] for p in N.prime_factors(): self.local_info = E.local_data(p, algorithm="generic") self.local_data.append({'p': web_latex(p), 'norm': web_latex(p.norm().factor()), 'tamagawa_number': self.local_info.tamagawa_number(), 'kodaira_symbol': web_latex(self.local_info.kodaira_symbol()).replace('$', ''), 'reduction_type': self.local_info.bad_reduction_type(), 'ord_den_j': max(0, -E.j_invariant().valuation(p)), 'ord_mindisc': self.local_info.discriminant_valuation(), 'ord_cond': self.local_info.conductor_valuation() }) # URLs of self and related objects: self.urls = {} # It's useful to be able to use this class out of context, when calling url_for will fail: try: self.urls['curve'] = url_for(".show_ecnf", nf=self.field_label, conductor_label=quote(self.conductor_label), class_label=self.iso_label, number=self.number) except RuntimeError: return self.urls['class'] = url_for(".show_ecnf_isoclass", nf=self.field_label, conductor_label=quote(self.conductor_label), class_label=self.iso_label) self.urls['conductor'] = url_for(".show_ecnf_conductor", nf=self.field_label, conductor_label=quote(self.conductor_label)) self.urls['field'] = url_for(".show_ecnf1", nf=self.field_label) sig = self.signature real_quadratic = sig == [2,0] totally_real = sig[1] == 0 imag_quadratic = sig == [0,1] if totally_real: self.hmf_label = "-".join([self.field.label, self.conductor_label, self.iso_label]) self.urls['hmf'] = url_for('hmf.render_hmf_webpage', field_label=self.field.label, label=self.hmf_label) self.urls['Lfunction'] = url_for("l_functions.l_function_hmf_page", field=self.field_label, label=self.hmf_label, character='0', number='0') if imag_quadratic: self.bmf_label = "-".join([self.field.label, self.conductor_label, self.iso_label]) self.friends = [] self.friends += [('Isogeny class ' + self.short_class_label, self.urls['class'])] self.friends += [('Twists', url_for('ecnf.index', field_label=self.field_label, jinv=self.jinv))] if totally_real: self.friends += [('Hilbert Modular Form ' + self.hmf_label, self.urls['hmf'])] self.friends += [('L-function', self.urls['Lfunction'])] if imag_quadratic: self.friends += [('Bianchi Modular Form %s not available' % self.bmf_label, '')] self.properties = [ ('Base field', self.field.field_pretty()), ('Label', self.label)] # Plot if E.base_field().signature()[0]: self.plot = encode_plot(EC_nf_plot(E, self.field.generator_name())) self.plot_link = '<img src="%s" width="200" height="150"/>' % self.plot self.properties += [(None, self.plot_link)] self.properties += [ ('Conductor', self.cond), ('Conductor norm', self.cond_norm), # See issue #796 for why this is hidden # ('j-invariant', self.j), ('CM', self.cm_bool)] if self.base_change: self.properties += [('base-change', 'yes: %s' % ','.join([str(lab) for lab in self.base_change]))] else: self.base_change = [] # in case it was False instead of [] self.properties += [('Q-curve', self.qc)] r = self.rk if r == "?": r = self.rk_bnds self.properties += [ ('Torsion order', self.ntors), ('Rank', r), ] for E0 in self.base_change: self.friends += [('Base-change of %s /\(\Q\)' % E0, url_for("ec.by_ec_label", label=E0))] self._code = None # will be set if needed by get_code()
def make_E(self): coeffs = self.ainvs # list of 5 lists of d strings self.ainvs = [self.field.parse_NFelt(x) for x in coeffs] self.latex_ainvs = web_latex(self.ainvs) from sage.schemes.elliptic_curves.all import EllipticCurve self.E = E = EllipticCurve(self.ainvs) self.equn = web_latex(E) self.numb = str(self.number) # Conductor, discriminant, j-invariant N = E.conductor() self.cond = web_latex(N) self.cond_norm = web_latex(N.norm()) if N.norm() == 1: # since the factorization of (1) displays as "1" self.fact_cond = self.cond else: self.fact_cond = web_latex_ideal_fact(N.factor()) self.fact_cond_norm = web_latex(N.norm().factor()) D = self.field.K().ideal(E.discriminant()) self.disc = web_latex(D) self.disc_norm = web_latex(D.norm()) if D.norm() == 1: # since the factorization of (1) displays as "1" self.fact_disc = self.disc else: self.fact_disc = web_latex_ideal_fact(D.factor()) self.fact_disc_norm = web_latex(D.norm().factor()) # Minimal model? # # All curves in the database should be given # by models which are globally minimal if possible, else # minimal at all but one prime. But we do not rely on this # here, and the display should be correct if either (1) there # exists a global minimal model but this model is not; or (2) # this model is non-minimal at more than one prime. # self.non_min_primes = non_minimal_primes(E) self.is_minimal = (len(self.non_min_primes) == 0) self.has_minimal_model = True if not self.is_minimal: self.non_min_prime = ','.join( [web_latex(P) for P in self.non_min_primes]) self.has_minimal_model = has_global_minimal_model(E) if not self.is_minimal: Dmin = minimal_discriminant_ideal(E) self.mindisc = web_latex(Dmin) self.mindisc_norm = web_latex(Dmin.norm()) if Dmin.norm( ) == 1: # since the factorization of (1) displays as "1" self.fact_mindisc = self.mindisc else: self.fact_mindisc = web_latex_ideal_fact(Dmin.factor()) self.fact_mindisc_norm = web_latex(Dmin.norm().factor()) j = E.j_invariant() if j: d = j.denominator() n = d * j # numerator exists for quadratic fields only! g = GCD(list(n)) n1 = n / g self.j = web_latex(n1) if d != 1: if n1 > 1: # self.j = "("+self.j+")\(/\)"+web_latex(d) self.j = web_latex(r"\frac{%s}{%s}" % (self.j, d)) else: self.j = web_latex(d) if g > 1: if n1 > 1: self.j = web_latex(g) + self.j else: self.j = web_latex(g) self.j = web_latex(j) self.fact_j = None # See issue 1258: some j factorizations work bu take too long (e.g. EllipticCurve/6.6.371293.1/1.1/a/1) # If these are really wanted, they could be precomputed and stored in the db if j.is_zero(): self.fact_j = web_latex(j) else: if self.field.K().degree( ) < 3: #j.numerator_ideal().norm()<1000000000000: try: self.fact_j = web_latex(j.factor()) except (ArithmeticError, ValueError ): # if not all prime ideal factors principal pass # CM and End(E) self.cm_bool = "no" self.End = "\(\Z\)" if self.cm: self.cm_bool = "yes (\(%s\))" % self.cm if self.cm % 4 == 0: d4 = ZZ(self.cm) // 4 self.End = "\(\Z[\sqrt{%s}]\)" % (d4) else: self.End = "\(\Z[(1+\sqrt{%s})/2]\)" % self.cm # The line below will need to change once we have curves over non-quadratic fields # that contain the Hilbert class field of an imaginary quadratic field if self.signature == [0, 1] and ZZ( -self.abs_disc * self.cm).is_square(): self.ST = '<a href="%s">$%s$</a>' % (url_for( 'st.by_label', label='1.2.U(1)'), '\\mathrm{U}(1)') else: self.ST = '<a href="%s">$%s$</a>' % (url_for( 'st.by_label', label='1.2.N(U(1))'), 'N(\\mathrm{U}(1))') else: self.ST = '<a href="%s">$%s$</a>' % (url_for( 'st.by_label', label='1.2.SU(2)'), '\\mathrm{SU}(2)') # Q-curve / Base change self.qc = "no" try: if self.q_curve: self.qc = "yes" except AttributeError: # in case the db entry does not have this field set pass # Torsion self.ntors = web_latex(self.torsion_order) self.tr = len(self.torsion_structure) if self.tr == 0: self.tor_struct_pretty = "Trivial" if self.tr == 1: self.tor_struct_pretty = "\(\Z/%s\Z\)" % self.torsion_structure[0] if self.tr == 2: self.tor_struct_pretty = r"\(\Z/%s\Z\times\Z/%s\Z\)" % tuple( self.torsion_structure) torsion_gens = [ E([self.field.parse_NFelt(x) for x in P]) for P in self.torsion_gens ] self.torsion_gens = ",".join([web_latex(P) for P in torsion_gens]) # Rank or bounds try: self.rk = web_latex(self.rank) except AttributeError: self.rk = "?" try: self.rk_bnds = "%s...%s" % tuple(self.rank_bounds) except AttributeError: self.rank_bounds = [0, Infinity] self.rk_bnds = "not available" # Generators try: gens = [ E([self.field.parse_NFelt(x) for x in P]) for P in self.gens ] self.gens = ", ".join([web_latex(P) for P in gens]) if self.rk == "?": self.reg = "not available" else: if gens: self.reg = E.regulator_of_points(gens) else: self.reg = 1 # otherwise we only get 1.00000... except AttributeError: self.gens = "not available" self.reg = "not available" try: if self.rank == 0: self.reg = 1 except AttributeError: pass # Local data self.local_data = [] for p in N.prime_factors(): self.local_info = E.local_data(p, algorithm="generic") self.local_data.append({ 'p': web_latex(p), 'norm': web_latex(p.norm().factor()), 'tamagawa_number': self.local_info.tamagawa_number(), 'kodaira_symbol': web_latex(self.local_info.kodaira_symbol()).replace('$', ''), 'reduction_type': self.local_info.bad_reduction_type(), 'ord_den_j': max(0, -E.j_invariant().valuation(p)), 'ord_mindisc': self.local_info.discriminant_valuation(), 'ord_cond': self.local_info.conductor_valuation() }) # URLs of self and related objects: self.urls = {} # It's useful to be able to use this class out of context, when calling url_for will fail: try: self.urls['curve'] = url_for(".show_ecnf", nf=self.field_label, conductor_label=quote( self.conductor_label), class_label=self.iso_label, number=self.number) except RuntimeError: return self.urls['class'] = url_for(".show_ecnf_isoclass", nf=self.field_label, conductor_label=quote( self.conductor_label), class_label=self.iso_label) self.urls['conductor'] = url_for(".show_ecnf_conductor", nf=self.field_label, conductor_label=quote( self.conductor_label)) self.urls['field'] = url_for(".show_ecnf1", nf=self.field_label) sig = self.signature real_quadratic = sig == [2, 0] totally_real = sig[1] == 0 imag_quadratic = sig == [0, 1] if totally_real: self.hmf_label = "-".join( [self.field.label, self.conductor_label, self.iso_label]) self.urls['hmf'] = url_for('hmf.render_hmf_webpage', field_label=self.field.label, label=self.hmf_label) self.urls['Lfunction'] = url_for("l_functions.l_function_hmf_page", field=self.field_label, label=self.hmf_label, character='0', number='0') if imag_quadratic: self.bmf_label = "-".join( [self.field.label, self.conductor_label, self.iso_label]) self.friends = [] self.friends += [('Isogeny class ' + self.short_class_label, self.urls['class'])] self.friends += [('Twists', url_for('ecnf.index', field_label=self.field_label, jinv=self.jinv))] if totally_real: self.friends += [('Hilbert Modular Form ' + self.hmf_label, self.urls['hmf'])] self.friends += [('L-function', self.urls['Lfunction'])] if imag_quadratic: self.friends += [ ('Bianchi Modular Form %s not available' % self.bmf_label, '') ] self.properties = [('Base field', self.field.field_pretty()), ('Label', self.label)] # Plot if E.base_field().signature()[0]: self.plot = encode_plot(EC_nf_plot(E, self.field.generator_name())) self.plot_link = '<img src="%s" width="200" height="150"/>' % self.plot self.properties += [(None, self.plot_link)] self.properties += [ ('Conductor', self.cond), ('Conductor norm', self.cond_norm), # See issue #796 for why this is hidden # ('j-invariant', self.j), ('CM', self.cm_bool) ] if self.base_change: self.properties += [ ('base-change', 'yes: %s' % ','.join([str(lab) for lab in self.base_change])) ] else: self.base_change = [] # in case it was False instead of [] self.properties += [('Q-curve', self.qc)] r = self.rk if r == "?": r = self.rk_bnds self.properties += [ ('Torsion order', self.ntors), ('Rank', r), ] for E0 in self.base_change: self.friends += [('Base-change of %s /\(\Q\)' % E0, url_for("ec.by_ec_label", label=E0))] self._code = None # will be set if needed by get_code()
def make_E(self): coeffs = self.ainvs # list of 5 lists of d strings self.ainvs = [self.field.parse_NFelt(x) for x in coeffs] self.latex_ainvs = web_latex(self.ainvs) from sage.schemes.elliptic_curves.all import EllipticCurve self.E = E = EllipticCurve(self.ainvs) self.equn = web_latex(E) self.numb = str(self.number) # Conductor, discriminant, j-invariant N = E.conductor() self.cond = web_latex(N) self.cond_norm = web_latex(N.norm()) if N.norm() == 1: # since the factorization of (1) displays as "1" self.fact_cond = self.cond else: self.fact_cond = web_latex_ideal_fact(N.factor()) self.fact_cond_norm = web_latex(N.norm().factor()) D = self.field.K().ideal(E.discriminant()) self.disc = web_latex(D) self.disc_norm = web_latex(D.norm()) if D.norm() == 1: # since the factorization of (1) displays as "1" self.fact_disc = self.disc else: self.fact_disc = web_latex_ideal_fact(D.factor()) self.fact_disc_norm = web_latex(D.norm().factor()) # Minimal model? # # All curves in the database should be given # by models which are globally minimal if possible, else # minimal at all but one prime. But we do not rely on this # here, and the display should be correct if either (1) there # exists a global minimal model but this model is not; or (2) # this model is non-minimal at more than one prime. # self.non_min_primes = non_minimal_primes(E) self.is_minimal = len(self.non_min_primes) == 0 self.has_minimal_model = True if not self.is_minimal: self.non_min_prime = ",".join([web_latex(P) for P in self.non_min_primes]) self.has_minimal_model = has_global_minimal_model(E) if not self.is_minimal: Dmin = minimal_discriminant_ideal(E) self.mindisc = web_latex(Dmin) self.mindisc_norm = web_latex(Dmin.norm()) if Dmin.norm() == 1: # since the factorization of (1) displays as "1" self.fact_mindisc = self.mindisc else: self.fact_mindisc = web_latex_ideal_fact(Dmin.factor()) self.fact_mindisc_norm = web_latex(Dmin.norm().factor()) j = E.j_invariant() if j: d = j.denominator() n = d * j # numerator exists for quadratic fields only! g = GCD(list(n)) n1 = n / g self.j = web_latex(n1) if d != 1: if n1 > 1: # self.j = "("+self.j+")\(/\)"+web_latex(d) self.j = web_latex(r"\frac{%s}{%s}" % (self.j, d)) else: self.j = web_latex(d) if g > 1: if n1 > 1: self.j = web_latex(g) + self.j else: self.j = web_latex(g) self.j = web_latex(j) self.fact_j = None if j.is_zero(): self.fact_j = web_latex(j) else: try: self.fact_j = web_latex(j.factor()) except (ArithmeticError, ValueError): # if not all prime ideal factors principal pass # CM and End(E) self.cm_bool = "no" self.End = "\(\Z\)" if self.cm: self.cm_bool = "yes (\(%s\))" % self.cm if self.cm % 4 == 0: d4 = ZZ(self.cm) // 4 self.End = "\(\Z[\sqrt{%s}]\)" % (d4) else: self.End = "\(\Z[(1+\sqrt{%s})/2]\)" % self.cm # Q-curve / Base change self.qc = "no" try: if self.q_curve: self.qc = "yes" except AttributeError: # in case the db entry does not have this field set pass # Torsion self.ntors = web_latex(self.torsion_order) self.tr = len(self.torsion_structure) if self.tr == 0: self.tor_struct_pretty = "Trivial" if self.tr == 1: self.tor_struct_pretty = "\(\Z/%s\Z\)" % self.torsion_structure[0] if self.tr == 2: self.tor_struct_pretty = r"\(\Z/%s\Z\times\Z/%s\Z\)" % tuple(self.torsion_structure) torsion_gens = [E([self.field.parse_NFelt(x) for x in P]) for P in self.torsion_gens] self.torsion_gens = ",".join([web_latex(P) for P in torsion_gens]) # Rank or bounds try: self.rk = web_latex(self.rank) except AttributeError: self.rk = "?" try: self.rk_bnds = "%s...%s" % tuple(self.rank_bounds) except AttributeError: self.rank_bounds = [0, Infinity] self.rk_bnds = "not recorded" # Generators try: gens = [E([self.field.parse_NFelt(x) for x in P]) for P in self.gens] self.gens = ", ".join([web_latex(P) for P in gens]) if self.rk == "?": self.reg = "unknown" else: if gens: self.reg = E.regulator_of_points(gens) else: self.reg = 1 # otherwise we only get 1.00000... except AttributeError: self.gens = "not recorded" self.reg = "unknown" try: if self.rank == 0: self.reg = 1 except AttributeError: pass # Local data self.local_data = [] for p in N.prime_factors(): self.local_info = E.local_data(p, algorithm="generic") self.local_data.append( { "p": web_latex(p), "norm": web_latex(p.norm().factor()), "tamagawa_number": self.local_info.tamagawa_number(), "kodaira_symbol": web_latex(self.local_info.kodaira_symbol()).replace("$", ""), "reduction_type": self.local_info.bad_reduction_type(), "ord_den_j": max(0, -E.j_invariant().valuation(p)), "ord_mindisc": self.local_info.discriminant_valuation(), "ord_cond": self.local_info.conductor_valuation(), } ) # URLs of self and related objects: self.urls = {} # It's useful to be able to use this class out of context, when calling url_for will fail: try: self.urls["curve"] = url_for( ".show_ecnf", nf=self.field_label, conductor_label=quote(self.conductor_label), class_label=self.iso_label, number=self.number, ) except RuntimeError: return self.urls["class"] = url_for( ".show_ecnf_isoclass", nf=self.field_label, conductor_label=quote(self.conductor_label), class_label=self.iso_label, ) self.urls["conductor"] = url_for( ".show_ecnf_conductor", nf=self.field_label, conductor_label=quote(self.conductor_label) ) self.urls["field"] = url_for(".show_ecnf1", nf=self.field_label) sig = self.signature real_quadratic = sig == [2, 0] totally_real = sig[1] == 0 imag_quadratic = sig == [0, 1] if totally_real: self.hmf_label = "-".join([self.field.label, self.conductor_label, self.iso_label]) self.urls["hmf"] = url_for("hmf.render_hmf_webpage", field_label=self.field.label, label=self.hmf_label) self.urls["Lfunction"] = url_for( "l_functions.l_function_hmf_page", field=self.field_label, label=self.hmf_label, character="0", number="0", ) if imag_quadratic: self.bmf_label = "-".join([self.field.label, self.conductor_label, self.iso_label]) self.friends = [] self.friends += [("Isogeny class " + self.short_class_label, self.urls["class"])] self.friends += [("Twists", url_for("ecnf.index", field_label=self.field_label, jinv=self.jinv))] if totally_real: self.friends += [("Hilbert Modular Form " + self.hmf_label, self.urls["hmf"])] self.friends += [("L-function", self.urls["Lfunction"])] if imag_quadratic: self.friends += [("Bianchi Modular Form %s not yet available" % self.bmf_label, "")] self.properties = [("Base field", self.field.field_pretty()), ("Label", self.label)] # Plot if E.base_field().signature()[0]: self.plot = encode_plot(EC_nf_plot(E, self.field.generator_name())) self.plot_link = '<img src="%s" width="200" height="150"/>' % self.plot self.properties += [(None, self.plot_link)] self.properties += [ ("Conductor", self.cond), ("Conductor norm", self.cond_norm), # See issue #796 for why this is hidden # ('j-invariant', self.j), ("CM", self.cm_bool), ] if self.base_change: self.properties += [("base-change", "yes: %s" % ",".join([str(lab) for lab in self.base_change]))] else: self.base_change = [] # in case it was False instead of [] self.properties += [("Q-curve", self.qc)] r = self.rk if r == "?": r = self.rk_bnds self.properties += [("Torsion order", self.ntors), ("Rank", r)] for E0 in self.base_change: self.friends += [("Base-change of %s /\(\Q\)" % E0, url_for("ec.by_ec_label", label=E0))] self.make_code_snippets()