def taut_rays(tri, angle): # get the extreme rays of the taut cone - note that the returned # vectors are non-negative because they "point up" N = edge_equation_matrix_taut(tri, angle) N = Matrix(N) dim = N.dimensions()[1] elem_ieqs = [[0] + list(elem_vector(i, dim)) for i in range(dim)] N_rows = [v.list() for v in N.rows()] N_eqns = [[0] + v for v in N_rows] P = Polyhedron(ieqs = elem_ieqs, eqns = N_eqns) rays = [ray.vector() for ray in P.rays()] for ray in rays: assert all(a.is_integer() for a in ray) # all of the entries are integers, represented in QQ, so we clean them. return [vector(ZZ(a) for a in ray) for ray in rays]
def hecke_matrix_on_ord(ll, ord_basis, weight=2, level=1, eps=None): R = ord_basis.parent().base_ring() ncols = ZZ(floor((ord_basis.ncols() - 1) / ll)) + 1 M = Matrix(R, ord_basis.nrows(), ncols, 0) if eps is None: if level % ll == 0: llpow_eps = ZZ(0) else: llpow_eps = ll**(weight - 1) else: llpow_eps = ll**(weight - 1) * eps(ll) for i, b in enumerate(ord_basis): for j in range(ncols): M[i, j] = b[j * ll] if j % ll == 0: M[i, j] += llpow_eps * b[j // ll] small_mat = ord_basis.submatrix(0, 0, ncols=M.ncols()) return Matrix([solve_xAb_echelon(small_mat, rw) for rw in M.rows()])
def product_space(chi, k, weights=False, base_ring=None, verbose=False): r""" Computes all eisenstein series, and products of pairs of eisenstein series of lower weight, lying in the space of modular forms of weight $k$ and nebentypus $\chi$. INPUT: - chi - Dirichlet character, the nebentypus of the target space - k - an integer, the weight of the target space OUTPUT: - a matrix of coefficients of q-expansions, which are the products of Eisenstein series in M_k(chi). WARNING: It is only for principal chi that we know that the resulting space is the whole space of modular forms. """ if weights == False: weights = srange(1, k / 2 + 1) weight_dict = {} weight_dict[-1] = [w for w in weights if w % 2] # Odd weights weight_dict[1] = [w for w in weights if not w % 2] # Even weights try: N = chi.modulus() except AttributeError: if chi.parent() == ZZ: N = chi chi = DirichletGroup(N)[0] Id = DirichletGroup(1)[0] if chi(-1) != (-1)**k: raise ValueError('chi(-1)!=(-1)^k') sturm = ModularForms(N, k).sturm_bound() + 1 if N > 1: target_dim = dimension_modular_forms(chi, k) else: target_dim = dimension_modular_forms(1, k) D = DirichletGroup(N) # product_space should ideally be called over number fields. Over complex # numbers the exact linear algebra solutions might not exist. if base_ring == None: base_ring = CyclotomicField(euler_phi(N)) Q = PowerSeriesRing(base_ring, 'q') q = Q.gen() d = len(D) prim_chars = [phi.primitive_character() for phi in D] divs = divisors(N) products = Matrix(base_ring, []) indexlist = [] rank = 0 if verbose: print(D) print('Sturm bound', sturm) #TODO: target_dim needs refinment in the case of weight 2. print('Target dimension', target_dim) for i in srange(0, d): # First character phi = prim_chars[i] M1 = phi.conductor() for j in srange(0, d): # Second character psi = prim_chars[j] M2 = psi.conductor() if not M1 * M2 in divs: continue parity = psi(-1) * phi(-1) for t1 in divs: if not M1 * M2 * t1 in divs: continue #TODO: THE NEXT CONDITION NEEDS TO BE CORRECTED. THIS IS JUST A TEST if phi.bar() == psi and not ( k == 2): #and i==0 and j==0 and t1==1): E = eisenstein_series_at_inf(phi, psi, k, sturm, t1, base_ring).padded_list() try: products.T.solve_right(vector(base_ring, E)) except ValueError: products = Matrix(products.rows() + [E]) indexlist.append([k, i, j, t1]) rank += 1 if verbose: print('Added ', [k, i, j, t1]) print('Rank is now', rank) if rank == target_dim: return products, indexlist for t in divs: if not M1 * M2 * t1 * t in divs: continue for t2 in divs: if not M1 * M2 * t1 * t2 * t in divs: continue for l in weight_dict[parity]: if l == 1 and phi.is_odd(): continue if i == 0 and j == 0 and (l == 2 or l == k - 2): continue #TODO: THE NEXT CONDITION NEEDS TO BE REMOVED. THIS IS JUST A TEST if l == 2 or l == k - 2: continue E1 = eisenstein_series_at_inf( phi, psi, l, sturm, t1 * t, base_ring) E2 = eisenstein_series_at_inf( phi**(-1), psi**(-1), k - l, sturm, t2 * t, base_ring) #If chi is non-principal this needs to be changed to be something like chi*phi^(-1) instead of phi^(-1) E = (E1 * E2 + O(q**sturm)).padded_list() try: products.T.solve_right(vector(base_ring, E)) except ValueError: products = Matrix(products.rows() + [E]) indexlist.append([l, k - l, i, j, t1, t2, t]) rank += 1 if verbose: print('Added ', [l, k - l, i, j, t1, t2, t]) print('Rank', rank) if rank == target_dim: return products, indexlist return products, indexlist