def weil_representation(self) : r""" OUTPUT: - A pair of matrices corresponding to T and S. """ disc_bilinear = lambda a, b: (self._dual_basis * vector(QQ, a.lift())) * self._L * (self._dual_basis * vector(QQ, b.lift())) disc_quadratic = lambda a: disc_bilinear(a, a) / ZZ(2) zeta_order = ZZ(lcm([8, 12, prod(self.invariants())] + map(lambda ed: 2 * ed, self.invariants()))) K = CyclotomicField(zeta_order); zeta = K.gen() R = PolynomialRing(K, 'x'); x = R.gen() # sqrt2s = (x**2 - 2).factor() # if sqrt2s[0][0][0].complex_embedding().real() > 0 : # sqrt2 = sqrt2s[0][0][0] # else : # sqrt2 = sqrt2s[0][1] Ldet_rts = (x**2 - prod(self.invariants())).factor() if Ldet_rts[0][0][0].complex_embedding().real() > 0 : Ldet_rt = Ldet_rts[0][0][0] else : Ldet_rt = Ldet_rts[0][0][0] Tmat = diagonal_matrix( K, [zeta**(zeta_order*disc_quadratic(a)) for a in self] ) Smat = zeta**(zeta_order / 8 * self._L.nrows()) / Ldet_rt \ * matrix( K, [ [ zeta**ZZ(-zeta_order * disc_bilinear(gamma,delta)) for delta in self ] for gamma in self ]) return (Tmat, Smat)
def _denominator(): R = PolynomialRing(ZZ, "T") T = R.gen() denom = R(1) lc = self._f.list()[-1] if lc == 1: # MONIC for i in range(2, self._delta + 1): if self._delta % i == 0: phi = euler_phi(i) G = IntegerModRing(i) ki = G(self._q).multiplicative_order() denom = denom * (T**ki - 1)**(phi // ki) return denom else: # Non-monic x = PolynomialRing(self._Fq, "x").gen() f = x**self._delta - lc L = f.splitting_field("a") roots = [r for r, _ in f.change_ring(L).roots()] roots_dict = dict([(r, i) for i, r in enumerate(roots)]) rootsfrob = [ L.frobenius_endomorphism(self._Fq.degree())(r) for r in roots ] m = zero_matrix(len(roots)) for i, r in enumerate(roots): m[i, roots_dict[rootsfrob[i]]] = 1 return R(R(m.characteristic_polynomial()) // (T - 1))
def compute_tau0(v0,gamma,wD,return_exact = False): r''' INPUT: - v0: F -> its localization at p - gamma: the image of wD (the generator for an order of F) under an optimal embedding OUTPUT: The element tau_0 such that gamma * [tau_0,1] = wD * [tau_0,1] ''' R = PolynomialRing(QQ,names = 'X') X = R.gen() F = v0.domain() Cp = v0.codomain() assert wD.minpoly() == gamma.minpoly() a,b,c,d = gamma.list() tau0_vec = (c*X**2+(d-a)*X-b).roots(F) tau0 = v0(tau0_vec[0][0]) idx = 0 if c * tau0 + d != v0(wD): tau0 = v0(tau0_vec[1][0]) idx = 1 return tau0_vec[idx][0] if return_exact == True else tau0
def generator_relations(self, K): """ An ideal `I` in a polynomial ring `R` over `K`, such that the associated ring is `R / I` surjects onto the ring of modular forms with coefficients in `K`. INPUT: - `K` -- A ring. OUTPUT: An ideal in a polynomial ring. TESTS:: sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_testtype import * sage: t = ModularFormTestType_scalar() sage: t.generator_relations(QQ) Ideal (g1^2 - g2, g1^3 - g3, g1^4 - g4, g1^5 - g5) of Multivariate Polynomial Ring in g1, g2, g3, g4, g5 over Rational Field """ if K.has_coerce_map_from(ZZ): R = PolynomialRing(K, self._generator_names(K)) g1 = R.gen(0) return R.ideal([ g1**i - g for (i, g) in list(enumerate([None] + list(R.gens())))[2:] ]) raise NotImplementedError
def get_basic_integral(G, cocycle, gamma, center, j, prec=None): p = G.p HOC = cocycle.parent() V = HOC.coefficient_module() if prec is None: prec = V.precision_cap() Cp = Qp(p, prec) verbose('precision = %s' % prec) R = PolynomialRing(Cp, names='t') PS = PowerSeriesRing(Cp, names='z') t = R.gen() z = PS.gen() if prec is None: prec = V.precision_cap() try: coeff_depth = V.precision_cap() except AttributeError: coeff_depth = V.coefficient_module().precision_cap() resadd = ZZ(0) edgelist = G.get_covering(1)[1:] for rev, h in edgelist: a, b, c, d = [Cp(o) for o in G.embed(h, prec).list()] try: c0val = 0 pol = PS(d * z + b) / PS(c * z + a) pol -= Cp.teichmuller(center) pol = pol**j pol = pol.polynomial() newgamma = G.Gpn( G.reduce_in_amalgam(h * gamma.quaternion_rep, return_word=False)) if rev: # DEBUG newgamma = newgamma.conjugate_by(G.wp()) print 'reversing' if G.use_shapiro(): mu_e = cocycle.evaluate_and_identity(newgamma) else: mu_e = cocycle.evaluate(newgamma) if newgamma.quaternion_rep != 1: print 'newgamma = ', newgamma except AttributeError: verbose('...') continue if HOC._use_ps_dists: tmp = sum(a * mu_e.moment(i) for a, i in izip(pol.coefficients(), pol.exponents()) if i < len(mu_e._moments)) else: tmp = mu_e.evaluate_at_poly(pol, Cp, coeff_depth) resadd += tmp try: if G.use_shapiro(): tmp = cocycle.get_liftee().evaluate_and_identity(newgamma) else: tmp = cocycle.get_liftee().evaluate(newgamma) except IndexError: pass return resadd
def lfsr_connection_polynomial(s): """ INPUT: - ``s`` -- a sequence of elements of a finite field of even length OUTPUT: - ``C(x)`` -- the connection polynomial of the minimal LFSR. This implements the algorithm in section 3 of J. L. Massey's article [Mas1969]_. EXAMPLES:: sage: F = GF(2) sage: F Finite Field of size 2 sage: o = F(0); l = F(1) sage: key = [l,o,o,l]; fill = [l,l,o,l]; n = 20 sage: s = lfsr_sequence(key,fill,n); s [1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0] sage: lfsr_connection_polynomial(s) x^4 + x + 1 sage: from sage.matrix.berlekamp_massey import berlekamp_massey sage: berlekamp_massey(s) x^4 + x^3 + 1 Notice that ``berlekamp_massey`` returns the reverse of the connection polynomial (and is potentially must faster than this implementation). """ # Initialization: FF = s[0].base_ring() R = PolynomialRing(FF, "x") x = R.gen() C = R(1); B = R(1); m = 1; b = FF(1); L = 0; N = 0 while N < len(s): if L > 0: r = min(L+1,C.degree()+1) d = s[N] + sum([(C.list())[i]*s[N-i] for i in range(1,r)]) if L == 0: d = s[N] if d == 0: m += 1 N += 1 if d > 0: if 2*L > N: C = C - d*b**(-1)*x**m*B m += 1 N += 1 else: T = C C = C - d*b**(-1)*x**m*B L = N + 1 - L m = 1 b = d B = T N += 1 return C
def local_coordinates_at_infinity(self, prec=20, name='t'): """ For the genus `g` hyperelliptic curve `y^2 = f(x)`, return `(x(t), y(t))` such that `(y(t))^2 = f(x(t))`, where `t = x^g/y` is the local parameter at infinity INPUT: - ``prec`` -- desired precision of the local coordinates - ``name`` -- generator of the power series ring (default: ``t``) OUTPUT: `(x(t),y(t))` such that `y(t)^2 = f(x(t))` and `t = x^g/y` is the local parameter at infinity EXAMPLES:: sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^5-5*x^2+1) sage: x,y = H.local_coordinates_at_infinity(10) sage: x t^-2 + 5*t^4 - t^8 - 50*t^10 + O(t^12) sage: y t^-5 + 10*t - 2*t^5 - 75*t^7 + 50*t^11 + O(t^12) :: sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^3-x+1) sage: x,y = H.local_coordinates_at_infinity(10) sage: x t^-2 + t^2 - t^4 - t^6 + 3*t^8 + O(t^12) sage: y t^-3 + t - t^3 - t^5 + 3*t^7 - 10*t^11 + O(t^12) Note: if even degree model, just returns local coordinate above one point AUTHOR: - Jennifer Balakrishnan (2007-12) """ g = self.genus() pol = self.hyperelliptic_polynomials()[0] K = LaurentSeriesRing(self.base_ring(), name) t = K.gen() K.set_default_prec(prec + 2) L = PolynomialRing(K, 'x') x = L.gen() i = 0 w = (x**g / t)**2 - pol wprime = w.derivative(x) if pol.degree() == 2 * g + 1: x = t**-2 else: x = t**-1 for i in range((RR(log(prec + 2) / log(2))).ceil()): x = x - w(x) / wprime(x) y = x**g / t return x + O(t**(prec + 2)), y + O(t**(prec + 2))
def eisenstein_basis(N, k, verbose=False): r""" Find spanning list of 'easy' generators for the subspace of `M_k(\Gamma_0(N))` generated by level 1 Eisenstein series and their images of even integer weights up to `k`. INPUT: - N -- positive integer - k -- positive integer - ``verbose`` -- bool (default: False) OUTPUT: - list of monomials in images of level 1 Eisenstein series - prec of q-expansions needed to determine element of `M_k(\Gamma_0(N))`. EXAMPLES:: sage: from psage.modform.rational.special import eisenstein_basis sage: eisenstein_basis(5,4) ([E4(q^5)^1, E4(q^1)^1, E2^*(q^5)^2], 3) sage: eisenstein_basis(11,2,verbose=True) # warning below because of verbose Warning -- not enough series. ([E2^*(q^11)^1], 2) sage: eisenstein_basis(11,2,verbose=False) ([E2^*(q^11)^1], 2) """ assert N > 1 if k % 2 != 0: return [] # Make list E of Eisenstein series, to enough precision to # determine them, until we span space. M = ModularForms(N, k) prec = M.echelon_basis()[-1].valuation() + 1 gens = eisenstein_gens(N, k, prec) R = PolynomialRing(ZZ, len(gens), ['E%sq%s'%(g[1],g[0]) for g in gens]) z = [(R.gen(i), g[1]) for i, g in enumerate(gens)] m = monomials(z, k) A = QQ**prec V = A.zero_subspace() E = [] for i, z in enumerate(m): d = z.degrees() f = prod(g[2]**d[i] for i, g in enumerate(gens) if d[i]) v = A(f.padded_list(prec)) if v not in V: V = V + A.span([v]) w = [(gens[i][0],gens[i][1],d[i]) for i in range(len(d)) if d[i]] E.append(EisensteinMonomial(w)) if V.dimension() == M.dimension(): return E, prec if verbose: print "Warning -- not enough series." return E, prec
def integrate_H1(G, cycle, cocycle, depth=1, method='moments', prec=None, parallelize=False, twist=False, progress_bar=False, multiplicative=True, return_valuation=False): if prec is None: prec = cocycle.parent().coefficient_module().base_ring().precision_cap( ) verbose('precision = %s' % prec) Cp = cycle.parent().coefficient_module().base_field() R = PolynomialRing(Cp, names='t') t = R.gen() if method == 'moments': integrate_H0 = integrate_H0_moments else: assert method == 'riemann' integrate_H0 = integrate_H0_riemann jj = 0 total_integrals = cycle.size_of_support() verbose('Will do %s integrals' % total_integrals) input_vec = [] resmul = Cp(1) resadd = Cp(0) resval = ZZ(0) for g, divisor in cycle.get_data(): jj += 1 if divisor.degree() != 0: raise ValueError( 'Divisor must be of degree 0. Now it is of degree %s. And g = %s.' % (divisor.degree(), g.quaternion_rep)) if twist: divisor = divisor.left_act_by_matrix( G.embed(G.wp(), prec).change_ring(Cp)) g = g.conjugate_by(G.wp()**-1) newresadd, newresmul, newresval = integrate_H0(G, divisor, cocycle, depth, g, prec, jj, total_integrals, progress_bar, parallelize) resadd += newresadd resmul *= newresmul resval += newresval if not multiplicative: if return_valuation: return resadd, resval, Cp.teichmuller(resmul) else: return resadd else: return Cp.prime()**resval * Cp.teichmuller(resmul) * resadd.exp()
def local_coordinates_at_infinity(self, prec = 20, name = 't'): """ For the genus `g` hyperelliptic curve `y^2 = f(x)`, return `(x(t), y(t))` such that `(y(t))^2 = f(x(t))`, where `t = x^g/y` is the local parameter at infinity INPUT: - ``prec`` -- desired precision of the local coordinates - ``name`` -- generator of the power series ring (default: ``t``) OUTPUT: `(x(t),y(t))` such that `y(t)^2 = f(x(t))` and `t = x^g/y` is the local parameter at infinity EXAMPLES:: sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^5-5*x^2+1) sage: x,y = H.local_coordinates_at_infinity(10) sage: x t^-2 + 5*t^4 - t^8 - 50*t^10 + O(t^12) sage: y t^-5 + 10*t - 2*t^5 - 75*t^7 + 50*t^11 + O(t^12) :: sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^3-x+1) sage: x,y = H.local_coordinates_at_infinity(10) sage: x t^-2 + t^2 - t^4 - t^6 + 3*t^8 + O(t^12) sage: y t^-3 + t - t^3 - t^5 + 3*t^7 - 10*t^11 + O(t^12) AUTHOR: - Jennifer Balakrishnan (2007-12) """ g = self.genus() pol = self.hyperelliptic_polynomials()[0] K = LaurentSeriesRing(self.base_ring(), name, default_prec=prec+2) t = K.gen() L = PolynomialRing(self.base_ring(),'x') x = L.gen() i = 0 w = (x**g/t)**2-pol wprime = w.derivative(x) x = t**-2 for i in range((RR(log(prec+2)/log(2))).ceil()): x = x-w(x)/wprime(x) y = x**g/t return x+O(t**(prec+2)) , y+O(t**(prec+2))
def local_coordinates_at_infinity(self, prec=20, name="t"): """ For the genus g hyperelliptic curve y^2 = f(x), returns (x(t), y(t)) such that (y(t))^2 = f(x(t)), where t = x^g/y is the local parameter at infinity INPUT: - prec: desired precision of the local coordinates - name: gen of the power series ring (default: 't') OUTPUT: (x(t),y(t)) such that y(t)^2 = f(x(t)) and t = x^g/y is the local parameter at infinity EXAMPLES: sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^5-5*x^2+1) sage: x,y = H.local_coordinates_at_infinity(10) sage: x t^-2 + 5*t^4 - t^8 - 50*t^10 + O(t^12) sage: y t^-5 + 10*t - 2*t^5 - 75*t^7 + 50*t^11 + O(t^12) sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^3-x+1) sage: x,y = H.local_coordinates_at_infinity(10) sage: x t^-2 + t^2 - t^4 - t^6 + 3*t^8 + O(t^12) sage: y t^-3 + t - t^3 - t^5 + 3*t^7 - 10*t^11 + O(t^12) AUTHOR: - Jennifer Balakrishnan (2007-12) """ g = self.genus() pol = self.hyperelliptic_polynomials()[0] K = LaurentSeriesRing(self.base_ring(), name) t = K.gen() K.set_default_prec(prec + 2) L = PolynomialRing(self.base_ring(), "x") x = L.gen() i = 0 w = (x ** g / t) ** 2 - pol wprime = w.derivative(x) x = t ** -2 for i in range((RR(log(prec + 2) / log(2))).ceil()): x = x - w(x) / wprime(x) y = x ** g / t return x + O(t ** (prec + 2)), y + O(t ** (prec + 2))
def local_coordinates_at_infinity(self, prec=20, name='t'): """ For the genus g hyperelliptic curve y^2 = f(x), returns (x(t), y(t)) such that (y(t))^2 = f(x(t)), where t = x^g/y is the local parameter at infinity INPUT: - prec: desired precision of the local coordinates - name: gen of the power series ring (default: 't') OUTPUT: (x(t),y(t)) such that y(t)^2 = f(x(t)) and t = x^g/y is the local parameter at infinity EXAMPLES: sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^5-5*x^2+1) sage: x,y = H.local_coordinates_at_infinity(10) sage: x t^-2 + 5*t^4 - t^8 - 50*t^10 + O(t^12) sage: y t^-5 + 10*t - 2*t^5 - 75*t^7 + 50*t^11 + O(t^12) sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^3-x+1) sage: x,y = H.local_coordinates_at_infinity(10) sage: x t^-2 + t^2 - t^4 - t^6 + 3*t^8 + O(t^12) sage: y t^-3 + t - t^3 - t^5 + 3*t^7 - 10*t^11 + O(t^12) AUTHOR: - Jennifer Balakrishnan (2007-12) """ g = self.genus() pol = self.hyperelliptic_polynomials()[0] K = LaurentSeriesRing(self.base_ring(), name) t = K.gen() K.set_default_prec(prec + 2) L = PolynomialRing(self.base_ring(), 'x') x = L.gen() i = 0 w = (x**g / t)**2 - pol wprime = w.derivative(x) x = t**-2 for i in range((RR(log(prec + 2) / log(2))).ceil()): x = x - w(x) / wprime(x) y = x**g / t return x + O(t**(prec + 2)), y + O(t**(prec + 2))
def standard_form(f, E): Q = PolynomialRing(E.base_field(), ['x', 'y']) y = Q.gen() u, v = Q(f[0].numerator()), Q(f[0].denominator()) deg = v.degree(y) if deg % 2 == 1: u *= y v *= y v = reduce_mod_curve(v, E) u = reduce_mod_curve(u, E) s, t = Q(f[1].numerator()), Q(f[1].denominator()) deg = t.degree(y) if deg % 2 == 1: s *= y t *= y t = reduce_mod_curve(t, E) s = reduce_mod_curve(s, E) return normalize_map((u / v, s / t), E)
def curve_over_ram_extn(self, deg): r""" Returns self over $\Q_p(p^(1/deg))$ INPUT: - deg: the degree of the ramified extension OUTPUT: self over $\Q_p(p^(1/deg))$ EXAMPLES:: sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x) sage: K = Qp(11,5) sage: HK = H.change_ring(K) sage: HL = HK.curve_over_ram_extn(2) sage: HL Hyperelliptic Curve over Eisenstein Extension of 11-adic Field with capped relative precision 5 in a defined by (1 + O(11^5))*x^2 + (O(11^6))*x + (10*11 + 10*11^2 + 10*11^3 + 10*11^4 + 10*11^5 + O(11^6)) defined by (1 + O(a^10))*y^2 = (1 + O(a^10))*x^5 + (10 + 8*a^2 + 10*a^4 + 10*a^6 + 10*a^8 + O(a^10))*x^3 + (7 + a^2 + O(a^10))*x^2 + (7 + 3*a^2 + O(a^10))*x AUTHOR: - Jennifer Balakrishnan """ from sage.schemes.hyperelliptic_curves.constructor import HyperellipticCurve K = self.base_ring() p = K.prime() A = PolynomialRing(QQ, "x") x = A.gen() J = K.extension(x ** deg - p, names="a") pol = self.hyperelliptic_polynomials()[0] H = HyperellipticCurve(A(pol)) HJ = H.change_ring(J) self._curve_over_ram_extn = HJ self._curve_over_ram_extn._curve_over_Qp = self return HJ
def curve_over_ram_extn(self, deg): r""" Return ``self`` over `\QQ_p(p^(1/deg))`. INPUT: - deg: the degree of the ramified extension OUTPUT: ``self`` over `\QQ_p(p^(1/deg))` EXAMPLES:: sage: R.<x> = QQ['x'] sage: H = HyperellipticCurve(x^5-23*x^3+18*x^2+40*x) sage: K = Qp(11,5) sage: HK = H.change_ring(K) sage: HL = HK.curve_over_ram_extn(2) sage: HL Hyperelliptic Curve over Eisenstein Extension in a defined by x^2 - 11 with capped relative precision 10 over 11-adic Field defined by (1 + O(a^10))*y^2 = (1 + O(a^10))*x^5 + (10 + 8*a^2 + 10*a^4 + 10*a^6 + 10*a^8 + O(a^10))*x^3 + (7 + a^2 + O(a^10))*x^2 + (7 + 3*a^2 + O(a^10))*x AUTHOR: - Jennifer Balakrishnan """ from sage.schemes.hyperelliptic_curves.constructor import HyperellipticCurve K = self.base_ring() p = K.prime() A = PolynomialRing(QQ, 'x') x = A.gen() J = K.extension(x**deg - p, names='a') pol = self.hyperelliptic_polynomials()[0] H = HyperellipticCurve(A(pol)) HJ = H.change_ring(J) self._curve_over_ram_extn = HJ self._curve_over_ram_extn._curve_over_Qp = self return HJ
def is_8_order(E): Q = PolynomialRing(E.base_field(), 'x') x = Q.gen() A = E.a4() B = E.a6() f = -x**6 - 5 * A * x**4 + 5 * A**2 * x**2 - 20 * B * x**3 + A**3 + 4 * A * B * x + 8 * B**2 counter = 0 for r in f.roots(): try: P = E.lift_x(r[0]) counter += 1 g = -x**4 + 2 * A * x**2 - A**2 + 8 * B * x + 4 * (x**3 + A * x + B) * P[0] for s in g.roots(): y1 = (2 * P[1])**(-1) * ((3 * s[0]**2 + A) * (s[0] - P[0]) - 2 * (s[0]**3 + A * s[0] + B)) Q = E(s[0], y1) return True except: pass return counter >= 4
def integrate_H0_riemann(G, divisor, hc, depth, gamma, prec, counter, total_counter, progress_bar, parallelize): # verbose('Integral %s/%s...'%(counter,total_counter)) HOC = hc.parent() if prec is None: prec = HOC.coefficient_module().precision_cap() K = divisor.parent().base_ring() R = PolynomialRing(K, names='t').fraction_field() t = R.gen() phi = lambda t: prod([(t - P)**ZZ(n) for P, n in divisor], K(1)) try: hc = hc.get_liftee() except AttributeError: pass ans = K( riemann_sum(G, phi, ShapiroImage(G, hc)(gamma.quaternion_rep), depth, mult=True, progress_bar=progress_bar, K=K)) return ans, ans.log(p_branch=0)
def weil_representation(self): r""" OUTPUT: - A pair of matrices corresponding to T and S. """ disc_bilinear = lambda a, b: (self._dual_basis * vector(QQ, a.lift( ))) * self._L * (self._dual_basis * vector(QQ, b.lift())) disc_quadratic = lambda a: disc_bilinear(a, a) / ZZ(2) zeta_order = ZZ( lcm([8, 12, prod(self.invariants())] + map(lambda ed: 2 * ed, self.invariants()))) K = CyclotomicField(zeta_order) zeta = K.gen() R = PolynomialRing(K, 'x') x = R.gen() # sqrt2s = (x**2 - 2).factor() # if sqrt2s[0][0][0].complex_embedding().real() > 0 : # sqrt2 = sqrt2s[0][0][0] # else : # sqrt2 = sqrt2s[0][1] Ldet_rts = (x**2 - prod(self.invariants())).factor() if Ldet_rts[0][0][0].complex_embedding().real() > 0: Ldet_rt = Ldet_rts[0][0][0] else: Ldet_rt = Ldet_rts[0][0][0] Tmat = diagonal_matrix( K, [zeta**(zeta_order * disc_quadratic(a)) for a in self]) Smat = zeta**(zeta_order / 8 * self._L.nrows()) / Ldet_rt \ * matrix( K, [ [ zeta**ZZ(-zeta_order * disc_bilinear(gamma,delta)) for delta in self ] for gamma in self ]) return (Tmat, Smat)
def generator_relations(self, K) : """ An ideal `I` in a polynomial ring `R` over `K`, such that the associated ring is `R / I` surjects onto the ring of modular forms with coefficients in `K`. INPUT: - `K` -- A ring. OUTPUT: An ideal in a polynomial ring. TESTS:: sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_testtype import * sage: t = ModularFormTestType_scalar() sage: t.generator_relations(QQ) Ideal (g1^2 - g2, g1^3 - g3, g1^4 - g4, g1^5 - g5) of Multivariate Polynomial Ring in g1, g2, g3, g4, g5 over Rational Field """ if K.has_coerce_map_from(ZZ) : R = PolynomialRing(K, self._generator_names(K)) g1 = R.gen(0) return R.ideal([g1**i - g for (i,g) in list(enumerate([None] + list(R.gens())))[2:]]) raise NotImplementedError
def _normalize_2x2(G): r""" Normalize this indecomposable `2` by `2` block. INPUT: ``G`` - a `2` by `2` matrix over `\ZZ_p` with ``type = 'fixed-mod'`` of the form:: [2a b] [ b 2c] * 2^n with `b` of valuation 1. OUTPUT: A unimodular `2` by `2` matrix ``B`` over `\ZZ_p` with ``B * G * B.transpose()`` either:: [0 1] [2 1] [1 0] * 2^n or [1 2] * 2^n EXAMPLES:: sage: from sage.quadratic_forms.genera.normal_form import _normalize_2x2 sage: R = Zp(2, prec = 15, type = 'fixed-mod', print_mode='series', show_prec=False) sage: G = Matrix(R, 2, [-17*2,3,3,23*2]) sage: B =_normalize_2x2(G) sage: B * G * B.T [2 1] [1 2] sage: G = Matrix(R,2,[-17*4,3,3,23*2]) sage: B = _normalize_2x2(G) sage: B*G*B.T [0 1] [1 0] sage: G = 2^3 * Matrix(R, 2, [-17*2,3,3,23*2]) sage: B = _normalize_2x2(G) sage: B * G * B.T [2^4 2^3] [2^3 2^4] """ from sage.rings.all import PolynomialRing from sage.modules.free_module_element import vector B = copy(G.parent().identity_matrix()) R = G.base_ring() P = PolynomialRing(R, 'x') x = P.gen() # The input must be an even block odd1 = (G[0, 0].valuation() < G[1, 0].valuation()) odd2 = (G[1, 1].valuation() < G[1, 0].valuation()) if odd1 or odd2: raise ValueError("Not a valid 2 x 2 block.") scale = 2**G[0, 1].valuation() D = Matrix(R, 2, 2, [d // scale for d in G.list()]) # now D is of the form # [2a b ] # [b 2c] # where b has valuation 1. G = copy(D) # Make sure G[1, 1] has valuation 1. if D[1, 1].valuation() > D[0, 0].valuation(): B.swap_columns(0, 1) D.swap_columns(0, 1) D.swap_rows(0, 1) if D[1, 1].valuation() != 1: # this works because # D[0, 0] has valuation at least 2 B[1, :] += B[0, :] D = B * G * B.transpose() assert D[1, 1].valuation() == 1 if mod(D.det(), 8) == 3: # in this case we can transform D to # 2 1 # 1 2 # Find a point of norm 2 # solve: 2 == D[1,1]*x^2 + 2*D[1,0]*x + D[0,0] pol = (D[1, 1] * x**2 + 2 * D[1, 0] * x + D[0, 0] - 2) // 2 # somehow else pari can get a hickup see trac #24065 pol = pol // pol.leading_coefficient() sol = pol.roots()[0][0] B[0, 1] = sol D = B * G * B.transpose() # make D[0, 1] = 1 B[1, :] *= D[1, 0].inverse_of_unit() D = B * G * B.transpose() # solve: v*D*v == 2 with v = (x, -2*x+1) if D[1, 1] != 2: v = vector([x, -2 * x + 1]) pol = (v * D * v - 2) // 2 # somehow else pari can get a hickup see trac #24065 pol = pol // pol.leading_coefficient() sol = pol.roots()[0][0] B[1, :] = sol * B[0, :] + (-2 * sol + 1) * B[1, :] D = B * G * B.transpose() # check the result assert D == Matrix(G.parent(), 2, 2, [2, 1, 1, 2]), "D1 \n %r" % D elif mod(D.det(), 8) == 7: # in this case we can transform D to # 0 1 # 1 0 # Find a point representing 0 # solve: 0 == D[1,1]*x^2 + 2*D[1,0]*x + D[0,0] pol = (D[1, 1] * x**2 + 2 * D[1, 0] * x + D[0, 0]) // 2 # somehow else pari can get a hickup, see trac #24065 pol = pol // pol.leading_coefficient() sol = pol.roots()[0][0] B[0, :] += sol * B[1, :] D = B * G * B.transpose() # make the second basis vector have 0 square as well. B[1, :] = B[1, :] - D[1, 1] // (2 * D[0, 1]) * B[0, :] D = B * G * B.transpose() # rescale to get D[0,1] = 1 B[0, :] *= D[1, 0].inverse_of_unit() D = B * G * B.transpose() # check the result assert D == Matrix(G.parent(), 2, 2, [0, 1, 1, 0]), "D2 \n %r" % D return B
def _normalize_2x2(G): r""" Normalize this indecomposable `2` by `2` block. INPUT: ``G`` - a `2` by `2` matrix over `\ZZ_p` with ``type = 'fixed-mod'`` of the form:: [2a b] [ b 2c] * 2^n with `b` of valuation 1. OUTPUT: A unimodular `2` by `2` matrix ``B`` over `\ZZ_p` with ``B * G * B.transpose()`` either:: [0 1] [2 1] [1 0] * 2^n or [1 2] * 2^n EXAMPLES:: sage: from sage.quadratic_forms.genera.normal_form import _normalize_2x2 sage: R = Zp(2, prec = 15, type = 'fixed-mod', print_mode='series', show_prec=False) sage: G = Matrix(R, 2, [-17*2,3,3,23*2]) sage: B =_normalize_2x2(G) sage: B * G * B.T [2 1] [1 2] sage: G = Matrix(R,2,[-17*4,3,3,23*2]) sage: B = _normalize_2x2(G) sage: B*G*B.T [0 1] [1 0] sage: G = 2^3 * Matrix(R, 2, [-17*2,3,3,23*2]) sage: B = _normalize_2x2(G) sage: B * G * B.T [2^4 2^3] [2^3 2^4] """ from sage.rings.all import PolynomialRing from sage.modules.free_module_element import vector B = copy(G.parent().identity_matrix()) R = G.base_ring() P = PolynomialRing(R, 'x') x = P.gen() # The input must be an even block odd1 = (G[0, 0].valuation() < G[1, 0].valuation()) odd2 = (G[1, 1].valuation() < G[1, 0].valuation()) if odd1 or odd2: raise ValueError("Not a valid 2 x 2 block.") scale = 2 ** G[0,1].valuation() D = Matrix(R, 2, 2, [d // scale for d in G.list()]) # now D is of the form # [2a b ] # [b 2c] # where b has valuation 1. G = copy(D) # Make sure G[1, 1] has valuation 1. if D[1, 1].valuation() > D[0, 0].valuation(): B.swap_columns(0, 1) D.swap_columns(0, 1) D.swap_rows(0, 1) if D[1, 1].valuation() != 1: # this works because # D[0, 0] has valuation at least 2 B[1, :] += B[0, :] D = B * G * B.transpose() assert D[1, 1].valuation() == 1 if mod(D.det(), 8) == 3: # in this case we can transform D to # 2 1 # 1 2 # Find a point of norm 2 # solve: 2 == D[1,1]*x^2 + 2*D[1,0]*x + D[0,0] pol = (D[1,1]*x**2 + 2*D[1,0]*x + D[0,0]-2) // 2 # somehow else pari can get a hickup see `trac`:#24065 pol = pol // pol.leading_coefficient() sol = pol.roots()[0][0] B[0, 1] = sol D = B * G * B.transpose() # make D[0, 1] = 1 B[1, :] *= D[1, 0].inverse_of_unit() D = B * G * B.transpose() # solve: v*D*v == 2 with v = (x, -2*x+1) if D[1, 1] != 2: v = vector([x, -2*x + 1]) pol = (v*D*v - 2) // 2 # somehow else pari can get a hickup `trac`:#24065 pol = pol // pol.leading_coefficient() sol = pol.roots()[0][0] B[1, :] = sol * B[0,:] + (-2*sol + 1)*B[1, :] D = B * G * B.transpose() # check the result assert D == Matrix(G.parent(), 2, 2, [2, 1, 1, 2]), "D1 \n %r" %D elif mod(D.det(), 8) == 7: # in this case we can transform D to # 0 1 # 1 0 # Find a point representing 0 # solve: 0 == D[1,1]*x^2 + 2*D[1,0]*x + D[0,0] pol = (D[1,1]*x**2 + 2*D[1,0]*x + D[0,0])//2 # somehow else pari can get a hickup, see `trac`:#24065 pol = pol // pol.leading_coefficient() sol = pol.roots()[0][0] B[0,:] += sol*B[1, :] D = B * G * B.transpose() # make the second basis vector have 0 square as well. B[1, :] = B[1, :] - D[1, 1]//(2*D[0, 1])*B[0,:] D = B * G * B.transpose() # rescale to get D[0,1] = 1 B[0, :] *= D[1, 0].inverse_of_unit() D = B * G * B.transpose() # check the result assert D == Matrix(G.parent(), 2, 2, [0, 1, 1, 0]), "D2 \n %r" %D return B
def segre_embedding(self, PP=None, var='u'): r""" Return the Segre embedding of this space into the appropriate projective space. INPUT: - ``PP`` -- (default: ``None``) ambient image projective space; this is constructed if it is not given. - ``var`` -- string, variable name of the image projective space, default `u` (optional). OUTPUT: Hom -- from this space to the appropriate subscheme of projective space. .. TODO:: Cartesian products with more than two components. EXAMPLES:: sage: X.<y0,y1,y2,y3,y4,y5> = ProductProjectiveSpaces(ZZ, [2, 2]) sage: phi = X.segre_embedding(); phi Scheme morphism: From: Product of projective spaces P^2 x P^2 over Integer Ring To: Closed subscheme of Projective Space of dimension 8 over Integer Ring defined by: -u5*u7 + u4*u8, -u5*u6 + u3*u8, -u4*u6 + u3*u7, -u2*u7 + u1*u8, -u2*u4 + u1*u5, -u2*u6 + u0*u8, -u1*u6 + u0*u7, -u2*u3 + u0*u5, -u1*u3 + u0*u4 Defn: Defined by sending (y0 : y1 : y2 , y3 : y4 : y5) to (y0*y3 : y0*y4 : y0*y5 : y1*y3 : y1*y4 : y1*y5 : y2*y3 : y2*y4 : y2*y5). :: sage: T = ProductProjectiveSpaces([1, 2], CC, 'z') sage: T.segre_embedding() Scheme morphism: From: Product of projective spaces P^1 x P^2 over Complex Field with 53 bits of precision To: Closed subscheme of Projective Space of dimension 5 over Complex Field with 53 bits of precision defined by: -u2*u4 + u1*u5, -u2*u3 + u0*u5, -u1*u3 + u0*u4 Defn: Defined by sending (z0 : z1 , z2 : z3 : z4) to (z0*z2 : z0*z3 : z0*z4 : z1*z2 : z1*z3 : z1*z4). :: sage: T = ProductProjectiveSpaces([1, 2, 1], QQ, 'z') sage: T.segre_embedding() Scheme morphism: From: Product of projective spaces P^1 x P^2 x P^1 over Rational Field To: Closed subscheme of Projective Space of dimension 11 over Rational Field defined by: -u9*u10 + u8*u11, -u7*u10 + u6*u11, -u7*u8 + u6*u9, -u5*u10 + u4*u11, -u5*u8 + u4*u9, -u5*u6 + u4*u7, -u5*u9 + u3*u11, -u5*u8 + u3*u10, -u5*u8 + u2*u11, -u4*u8 + u2*u10, -u3*u8 + u2*u9, -u3*u6 + u2*u7, -u3*u4 + u2*u5, -u5*u7 + u1*u11, -u5*u6 + u1*u10, -u3*u7 + u1*u9, -u3*u6 + u1*u8, -u5*u6 + u0*u11, -u4*u6 + u0*u10, -u3*u6 + u0*u9, -u2*u6 + u0*u8, -u1*u6 + u0*u7, -u1*u4 + u0*u5, -u1*u2 + u0*u3 Defn: Defined by sending (z0 : z1 , z2 : z3 : z4 , z5 : z6) to (z0*z2*z5 : z0*z2*z6 : z0*z3*z5 : z0*z3*z6 : z0*z4*z5 : z0*z4*z6 : z1*z2*z5 : z1*z2*z6 : z1*z3*z5 : z1*z3*z6 : z1*z4*z5 : z1*z4*z6). """ N = self._dims M = prod([n + 1 for n in N]) - 1 CR = self.coordinate_ring() vars = list(self.coordinate_ring().variable_names()) + [ var + str(i) for i in range(M + 1) ] R = PolynomialRing(self.base_ring(), self.ngens() + M + 1, vars, order='lex') #set-up the elimination for the segre embedding mapping = [] k = self.ngens() index = self.num_components() * [0] for count in range(M + 1): mapping.append( R.gen(k + count) - prod([CR(self[i].gen(index[i])) for i in range(len(index))])) for i in range(len(index) - 1, -1, -1): if index[i] == N[i]: index[i] = 0 else: index[i] += 1 break #only increment once #change the defining ideal of the subscheme into the variables I = R.ideal(list(self.defining_polynomials()) + mapping) J = I.groebner_basis() s = set(R.gens()[:self.ngens()]) n = len(J) - 1 L = [] while s.isdisjoint(J[n].variables()): L.append(J[n]) n = n - 1 #create new subscheme if PP is None: PS = ProjectiveSpace(self.base_ring(), M, R.variable_names()[self.ngens():]) Y = PS.subscheme(L) else: if PP.dimension_relative() != M: raise ValueError( "projective Space %s must be dimension %s") % (PP, M) S = PP.coordinate_ring() psi = R.hom([0] * k + list(S.gens()), S) L = [psi(l) for l in L] Y = PP.subscheme(L) #create embedding for points mapping = [] index = self.num_components() * [0] for count in range(M + 1): mapping.append( prod([CR(self[i].gen(index[i])) for i in range(len(index))])) for i in range(len(index) - 1, -1, -1): if index[i] == N[i]: index[i] = 0 else: index[i] += 1 break #only increment once phi = self.hom(mapping, Y) return phi
def segre_embedding(self, PP=None, var='u'): r""" Return the Segre embedding of ``self`` into the appropriate projective space. INPUT: - ``PP`` -- (default: ``None``) ambient image projective space; this is constructed if it is not given. - ``var`` -- string, variable name of the image projective space, default `u` (optional) OUTPUT: Hom -- from ``self`` to the appropriate subscheme of projective space .. TODO:: Cartesian products with more than two components EXAMPLES:: sage: X.<y0,y1,y2,y3,y4,y5> = ProductProjectiveSpaces(ZZ,[2,2]) sage: phi = X.segre_embedding(); phi Scheme morphism: From: Product of projective spaces P^2 x P^2 over Integer Ring To: Closed subscheme of Projective Space of dimension 8 over Integer Ring defined by: -u5*u7 + u4*u8, -u5*u6 + u3*u8, -u4*u6 + u3*u7, -u2*u7 + u1*u8, -u2*u4 + u1*u5, -u2*u6 + u0*u8, -u1*u6 + u0*u7, -u2*u3 + u0*u5, -u1*u3 + u0*u4 Defn: Defined by sending (y0 : y1 : y2 , y3 : y4 : y5) to (y0*y3 : y0*y4 : y0*y5 : y1*y3 : y1*y4 : y1*y5 : y2*y3 : y2*y4 : y2*y5). :: sage: T = ProductProjectiveSpaces([1,2],CC,'z') sage: T.segre_embedding() Scheme morphism: From: Product of projective spaces P^1 x P^2 over Complex Field with 53 bits of precision To: Closed subscheme of Projective Space of dimension 5 over Complex Field with 53 bits of precision defined by: -u2*u4 + u1*u5, -u2*u3 + u0*u5, -u1*u3 + u0*u4 Defn: Defined by sending (z0 : z1 , z2 : z3 : z4) to (z0*z2 : z0*z3 : z0*z4 : z1*z2 : z1*z3 : z1*z4). """ N = self._dims if len(N) > 2: raise NotImplementedError("Cannot have more than two components.") M = (N[0]+1)*(N[1]+1)-1 vars = list(self.coordinate_ring().variable_names()) + [var + str(i) for i in range(M+1)] R = PolynomialRing(self.base_ring(),self.ngens()+M+1, vars, order='lex') #set-up the elimination for the segre embedding mapping = [] k = self.ngens() for i in range(N[0]+1): for j in range(N[0]+1,N[0]+N[1]+2): mapping.append(R.gen(k)-R(self.gen(i)*self.gen(j))) k+=1 #change the defining ideal of the subscheme into the variables I = R.ideal(list(self.defining_polynomials()) + mapping) J = I.groebner_basis() s = set(R.gens()[:self.ngens()]) n = len(J)-1 L = [] while s.isdisjoint(J[n].variables()): L.append(J[n]) n = n-1 #create new subscheme if PP is None: PS = ProjectiveSpace(self.base_ring(),M,R.gens()[self.ngens():]) Y = PS.subscheme(L) else: if PP.dimension_relative()!= M: raise ValueError("Projective Space %s must be dimension %s")%(PP, M) S = PP.coordinate_ring() psi = R.hom([0]*(N[0]+N[1]+2) + list(S.gens()),S) L = [psi(l) for l in L] Y = PP.subscheme(L) #create embedding for points mapping = [] for i in range(N[0]+1): for j in range(N[0]+1,N[0]+N[1]+2): mapping.append(self.gen(i)*self.gen(j)) phi = self.hom(mapping,Y) return phi
def rational_type(f, n=ZZ(3), base_ring=ZZ): r""" Return the basic analytic properties that can be determined directly from the specified rational function ``f`` which is interpreted as a representation of an element of a FormsRing for the Hecke Triangle group with parameter ``n`` and the specified ``base_ring``. In particular the following degree of the generators is assumed: `deg(1) := (0, 1)` `deg(x) := (4/(n-2), 1)` `deg(y) := (2n/(n-2), -1)` `deg(z) := (2, -1)` The meaning of homogeneous elements changes accordingly. INPUT: - ``f`` -- A rational function in ``x,y,z,a,b,c,d`` over ``base_ring``. - ``n`` -- An integer greater or equal to `3` corresponding to the ``HeckeTriangleGroup`` with that parameter (default: `3`). - ``base_ring`` -- The base ring of the corresponding forms ring, resp. polynomial ring (default: ``ZZ``). OUTPUT: A tuple ``(elem, h**o, k, ep, analytic_type)`` describing the basic analytic properties of `f` (with the interpretation indicated above). - ``elem`` -- ``True`` if `f` has a homogeneous denominator. - ``h**o`` -- ``True`` if `f` also has a homogeneous numerator. - ``k`` -- ``None`` if `f` is not homogeneneous, otherwise the weight of `f` (which is the first component of its degree). - ``ep`` -- ``None`` if `f` is not homogeneous, otherwise the multiplier of `f` (which is the second component of its degree) - ``analytic_type`` -- The ``AnalyticType`` of `f`. For the zero function the degree `(0, 1)` is choosen. This function is (heavily) used to determine the type of elements and to check if the element really is contained in its parent. EXAMPLES:: sage: from sage.modular.modform_hecketriangle.constructor import rational_type sage: (x,y,z,a,b,c,d) = var("x,y,z,a,b,c,d") sage: rational_type(0, n=4) (True, True, 0, 1, zero) sage: rational_type(1, n=12) (True, True, 0, 1, modular) sage: rational_type(x^3 - y^2) (True, True, 12, 1, cuspidal) sage: rational_type(x * z, n=7) (True, True, 14/5, -1, quasi modular) sage: rational_type(1/(x^3 - y^2) + z/d) (True, False, None, None, quasi weakly holomorphic modular) sage: rational_type(x^3/(x^3 - y^2)) (True, True, 0, 1, weakly holomorphic modular) sage: rational_type(1/(x + z)) (False, False, None, None, None) sage: rational_type(1/x + 1/z) (True, False, None, None, quasi meromorphic modular) sage: rational_type(d/x, n=10) (True, True, -1/2, 1, meromorphic modular) sage: rational_type(1.1 * z * (x^8-y^2), n=8, base_ring=CC) (True, True, 22/3, -1, quasi cuspidal) sage: rational_type(x-y^2, n=infinity) (True, True, 4, 1, modular) sage: rational_type(x*(x-y^2), n=infinity) (True, True, 8, 1, cuspidal) sage: rational_type(1/x, n=infinity) (True, True, -4, 1, weakly holomorphic modular) """ from analytic_type import AnalyticType AT = AnalyticType() # Determine whether f is zero if (f == 0): # elem, h**o, k, ep, m, analytic_type return (True, True, QQ(0), ZZ(1), QQ(0), AT([])) analytic_type = AT(["quasi", "mero", "jacobi"]) R = PolynomialRing(base_ring,'x,y,z,a,b,c,d') F = FractionField(R) (x,y,z,a,b,c,d) = R.gens() R2 = PolynomialRing(PolynomialRing(base_ring, 'd'), 'x,y,z,a,b,c') R3 = PolynomialRing(PolynomialRing(base_ring, 'x,y,z,b,c,d'), 'a') dhom = R.hom( R2.gens() + (R2.base().gen(),), R2) dhomindex = R.hom( R3.base().gens()[0:3] + (R3.gen(),) + R3.base().gens()[3:6], R3) f = F(f) num = R(f.numerator()) denom = R(f.denominator()) #TODO ep_num = set([ZZ(1) - 2*(( sum([g.exponents()[0][m] for m in [1,2,4]]) )%2) for g in dhom(num).monomials()]) ep_denom = set([ZZ(1) - 2*(( sum([g.exponents()[0][m] for m in [1,2,4]]) )%2) for g in dhom(denom).monomials()]) if (n == infinity): hom_num = R( num.subs(x=x**4, y=y**2, z=z**2) ) hom_denom = R( denom.subs(x=x**4, y=y**2, z=z**2) ) else: n = ZZ(n) hom_num = R( num.subs(x=x**4, y=y**(2*n), z=z**(2*(n-2)), a=a**ZZ(1), b=b**ZZ(2), c=c**ZZ(1)) ) hom_denom = R( denom.subs(x=x**4, y=y**(2*n), z=z**(2*(n-2)), a=a**ZZ(1), b=b**ZZ(2), c=c**ZZ(1)) ) # Determine whether the denominator of f is homogeneous if (len(ep_denom) == 1 and dhom(hom_denom).is_homogeneous()): elem = True else: # elem, h**o, k, ep, m, analytic_type return (False, False, None, None, None, None) # Determine whether f is homogeneous if (len(ep_num) == 1 and dhom(hom_num).is_homogeneous() and dhomindex(num).is_homogeneous()): h**o = True if (n == infinity): weight = (dhom(hom_num).degree() - dhom(hom_denom).degree()) else: weight = (dhom(hom_num).degree() - dhom(hom_denom).degree()) / (n-2) index = (dhomindex(num).degree() - dhomindex(denom).degree()) / ZZ(2) ep = ep_num.pop() / ep_denom.pop() # TODO: decompose f (resp. its degrees) into homogeneous parts else: h**o = False weight = None ep = None index = None # Note that we intentially leave out the d-factor! if (n == infinity): finf_pol = (x-y**2) else: finf_pol = x**n-y**2 # Determine whether f is jacobi or not if not any([num.degree(sym) or denom.degree(sym) for sym in (a,b,c)]): analytic_type = analytic_type.reduce_to(["mero", "quasi"]) # Determine whether f is modular if not ( (num.degree(z) > 0) or (denom.degree(z) > 0) or (num.degree(c) > 0) or (denom.degree(c) > 0)): analytic_type = analytic_type.reduce_to(["mero", "jacobi"]) # Determine whether f is holomorphic if (dhom(denom).is_constant()): analytic_type = analytic_type.reduce_to(["quasi", "jacobi", "holo"]) # Determine whether f is cuspidal in the sense that finf divides it... # Bug in singular: finf_pol.dividess(1.0) fails over RR if (not dhom(num).is_constant() and finf_pol.divides(num)): if (n != infinity or x.divides(num)): analytic_type = analytic_type.reduce_to(["quasi", "jacobi", "cusp"]) else: # -> Because of a bug with singular in some cases try: while (finf_pol.divides(denom)): # a simple "denom /= finf_pol" is strangely not enough for non-exact rings # and dividing would/may result with an element of the quotient ring of the polynomial ring denom = denom.quo_rem(finf_pol)[0] denom = R(denom) if (n == infinity): while (x.divides(denom)): # a simple "denom /= x" is strangely not enough for non-exact rings # and dividing would/may result with an element of the quotient ring of the polynomial ring denom = denom.quo_rem(x)[0] denom = R(denom) except TypeError: pass # Determine whether f is weakly holomorphic in the sense that at most powers of finf occur in denom if (dhom(denom).is_constant()): analytic_type = analytic_type.reduce_to(["quasi", "jacobi", "weak"]) return (elem, h**o, weight, ep, index, analytic_type)
def elkies_next_step(j_0, j_1, l, lam): Phi = ClassicalModularPolynomialDatabase()[l] R = PolynomialRing(j_0.parent(), 'x') x = R.gen() f = R(Phi(x, j_1) / (x - j_0)) return f.roots()[0][0]
def segre_embedding(self, PP=None, var='u'): r""" Return the Segre embedding of this space into the appropriate projective space. INPUT: - ``PP`` -- (default: ``None``) ambient image projective space; this is constructed if it is not given. - ``var`` -- string, variable name of the image projective space, default `u` (optional). OUTPUT: Hom -- from this space to the appropriate subscheme of projective space. .. TODO:: Cartesian products with more than two components. EXAMPLES:: sage: X.<y0,y1,y2,y3,y4,y5> = ProductProjectiveSpaces(ZZ, [2, 2]) sage: phi = X.segre_embedding(); phi Scheme morphism: From: Product of projective spaces P^2 x P^2 over Integer Ring To: Closed subscheme of Projective Space of dimension 8 over Integer Ring defined by: -u5*u7 + u4*u8, -u5*u6 + u3*u8, -u4*u6 + u3*u7, -u2*u7 + u1*u8, -u2*u4 + u1*u5, -u2*u6 + u0*u8, -u1*u6 + u0*u7, -u2*u3 + u0*u5, -u1*u3 + u0*u4 Defn: Defined by sending (y0 : y1 : y2 , y3 : y4 : y5) to (y0*y3 : y0*y4 : y0*y5 : y1*y3 : y1*y4 : y1*y5 : y2*y3 : y2*y4 : y2*y5). :: sage: T = ProductProjectiveSpaces([1, 2], CC, 'z') sage: T.segre_embedding() Scheme morphism: From: Product of projective spaces P^1 x P^2 over Complex Field with 53 bits of precision To: Closed subscheme of Projective Space of dimension 5 over Complex Field with 53 bits of precision defined by: -u2*u4 + u1*u5, -u2*u3 + u0*u5, -u1*u3 + u0*u4 Defn: Defined by sending (z0 : z1 , z2 : z3 : z4) to (z0*z2 : z0*z3 : z0*z4 : z1*z2 : z1*z3 : z1*z4). :: sage: T = ProductProjectiveSpaces([1, 2, 1], QQ, 'z') sage: T.segre_embedding() Scheme morphism: From: Product of projective spaces P^1 x P^2 x P^1 over Rational Field To: Closed subscheme of Projective Space of dimension 11 over Rational Field defined by: -u9*u10 + u8*u11, -u7*u10 + u6*u11, -u7*u8 + u6*u9, -u5*u10 + u4*u11, -u5*u8 + u4*u9, -u5*u6 + u4*u7, -u5*u9 + u3*u11, -u5*u8 + u3*u10, -u5*u8 + u2*u11, -u4*u8 + u2*u10, -u3*u8 + u2*u9, -u3*u6 + u2*u7, -u3*u4 + u2*u5, -u5*u7 + u1*u11, -u5*u6 + u1*u10, -u3*u7 + u1*u9, -u3*u6 + u1*u8, -u5*u6 + u0*u11, -u4*u6 + u0*u10, -u3*u6 + u0*u9, -u2*u6 + u0*u8, -u1*u6 + u0*u7, -u1*u4 + u0*u5, -u1*u2 + u0*u3 Defn: Defined by sending (z0 : z1 , z2 : z3 : z4 , z5 : z6) to (z0*z2*z5 : z0*z2*z6 : z0*z3*z5 : z0*z3*z6 : z0*z4*z5 : z0*z4*z6 : z1*z2*z5 : z1*z2*z6 : z1*z3*z5 : z1*z3*z6 : z1*z4*z5 : z1*z4*z6). """ N = self._dims M = prod([n+1 for n in N]) - 1 CR = self.coordinate_ring() vars = list(self.coordinate_ring().variable_names()) + [var + str(i) for i in range(M+1)] R = PolynomialRing(self.base_ring(), self.ngens()+M+1, vars, order='lex') #set-up the elimination for the segre embedding mapping = [] k = self.ngens() index = self.num_components()*[0] for count in range(M + 1): mapping.append(R.gen(k+count)-prod([CR(self[i].gen(index[i])) for i in range(len(index))])) for i in range(len(index)-1, -1, -1): if index[i] == N[i]: index[i] = 0 else: index[i] += 1 break #only increment once #change the defining ideal of the subscheme into the variables I = R.ideal(list(self.defining_polynomials()) + mapping) J = I.groebner_basis() s = set(R.gens()[:self.ngens()]) n = len(J)-1 L = [] while s.isdisjoint(J[n].variables()): L.append(J[n]) n = n-1 #create new subscheme if PP is None: PS = ProjectiveSpace(self.base_ring(), M, R.variable_names()[self.ngens():]) Y = PS.subscheme(L) else: if PP.dimension_relative() != M: raise ValueError("projective Space %s must be dimension %s")%(PP, M) S = PP.coordinate_ring() psi = R.hom([0]*k + list(S.gens()), S) L = [psi(l) for l in L] Y = PP.subscheme(L) #create embedding for points mapping = [] index = self.num_components()*[0] for count in range(M + 1): mapping.append(prod([CR(self[i].gen(index[i])) for i in range(len(index))])) for i in range(len(index)-1, -1, -1): if index[i] == N[i]: index[i] = 0 else: index[i] += 1 break #only increment once phi = self.hom(mapping, Y) return phi
def double_integral_zero_infty(Phi, tau1, tau2): p = Phi.parent().prime() K = tau1.parent() R = PolynomialRing(K, 'x') x = R.gen() R1 = PowerSeriesRing(K, 'r1') r1 = R1.gen() try: R1.set_default_prec(Phi.precision_absolute()) except AttributeError: R1.set_default_prec(Phi.precision_relative()) level = Phi._map._manin.level() E0inf = [M2Z([0, -1, level, 0])] E0Zp = [M2Z([p, a, 0, 1]) for a in range(p)] predicted_evals = num_evals(tau1, tau2) a, b, c, d = find_center(p, level, tau1, tau2).list() h = M2Z([a, b, c, d]) E = [h * e0 for e0 in E0Zp + E0inf] resadd = 0 resmul = 1 total_evals = 0 percentage = QQ(0) ii = 0 f = (x - tau2) / (x - tau1) while len(E) > 0: ii += 1 increment = QQ((100 - percentage) / len(E)) verbose( 'remaining %s percent (and done %s of %s evaluations)' % (RealField(10)(100 - percentage), total_evals, predicted_evals)) newE = [] for e in E: a, b, c, d = e.list() assert ZZ(c) % level == 0 try: y0 = f((a * r1 + b) / (c * r1 + d)) val = y0(y0.parent().base_ring()(0)) if all([xx.valuation(p) > 0 for xx in (y0 / val - 1).list()]): if total_evals % 100 == 0: Phi._map._codomain.clear_cache() pol = val.log(p_branch=0) + ( (y0.derivative() / y0).integral()) V = [0] * pol.valuation() + pol.shift( -pol.valuation()).list() try: phimap = Phi._map(M2Z([b, d, a, c])) except OverflowError: print(a, b, c, d) raise OverflowError, 'Matrix too large?' # mu_e0 = ZZ(phimap.moment(0).rational_reconstruction()) mu_e0 = ZZ(Phi._liftee._map(M2Z([b, d, a, c])).moment(0)) mu_e = [mu_e0] + [ phimap.moment(o).lift() for o in range(1, len(V)) ] resadd += sum(starmap(mul, izip(V, mu_e))) resmul *= val**mu_e0 percentage += increment total_evals += 1 else: newE.extend([e * e0 for e0 in E0Zp]) except ZeroDivisionError: #raise RuntimeError,'Probably not enough working precision...' newE.extend([e * e0 for e0 in E0Zp]) E = newE verbose('total evaluations = %s' % total_evals) val = resmul.valuation() return p**val * K.teichmuller(p**(-val) * resmul) * resadd.exp()