def _anihilate_pol(k, M): ''' k: The weight of an element c, where c is a construction for generators of M_{det^* sym(10)} and an instance of ConstDivision. M: an instance of Sym10EvenDiv or Sym10OddDiv. Return a polynomial pl such that the subspace of M anihilated by pl(T(2)) is equal to the subspace of holomorphic modular forms. ''' R = PolynomialRing(QQ, names="x") x = R.gens()[0] if k % 2 == 0: # Klingen-Eisenstein series f = CuspForms(1, k + 10).basis()[0] return x - f[2] * (1 + QQ(2) ** (k - 2)) elif k == 13: # Kim-Ramakrishnan-Shahidi lift f = CuspForms(1, 12).basis()[0] a = f[2] return x - f[2] ** 3 + QQ(2) ** 12 * f[2] else: chrply = M.hecke_charpoly(2) dim = hilbert_series_maybe(10)[k] l = [(a, b) for a, b in chrply.factor() if a.degree() == dim] if len(l) > 1 or l[0][1] != 1: raise RuntimeError else: return l[0][0]
def main1(): S = PolynomialRing(GF(Integer(13)), names=('x',)) (x,) = S.gens() R = S.quotient(x**Integer(2) - Integer(3), names=('alpha',)) (alpha,) = R.gens() print((Integer(2) + Integer(3) * alpha) * (Integer(1) + Integer(2) * alpha))
def to_polredabs(K): """ INPUT: * "K" - a number field OUTPUT: * "phi" - an isomorphism K -> L, where L = QQ['x']/f and f a polynomial such that f = polredabs(f) """ R = PolynomialRing(QQ,'x') x = R.gen(0) if K == QQ: L = QQ.extension(x,'w') return QQ.hom(L) L = K.absolute_field('a') m1 = L.structure()[1] f = L.absolute_polynomial() g = pari(f).polredabs(1) g,h = g[0].sage(locals={'x':x}),g[1].lift().sage(locals={'x':x}) if debug: print 'f',f print 'g',g print 'h',h M = QQ.extension(g,'w') m2 = L.hom([h(M.gen(0))]) return m2*m1
def EllipticCurve_from_hoeij_data(line): """Given a line of the file "http://www.math.fsu.edu/~hoeij/files/X1N/LowDegreePlaces" that is actually corresponding to an elliptic curve, this function returns the elliptic curve corresponding to this """ Rx=PolynomialRing(QQ,'x') x = Rx.gen(0) Rxy = PolynomialRing(Rx,'y') y = Rxy.gen(0) N=ZZ(line.split(",")[0].split()[-1]) x_rel=Rx(line.split(',')[-2][2:-4]) assert x_rel.leading_coefficient()==1 y_rel=line.split(',')[-1][1:-5] K = QQ.extension(x_rel,'x') x = K.gen(0) y_rel=Rxy(y_rel).change_ring(K) y_rel=y_rel/y_rel.leading_coefficient() if y_rel.degree()==1: y = - y_rel[0] else: #print "needing an extension!!!!" L = K.extension(y_rel,'y') y = L.gen(0) K = L #B=L.absolute_field('s') #f1,f2 = B.structure() #x,y=f2(x),f2(y) r = (x**2*y-x*y+y-1)/x/(x*y-1) s = (x*y-y+1)/x/y b = r*s*(r-1) c = s*(r-1) E=EllipticCurve([1-c,-b,-b,0,0]) return N,E,K
def theta_sym(self, j=2): ''' Returns an image as a vector valued (Sym_{j} j:even) Fourier expansion of the generalized Theta operator associated with the Rankin-cohen operator {F, G}_{Sym_{j}}. [Reference] Ibukiyama, Vector valued Siegel modular forms of symmetric tensor weight of small degrees, COMMENTARI MATHEMATICI UNIVERSITATIS SANCTI PAULI VOL 61, NO 1, 2012. Boecherer, Nagaoka, On p-adic properties of Siegel modular forms, arXiv, 2013. ''' R = PolynomialRing(QQ, "r1, r2, r3") (r1, r2, r3) = R.gens() S = PolynomialRing(R, "u1, u2") (u1, u2) = S.gens() pl = (r1 * u1 ** 2 + r2 * u1 * u2 + r3 * u2 ** 2) ** (j // 2) pldct = pl.dict() formsdict = {} for (_, i), ply in pldct.iteritems(): formsdict[i] = sum([v * self._differential_operator_monomial(a, b, c) for (a, b, c), v in ply.dict().iteritems()]) forms = [x for _, x in sorted([(i, v) for i, v in formsdict.iteritems()], key=lambda x: x[0])] return SymWtGenElt(forms, self.prec, self.base_ring)
def test_karatsuba_multiplication(base_ring, maxdeg1, maxdeg2, ref_mul=lambda f, g: f._mul_generic(g), base_ring_random_elt_args=[], numtests=10, verbose=False): """ Test univariate karatsuba multiplication against other multiplication algorithms. EXAMPLES: First check that random tests are reproducible:: sage: import sage.rings.tests sage: sage.rings.tests.test_karatsuba_multiplication(ZZ, 6, 5, verbose=True, seed=42) test_karatsuba_multiplication: ring=Univariate Polynomial Ring in x over Integer Ring, threshold=2 (2*x^6 - x^5 - x^4 - 3*x^3 + 4*x^2 + 4*x + 1)*(4*x^4 + x^3 - 2*x^2 - 20*x + 3) (16*x^2)*(x^2 - 41*x + 1) (-x + 1)*(x^2 + 2*x + 8) (-x^6 - x^4 - 8*x^3 - x^2 - 4*x + 3)*(-x^3 - x^2) (2*x^2 + x + 1)*(x^4 - x^3 + 3*x^2 - x) (-x^3 + x^2 + x + 1)*(4*x^2 + 76*x - 1) (6*x + 1)*(-5*x - 1) (-x^3 + 4*x^2 + x)*(-x^5 + 3*x^4 - 2*x + 5) (-x^5 + 4*x^4 + x^3 + 21*x^2 + x)*(14*x^3) (2*x + 1)*(12*x^3 - 12) Test Karatsuba multiplication of polynomials of small degree over some common rings:: sage: for C in [QQ, ZZ[I], ZZ[I, sqrt(2)], GF(49, 'a'), MatrixSpace(GF(17), 3)]: ....: sage.rings.tests.test_karatsuba_multiplication(C, 10, 10) Zero-tests over ``QQbar`` are currently very slow, so we test only very small examples:: sage.rings.tests.test_karatsuba_multiplication(QQbar, 3, 3, numtests=2) Larger degrees (over ``ZZ``, using FLINT):: sage: sage.rings.tests.test_karatsuba_multiplication(ZZ, 1000, 1000, ref_mul=lambda f,g: f*g, base_ring_random_elt_args=[1000]) Some more aggressive tests:: sage: for C in [QQ, ZZ[I], ZZ[I, sqrt(2)], GF(49, 'a'), MatrixSpace(GF(17), 3)]: ....: sage.rings.tests.test_karatsuba_multiplication(C, 10, 10) # long time sage: sage.rings.tests.test_karatsuba_multiplication(ZZ, 10000, 10000, ref_mul=lambda f,g: f*g, base_ring_random_elt_args=[100000]) """ from sage.all import randint, PolynomialRing threshold = randint(0, min(maxdeg1,maxdeg2)) R = PolynomialRing(base_ring, 'x') if verbose: print "test_karatsuba_multiplication: ring={}, threshold={}".format(R, threshold) for i in range(numtests): f = R.random_element(randint(0, maxdeg1), *base_ring_random_elt_args) g = R.random_element(randint(0, maxdeg2), *base_ring_random_elt_args) if verbose: print " ({})*({})".format(f, g) if ref_mul(f, g) - f._mul_karatsuba(g, threshold) != 0: raise ValueError("Multiplication failed") return
def _pair_gens_r_s(): rnames = "r11, r12, r22, s11, s12, s22" unames = "u1, u2" RS_ring = PolynomialRing(QQ, names=rnames) (r11, r12, r22, s11, s12, s22) = RS_ring.gens() (u1, u2) = PolynomialRing(RS_ring, names=unames).gens() r = r11 * u1 ** 2 + 2 * r12 * u1 * u2 + r22 * u2 ** 2 s = s11 * u1 ** 2 + 2 * s12 * u1 * u2 + s22 * u2 ** 2 return (RS_ring.gens(), (u1, u2), (r, s))
def eu(p): """ local euler factor """ f = rho.local_factor(p) co = [ZZ(round(x)) for x in f.coefficients(sparse=False)] R = PolynomialRing(QQ, "T") T = R.gens()[0] return sum( co[n] * T**n for n in range(len(co)))
def _hecke_pol_klingen(k, j): '''k: even. F: Kligen-Eisenstein series of determinant weight k whose Hecke field is the rational filed. Return the Hecke polynomial of F at 2. ''' f = CuspForms(1, k + j).basis()[0] R = PolynomialRing(QQ, names="x") x = R.gens()[0] pl = QQ(1) - f[2] * x + QQ(2) ** (k + j - 1) * x ** 2 return pl * pl.subs({x: x * QQ(2) ** (k - 2)})
def _hecke_pol_krs_lift(): '''Return the Hecke polynomial of KRS lift of weight det^{13}Sym(10) at 2. ''' R = PolynomialRing(QQ, names="x") x = R.gens()[0] f = CuspForms(1, 12).basis()[0] a = f[2] b = QQ(2) ** 11 return ((1 - (a ** 3 - 3 * a * b) * x + b ** 3 * x ** 2) * (1 - a * b * x + b ** 3 * x ** 2))
def polredabs(self): if "polredabs" in self._data.keys(): return self._data["polredabs"] else: pol = PolynomialRing(QQ, 'x')(self.polynomial()) pol *= pol.denominator() R = pol.parent() from sage.all import pari pol = R(pari(pol).polredabs()) self._data["polredabs"] = pol return pol
def _hecke_tp_charpoly(self, p, var='x', algorithm='linbox'): a = p ** (self.wt - 2) + 1 N = self.klingeneisensteinAndCuspForms() S = CuspForms(1, self.wt) m = S.dimension() R = PolynomialRing(QQ, names=var) x = R.gens()[0] f = R(S.hecke_matrix(p).charpoly(var=var, algorithm=algorithm)) f1 = f.subs({x: a ** (-1) * x}) * a ** m g = R(N.hecke_matrix(p).charpoly(var=var, algorithm=algorithm)) return R(g / f1)
def G_poly(l, m): '''The polynomial G of y1, y2 and y3 given in Proposition 3.7, [Kat]. ''' R = PolynomialRing(QQ, names="y1, y2, y3") y1, y2, y3 = R.gens() return sum(binomial(2 * n + l - QQ(5) / QQ(2), n) * y3 ** n * sum((-y2) ** nu * (2 * y1) ** (m - 2 * n - 2 * nu) * binomial(l + m - nu - QQ(5) / QQ(2), m - 2 * n - nu) * binomial(m - 2 * n - nu, nu) for nu in range((m - 2 * n) // 2 + 1)) for n in range(m // 2 + 1))
def _get_Rgens(self): d = self.dim if self.single_generator: if self.hecke_ring_power_basis and self.field_poly_root_of_unity != 0: R = PolynomialRing(QQ, self._nu_var) else: R = PolynomialRing(QQ, 'beta') beta = R.gen() return [beta**i for i in range(d)] else: R = PolynomialRing(QQ, ['beta%s' % i for i in range(1,d)]) return [1] + [g for g in R.gens()]
def test_cusp_sp_wt28_hecke_charpoly(self): R = PolynomialRing(QQ, names="x") x = R.gens()[0] pl = (x ** Integer(7) - Integer(599148384) * x ** Integer(6) + Integer(85597740037545984) * x ** Integer(5) + Integer(4052196666582552432082944) * x ** Integer(4) - Integer(992490558368877866775830593536000) * x ** Integer(3) - Integer(7786461340613962559507216233894458163200) * x ** Integer(2) + Integer(2554655965904300151500968857660777576875950080000) * x + Integer(2246305351725266922462270484154998253269432286576640000)) S = CuspFormsDegree2(28) self.assertTrue(R(S.hecke_charpoly(2)) == pl)
def polredabs(self): if "polredabs" in self._data.keys(): return self._data["polredabs"] else: pol = PolynomialRing(QQ, 'x')(map(str,self.polynomial())) # Need to map because the coefficients are given as unicode, which does not convert to QQ pol *= pol.denominator() R = pol.parent() from sage.all import pari pol = R(pari(pol).polredabs()) self._data["polredabs"] = pol return pol
def pol_string_to_list(pol, deg=None, var=None): if var is None: from lmfdb.hilbert_modular_forms.hilbert_field import findvar var = findvar(pol) if not var: var = 'a' pol = PolynomialRing(QQ, var)(str(pol)) if deg is None: fill = 0 else: fill = deg - pol.degree() - 1 return [str(c) for c in pol.coefficients(sparse=False)] + ['0']*fill
def dict_to_pol(dct, bd=global_prec, base_ring=QQ): R = PolynomialRing(base_ring, "u1, u2, q1, q2") (u1, u2, q1, q2) = R.gens() S = R.quotient(u1 * u2 - 1) (uu1, uu2, qq1, qq2) = S.gens() l = PrecisionDeg2(bd) if not hasattr(dct, "__getitem__"): return dct return sum([dct[(n, r, m)] * uu1 ** r * qq1 ** n * qq2 ** m if r > 0 else dct[(n, r, m)] * uu2 ** (-r) * qq1 ** n * qq2 ** m for n, r, m in l])
def coeffs_to_poly(c_string): """Given a string of coefficients, returns the polynomial with those coefficients INPUT: c_string -- string, a a comma-separated string (with no spaces) of rational numbers OUTPUT: The polynomial with these coefficients """ R = PolynomialRing(QQ, names=('x',)) (x,) = R._first_ngens(1) tup = eval(c_string) return sum([tup[i]*x**i for i in range(0,len(tup))])
def _to_polynomial(f, val1): prec = f.prec.value R = PolynomialRing(QQ if f.base_ring == ZZ else f.base_ring, names="q1, q2") q1, q2 = R.gens() I = R.ideal([q1 ** (prec + 1), q2 ** (prec + 1)]) S = R.quotient_ring(I) res = sum([sum([f.fc_dct.get((n, r, m), 0) * QQ(val1) ** r for r in range(-int(floor(2 * sqrt(n * m))), int(floor(2 * sqrt(n * m))) + 1)]) * q1 ** n * q2 ** m for n in range(prec + 1) for m in range(prec + 1)]) return S(res)
def eu(p): """ local euler factor """ if self.selfdual: K = QQ else: K = ComplexField() R = PolynomialRing(K, "T") T = R.gens()[0] if self.conductor % p != 0: return 1 - ComplexField()(chi(p)) * T else: return R(1)
def _method_pt1(num_bits,k,D,y): a = Integer(-D*y**2) R = PolynomialRing(ZZ,'x') f = R.cyclotomic_polynomial(k)(x-1).polynomial(base_ring = R) g = (a+(x-2)**2).polynomial(base_ring = R) r = Integer(f.resultant(g)) if (Mod(r, k) == 1) and r > 2**(num_bits-1) and utils.is_suitable_r(r): # found a valid r, so use it F = GF(r) f = f.change_ring(F) g = g.change_ring(F) t = Integer(f.gcd(g).any_root()) return t,r else: return 0,0
def eu(p): """ Local euler factor """ ans = F.q_expansion_embeddings(p + 1) K = ComplexField() R = PolynomialRing(K, "T") T = R.gens()[0] N = self.conductor if N % p != 0 : # good reduction return 1 - ans[p-1][self.number] * T + T**2 elif N % (p**2) != 0: # semistable reduction return 1 - ans[p-1][self.number] * T else: return R(1)
def euler_factor_of_spinor_l(self, p, var="x"): ''' Assuming self is eigenform, this method returns p-Euler factor of spinor L as a polynomial. ''' K = self.base_ring if hasattr(K, "fraction_field"): K = K.fraction_field() R = PolynomialRing(K, 1, names=var, order='neglex') x = R.gens()[0] a1 = self.hecke_eigenvalue(p) a2 = self.hecke_eigenvalue(p ** 2) mu = 2 * self.wt + self.sym_wt - 3 return (1 - a1 * x + (a1 ** 2 - a2 - p ** (mu - 1)) * x ** 2 - a1 * p ** mu * x ** 3 + p ** (2 * mu) * x ** 4)
def poly_to_field_label(pol): try: pol = PolynomialRing(QQ, 'x')(str(pol)) pol *= pol.denominator() R = pol.parent() pol = R(pari(pol).polredabs()) except: return None coeffs = list2string([int(c) for c in pol.coeffs()]) d = int(pol.degree()) query = {'coeffs': coeffs} C = base.getDBConnection() one = C.numberfields.fields.find_one(query) if one: return one['label'] return None
def create_key(self,base_ring, arg1=None, arg2=None, sparse=False, order='degrevlex', names=None, name=None, implementation=None, degrees=None): """ Create the key under which a free algebra is stored. TESTS:: sage: FreeAlgebra.create_key(GF(5),['x','y','z']) (Finite Field of size 5, ('x', 'y', 'z')) sage: FreeAlgebra.create_key(GF(5),['x','y','z'],3) (Finite Field of size 5, ('x', 'y', 'z')) sage: FreeAlgebra.create_key(GF(5),3,'xyz') (Finite Field of size 5, ('x', 'y', 'z')) sage: FreeAlgebra.create_key(GF(5),['x','y','z'], implementation='letterplace') (Multivariate Polynomial Ring in x, y, z over Finite Field of size 5,) sage: FreeAlgebra.create_key(GF(5),['x','y','z'],3, implementation='letterplace') (Multivariate Polynomial Ring in x, y, z over Finite Field of size 5,) sage: FreeAlgebra.create_key(GF(5),3,'xyz', implementation='letterplace') (Multivariate Polynomial Ring in x, y, z over Finite Field of size 5,) sage: FreeAlgebra.create_key(GF(5),3,'xyz', implementation='letterplace', degrees=[1,2,3]) ((1, 2, 3), Multivariate Polynomial Ring in x, y, z, x_ over Finite Field of size 5) """ if arg1 is None and arg2 is None and names is None: # this is used for pickling if degrees is None: return (base_ring,) return tuple(degrees),base_ring PolRing = None # test if we can use libSingular/letterplace if implementation is not None and implementation != 'generic': try: PolRing = PolynomialRing(base_ring, arg1, arg2, sparse=sparse, order=order, names=names, name=name, implementation=implementation if implementation!='letterplace' else None) if not isinstance(PolRing,MPolynomialRing_libsingular): if PolRing.ngens() == 1: PolRing = PolynomialRing(base_ring,1,PolRing.variable_names()) if not isinstance(PolRing,MPolynomialRing_libsingular): raise TypeError else: raise TypeError except (TypeError, NotImplementedError),msg: raise NotImplementedError, "The letterplace implementation is not available for the free algebra you requested"
def eu(p): """ Local euler factor """ # There was no function q_expansion_embeddings before the transition to postgres # so I'm not sure what this is supposed to do. ans = F.q_expansion_embeddings(p + 1) K = ComplexField() R = PolynomialRing(K, "T") T = R.gens()[0] N = self.conductor if N % p != 0 : # good reduction return 1 - ans[p-1][self.number] * T + T**2 elif N % (p**2) != 0: # semistable reduction return 1 - ans[p-1][self.number] * T else: return R(1)
def _hecke_tp2_charpoly(self, p, var='x', algorithm='linbox'): u = p ** (self.wt - 2) N = self.klingeneisensteinAndCuspForms() S = CuspForms(1, self.wt) m = S.dimension() R = PolynomialRing(QQ, names=var) x = R.gens()[0] f = R(S.hecke_matrix(p).charpoly(var=var, algorithm=algorithm)) g = R(N.hecke_matrix(p ** 2).charpoly(var=var, algorithm=algorithm)) def morph(a, b, f, m): G = (-1) ** m * f.subs({x: -x}) * f alst = [[k // 2, v] for k, v in G.dict().iteritems()] F = sum([v * x ** k for k, v in alst]) return a ** m * F.subs({x: (x - b) / a}) f1 = morph(u ** 2 + u + 1, -p * u ** 3 - u ** 2 - p * u, f, m) return R(g / f1)
def pol_to_dict(pl, bd=global_prec, base_ring=QQ): R = PolynomialRing(base_ring, "u1,u2,q1,q2") (u1, u2, q1, q2) = R.gens() S = R.quotient(u1 * u2 - 1) (uu1, uu2, qq1, qq2) = S.gens() l = PrecisionDeg2(bd) pl_lft = pl.lift() dct = dict() for n, r, m in l: if r >= 0: cfs = pl_lft.coefficient({u1: r, u2: 0, q1: n, q2: m}) else: cfs = pl_lft.coefficient({u1: 0, u2: -r, q1: n, q2: m}) dct[(n, r, m)] = cfs for t in l: if not t in dct.keys(): dct[t] = 0 return dct
def eu(p): """ Local Euler factor passed as a function whose input is a prime and whose output is a polynomial such that evaluated at p^-s, we get the inverse of the local factor of the L-function """ R = PolynomialRing(QQ, "T") T = R.gens()[0] N = self.conductor if N % p != 0 : # good reduction return 1 - E.ap(p) * T + p * T**2 elif N % (p**2) != 0: # multiplicative reduction return 1 - E.ap(p) * T else: return R(1)
def test_download_sage(self): # A dimension 1 example L1_sage_code = self.tc.get( '/ModularForm/GL2/ImaginaryQuadratic/2.0.3.1/18333.3/a/download/sage' ).get_data(as_text=True) L1_level = self.check_sage_compiles_and_extract_var(L1_sage_code, 'NN') assert L1_level.norm() == Integer(18333) assert 'NN = ZF.ideal((6111, 3*a + 5052))' in L1_sage_code assert '(27*a-22,),(-29*a+15,),(-29*a+14,),(29*a-11,),(-29*a+18,),(-29*a+9,)' in L1_sage_code assert 'hecke_eigenvalues_array = [0, -1, 2, -1, 1, -3, 4, 0, -2, -8, 7, -9, -8, -4, -9, 8, 10, -11,' in L1_sage_code """ Observe that example 1 above checks equality of the level norm between the loaded sage code and what appears on the homepage, but then checks for a particular presentation of that ideal in the text file. The problem with this is that the choice of generators for the ideal are not unique, and could potentially change from one sage release to the next. An alternative is to check for equality of the ideals themselves, and that is the strategy adopted in the following example. """ # A dimension 2 example L2_sage_code = self.tc.get( '/ModularForm/GL2/ImaginaryQuadratic/2.0.4.1/377.1/a2/download/sage' ).get_data(as_text=True) L2_level = self.check_sage_compiles_and_extract_var(L2_sage_code, 'NN') P = PolynomialRing(QQ, 'x') g = P([1, 0, 1]) F = NumberField(g, 'i') i = F.gen() ZF = F.ring_of_integers() L2_level_actual = ZF.ideal( (16 * i - 11)) # the level displayed on BMF homepage assert L2_level == L2_level_actual assert L2_level.norm() == 377 assert '(2*i+3,),(i+4,),(i-4,),(-2*i+5,),(2*i+5,),(i+6,)' in L2_sage_code assert 'hecke_eigenvalues_array = [-z, 2*z, -1, 2*z+2, "not known", 2*z-1, 4, 2*z+3, "not known", 2*z+1, -2*z-5, -4*z+5, -4*z+5, 2*z+1, 2*z]' in L2_sage_code
def InsolublePlaces(f,h=0): # List of primes at which the curve y²+h(x)*y=f(x) is not soluble # Assumes f and h have integer coefficients S = [] # List of primes at which not soluble # Get eqn of the form y²=F(x) F = f if h: F = 4*f + h**2 # Do we have a rational point an Infty ? if F.degree()%2 or F.leading_coefficient().is_square(): return [] # Treat case of RR if F.leading_coefficient() < 0 and F.number_of_real_roots() == 0: S.append(0) # Remove squares from lc(F) d = F.degree() lc = F.leading_coefficient() t = F.variables()[0] a = lc.squarefree_part() # lc/a is a square a = lc//a Zx = PolynomialRing(ZZ,'x') F = Zx(a**(d-1) * F(t/a)) # Find primes of bad reduction for our model D = F.disc() P = Set(D.prime_divisors()) # Add primes at which Weil bounds do not guarantee a mod p point g = (d-2)//2 Weil = [] p = 2 while (p+1)**2 <= 4 * g**2 * p: Weil.append(p) p = next_prime(p) P = P.union(Set(Weil)) # Test for solubility for p in P: if not IsSolubleAt(F,p): S.append(p) S.sort() return S
def repair_fields(D): F = hmf_fields.find_one({"label": '2.2.' + str(D) + '.1'}) P = PolynomialRing(QQ, 'w') # P is used implicitly in the eval() calls below. When these are # removed, this will not longer be neceesary, but until then the # assert statement is for pyflakes. assert P primes = F['primes'] primes = [[int(eval(p)[0]), int(eval(p)[1]), str(eval(p)[2])] for p in primes] F['primes'] = primes hmff = open("data_2_" + (4 - len(str(D))) * '0' + str(D)) # Parse field data for i in range(7): v = hmff.readline() ideals = eval(v[10:][:-2]) ideals = [[p[0], p[1], str(p[2])] for p in ideals] F['ideals'] = ideals hmf_fields.save(F)
def qexp_as_nf_elt(self, prec=None): assert self.has_exact_qexp if prec is None: qexp = self.qexp else: qexp = self.qexp[:prec + 1] if self.dim == 1: return [QQ(i[0]) for i in self.qexp] R = PolynomialRing(QQ, 'x') K = QQ.extension(R(self.field_poly), 'a') if self.hecke_ring_power_basis: return [K(c) for c in qexp] else: # need to add code to hande cyclotomic_generators assert self.hecke_ring_numerators, self.hecke_ring_denominators basis_data = zip(self.hecke_ring_numerators, self.hecke_ring_denominators) betas = [K([ZZ(c) / den for c in num]) for num, den in basis_data] return [ sum(c * beta for c, beta in zip(coeffs, betas)) for coeffs in qexp ]
def poly_to_field_label(pol): try: pol = PolynomialRing(QQ, 'x')(str(pol)) pol *= pol.denominator() R = pol.parent() pol = R(pari(pol).polredabs()) except: return None coeffs = [int(c) for c in pol.coeffs()] d = int(pol.degree()) query = {'degree': d, 'coefficients': coeffs} import base C = base.getDBConnection() one = C.numberfields.fields.find_one(query) if one: return one['label'] return None
def __init__(self, K, L, approximation=None): if isinstance(approximation, MacLaneLimitValuation): # v = apprximation determines phi uniquely v = approximation assert v(K.polynomial()) == Infinity else: if approximation == None: R = PolynomialRing(L.number_field(), 'x') v0 = GaussValuation(R, L.valuation()) else: v0 = approximation # now we have to find a limit valuation v such that v(P_K)=infinity # which is approximated by v0 P = R(K.polynomial()) V = [v0] done = False while len(V) > 0 and not done > 0: V_new = [] for v in V: if v.phi().degree() == 1: if v.effective_degree(P) == 1 or v.mu() == Infinity: V_new = [v] done = True break else: V_new += v.mac_lane_step(P, assume_squarefree=True, check=False) V = V_new if len(V) == 0: raise AssertionError("no embedding exists") else: v = V[0] # now v is an approximation of an irreducible factor of P of degree 1 v = LimitValuation(v, P) self._domain = K self._target = L self._limit_valuation = v
def divisor_data(P): R = PolynomialRing(QQ, ['x', 'z']) x = R('x') z = R('z') xP, yP = P[0], P[1] xden, yden = lcm([r[1] for r in xP]), lcm([r[1] for r in yP]) xD = sum([ ZZ(xden) * ZZ(xP[i][0]) / ZZ(xP[i][1]) * x**i * z**(len(xP) - i - 1) for i in range(len(xP)) ]) if str(xD.factor())[:4] == "(-1)": xD = -xD yD = sum([ ZZ(yden) * ZZ(yP[i][0]) / ZZ(yP[i][1]) * x**i * z**(len(yP) - i - 1) for i in range(len(yP)) ]) return [ make_bigint(elt, 10) for elt in [ str(xD.factor()).replace("**", "^").replace("*", ""), str(yden) + "y" if yden > 1 else "y", str(yD).replace("**", "^").replace("*", "") ] ], xD, yD, yden
def get_local_algebra(self, p): local_algebra_dict = self._data.get('loc_algebras', None) if local_algebra_dict is None: return None if str(p) in local_algebra_dict: R = PolynomialRing(QQ, 'x') palg = local_algebra_dict[str(p)] palgs = [R(str(s)) for s in palg.split(',')] palgs = [ list2string([int(c) for c in pol.coefficients(sparse=False)]) for pol in palgs ] palgs = [lfdb().find_one({'p': p, 'coeffs': c}) for c in palgs] return [[ f['label'], latex(R(string2list(f['coeffs']))), int(f['e']), int(f['f']), int(f['c']), group_display_knowl(f['gal'][0], f['gal'][1], db()), f['t'], f['u'], f['slopes'] ] for f in palgs] return None
def taylor_processor_naive(new_ring, Phi, scalar, alpha, I, omega): k = alpha.nrows() - 1 tau = SR.var('tau') y = [SR('y%d' % i) for i in range(k + 1)] R = PolynomialRing(QQ, len(y), y) beta = [a * Phi for a in alpha] def f(i): if i == 0: return QQ(scalar) * y[0] * exp(tau * omega[0]) elif i in I: return 1 / (1 - exp(tau * omega[i])) else: return 1 / (1 - y[i] * exp(tau * omega[i])) h = prod(f(i) for i in range(k + 1)) # Get constant term of h as a Laurent series in tau. g = h.series(tau, 1).truncate().collect(tau).coefficient(tau, 0) g = g.factor() if g else g yield CyclotomicRationalFunction.from_split_expression( g, y, R).monomial_substitution(new_ring, beta)
def Relative_Splitting_Field_Extra(fs, bound=0): bound_set = (bound != 0) F = magma.BaseRing(fs[1]) overQQ = (magma.Degree(F) == 1) if overQQ: R = PolynomialRing(QQ, 'x') fs = sorted(fs, key=lambda f: -magma.Degree(f)) K = F for f in fs: if not magma.HasRoot(f, K): for tup in magma.Factorization(f, K): K = magma.ExtendRelativeSplittingField(K, F, tup[1]) if overQQ: g = magma.DefiningPolynomial(K) g = R(str(gp.polredabs(R(magma.Eltseq(g))))) K = magma.NumberField(g) else: K = magma.ClearFieldDenominator(K) if bound_set and magma.Degree(K) >= bound: K = magma.DefineOrExtendInfinitePlaceFunction(K) return K K = magma.DefineOrExtendInfinitePlaceFunction(K) return K
def list_to_factored_poly_otherorder(s, galois=False, vari='T', p=None): """ Either return the polynomial in a nice factored form, or return a pair, with first entry the factored polynomial and the second entry a list describing the Galois groups of the factors. vari allows to choose the variable of the polynomial to be returned. """ if len(s) == 1: if galois: return [str(s[0]), [[0, 0]]] return str(s[0]) ZZT = PolynomialRing(ZZ, vari) sfacts = ZZT(s).factor() sfacts_fc = [[g, e] for g, e in sfacts] if sfacts.unit() == -1: sfacts_fc[0][0] *= -1 # if the factor is -1+T^2, replace it by 1-T^2 # this should happen an even number of times, mod powers sfacts_fc_list = [[(-g).list() if g[0] == -1 else g.list(), e] for g, e in sfacts_fc] return list_factored_to_factored_poly_otherorder(sfacts_fc_list, galois, vari, p)
def compute_local_roots_SMF2_scalar_valued(K, ev, k, embedding): ''' computes the dirichlet series for a Lfunction_SMF2_scalar_valued ''' L = ev.keys() m = ZZ(max(L)).isqrt() + 1 ev2 = {} for p in primes(m): try: ev2[p] = (ev[p], ev[p * p]) except: break logger.debug(str(ev2)) ret = [] for p in ev2: R = PolynomialRing(K, 'x') x = R.gens()[0] f = (1 - ev2[p][0] * x + (ev2[p][0]**2 - ev2[p][1] - p**(2 * k - 4)) * x**2 - ev2[p][0] * p**(2 * k - 3) * x**3 + p**(4 * k - 6) * x**4) Rnum = PolynomialRing(CF, 'y') x = Rnum.gens()[0] fnum = Rnum(0) if K != QQ: for i in range(int(f.degree()) + 1): fnum = fnum + f[i].complex_embeddings(NN)[embedding] * ( x / p**(k - 1.5))**i else: for i in range(int(f.degree()) + 1): fnum = fnum + f[i] * (x / CF(p**(k - 1.5)))**i r = fnum.roots(CF) r = [1 / a[0] for a in r] # a1 = r[1][0]/r[0][0] # a2 = r[2][0]/r[0][0] # a0 = 1/r[3][0] ret.append((p, r)) return ret
def h(t, prec): Dop, x, Dx = DifferentialOperators(QQ) L = Dx * (x * (x - 1) * (x - t)) * Dx + x hprec = prec + 100 C = ComplexField(hprec) CBF = ComplexBallField(hprec) # Formal monodromy + connection matrices base = t / 2 m1 = L.numerical_transition_matrix([0, base], ZZ(2)**(-prec)) m2 = L.numerical_transition_matrix([t, base], ZZ(2)**(-prec)) delta = matrix(CBF, [[1, 0], [2 * pi * i, 1]]) mat = m1 * delta * ~m1 * m2 * delta * ~m2 # log(eigenvalue) tr = mat.trace().real().mid() Pol, la = PolynomialRing(C, 'la').objgen() char = (la + 1 / la - tr).numerator() rt = char.roots(multiplicities=False)[0] val = (rt.log() / C(2 * i * pi))**2 return val
def test_skipper_prec(skipper=Skipper4, kyber=Kyber, l=None): """Test precision prediction by construction worst case instance (?) :param skipper: Skipper instance :param kyber: Kyber instance for parameters such as `n` and `q` :param l: bits of precision to use TESTS:: sage: test_skipper_prec(Skipper4, Kyber) sage: l = ceil(Skipper4.prec(Kyber)) - 1 sage: test_skipper_prec(Skipper4, Kyber, l=l) Traceback (most recent call last): ... AssertionError sage: test_skipper_prec(Skipper2Negated, Kyber) sage: l = ceil(Skipper2Negated.prec(Kyber)) - 1 sage: test_skipper_prec(Skipper2Negated, Kyber, l=l) Traceback (most recent call last): ... AssertionError """ n, q, k, eta = kyber.n, kyber.q, kyber.k, kyber.eta R, x = PolynomialRing(ZZ, "x").objgen() f = R(kyber.f) # attempt to construct a worst-case instance a = vector(R, k, [R([q // 2 for _ in range(n)]) for _ in range(k)]) b = vector(R, k, [R([eta for _ in range(n)]) for _ in range(k)]) c = R([eta for _ in range(n)]) d0 = (a * b + c) % f d1 = skipper.muladd(kyber, a, b, c, l=l) assert (d0 == d1)
def p2sage(s): """Convert s to something sensible in Sage. Can handle objects (including strings) representing integers, reals, complexes (in terms of 'i' or 'I'), polynomials in 'a' with integer coefficients, or lists of the above. """ z = s if type(z) in [list, tuple]: return [p2sage(t) for t in z] else: Qa = PolynomialRing(RationalField(),"a") for f in [ZZ, RR, CC, Qa]: try: return f(z) # SyntaxError is raised by CC('??') # NameError is raised by CC('a') except (ValueError, TypeError, NameError, SyntaxError): try: return f(str(z)) except (ValueError, TypeError, NameError, SyntaxError): pass if z!='??': logger.error('Error converting "{}" in p2sage'.format(z)) return z
def nf_data(**args): label = args['nf'] nf = WebNumberField(label) data = '/* Data is in the following format\n' data += ' Note, if the class group has not been computed, it, the class number, the fundamental units, regulator and whether grh was assumed are all 0.\n' data += '[polynomial,\ndegree,\nt-number of Galois group,\nsignature [r,s],\ndiscriminant,\nlist of ramifying primes,\nintegral basis as polynomials in a,\n1 if it is a cm field otherwise 0,\nclass number,\nclass group structure,\n1 if grh was assumed and 0 if not,\nfundamental units,\nregulator,\nlist of subfields each as a pair [polynomial, number of subfields isomorphic to one defined by this polynomial]\n]' data += '\n*/\n\n' zk = nf.zk() Ra = PolynomialRing(QQ, 'a') zk = [str(Ra(x)) for x in zk] zk = ', '.join(zk) units = str(unlatex(nf.units())) units = units.replace(' ', ' ') subs = nf.subfields() subs = [[coeff_to_poly(string2list(z[0])), z[1]] for z in subs] # Now add actual data data += '[%s, ' % nf.poly() data += '%s, ' % nf.degree() data += '%s, ' % nf.galois_t() data += '%s, ' % nf.signature() data += '%s, ' % nf.disc() data += '%s, ' % nf.ramified_primes() data += '[%s], ' % zk data += '%s, ' % str(1 if nf.is_cm_field() else 0) if nf.can_class_number(): data += '%s, ' % nf.class_number() data += '%s, ' % nf.class_group_invariants_raw() data += '%s, ' % (1 if nf.used_grh() else 0) data += '[%s], ' % units data += '%s, ' % nf.regulator() else: data += '0,0,0,0,0, ' data += '%s' % subs data += ']' return data
def computation_roots(self): # Write these as p-adic series. Start with helper def help_padic(n,p, prec): """ Take an integer n, prime p, and precision prec, and return a prec-tuple of the p-adic coefficients of j """ n = int(n) res = [0 for j in range(prec)] while n<0: n += p**prec for k in range(prec): res[k] = n % p n = (n-res[k])/p return res # Second helper, in case some arrays are not extended by 0 def getel(li,j): if j<len(li): return li[j] return 0 myroots = self._data["QpRts"] p = self._data['QpRts-p'] myroots = [[help_padic(z, p, self._data['QpRts-prec']) for z in t] for t in myroots] myroots = [[[getel(root[j], r) for j in range(len(self._data['QpRts-minpoly'])-1)] for r in range(self._data['QpRts-prec'])] for root in myroots] myroots = [[coeff_to_poly(x, var='a') for x in root] for root in myroots] # Use power series so degrees increase # Use formal p so we can make a power series PR = PowerSeriesRing(PolynomialRing(QQ, 'a'), 'p') myroots = [web_latex(PR(x), enclose=False) for x in myroots] # change p into its value myroots = [re.sub(r'([a)\d]) *p', r'\1\\cdot '+str(p), z) for z in myroots] return [z.replace('p',str(p)) for z in myroots]
def intersection_points(F,G): """Given F, G homogeneous in 3 variables, returns a list of their intersection points in P^2. Note that we can just find the rational_points() on the associated subscheme of P^2 but over Q that takes much longer. """ R3 = F.parent() k = R3.base_ring() R2 = PolynomialRing(k,2,'uv') u,v = R2.gens() R1 = PolynomialRing(k,'w') w = R1.gens()[0] sols = [] # We stratify the possible points as follows: # (1) [0,1,0], checked directly; # (2) [1,y,0], roots of a univariate polynomial; # (3) [x,y,1], found using resultants # Check the point [0,1,0] with X=Z=0: if F([0,1,0])==0 and G([0,1,0])==0: sols = [[0,1,0]] # Find other points [1,y,0] with Z=0: f = F([1,w,0]) g = G([1,w,0]) h = f.gcd(g) sols += [[1,r,0] for r in h.roots(multiplicities=False)] # Find all other points [x,y,1] with Z!=0: f = F([u,v,1]) g = G([u,v,1]) # the following resultant is w.r.t. the first variable u, so is a # polynomial in v; we convert it into a univariate polynomial in # w: res = (f.resultant(g))([1,w]) for r in res.roots(multiplicities=False): h = f([w,r]).gcd(g([w,r])) for s in h.roots(multiplicities=False): sols.append([s,r,1]) return sols
def curve_string_parser(self, rec): curve_str = rec["curve"] curve_str = curve_str.replace("^", "**") K = self.make_base_field(rec) nu = K.gens()[0] S0 = PolynomialRing(K, "x") x = S0.gens()[0] S = PolynomialRing(S0, "y") y = S.gens()[0] parts = curve_str.split("=") lhs_poly = sage_eval(parts[0], locals={"x": x, "y": y, "nu": nu}) lhs_cs = lhs_poly.coefficients() if len(lhs_cs) == 1: h = 0 elif len(lhs_cs) == 2: # if there is a cross-term h = lhs_poly.coefficients()[0] else: raise NotImplementedError("for genus > 2") # rhs_poly = sage_eval(parts[1], locals = {'x':x, 'y':y, 'nu':nu}) f = sage_eval(parts[1], locals={"x": x, "y": y, "nu": nu}) return f, h
from sage.all import PolynomialRing, ZZ pr = PolynomialRing(ZZ, ('a', 'd', 'X1', 'X2', 'Y1', 'Y2'), 6) a, d, X1, X2, Y1, Y2 = pr.gens() k, d2 = 2 * d, 2 * d T1 = X1 * Y1 T2 = X2 * Y2 Z1, Z2 = 1, 1 formula = {} t0 = Y1 - X1 formula['t0'] = t0 t1 = Y2 - X2 formula['t1'] = t1 A = t0 * t1 formula['A'] = A t2 = Y1 + X1 formula['t2'] = t2 t3 = Y2 + X2 formula['t3'] = t3 B = t2 * t3 formula['B'] = B t4 = k * T2 formula['t4'] = t4 C = T1 * t4 formula['C'] = C D = 2 * Z1 formula['D'] = D E = B - A formula['E'] = E F = D - C formula['F'] = F
def list_to_factored_poly(s): return str(factor(PolynomialRing(ZZ, 't')(s))).replace('*', '')
def list_to_poly(s): return str(PolynomialRing(QQ, 'x')(s)).replace('*', '')
def alex_by_KnotTheory(L): p = mathematica.MyAlex(L.PD_code(True)).sage() i = min([i for i, c in enumerate(p) if c != 0]) R = PolynomialRing(ZZ, 'a') return R(p[i:])
def make_passport_object(self, passport): from lmfdb.belyi.main import url_for_belyi_galmap_label # all information about the map goes in the data dictionary # most of the data from the database gets polished/formatted before we put it in the data dictionary data = self.data = {} for elt in ('plabel', 'abc', 'num_orbits', 'g', 'abc', 'deg', 'maxdegbf'): data[elt] = passport[elt] nt = passport['group'].split('T') data['group'] = group_display_knowl(int(nt[0]), int(nt[1]), getDBConnection()) data['geomtype'] = geomtypelet_to_geomtypename_dict[ passport['geomtype']] data['lambdas'] = [str(c)[1:-1] for c in passport['lambdas']] data['pass_size'] = passport['pass_size'] # Permutation triples galmaps_for_plabel = belyi_db_galmaps().find({ "plabel": passport['plabel'] }).sort([('label_index', ASCENDING)]) galmapdata = [] for galmap in galmaps_for_plabel: # wrap number field nonsense F = belyi_base_field(galmap) # inLMFDB = False; field = {} if F._data == None: field['in_LMFDB'] = False fld_coeffs = galmap['base_field'] pol = PolynomialRing(QQ, 'x')(fld_coeffs) field['base_field'] = latex(pol) field['isQQ'] = False else: field['in_LMFDB'] = True if F.poly().degree() == 1: field['isQQ'] = True F.latex_poly = web_latex(F.poly()) field['base_field'] = F galmapdatum = [ galmap['label'].split('-')[-1], url_for_belyi_galmap_label(galmap['label']), galmap['orbit_size'], field, galmap['triples_cyc'][0][0], galmap['triples_cyc'][0][1], galmap['triples_cyc'][0][2], ] galmapdata.append(galmapdatum) data['galmapdata'] = galmapdata # Properties properties = [('Label', passport['plabel']), ('Group', str(passport['group'])), ('Orders', str(passport['abc'])), ('Genus', str(passport['g'])), ('Size', str(passport['pass_size'])), ('Galois orbits', str(passport['num_orbits']))] self.properties = properties # Friends self.friends = [] # Breadcrumbs groupstr, abcstr, sigma0, sigma1, sigmaoo, gstr = data['plabel'].split( "-") lambdasstr = '%s-%s-%s' % (sigma0, sigma1, sigmaoo) lambdasgstr = lambdasstr + "-" + gstr self.bread = [('Belyi Maps', url_for(".index")), (groupstr, url_for(".by_url_belyi_search_group", group=groupstr)), (abcstr, url_for(".by_url_belyi_search_group_triple", group=groupstr, abc=abcstr)), (lambdasgstr, url_for(".by_url_belyi_passport_label", group=groupstr, abc=abcstr, sigma0=sigma0, sigma1=sigma1, sigmaoo=sigmaoo, g=gstr))] # Title self.title = "Passport " + data['plabel'] # Code snippets (only for curves) self.code = {} return
def crystalline_obstruction(f, p, precision, over_Qp=False, pedantic=False, **kwargs): """ INPUT: - ``f`` -- a polynomial defining the curve or surface. Note if given an hyperelliptic curve we will try to change the model over Qpbar, in order to work with an odd and monic model over Qp. - ``p`` -- a prime of good reduction - ``precision`` -- a lower bound for the desired precision to run the computations, this increases the time exponentially - ``over_Qp`` -- by default False, if True uses the factorization of the cyclotomic polynomials over Qp - ``pedantic` -- by default False, if True might inform user of some bound improvements which werent achieved by pure linear algebra arguments - ``kwargs`` -- keyword arguments to bypass some computations or to be passed to controlledreduction OUTPUT: - an upper bound on the number of Tate classes over Qbar - a dictionary more information, matching the papers notation, on how one we attained that bound EXAMPLES:: README examples Jacobians of hyperelliptic curves with a Weierstrass point over Qp Example 5.1 sage: from crystalline_obstruction import crystalline_obstruction sage: f = ZZ['x,y']('x^5 - 2*x^4 + 2*x^3 - 4*x^2 + 3*x - 1 -y^2') sage: crystalline_obstruction(f=f, p=31, precision=3) # bounding dim Pic (1, {'dim Li': [1], 'dim Ti': [2], 'factors': [(t - 1, 2)], 'p': 31, 'precision': 3, 'rank T(X_Fpbar)': 2}) Bounding the geometric dimension of Endomorphism algebra sage: f = ZZ['x,y']('x^5 - 2*x^4 + 2*x^3 - 4*x^2 + 3*x - 1 -y^2') sage: crystalline_obstruction(f=f, p=31, precision=3, tensor=True) # bounding dim End (1, {'dim Li': [1], 'dim Ti': [4], 'factors': [(t - 1, 4)], 'p': 31, 'precision': 3, 'rank T(X_Fpbar)': 4}) Example 5.2 sage: f = ZZ['x,y']('x^5 - 2*x^4 + 7*x^3 - 5*x^2 + 8*x + 3 -y^2') sage: crystalline_obstruction(f=f, p=4999, precision=20) # bounding dim Pic (2, {'dim Li': [2], 'dim Ti': [2], 'factors': [(t - 1, 2)], 'p': 4999, 'precision': 20, 'rank T(X_Fpbar)': 2}) Hyperelliptic curve given in a non-Weierstrass format sage: f = ZZ['x,y']('(2*x^6+3*x^5+5*x^4+6*x^3+4*x^2+x) -y*(x^4+x^3+x) -y^2') sage: crystalline_obstruction(f=f, p=59, precision=3) (3, {'dim Li': [1, 2], 'dim Ti': [3, 6], 'factors': [(t - 1, 3), (t^2 + t + 1, 3)], 'p': 59, 'precision': 3, 'rank T(X_Fpbar)': 9}) Jacobians of quartic plane curves Example 5.3 sage: f = ZZ['x,y,z']('x*y^3 + x^3*z - x*y^2*z + x^2*z^2 + y^2*z^2 - y*z^3') sage: crystalline_obstruction(f, p=31, precision=3) # bounding dim Pic (1, {'dim Li': [1], 'dim Ti': [3], 'factors': [(t - 1, 3)], 'p': 31, 'precision': 3, 'rank T(X_Fpbar)': 3}) Product of 3 elliptic curves over x^3 - 3*x - 1 sage: f=ZZ['x,y,z']('x^3*z + x^2*y*z + x^2*z^2 - x*y^3 - x*y*z^2 - x*z^3 + y^2*z^2') sage: crystalline_obstruction(f=f, p=31, precision=3) # bounding dim Pic (3, {'dim Li': [1, 2], 'dim Ti': [3, 6], 'factors': [(t - 1, 3), (t^2 + t + 1, 3)], 'p': 31, 'precision': 3, 'rank T(X_Fpbar)': 9}) Another gennus 3 plane quartic sage: f = ZZ['x,y,z']('x^4+x^2*y^2+2*x^2*y*z-x^2*z^2-6*y^4+16*y^3*z-12*y^2*z^2-16*y*z^3-6*z^4') sage: crystalline_obstruction(f=f, p=5003, precision=3) # bounding dim Pic (6, {'dim Li': [2, 2, 2], 'dim Ti': [2, 3, 4], 'factors': [(t + 1, 2), (t - 1, 3), (t^2 + 1, 2)], 'p': 5003, 'precision': 3, 'rank T(X_Fpbar)': 9}) sage: crystalline_obstruction(f=f, p=5003, precision=3, tensor=True) # bounding dim End (9, {'dim Li': [2, 3, 4], 'dim Ti': [4, 6, 8], 'factors': [(t + 1, 4), (t - 1, 6), (t^2 + 1, 4)], 'p': 5003, 'precision': 3, 'rank T(X_Fpbar)': 18}) Quartic surfaces Example 5.5 sage: f = ZZ['x,y,z,w']("x^4 + y^4 + z^4 + w^4 + 101^3*x*y*z*w") sage: crystalline_obstruction(f, p=101, precision=3) (20, {'dim Li': [1, 7, 12], 'dim Ti': [1, 7, 12], 'factors': [(t - 1, 1), (t - 1, 7), (t + 1, 12)], 'p': 101, 'precision': 3, 'rank T(X_Fpbar)': 20}) sage: crystalline_obstruction(f=f, p=101, precision=4) (19, {'dim Li': [1, 6, 12], 'dim Ti': [1, 7, 12], 'factors': [(t - 1, 1), (t - 1, 7), (t + 1, 12)], 'p': 101, 'precision': 4, 'rank T(X_Fpbar)': 20}) Example 5.6 sage: f = ZZ['x,y,z,w']("y^4 - x^3*z + y*z^3 + z*w^3 + w^4") sage: crystalline_obstruction(f=f, p=89, precision=3) (4, {'dim Li': [1, 0, 3, 0], 'dim Ti': [1, 1, 4, 4], 'factors': [(t - 1, 1), (t + 1, 1), (t - 1, 4), (t^4 + 1, 1)], 'p': 89, 'precision': 3, 'rank T(X_Fpbar)': 10}) Example 5.7 sage: f = ZZ['x,y,z,w']("x^4 + 2*y^4 + 2*y*z^3 + 3*z^4 - 2*x^3*w- 2*y*w^3") sage: crystalline_obstruction(f=f, p=67, precision=3) (3, {'dim Li': [1, 2], 'dim Ti': [1, 3], 'factors': [(t - 1, 1), (t + 1, 3)], 'p': 67, 'precision': 3, 'rank T(X_Fpbar)': 4}) TESTS:: Check that precision = 3 is sufficient sage: from crystalline_obstruction import crystalline_obstruction sage: crystalline_obstruction(f=ZZ['x,y']('y^2-(48*x^8 + 12*x^6 - 22*x^4- 13*x^2 - 2)'),p=107,precision=3) (2, {'dim Li': [2], 'dim Ti': [3], 'factors': [(t - 1, 3)], 'p': 107, 'precision': 3, 'rank T(X_Fpbar)': 3}) Check that the result is consistent at various primes and different precision parameters and never giving a wrong upper bound: sage: crystalline_obstruction(f=ZZ['x,y']('y^2-(48*x^8 + 12*x^6 - 22*x^4- 13*x^2 - 2)'),p=107,precision=3,tensor=True) (2, {'dim Li': [2], 'dim Ti': [6], 'factors': [(t - 1, 6)], 'p': 107, 'precision': 3, 'rank T(X_Fpbar)': 6}) sage: for p in [103, 107]: ....: for i in range(3,8): ....: print(crystalline_obstruction(f=ZZ['x,y']('-x^8 - 7*x^7 - 7*x^6 + 14*x^5 +35*x^4 + 35*x^3 + 14*x^2 - x - 1 - y^2'), ....: p=p,precision=i,tensor=True)) ....: (18, {'precision': 3, 'p': 103, 'rank T(X_Fpbar)': 36, 'factors': [(t - 1, 6), (t + 1, 6), (t^2 - t + 1, 6), (t^2 + t + 1, 6)], 'dim Ti': [6, 6, 12, 12], 'dim Li': [3, 3, 6, 6]}) (18, {'precision': 4, 'p': 103, 'rank T(X_Fpbar)': 36, 'factors': [(t - 1, 6), (t + 1, 6), (t^2 - t + 1, 6), (t^2 + t + 1, 6)], 'dim Ti': [6, 6, 12, 12], 'dim Li': [3, 3, 6, 6]}) (18, {'precision': 5, 'p': 103, 'rank T(X_Fpbar)': 36, 'factors': [(t - 1, 6), (t + 1, 6), (t^2 - t + 1, 6), (t^2 + t + 1, 6)], 'dim Ti': [6, 6, 12, 12], 'dim Li': [3, 3, 6, 6]}) (18, {'precision': 6, 'p': 103, 'rank T(X_Fpbar)': 36, 'factors': [(t - 1, 6), (t + 1, 6), (t^2 - t + 1, 6), (t^2 + t + 1, 6)], 'dim Ti': [6, 6, 12, 12], 'dim Li': [3, 3, 6, 6]}) (18, {'precision': 7, 'p': 103, 'rank T(X_Fpbar)': 36, 'factors': [(t - 1, 6), (t + 1, 6), (t^2 - t + 1, 6), (t^2 + t + 1, 6)], 'dim Ti': [6, 6, 12, 12], 'dim Li': [3, 3, 6, 6]}) (18, {'precision': 3, 'p': 107, 'rank T(X_Fpbar)': 36, 'factors': [(t - 1, 18), (t + 1, 18)], 'dim Ti': [18, 18], 'dim Li': [9, 9]}) (18, {'precision': 4, 'p': 107, 'rank T(X_Fpbar)': 36, 'factors': [(t - 1, 18), (t + 1, 18)], 'dim Ti': [18, 18], 'dim Li': [9, 9]}) (18, {'precision': 5, 'p': 107, 'rank T(X_Fpbar)': 36, 'factors': [(t - 1, 18), (t + 1, 18)], 'dim Ti': [18, 18], 'dim Li': [9, 9]}) (18, {'precision': 6, 'p': 107, 'rank T(X_Fpbar)': 36, 'factors': [(t - 1, 18), (t + 1, 18)], 'dim Ti': [18, 18], 'dim Li': [9, 9]}) (18, {'precision': 7, 'p': 107, 'rank T(X_Fpbar)': 36, 'factors': [(t - 1, 18), (t + 1, 18)], 'dim Ti': [18, 18], 'dim Li': [9, 9]}) Check that some prime attains the (3,3) bound: sage: for p in [101, 103, 113]: ....: print(p) ....: print(crystalline_obstruction(ZZ['x,y'](' 4*x^8 - 20*x^6 + 33*x^4 - 17*x^2 - 2 - y^2'), p=p, precision=3)) ....: print(crystalline_obstruction(ZZ['x,y'](' 4*x^8 - 20*x^6 + 33*x^4 - 17*x^2 - 2 - y^2'), p=p, precision=3, tensor=True)) ....: 101 (6, {'precision': 3, 'p': 101, 'rank T(X_Fpbar)': 9, 'factors': [(t + 1, 4), (t - 1, 5)], 'dim Ti': [4, 5], 'dim Li': [2, 4]}) (9, {'precision': 3, 'p': 101, 'rank T(X_Fpbar)': 18, 'factors': [(t + 1, 8), (t - 1, 10)], 'dim Ti': [8, 10], 'dim Li': [4, 5]}) 103 (4, {'precision': 3, 'p': 103, 'rank T(X_Fpbar)': 5, 'factors': [(t - 1, 5)], 'dim Ti': [5], 'dim Li': [4]}) (5, {'precision': 3, 'p': 103, 'rank T(X_Fpbar)': 10, 'factors': [(t - 1, 10)], 'dim Ti': [10], 'dim Li': [5]}) 113 (3, {'precision': 3, 'p': 113, 'rank T(X_Fpbar)': 3, 'factors': [(t - 1, 3)], 'dim Ti': [3], 'dim Li': [3]}) (3, {'precision': 3, 'p': 113, 'rank T(X_Fpbar)': 6, 'factors': [(t - 1, 6)], 'dim Ti': [6], 'dim Li': [3]}) """ if 'cp' in kwargs and 'frob_matrix' in kwargs: cp = kwargs['cp'] frob_matrix = kwargs['frob_matrix'] shift = kwargs.get('shift', 0) else: precision, cp, frob_matrix, shift = compute_frob_matrix_and_cp_H2( f, p, precision, **kwargs) Rt = PolynomialRing(ZZ, 't') t = Rt.gens()[0] cp = Rt(cp) rank, k, cyc_factor = rank_fieldextension(cp, shift) if cyc_factor: tate_factor = tate_factor_Zp(cyc_factor.expand()) max_degree = max(elt.degree() for elt, _ in tate_factor) if max_degree > precision - 1: warnings.warn( 'Precision is very likely too low to correctly compute the Tate classes at this prime' ) factor_i, dim_Ti, _, dim_Li = upper_bound_tate(cp, frob_matrix, precision, over_Qp=over_Qp, pedantic=pedantic) res = {} res['precision'] = precision res['p'] = p res['rank T(X_Fpbar)'] = rank res['factors'] = [] if shift > 0: res['factors'].append((t - 1, 1)) # normalize the cyclotomic factors for factor, exp in factor_i: res['factors'].append((factor(t / p), exp)) if over_Qp: if shift > 0: dim_Li = [[shift]] + dim_Li dim_Ti = [[shift]] + dim_Ti upper_bound = rank - (sum(sum(dim_Ti, [])) - sum(sum(dim_Li, []))) else: if shift > 0: dim_Li = [shift] + dim_Li dim_Ti = [shift] + dim_Ti upper_bound = rank - (sum(dim_Ti) - sum(dim_Li)) res['dim Ti'] = dim_Ti res['dim Li'] = dim_Li return upper_bound, res
def print_q_expansion(list): list = [str(c) for c in list] Qa = PolynomialRing(QQ, 'a') Qq = PowerSeriesRing(Qa, 'q') return str(Qq([c for c in list]).add_bigoh(len(list) + 1))
def base_change(Lpoly, r): R = Lpoly.parent() T = R.gen() S = PolynomialRing(R, 'u') u = S.gen() return R(Lpoly(u).resultant(u**r - T))
def rational_points(X, F=None, split=False, bound=None, tolerance=0.01, prec=53): r""" Return an iterator of rational points on a scheme ``X`` INPUT: - ``X`` - a scheme, affine or projective OPTIONS: - ``F`` - coefficient field - ``split`` - whether to compute the splitting field when the scheme is 0-dimensional - ``bound`` - a bound for multiplicative height - ``tolerance`` - tolerance used for computing height - ``prec`` - precision used for computing height OUTPUT: - an iterator of rational points on ``X`` ALGORITHM: Use brute force plus some elimination. The complexity is approximately `O(n^d)`, where `n` is the size of the field (or the number of elements with bounded height when the field is infinite) and `d` is the dimension of the scheme ``X``. Significantly faster than the current available algorithms in Sage, especially for low dimension schemes in large ambient spaces. EXAMPLES:: sage: from rational_points import rational_points A curve of genus 9 over `\mathbf F_{97}` with many rational points (from the website `<https://manypoints.org>`_):: sage: A.<x,y,z> = AffineSpace(GF(97),3) sage: C = A.subscheme([x^4+y^4+1+3*x^2*y^2+13*y^2+68*x^2,z^2+84*y^2+x^2+67]) sage: len(list(rational_points(C))) 228 The following example is from the `documentation <http://magma.maths.usyd.edu.au/magma/handbook/text/1354>`_ of Magma: a space rational curve with one cusp. Unfeasible with the old methods:: sage: F = GF(7823) sage: P.<x,y,z,w> = ProjectiveSpace(F,3) sage: C = P.subscheme([4*x*z+2*x*w+y^2+4*y*w+7821*z^2+7820*w^2,\ ....: 4*x^2+4*x*y+7821*x*w+7822*y^2+7821*y*w+7821*z^2+7819*z*w+7820*w^2]) sage: len(list(rational_points(C))) # long time 7824 31 nodes on a `Togliatti surface <https://en.wikipedia.org/wiki/Togliatti_surface>`_: only 7 of them are defined over the field of definition. Use ``split=True`` to automatically find the splitting field:: sage: q = QQ['q'].0 sage: F.<q> = NumberField(q^4-10*q^2+20) sage: P.<x,y,z,w> = ProjectiveSpace(F,3) sage: f = 5*q*(2*z-q*w)*(4*(x^2+y^2-z^2)+(1+3*(5-q^2))*w^2)^2-64*(x-w)*\ ....: (x^4-4*x^3*w-10*x^2*y^2-4*x^2*w^2+16*x*w^3-20*x*y^2*w+5*y^4+16*w^4-20*y^2*w^2) sage: X = P.subscheme([f]+f.jacobian_ideal()) sage: len(list(rational_points(X))) 7 sage: len(list(rational_points(X,split=True))) 31 Enumeration of points on a projective plane over a number field:: sage: a = QQ['a'].0 sage: F.<a> = NumberField(a^3-5) sage: P.<x,y,z> = ProjectiveSpace(F, 2) sage: len(list(rational_points(P, bound=RR(5^(1/3))))) 49 """ def base_change(k, F): ch = F.characteristic() if ch == 0: return k.embeddings(F)[0] else: return F def enum_proj_points(I): R = I.ring() k = R.base() n = R.ngens() - 1 for i in range(n + 1): R_ = PolynomialRing(k, 'x', n - i) v = [k(0)] * i + [k(1)] pr = R.hom(v + list(R_.gens()), R_) for rest in enum_points(pr(I)): pt = v + rest if bound == None or global_height( pt, prec=prec) <= bound + tolerance: yield pt def enum_points(I): possibleValues = get_elements() R = I.ring() F = R.base() ch = F.characteristic() n = R.ngens() if n == 0: if I.is_zero(): yield [] return if I.is_one(): return if all(map(lambda _: _.degree() == 1, I.gens())) and (ch > 0 or I.dimension() == 0): # solve using linear algebra f = R.hom(n * [0], F) A = matrix([f(g.coefficient(xi)) for xi in R.gens()] for g in I.gens()) b = vector(-g.constant_coefficient() for g in I.gens()) v0 = A.solve_right(b) r = A.rank() if r == n: yield list(v0) else: K = A.right_kernel().matrix() for v in F**(n - r): yield list(v * K + v0) return if ch > 0 and I.is_homogeneous(): yield [F(0)] * n for pt in enum_proj_points(I): for sca in get_elements(): if sca != 0: yield [x * sca for x in pt] return elim = I.elimination_ideal(I.ring().gens()[1:]) g = elim.gens()[0] if g != 0: S = F['u'] pr1 = R.hom([S.gen()] + [0] * (n - 1), S) possibleValues = (v[0] for v in pr1(g).roots() if bound == None or global_height([v[0], F(1)]) <= bound + tolerance) if split: nonSplit = (f[0] for f in factor(pr1(g)) if f[0].degree() > 1) for f in nonSplit: if ch == 0: F_ = f.splitting_field('a') # `polredbest` from PARI/GP, improves performance significantly f = gen_to_sage( pari(F_.gen().minpoly('x')).polredbest(), {'x': S.gen()}) F_ = f.splitting_field('a') R_ = PolynomialRing(F_, 'x', n) I = R_.ideal( [f.change_ring(base_change(F, F_)) for f in I.gens()]) for pt in enum_points(I): yield pt return R_ = PolynomialRing(F, 'x', n - 1) if n == 1: for v in possibleValues: yield [v] else: for v in possibleValues: pr2 = R.hom([v] + list(R_.gens()), R_) for rest in enum_points(pr2(I)): yield [v] + rest ####################################################################### # begin of main function try: I = X.defining_ideal() R = I.ring() except: # when X has no defining ideal, i.e. when it's the whole space R = X.coordinate_ring() I = R.ideal([]) k = R.base() n = R.ngens() ambient = X.ambient_space() if F: # specified coefficient field R_ = PolynomialRing(F, 'x', n) I = R_.ideal([f.change_ring(base_change(k, F)) for f in I.gens()]) k = F ambient = ambient.change_ring(k) split = False ch = k.characteristic() if (X.is_projective() and I.dimension() == 1) or (not X.is_projective() and I.dimension() == 0): # 0-dimensional dimension # in 0-dim use elimination only bound = None get_elements = lambda: [] else: # positive dimension split = False # splitting field does not work in positive dimension if ch == 0: if bound == None: raise ValueError("need to specify a valid bound") if is_RationalField(k): get_elements = lambda: k.range_by_height(floor(bound) + 1) else: get_elements = lambda: k.elements_of_bounded_height( bound=bound**(k.degree()), tolerance=tolerance, precision=prec) else: # finite field bound = None get_elements = lambda: k if X.is_projective(): # projective case for pt in enum_proj_points(I): if split: # TODO construct homogeneous coordinates from a bunch of # elements from different fields yield pt else: yield ambient(pt) else: # affine case for pt in enum_points(I): if split: yield pt else: yield ambient(pt)
def coeff_to_poly(c): from sage.all import PolynomialRing, QQ return PolynomialRing(QQ, 'x')(c)
def make_galmap_object(self, galmap): from lmfdb.belyi.main import url_for_belyi_passport_label # all information about the map goes in the data dictionary # most of the data from the database gets polished/formatted before we put it in the data dictionary data = self.data = {} # the stuff that does not need to be polished for elt in ('label', 'plabel', 'triples_cyc', 'orbit_size', 'g', 'abc', 'deg'): data[elt] = galmap[elt] nt = galmap['group'].split('T') data['group'] = group_display_knowl(int(nt[0]), int(nt[1]), getDBConnection()) data['geomtype'] = geomtypelet_to_geomtypename_dict[galmap['geomtype']] data['lambdas'] = [str(c)[1:-1] for c in galmap['lambdas']] data['isQQ'] = False data['in_LMFDB'] = False F = belyi_base_field(galmap) if F._data == None: fld_coeffs = galmap['base_field'] pol = PolynomialRing(QQ, 'x')(fld_coeffs) data['base_field'] = latex(pol) else: data['in_LMFDB'] = True if F.poly().degree() == 1: data['isQQ'] = True F.latex_poly = web_latex(F.poly()) data['base_field'] = F crv_str = galmap['curve'] if crv_str == 'PP1': data['curve'] = '\mathbb{P}^1' else: data['curve'] = make_curve_latex(crv_str) # change pairs of floats to complex numbers embeds = galmap['embeddings'] embed_strs = [] for el in embeds: if el[1] < 0: el_str = str(el[0]) + str(el[1]) + "\sqrt{-1}" else: el_str = str(el[0]) + "+" + str(el[1]) + "\sqrt{-1}" embed_strs.append(el_str) data['map'] = make_map_latex(galmap['map']) data['embeddings_and_triples'] = [] if data['isQQ']: for i in range(0, len(data['triples_cyc'])): triple_cyc = data['triples_cyc'][i] data['embeddings_and_triples'].append([ "\\text{not applicable (over $\mathbb{Q}$)}", triple_cyc[0], triple_cyc[1], triple_cyc[2] ]) else: for i in range(0, len(data['triples_cyc'])): triple_cyc = data['triples_cyc'][i] data['embeddings_and_triples'].append([ embed_strs[i], triple_cyc[0], triple_cyc[1], triple_cyc[2] ]) data['lambdas'] = [str(c)[1:-1] for c in galmap['lambdas']] # Properties properties = [ ('Label', galmap['label']), ('Group', str(galmap['group'])), ('Orders', str(galmap['abc'])), ('Genus', str(galmap['g'])), ('Size', str(galmap['orbit_size'])), ] self.properties = properties # Friends self.friends = [('Passport', url_for_belyi_passport_label(galmap['plabel']))] # Breadcrumbs groupstr, abcstr, sigma0, sigma1, sigmaoo, gstr, letnum = data[ 'label'].split("-") lambdasstr = '%s-%s-%s' % (sigma0, sigma1, sigmaoo) lambdasgstr = lambdasstr + "-" + gstr self.bread = [ ('Belyi Maps', url_for(".index")), (groupstr, url_for(".by_url_belyi_search_group", group=groupstr)), (abcstr, url_for(".by_url_belyi_search_group_triple", group=groupstr, abc=abcstr)), (lambdasgstr, url_for(".by_url_belyi_passport_label", group=groupstr, abc=abcstr, sigma0=sigma0, sigma1=sigma1, sigmaoo=sigmaoo, g=gstr)), (letnum, url_for(".by_url_belyi_galmap_label", group=groupstr, abc=abcstr, sigma0=sigma0, sigma1=sigma1, sigmaoo=sigmaoo, g=gstr, letnum=letnum)), ] # Title self.title = "Belyi map " + data['label'] # Code snippets (only for curves) self.code = {} return