def _explode_embedding_list(v0,M,emblist,power = 1): p = v0.codomain().base_ring().prime() list_embeddings = [] for tau0,gtau_orig in emblist: gtau = gtau_orig**power verbose('gtau = %s'%gtau) ## First method for u1 in is_represented_by_unit(M,ZZ(gtau[0,0]),p): u_M1 = matrix(QQ,2,2,[u1**-1,0,0,u1]) gtau1 = u_M1 * gtau tau01 = tau0 / (u1**2) if gtau1[0,0] % M == 1: list_embeddings.append((tau01,gtau1,1)) elif gtau1[0,0] % M == -1: list_embeddings.append((tau01,-gtau1,1)) ## Second method if M > 1: a_inv = ZZ((1/Zmod(M)(gtau[0,0])).lift()) for u2 in is_represented_by_unit(M,a_inv,p): u_M2 = matrix(QQ,2,2,[u2,0,0,u2**-1]) gtau2 = u_M2 * gtau tau02 = u2**2 * tau0 #act_flt(u_M2,tau0) if gtau2[0,0] % M == 1: list_embeddings.append((tau02,gtau2,1)) elif gtau1[0,0] % M == -1: list_embeddings.append((tau02,-gtau2,1)) verbose('Found %s embeddings...'%len(list_embeddings)) return list_embeddings
def _compute_padic_splitting(self, prec): verbose('Entering compute_padic_splitting') prime = self.p if self.seed is not None: self.magma.eval('SetSeed(%s)' % self.seed) R = Qp(prime, prec + 10) #Zmod(prime**prec) # B_magma = self.Gpn._get_B_magma() a, b = self.Gpn.B.invariants() if self._hardcode_matrices: self._II = matrix(R, 2, 2, [1, 0, 0, -1]) self._JJ = matrix(R, 2, 2, [0, 1, 1, 0]) goodroot = self.F.gen().minpoly().change_ring(R).roots()[0][0] self._F_to_local = self.F.hom([goodroot]) else: verbose('Calling magma pMatrixRing') if self.F == QQ: _, f = self.magma.pMatrixRing(self.Gpn._Omax_magma, prime * self.Gpn._Omax_magma.BaseRing(), Precision=20, nvals=2) self._F_to_local = QQ.hom([R(1)]) else: _, f = self.magma.pMatrixRing(self.Gpn._Omax_magma, sage_F_ideal_to_magma( self.Gpn._F_magma, self.ideal_p), Precision=20, nvals=2) try: self._goodroot = R( f.Image(B_magma( B_magma.BaseRing().gen(1))).Vector()[1]._sage_()) except SyntaxError: raise SyntaxError( "Magma has trouble finding local splitting") self._F_to_local = None for o, _ in self.F.gen().minpoly().change_ring(R).roots(): if (o - self._goodroot).valuation() > 5: self._F_to_local = self.F.hom([o]) break assert self._F_to_local is not None verbose('Initializing II,JJ,KK') v = f.Image(B_magma.gen(1)).Vector() self._II = matrix(R, 2, 2, [v[i + 1]._sage_() for i in xrange(4)]) v = f.Image(B_magma.gen(2)).Vector() self._JJ = matrix(R, 2, 2, [v[i + 1]._sage_() for i in xrange(4)]) v = f.Image(B_magma.gen(3)).Vector() self._KK = matrix(R, 2, 2, [v[i + 1]._sage_() for i in xrange(4)]) self._II, self._JJ = lift_padic_splitting(self._F_to_local(a), self._F_to_local(b), self._II, self._JJ, prime, prec) self.Gn._F_to_local = self._F_to_local if not self.use_shapiro(): self.Gpn._F_to_local = self._F_to_local self._KK = self._II * self._JJ self._prec = prec return self._II, self._JJ, self._KK
def _split_hyperbolic(L) : cur_cor = 2 Lcor = L + cur_cor * identity_matrix(L.nrows()) while not is_positive_definite(Lcor) : cur_cor += 2 Lcor = L + cur_cor * identity_matrix(L.nrows()) a = FreeModule(ZZ, L.nrows()).gen(0) if a * L * a >= 0 : Lcor_length_inc = max(3, a * L * a) cur_Lcor_length = Lcor_length_inc while True : short_vectors = flatten(QuadraticForm(Lcor).short_vector_list_up_to_length( a * Lcor * a )[cur_Lcor_length - Lcor_length_inc: cur_Lcor_length], max_level = 1) for a in short_vectors : if a * L * a < 0 : break else : continue break n = -a * L * a // 2 short_vectors = E8.short_vector_list_up_to_length(n + 1)[-1] for v in short_vectors : for w in short_vectors : if v * E8_gram * w == 2 * n - 1 : LE8_mat = L.block_sum(E8_gram) v_form = vector( list(a) + list(v) ) * LE8_mat w_form = vector( list(a) + list(w) ) * LE8_mat Lred_basis = matrix(ZZ, [v_form, w_form]).right_kernel().basis_matrix().transpose() Lred_basis = matrix(ZZ, Lred_basis) return Lred_basis.transpose() * LE8_mat * Lred_basis
def get_BT_reps(self): reps = [self.Gn.B(1)] + [None for i in xrange(self.p)] emb = self.get_embedding(20) matrices = [(i + 1, matrix(QQ, 2, 2, [i, 1, -1, 0])) for i in xrange(self.p)] if self._matrix_group: verbose('Using hard-coded matrices for BT (Bianchi)') if F == QQ: wp = self.wp() return [self.Gn(1).quaternion_rep] + [ 1 / self.p * wp * matrix(QQ, 2, 2, [1, -i, 0, self.p]) for i in xrange(self.p) ] else: pi = self.ideal_p.gens_reduced()[0] B = self.Gn.B BTreps0 = [ Matrix(self.F, 2, 2, [0, -1, 1, -i]) for a in range(self.prime()) ] BTreps = [self.Gn(1).quaternion_rep] + [ self.Gn( B([(o[0, 0] + o[1, 1]) / 2, (o[0, 0] - o[1, 1]) / 2, (-o[0, 1] - o[1, 0]) / 2, (-o[0, 1] + o[1, 0]) / 2])).quaternion_rep for o in BTreps0 ] return BTreps for n_iters, elt in enumerate(self.Gn.enumerate_elements()): new_inv = elt**(-1) embelt = emb(elt) if (embelt[0, 0] - 1).valuation() > 0 and all([ not self.is_in_Gpn_order(o * new_inv) for o in reps if o is not None ]): if hasattr(self.Gpn, 'nebentypus'): tmp = self.do_tilde(embelt)**-1 tmp = tmp[0, 0] / (self.p**tmp[0, 0].valuation()) tmp = ZZ(tmp.lift()) % self.Gpn.level if tmp not in self.Gpn.nebentypus: continue for idx, o1 in enumerate(matrices): i, mat = o1 if is_in_Gamma0loc(embelt * mat, det_condition=False): reps[i] = set_immutable(elt) del matrices[idx] verbose( '%s, len = %s/%s' % (n_iters, self.p + 1 - len(matrices), self.p + 1)) if len(matrices) == 0: return reps break
def matrix_of_independent_rows(field, rows, width): M = matrix(field, rows, sparse=True) N = matrix(field, 0, width, sparse=True) NE = copy(N) for i in range(M.nrows()): NE2 = NE.stack(M[i, :]) NE2.echelonize() if not NE2[-1, :].is_zero(): NE = NE2 N = N.stack(M[i, :]) return N
def _hecke_operator_on_basis(B, V, n, k, eps): """ Does the work for hecke_operator_on_basis once the input is normalized. EXAMPLES:: sage: hecke_operator_on_basis(ModularForms(1,16).q_expansion_basis(30), 3, 16) # indirect doctest [ -3348 0] [ 0 14348908] The following used to cause a segfault due to accidentally transposed second and third argument (#2107):: sage: B = victor_miller_basis(100,30) sage: t2 = hecke_operator_on_basis(B, 100, 2) Traceback (most recent call last): ... ValueError: The given basis vectors must be linearly independent. """ prec = V.degree() TB = [hecke_operator_on_qexp(f, n, k, eps, prec, check=False, _return_list=True) for f in B] TB = [V.coordinate_vector(w) for w in TB] return matrix(V.base_ring(), len(B), len(B), TB, sparse=False)
def _matrix_(self, R): r""" Return Sage matrix from this matlab element. EXAMPLES:: sage: A = matlab('[1,2;3,4]') # optional - matlab sage: matrix(ZZ, A) # optional - matlab [1 2] [3 4] sage: A = matlab('[1,2;3,4.5]') # optional - matlab sage: matrix(RR, A) # optional - matlab [1.00000000000000 2.00000000000000] [3.00000000000000 4.50000000000000] sage: a = matlab('eye(50)') # optional - matlab sage: matrix(RR, a) # optional - matlab 50 x 50 dense matrix over Real Field with 53 bits of precision """ from sage.matrix.all import matrix matlab = self.parent() entries = matlab.strip_answer(matlab.eval("mat2str({0})".format(self.name()))) entries = entries.strip()[1:-1].replace(';', ' ') entries = map(R, entries.split(' ')) nrows, ncols = map(int, str(self.size()).strip().split()) m = matrix(R, nrows, ncols, entries) return m
def transition_matrix(self, basis, n): """ Returns the transitions matrix between self and basis for the homogenous component of degree n. EXAMPLES:: sage: HLP = HallLittlewoodP(QQ) sage: s = SFASchur(HLP.base_ring()) sage: HLP.transition_matrix(s, 4) [ 1 -t 0 t^2 -t^3] [ 0 1 -t -t t^3 + t^2] [ 0 0 1 -t t^3] [ 0 0 0 1 -t^3 - t^2 - t] [ 0 0 0 0 1] sage: HLQ = HallLittlewoodQ(QQ) sage: HLQ.transition_matrix(s,3) [ -t + 1 t^2 - t -t^3 + t^2] [ 0 t^2 - 2*t + 1 -t^4 + t^3 + t^2 - t] [ 0 0 -t^6 + t^5 + t^4 - t^2 - t + 1] sage: HLQp = HallLittlewoodQp(QQ) sage: HLQp.transition_matrix(s,3) [ 1 0 0] [ t 1 0] [ t^3 t^2 + t 1] """ P = sage.combinat.partition.Partitions_n(n) Plist = P.list() m = [] for row_part in Plist: z = basis(self(row_part)) m.append(map(lambda col_part: z.coefficient(col_part), Plist)) return matrix(m)
def space(self): r''' Calculates the homology space as a Z-module. ''' verb = get_verbose() set_verbose(0) V = self.coefficient_module() R = V.base_ring() Vdim = V.dimension() G = self.group() gens = G.gens() ambient = R**(Vdim * len(gens)) if self.trivial_action(): cycles = ambient else: # Now find the subspace of cycles A = Matrix(R, Vdim, 0) for g in gens: for v in V.gens(): A = A.augment(matrix(R,Vdim,1,list(vector(g**-1 * v - v)))) K = A.right_kernel_matrix() cycles = ambient.submodule([ambient(list(o)) for o in K.rows()]) boundaries = [] for r in G.get_relation_words(): grad = self.twisted_fox_gradient(G(r).word_rep) for v in V.gens(): boundaries.append(cycles(ambient(sum([list(a * vector(v)) for a in grad],[])))) boundaries = cycles.submodule(boundaries) ans = cycles.quotient(boundaries) set_verbose(verb) return ans
def hecke_matrix(self, l, use_magma = True, g0 = None, with_torsion = False): # l can be oo verb = get_verbose() set_verbose(0) if with_torsion: dim = len(self.gens()) gens = self.gens() else: dim = self.rank() gens = self.free_gens() R = self.coefficient_module().base_ring() M = matrix(R,dim,dim,0) coeff_dim = self.coefficient_module().dimension() for j,cycle in enumerate(gens): # Construct column j of the matrix new_col = vector(self.apply_hecke_operator(cycle, l, use_magma = use_magma, g0 = g0)) if with_torsion: M.set_column(j,list(new_col)) else: try: invs = self.space().invariants() M.set_column(j,[o for o,a in zip(new_col,invs) if a == 0]) except AttributeError: M.set_column(j,list(new_col)) set_verbose(verb) return M
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 transition_matrix(self, basis, n): """ Returns the transitions matrix between self and basis for the homogenous component of degree n. EXAMPLES:: sage: HLP = HallLittlewoodP(QQ) sage: s = SFASchur(HLP.base_ring()) sage: HLP.transition_matrix(s, 4) [ 1 -t 0 t^2 -t^3] [ 0 1 -t -t t^3 + t^2] [ 0 0 1 -t t^3] [ 0 0 0 1 -t^3 - t^2 - t] [ 0 0 0 0 1] sage: HLQ = HallLittlewoodQ(QQ) sage: HLQ.transition_matrix(s,3) [ -t + 1 t^2 - t -t^3 + t^2] [ 0 t^2 - 2*t + 1 -t^4 + t^3 + t^2 - t] [ 0 0 -t^6 + t^5 + t^4 - t^2 - t + 1] sage: HLQp = HallLittlewoodQp(QQ) sage: HLQp.transition_matrix(s,3) [ 1 0 0] [ t 1 0] [ t^3 t^2 + t 1] """ P = sage.combinat.partition.Partitions_n(n) Plist = P.list() m = [] for row_part in Plist: z = basis(self(row_part)) m.append( map( lambda col_part: z.coefficient(col_part), Plist ) ) return matrix(m)
def _hecke_operator_on_basis(B, V, n, k, eps): """ Does the work for hecke_operator_on_basis once the input is normalized. EXAMPLES:: sage: hecke_operator_on_basis(ModularForms(1,16).q_expansion_basis(30), 3, 16) # indirect doctest [ -3348 0] [ 0 14348908] The following used to cause a segfault due to accidentally transposed second and third argument (#2107):: sage: B = victor_miller_basis(100,30) sage: t2 = hecke_operator_on_basis(B, 100, 2) Traceback (most recent call last): ... ValueError: The given basis vectors must be linearly independent. """ prec = V.degree() TB = [ hecke_operator_on_qexp(f, n, k, eps, prec, check=False, _return_list=True) for f in B ] TB = [V.coordinate_vector(w) for w in TB] return matrix(V.base_ring(), len(B), len(B), TB, sparse=False)
def element_of_norm(self,N,use_magma = False,return_all = False, radius = None, max_elements = None, local_condition = None): # in nonsplitcartan try: if return_all: return [self._element_of_norm[N]] else: return self._element_of_norm[N] except (AttributeError,KeyError): pass if not hasattr(self,'_element_of_norm'): self._element_of_norm = dict([]) eps = self.eps q = self.q M = self.level llinv = (self.GFq(N)**-1).lift() if M != 1: while llinv % M != 1: llinv += q found = False for a,b in product(range(q*M),repeat = 2): if (a**2*llinv - b**2*eps*llinv - 1) % (q*M) == 0 and (b*eps) % M == 0: verbose('Found a=%s, b=%s'%(a,b)) found = True break assert found m0 = matrix(ZZ,2,2,[a,b*llinv,b*eps,a*llinv]) a,b,c,d = lift(m0,q*M).list() candidate = self.B([a,N*b,c,N*d]) assert self._is_in_order(candidate) assert candidate.determinant() == N set_immutable(candidate) self._element_of_norm[N] = candidate if return_all: return [candidate] else: return candidate
def k2s_matrix(kmatrix): r""" Convert an array of ECL to a matrix of Sage. """ dimensions = array_dimensions(kmatrix).python() kmatrix_list = make_array_to_lists(kmatrix).python() return matrix(dimensions[0], dimensions[1], kmatrix_list)
def __init__(self, G, V, trivial_action = False): self._group = G self._coeffmodule = V self._trivial_action = trivial_action self._gen_pows = [] self._gen_pows_neg = [] if trivial_action: self._acting_matrix = lambda x, y: matrix(V.base_ring(),V.dimension(),V.dimension(),1) gens_local = [ (None, None) for g in G.gens() ] else: def acting_matrix(x,y): try: return V.acting_matrix(x,y) except: return V.acting_matrix(G.embed(x.quaternion_rep,V.base_ring().precision_cap()), y) self._acting_matrix = acting_matrix gens_local = [ (g, g**-1) for g in G.gens() ] onemat = G(1) try: dim = V.dimension() except AttributeError: dim = len(V.basis()) one = Matrix(V.base_ring(),dim,dim,1) for g, ginv in gens_local: A = self._acting_matrix(g, dim) self._gen_pows.append([one, A]) Ainv = self._acting_matrix(ginv, dim) self._gen_pows_neg.append([one, Ainv]) Parent.__init__(self) return
def Cube_deformation(self,k, names=None): r""" Construct, for each `k\in\ZZ_{\geq 0}`, a toric variety with `\ZZ_k`-torsion in the Chow group. The fans of this sequence of toric varieties all equal the face fan of a unit cube topologically, but the ``(1,1,1)``-vertex is moved to ``(1,1,2k+1)``. This example was studied in [FS]_. INPUT: - ``k`` -- integer. The case ``k=0`` is the same as :meth:`Cube_face_fan`. - ``names`` -- string. Names for the homogeneous coordinates. See :func:`~sage.schemes.toric.variety.normalize_names` for acceptable formats. OUTPUT: A :class:`toric variety <sage.schemes.toric.variety.ToricVariety_field>` `X_k`. Its Chow group is `A_1(X_k)=\ZZ_k`. EXAMPLES:: sage: X_2 = toric_varieties.Cube_deformation(2) sage: X_2 3-d toric variety covered by 6 affine patches sage: X_2.fan().ray_matrix() [ 1 1 -1 -1 -1 -1 1 1] [ 1 -1 1 -1 -1 1 -1 1] [ 5 1 1 1 -1 -1 -1 -1] sage: X_2.gens() (z0, z1, z2, z3, z4, z5, z6, z7) REFERENCES: .. [FS] William Fulton, Bernd Sturmfels, "Intersection Theory on Toric Varieties", http://arxiv.org/abs/alg-geom/9403002 """ # We are going to eventually switch off consistency checks, so we need # to be sure that the input is acceptable. try: k = ZZ(k) # make sure that we got a "mathematical" integer except TypeError: raise TypeError("cube deformations X_k are defined only for " "non-negative integer k!\nGot: %s" % k) if k < 0: raise ValueError("cube deformations X_k are defined only for " "non-negative k!\nGot: %s" % k) rays = lambda kappa: matrix([[ 1, 1, 2*kappa+1],[ 1,-1, 1],[-1, 1, 1],[-1,-1, 1], [-1,-1,-1],[-1, 1,-1],[ 1,-1,-1],[ 1, 1,-1]]) cones = [[0,1,2,3],[4,5,6,7],[0,1,7,6],[4,5,3,2],[0,2,5,7],[4,6,1,3]] fan = Fan(cones, rays(k)) return ToricVariety(fan, coordinate_names=names)
def normalize_square_matrices(matrices): """ Find a common space for all matrices. OUTPUT: A list of matrices, all elements of the same matrix space. EXAMPLES:: sage: from sage.groups.matrix_gps.finitely_generated import normalize_square_matrices sage: m1 = [[1,2],[3,4]] sage: m2 = [2, 3, 4, 5] sage: m3 = matrix(QQ, [[1/2,1/3],[1/4,1/5]]) sage: m4 = MatrixGroup(m3).gen(0) sage: normalize_square_matrices([m1, m2, m3, m4]) [ [1 2] [2 3] [1/2 1/3] [1/2 1/3] [3 4], [4 5], [1/4 1/5], [1/4 1/5] ] """ deg = [] gens = [] for m in matrices: if is_MatrixGroupElement(m): deg.append(m.parent().degree()) gens.append(m.matrix()) continue if is_Matrix(m): if not m.is_square(): raise TypeError('matrix must be square') deg.append(m.ncols()) gens.append(m) continue try: m = list(m) except TypeError: gens.append(m) continue if isinstance(m[0], (list, tuple)): m = [list(_) for _ in m] degree = ZZ(len(m)) else: degree, rem = ZZ(len(m)).sqrtrem() if rem != 0: raise ValueError( 'list of plain numbers must have square integer length') deg.append(degree) gens.append(matrix(degree, degree, m)) deg = set(deg) if len(set(deg)) != 1: raise ValueError('not all matrices have the same size') gens = Sequence(gens, immutable=True) MS = gens.universe() if not is_MatrixSpace(MS): raise TypeError('all generators must be matrices') if MS.nrows() != MS.ncols(): raise ValueError('matrices must be square') return gens
def get_relation_matrix(self): # Define the (abelian) relation matrix rel_words = self.get_relation_words() relation_matrix = matrix(ZZ,len(rel_words),len(self.gens()),0) for i,rel in enumerate(rel_words): for j in rel: relation_matrix[i,ZZ(j).abs() - 1] += ZZ(j).sign() return relation_matrix
def set_wp(self, wp): epsinv = matrix(QQ,2,2,[0,-1,self.p,0])**-1 set_immutable(wp) assert is_in_Gamma0loc(self.embed(wp,20) * epsinv, det_condition = False) assert all((self.is_in_Gpn_order(wp**-1 * g * wp) for g in self.Gpn_Obasis())) assert self.is_in_Gpn_order(wp) self._wp = wp return self._wp
def normalize_square_matrices(matrices): """ Find a common space for all matrices. OUTPUT: A list of matrices, all elements of the same matrix space. EXAMPLES:: sage: from sage.groups.matrix_gps.finitely_generated import normalize_square_matrices sage: m1 = [[1,2],[3,4]] sage: m2 = [2, 3, 4, 5] sage: m3 = matrix(QQ, [[1/2,1/3],[1/4,1/5]]) sage: m4 = MatrixGroup(m3).gen(0) sage: normalize_square_matrices([m1, m2, m3, m4]) [ [1 2] [2 3] [1/2 1/3] [1/2 1/3] [3 4], [4 5], [1/4 1/5], [1/4 1/5] ] """ deg = [] gens = [] for m in matrices: if is_MatrixGroupElement(m): deg.append(m.parent().degree()) gens.append(m.matrix()) continue if is_Matrix(m): if not m.is_square(): raise TypeError('matrix must be square') deg.append(m.ncols()) gens.append(m) continue try: m = list(m) except TypeError: gens.append(m) continue if isinstance(m[0], (list, tuple)): m = [list(_) for _ in m] degree = ZZ(len(m)) else: degree, rem = ZZ(len(m)).sqrtrem() if rem!=0: raise ValueError('list of plain numbers must have square integer length') deg.append(degree) gens.append(matrix(degree, degree, m)) deg = set(deg) if len(set(deg)) != 1: raise ValueError('not all matrices have the same size') gens = Sequence(gens, immutable=True) MS = gens.universe() if not is_MatrixSpace(MS): raise TypeError('all generators must be matrices') if MS.nrows() != MS.ncols(): raise ValueError('matrices must be square') return gens
def _compute_padic_splitting(self,prec): verbose('Entering compute_padic_splitting') prime = self.p if self.seed is not None: self.magma.eval('SetSeed(%s)'%self.seed) R = Qp(prime,prec+10) #Zmod(prime**prec) # B_magma = self.Gn._B_magma a,b = self.Gn.B.invariants() if self._matrix_group: self._II = matrix(R,2,2,[1,0,0,-1]) self._JJ = matrix(R,2,2,[0,1,1,0]) goodroot = self.F.gen().minpoly().change_ring(R).roots()[0][0] self._F_to_local = self.F.hom([goodroot]) else: verbose('Calling magma pMatrixRing') if self.F == QQ: _,f = self.magma.pMatrixRing(self.Gn._O_magma,prime*self.Gn._O_magma.BaseRing(),Precision = 20,nvals = 2) self._F_to_local = QQ.hom([R(1)]) else: _,f = self.magma.pMatrixRing(self.Gn._O_magma,sage_F_ideal_to_magma(self.Gn._F_magma,self.ideal_p),Precision = 20,nvals = 2) try: self._goodroot = R(f.Image(B_magma(B_magma.BaseRing().gen(1))).Vector()[1]._sage_()) except SyntaxError: raise SyntaxError("Magma has trouble finding local splitting") self._F_to_local = None for o,_ in self.F.gen().minpoly().change_ring(R).roots(): if (o - self._goodroot).valuation() > 5: self._F_to_local = self.F.hom([o]) break assert self._F_to_local is not None verbose('Initializing II,JJ,KK') v = f.Image(B_magma.gen(1)).Vector() self._II = matrix(R,2,2,[v[i+1]._sage_() for i in xrange(4)]) v = f.Image(B_magma.gen(2)).Vector() self._JJ = matrix(R,2,2,[v[i+1]._sage_() for i in xrange(4)]) v = f.Image(B_magma.gen(3)).Vector() self._KK = matrix(R,2,2,[v[i+1]._sage_() for i in xrange(4)]) self._II , self._JJ = lift_padic_splitting(self._F_to_local(a),self._F_to_local(b),self._II,self._JJ,prime,prec) self.Gn._F_to_local = self._F_to_local if not self.use_shapiro(): self.Gpn._F_to_local = self._F_to_local self._KK = self._II * self._JJ self._prec = prec return self._II, self._JJ, self._KK
def positive_quadratic_form(self) : r""" Find the Gram matrix of a positive definite quadratic form which is stabily equivalent to `L`. """ E8_gram = matrix(ZZ, 8, [2, -1, 0, 0, 0, 0, 0, 0, -1, 2, -1, 0, 0, 0, 0, 0, 0, -1, 2, -1, 0, 0, 0, -1, 0, 0, -1, 2, -1, 0, 0, 0, 0, 0, 0, -1, 2, -1, 0, 0, 0, 0, 0, 0, -1, 2, -1, 0, 0, 0, 0, 0, 0, -1, 2, 0, 0, 0, -1, 0, 0, 0, 0, 2]) E8 = QuadraticForm(E8_gram) L = self._L ## This is a workaround since GP crashes is_positive_definite = lambda L: all( L[:n,:n].det() > 0 for n in range(1, L.nrows() + 1) ) def _split_hyperbolic(L) : cur_cor = 2 Lcor = L + cur_cor * identity_matrix(L.nrows()) while not is_positive_definite(Lcor) : cur_cor += 2 Lcor = L + cur_cor * identity_matrix(L.nrows()) a = FreeModule(ZZ, L.nrows()).gen(0) if a * L * a >= 0 : Lcor_length_inc = max(3, a * L * a) cur_Lcor_length = Lcor_length_inc while True : short_vectors = flatten(QuadraticForm(Lcor).short_vector_list_up_to_length( a * Lcor * a )[cur_Lcor_length - Lcor_length_inc: cur_Lcor_length], max_level = 1) for a in short_vectors : if a * L * a < 0 : break else : continue break n = -a * L * a // 2 short_vectors = E8.short_vector_list_up_to_length(n + 1)[-1] for v in short_vectors : for w in short_vectors : if v * E8_gram * w == 2 * n - 1 : LE8_mat = L.block_sum(E8_gram) v_form = vector( list(a) + list(v) ) * LE8_mat w_form = vector( list(a) + list(w) ) * LE8_mat Lred_basis = matrix(ZZ, [v_form, w_form]).right_kernel().basis_matrix().transpose() Lred_basis = matrix(ZZ, Lred_basis) return Lred_basis.transpose() * LE8_mat * Lred_basis while not is_positive_definite(L) : L = _split_hyperbolic(L) return L
def compute_cusp_stabiliser(self,cusp_matrix): """ Compute (a finite index subgroup of) the stabiliser of a cusp in Q or a quadratic imaginary field. We know the stabiliser of infinity is given by matrices of form (u, a; 0, u^-1), so a finite index subgroup is generated by (1, alpha; 0, 1) and (1, 1; 0, 1) for K = Q(alpha). Given the cusp, we use a matrix sending infinty to that cusp, and the conjugate by it, before taking powers to ensure the result is integral and lies in Gamma_0(N). Input: - a cusp (in matrix form: as output by cusp_set) - N (the level: an ideal in K). Outputs a list of the generators (as matrices). """ P = self.get_P1List() if hasattr(P.N(),'number_field'): K = P.N().number_field() ## Write down generators of a finite index subgroup in Stab_Gamma(infinity) infinity_gens = [matrix(K,[[1,1],[0,1]]), matrix(K,[[1,K.gen()],[0,1]])] N_ideal = P.N() else: K = QQ infinity_gens = [matrix([[1,1],[0,1]])] N_ideal = ZZ.ideal(P.N()) ## Initilise (empty) list of generators of Stab_Gamma(cusp) cusp_gens = [] ## Loop over all the generators of stab at infinity, conjugate into stab at cusp for T in infinity_gens: T_conj = cusp_matrix * T * cusp_matrix.adjugate() gen = T_conj ## Now take successive powers until the result is in Gamma_0(N) while not gen[1][0] in N_ideal: gen *= T_conj ## We've found an element in Stab_Gamma(cusp): add to our list of generators cusp_gens.append(gen) return cusp_gens
def padic_regulator(self, prec=20): r""" Computes the canonical `p`-adic regulator on the extended Mordell-Weil group as in [MTT] (with the correction of [Wer] and sign convention in [SW].) The `p`-adic Birch and Swinnerton-Dyer conjecture predicts that this value appears in the formula for the leading term of the `p`-adic L-function. INPUT: - ``prec`` - the `p`-adic precision, default is 20. REFERENCES: - [MTT] B. Mazur, J. Tate, and J. Teitelbaum, On `p`-adic analogues of the conjectures of Birch and Swinnerton-Dyer, Inventiones mathematicae 84, (1986), 1-48. - [Wer] Annette Werner, Local heights on abelian varieties and rigid analytic unifomization, Doc. Math. 3 (1998), 301-319. - [SW] William Stein and Christian Wuthrich, Computations About Tate-Shafarevich Groups using Iwasawa theory, preprint 2009. EXAMPLES:: sage: eq = EllipticCurve('130a1').tate_curve(5) sage: eq.padic_regulator() 2*5^-1 + 1 + 2*5 + 2*5^2 + 3*5^3 + 3*5^6 + 5^7 + 3*5^9 + 3*5^10 + 3*5^12 + 4*5^13 + 3*5^15 + 2*5^16 + 3*5^18 + 4*5^19 + O(5^20) """ prec = prec + 4 K = Qp(self._p, prec=prec) rank = self._E.rank() if rank == 0: return K(1) if not self.is_split(): raise NotImplementedError( "The p-adic regulator is not implemented for non-split multiplicative reduction." ) basis = self._E.gens() M = matrix.matrix(K, rank, rank, 0) height = self.padic_height(prec=prec) point_height = [height(P) for P in basis] for i in range(rank): for j in range(i + 1, rank): M[i, j] = M[j, i] = (-point_height[i] - point_height[j] + height(basis[i] + basis[j])) / 2 for i in range(rank): M[i, i] = point_height[i] return M.determinant()
def set_wp(self, wp): epsinv = matrix(QQ, 2, 2, [0, -1, self.p, 0])**-1 set_immutable(wp) assert is_in_Gamma0loc(self.embed(wp, 20) * epsinv, det_condition=False) assert all((self.is_in_Gpn_order(wp**-1 * g * wp) for g in self.Gpn._get_O_basis())) assert self.is_in_Gpn_order(wp) self._wp = wp return self._wp
def P(self, n, names='z+', base_ring=QQ): r""" Construct the ``n``-dimensional projective space `\mathbb{P}^n`. INPUT: - ``n`` -- positive integer. The dimension of the projective space. - ``names`` -- string. Names for the homogeneous coordinates. See :func:`~sage.schemes.toric.variety.normalize_names` for acceptable formats. - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. OUTPUT: A :class:`CPR-Fano toric variety <sage.schemes.toric.fano_variety.CPRFanoToricVariety_field>`. EXAMPLES:: sage: P3 = toric_varieties.P(3) sage: P3 3-d CPR-Fano toric variety covered by 4 affine patches sage: P3.fan().rays() N( 1, 0, 0), N( 0, 1, 0), N( 0, 0, 1), N(-1, -1, -1) in 3-d lattice N sage: P3.gens() (z0, z1, z2, z3) """ # We are going to eventually switch off consistency checks, so we need # to be sure that the input is acceptable. try: n = ZZ(n) # make sure that we got a "mathematical" integer except TypeError: raise TypeError("dimension of the projective space must be a " "positive integer!\nGot: %s" % n) if n <= 0: raise ValueError("only projective spaces of positive dimension " "can be constructed!\nGot: %s" % n) m = identity_matrix(n).augment(matrix(n, 1, [-1] * n)) charts = [ list(range(i)) + list(range(i + 1, n + 1)) for i in range(n + 1) ] return CPRFanoToricVariety(Delta_polar=LatticePolytope( m.columns(), lattice=ToricLattice(n)), charts=charts, check=self._check, coordinate_names=names, base_ring=base_ring)
def padic_regulator(self,prec=20): r""" Computes the canonical `p`-adic regulator on the extended Mordell-Weil group as in [MTT] (with the correction of [Wer] and sign convention in [SW].) The `p`-adic Birch and Swinnerton-Dyer conjecture predicts that this value appears in the formula for the leading term of the `p`-adic L-function. INPUT: - ``prec`` - the `p`-adic precision, default is 20. REFERENCES: - [MTT] B. Mazur, J. Tate, and J. Teitelbaum, On `p`-adic analogues of the conjectures of Birch and Swinnerton-Dyer, Inventiones mathematicae 84, (1986), 1-48. - [Wer] Annette Werner, Local heights on abelian varieties and rigid analytic unifomization, Doc. Math. 3 (1998), 301-319. - [SW] William Stein and Christian Wuthrich, Computations About Tate-Shafarevich Groups using Iwasawa theory, preprint 2009. EXAMPLES:: sage: eq = EllipticCurve('130a1').tate_curve(5) sage: eq.padic_regulator() 2*5^-1 + 1 + 2*5 + 2*5^2 + 3*5^3 + 3*5^6 + 5^7 + 3*5^9 + 3*5^10 + 3*5^12 + 4*5^13 + 3*5^15 + 2*5^16 + 3*5^18 + 4*5^19 + O(5^20) """ prec = prec + 4 K = Qp(self._p, prec=prec) rank = self._E.rank() if rank == 0: return K(1) if not self.is_split(): raise NotImplementedError("The p-adic regulator is not implemented for non-split multiplicative reduction.") basis = self._E.gens() M = matrix.matrix(K, rank, rank, 0) height = self.padic_height(prec= prec) point_height = [height(P) for P in basis] for i in range(rank): for j in range(i+1, rank): M[i, j] = M[j, i] = (- point_height[i] - point_height[j] + height(basis[i] + basis[j]))/2 for i in range(rank): M[i,i] = point_height[i] return M.determinant()
def padic_regulator(self, prec=20): r""" Compute the canonical `p`-adic regulator on the extended Mordell-Weil group as in [MTT]_ (with the correction of [Wer]_ and sign convention in [SW]_.) The `p`-adic Birch and Swinnerton-Dyer conjecture predicts that this value appears in the formula for the leading term of the `p`-adic L-function. INPUT: - ``prec`` -- the `p`-adic precision, default is 20. REFERENCES: [MTT]_ .. [Wer] Annette Werner, Local heights on abelian varieties and rigid analytic uniformization, Doc. Math. 3 (1998), 301-319. [SW]_ EXAMPLES:: sage: eq = EllipticCurve('130a1').tate_curve(5) sage: eq.padic_regulator() 2*5^-1 + 1 + 2*5 + 2*5^2 + 3*5^3 + 3*5^6 + 5^7 + 3*5^9 + 3*5^10 + 3*5^12 + 4*5^13 + 3*5^15 + 2*5^16 + 3*5^18 + 4*5^19 + O(5^20) """ prec = prec + 4 K = Qp(self._p, prec=prec) rank = self._E.rank() if rank == 0: return K.one() if not self.is_split(): raise NotImplementedError( "The p-adic regulator is not implemented for non-split multiplicative reduction." ) basis = self._E.gens() M = matrix.matrix(K, rank, rank, 0) height = self.padic_height(prec=prec) point_height = [height(P) for P in basis] for i in range(rank): for j in range(i + 1, rank): M[i, j] = M[j, i] = (-point_height[i] - point_height[j] + height(basis[i] + basis[j])) / 2 for i in range(rank): M[i, i] = point_height[i] return M.determinant()
def _get_O_basis(self): if not hasattr(self.B, 'invariants'): return [matrix(ZZ,2,2,v) for v in [[1,0,0,0],[0,1,0,0],[0,0,self.level,0],[0,0,0,1]]] elif self.B.invariants() == (1,1): i, j, k = self.B.gens() Pgen = self.level.gens_reduced()[0] tmpObasis_F = [(1 + i)/2, (j+k)/2, (Pgen/2)*(j-k), (1-i)/2] return [self.F.gen()**i * o for o in tmpObasis_F for i in range(self.F.degree())] else: O_magma = self._get_O_magma() return [magma_quaternion_to_sage(self.B,o,self.magma) for o in O_magma.ZBasis()]
def matrix_generating_function(m): r""" returns the generating function of each scalar as a matrix """ num_var = 10 dimx = m.nrows() dimy = m.ncols() d = dict() for x in range(dimx): for y in range(dimy): d[(x,y)]=m[x,y].get_generating_function() return matrix(PolynomialRing(ZZ,['x'+str(i) for i in range(num_var)]),d)
def generate_wp_candidates(self, p, ideal_p, **kwargs): eps = self.eps q = self.q for a,b in product(range(q),repeat = 2): if (p**2*a**2 - b**2*eps - p) % (q) == 0: verbose('Found a=%s, b=%s'%(a,b)) break c = (self.GFq(p)**-1 * b * eps).lift() d = a a,b,c,d = lift(matrix(ZZ,2,2,[p*a,b,c,d]),q).list() Fp = FiniteField(p) if c % p == 0: c += a*q d += b*q assert c % p != 0 r = (Fp(-a)*Fp(c*q)**-1).lift() a += q*c*r b += q*d*r ans = matrix(ZZ,2,2,[a,b,p*c,p*d]) ans.set_immutable() yield ans
def generate_wp_candidates(self, p, ideal_p, **kwargs): eps = self.eps q = self.q for a, b in product(range(q), repeat=2): if (p**2 * a**2 - b**2 * eps - p) % (q) == 0: verbose('Found a=%s, b=%s' % (a, b)) break c = (self.GFq(p)**-1 * b * eps).lift() d = a a, b, c, d = lift(matrix(ZZ, 2, 2, [p * a, b, c, d]), q).list() Fp = FiniteField(p) if c % p == 0: c += a * q d += b * q assert c % p != 0 r = (Fp(-a) * Fp(c * q)**-1).lift() a += q * c * r b += q * d * r ans = matrix(ZZ, 2, 2, [a, b, p * c, p * d]) ans.set_immutable() yield ans
def lift(A, N): r""" Lift a matrix A from SL_m(Z/NZ) to SL_m(Z). Follows Shimura, Lemma 1.38, p21. """ assert A.is_square() assert A.determinant() != 0 m = A.nrows() if m == 1: return identity_matrix(1) D, U, V = A.smith_form() if U.determinant() == -1: U = matrix(2, 2, [-1, 0, 0, 1]) * U if V.determinant() == -1: V = V * matrix(2, 2, [-1, 0, 0, 1]) D = U * A * V assert U.determinant() == 1 assert V.determinant() == 1 a = [D[i, i] for i in range(m)] b = prod(a[1:]) W = identity_matrix(m) W[0, 0] = b W[1, 0] = b - 1 W[0, 1] = 1 X = identity_matrix(m) X[0, 1] = -a[1] Ap = D.parent()(D) Ap[0, 0] = 1 Ap[1, 0] = 1 - a[0] Ap[1, 1] *= a[0] assert (W * U * A * V * X).change_ring(Zmod(N)) == Ap.change_ring(Zmod(N)) Cp = diagonal_matrix(a[1:]) Cp[0, 0] *= a[0] C = lift(Cp, N) Cpp = block_diagonal_matrix(identity_matrix(1), C) Cpp[1, 0] = 1 - a[0] return (~U * ~W * Cpp * ~X * ~V).change_ring(ZZ)
def lift(A, N): r""" Lift a matrix A from SL_m(Z/NZ) to SL_m(Z). Follows Shimura, Lemma 1.38, p21. """ assert A.is_square() assert A.determinant() != 0 m = A.nrows() if m == 1: return identity_matrix(1) D, U, V = A.smith_form() if U.determinant() == -1 : U = matrix(2,2,[-1,0,0,1])* U if V.determinant() == -1 : V = V *matrix(2,2,[-1,0,0,1]) D = U*A*V assert U.determinant() == 1 assert V.determinant() == 1 a = [ D[i, i] for i in range(m) ] b = prod(a[1:]) W = identity_matrix(m) W[0, 0] = b W[1, 0] = b-1 W[0, 1] = 1 X = identity_matrix(m) X[0, 1] = -a[1] Ap = D.parent()(D) Ap[0, 0] = 1 Ap[1, 0] = 1-a[0] Ap[1, 1] *= a[0] assert (W*U*A*V*X).change_ring(Zmod(N)) == Ap.change_ring(Zmod(N)) Cp = diagonal_matrix(a[1:]) Cp[0, 0] *= a[0] C = lift(Cp, N) Cpp = block_diagonal_matrix(identity_matrix(1), C) Cpp[1, 0] = 1-a[0] return (~U * ~W * Cpp * ~X * ~V).change_ring(ZZ)
def P(self, n, names='z+', base_ring=QQ): r""" Construct the ``n``-dimensional projective space `\mathbb{P}^n`. INPUT: - ``n`` -- positive integer. The dimension of the projective space. - ``names`` -- string. Names for the homogeneous coordinates. See :func:`~sage.schemes.toric.variety.normalize_names` for acceptable formats. - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. OUTPUT: A :class:`CPR-Fano toric variety <sage.schemes.toric.fano_variety.CPRFanoToricVariety_field>`. EXAMPLES:: sage: P3 = toric_varieties.P(3) sage: P3 3-d CPR-Fano toric variety covered by 4 affine patches sage: P3.fan().rays() N( 1, 0, 0), N( 0, 1, 0), N( 0, 0, 1), N(-1, -1, -1) in 3-d lattice N sage: P3.gens() (z0, z1, z2, z3) """ # We are going to eventually switch off consistency checks, so we need # to be sure that the input is acceptable. try: n = ZZ(n) # make sure that we got a "mathematical" integer except TypeError: raise TypeError("dimension of the projective space must be a " "positive integer!\nGot: %s" % n) if n <= 0: raise ValueError("only projective spaces of positive dimension " "can be constructed!\nGot: %s" % n) m = identity_matrix(n).augment(matrix(n, 1, [-1]*n)) charts = [list(range(i)) + list(range(i + 1, n + 1)) for i in range(n + 1)] return CPRFanoToricVariety( Delta_polar=LatticePolytope(m.columns(), lattice=ToricLattice(n)), charts=charts, check=self._check, coordinate_names=names, base_ring=base_ring)
def _split_hyperbolic(L): cur_cor = 2 Lcor = L + cur_cor * identity_matrix(L.nrows()) while not is_positive_definite(Lcor): cur_cor += 2 Lcor = L + cur_cor * identity_matrix(L.nrows()) a = FreeModule(ZZ, L.nrows()).gen(0) if a * L * a >= 0: Lcor_length_inc = max(3, a * L * a) cur_Lcor_length = Lcor_length_inc while True: short_vectors = flatten( QuadraticForm(Lcor).short_vector_list_up_to_length( a * Lcor * a)[cur_Lcor_length - Lcor_length_inc:cur_Lcor_length], max_level=1) for a in short_vectors: if a * L * a < 0: break else: continue break n = -a * L * a // 2 short_vectors = E8.short_vector_list_up_to_length(n + 1)[-1] for v in short_vectors: for w in short_vectors: if v * E8_gram * w == 2 * n - 1: LE8_mat = L.block_sum(E8_gram) v_form = vector(list(a) + list(v)) * LE8_mat w_form = vector(list(a) + list(w)) * LE8_mat Lred_basis = matrix( ZZ, [v_form, w_form ]).right_kernel().basis_matrix().transpose() Lred_basis = matrix(ZZ, Lred_basis) return Lred_basis.transpose() * LE8_mat * Lred_basis
def matrix_generating_function(m): r""" returns the generating function of each scalar as a matrix """ num_var = 10 dimx = m.nrows() dimy = m.ncols() d = dict() for x in range(dimx): for y in range(dimy): d[(x, y)] = m[x, y].get_generating_function() return matrix(PolynomialRing(ZZ, ['x' + str(i) for i in range(num_var)]), d)
def padic_regulator(self, prec=20): r""" Compute the canonical `p`-adic regulator on the extended Mordell-Weil group as in [MTT]_ (with the correction of [Wer]_ and sign convention in [SW]_.) The `p`-adic Birch and Swinnerton-Dyer conjecture predicts that this value appears in the formula for the leading term of the `p`-adic L-function. INPUT: - ``prec`` -- the `p`-adic precision, default is 20. REFERENCES: [MTT]_ .. [Wer] Annette Werner, Local heights on abelian varieties and rigid analytic uniformization, Doc. Math. 3 (1998), 301-319. [SW]_ EXAMPLES:: sage: eq = EllipticCurve('130a1').tate_curve(5) sage: eq.padic_regulator() 2*5^-1 + 1 + 2*5 + 2*5^2 + 3*5^3 + 3*5^6 + 5^7 + 3*5^9 + 3*5^10 + 3*5^12 + 4*5^13 + 3*5^15 + 2*5^16 + 3*5^18 + 4*5^19 + O(5^20) """ prec = prec + 4 K = Qp(self._p, prec=prec) rank = self._E.rank() if rank == 0: return K.one() if not self.is_split(): raise NotImplementedError("The p-adic regulator is not implemented for non-split multiplicative reduction.") basis = self._E.gens() M = matrix.matrix(K, rank, rank, 0) height = self.padic_height(prec=prec) point_height = [height(P) for P in basis] for i in range(rank): for j in range(i + 1, rank): M[i, j] = M[j, i] = (- point_height[i] - point_height[j] + height(basis[i] + basis[j])) / 2 for i in range(rank): M[i, i] = point_height[i] return M.determinant()
def matrix_remove_row_col(mat, row, col): r""" Return matrix with row, col removed """ L = list() newrows = range(mat.nrows()) newcols = range(mat.ncols()) newrows.pop(row) newcols.pop(col) for x in newrows: L.append(list()) for y in newcols: L[len(L) - 1].append(mat[x, y]) return matrix(mat.parent().base_ring(), len(newrows), len(newcols), L)
def matrix_remove_row_col(mat,row,col): r""" Return matrix with row, col removed """ L = list() newrows = range(mat.nrows()) newcols= range(mat.ncols()) newrows.pop(row) newcols.pop(col) for x in newrows: L.append(list()) for y in newcols: L[len(L)-1].append(mat[x,y]) return matrix(mat.parent().base_ring(),len(newrows),len(newcols),L)
def _compute_acting_matrix(self, g, M): r""" INPUT: - ``g`` -- an instance of :class:`sage.matrices.matrix_integer_2x2.Matrix_integer_2x2` or :class:`sage.matrix.matrix_generic_dense.Matrix_generic_dense` - ``M`` -- a positive integer giving the precision at which ``g`` should act. OUTPUT: - """ #tim = verbose("Starting") a, b, c, d = self._adjuster(g) # if g.parent().base_ring().is_exact(): # self._check_mat(a, b, c, d) #k = self._k base_ring = self.domain().base_ring() #cdef Matrix B = matrix(base_ring,M,M) B = matrix(base_ring, M, M) # if M == 0: return B.change_ring(self.codomain().base_ring()) R = PowerSeriesRing(base_ring, 'y', default_prec = M) y = R.gen() #tim = verbose("Checked, made R",tim) # special case for small precision, large weight scale = (b+d*y)/(a+c*y) #t = (a+c*y)**k # will already have precision M t = R.one() #cdef long row, col # #tim = verbose("Made matrix",tim) for col in range(M): for row in range(M): #B.set_unsafe(row, col, t[row]) B[row, col] = t[row] t *= scale #verbose("Finished loop",tim) # the change_ring here is annoying, but otherwise we have to change ring each time we multiply B = B.change_ring(self.codomain().base_ring()) #if self._character is not None: # B *= self._character(a) if self._dettwist is not None: B *= (a*d - b*c) ** (self._dettwist) return B
def add_unimodular_lattice(self, L=None): r""" Add a unimodular lattice (which is not necessarily positive definite) to the underlying lattice and the resulting discriminant group and an isomorphism to ``self``. INPUT: - `L` -- The Gram matrix of a unimodular lattice or ``None`` (default: ``None``). If ``None``, `E_8` will be added. OUTPUT: - A pair of a discriminant group and a homomorphism from self to this group. """ if L is None: L = matrix(8, [ 2, -1, 0, 0, 0, 0, 0, 0, -1, 2, -1, 0, 0, 0, 0, 0, 0, -1, 2, -1, 0, 0, 0, -1, 0, 0, -1, 2, -1, 0, 0, 0, 0, 0, 0, -1, 2, -1, 0, 0, 0, 0, 0, 0, -1, 2, -1, 0, 0, 0, 0, 0, 0, -1, 2, 0, 0, 0, -1, 0, 0, 0, 0, 2 ]) else: if L.base_ring() is not ZZ or all(e % 2 == 0 for e in L.diagonal()) \ or L.det() != 1 : raise ValueError( "L must be the Gram matrix of an even unimodular lattice") nL = self._L.block_sum(L) n_disc = DiscriminantForm(nL) basis_images = [ sum(map(operator.mul, b.lift(), self._dual_basis.columns())) for b in self.smith_form_gens() ] basis_images = [ n_disc._dual_basis.solve_right( vector(QQ, b.list() + L.nrows() * [0])).list() for b in basis_images ] coercion_hom = self.hom([ sum( map(operator.mul, map(ZZ, b), map(n_disc, FreeModule(ZZ, nL.nrows()).gens()))) for b in basis_images ]) return (n_disc, coercion_hom)
def matrix(self, p, i, j): r""" Return the matrix that determines the differential from the ``i,j``'th group of the ``p``'th page. INPUT: - ``p`` -- the page. - ``i`` -- the column of the differential domain. - ``j`` -- the row of the differential domain. EXAMPLES:: sage: from sage.interfaces.kenzo import Sphere # optional -- kenzo sage: S3 = Sphere(3) # optional -- kenzo sage: L = S3.loop_space() # optional -- kenzo sage: EMS = L.em_spectral_sequence() # optional -- kenzo sage: EMS.table(1, -5, -2, 5, 8) # optional -- kenzo 0 Z Z + Z + Z Z + Z + Z 0 0 0 0 0 0 Z Z + Z 0 0 0 0 sage: EMS.matrix(1, -2 ,8) # optional -- kenzo [ 3 3 0] [-2 0 2] [ 0 -3 -3] """ klist = spectral_sequence_differential_matrix(self._kenzo, p, i, j) plist = klist.python() if plist is None or plist == [None]: i = len(self.group(p, i, j).invariants()) j = len(self.group(p, i - p, j + p - 1).invariants()) return matrix(i, j) return matrix(plist)
def get_BT_reps(self): reps = [self.Gn.B(1)] + [None for i in xrange(self.p)] emb = self.get_embedding(20) matrices = [(i+1,matrix(QQ,2,2,[i,1,-1,0])) for i in xrange(self.p)] if self._matrix_group: verbose('Using hard-coded matrices for BT (Bianchi)') if F == QQ: wp = self.wp() return [self.Gn(1).quaternion_rep] + [1 / self.p * wp * matrix(QQ,2,2,[1,-i,0,self.p]) for i in xrange(self.p)] else: pi = self.ideal_p.gens_reduced()[0] B = self.Gn.B BTreps0 = [ Matrix(self.F,2,2,[0, -1, 1, -i]) for a in range(self.prime()) ] BTreps = [self.Gn(1).quaternion_rep] + [self.Gn(B([(o[0,0] + o[1,1])/2, (o[0,0] - o[1,1])/2, (-o[0,1] - o[1,0])/2, (-o[0,1] + o[1,0])/2])).quaternion_rep for o in BTreps0] return BTreps for n_iters,elt in enumerate(self.Gn.enumerate_elements()): new_inv = elt**(-1) embelt = emb(elt) if (embelt[0,0]-1).valuation() > 0 and all([not self.is_in_Gpn_order(o * new_inv) for o in reps if o is not None]): if hasattr(self.Gpn,'nebentypus'): tmp = self.do_tilde(embelt)**-1 tmp = tmp[0,0] / (self.p**tmp[0,0].valuation()) tmp = ZZ(tmp.lift()) % self.Gpn.level if tmp not in self.Gpn.nebentypus: continue for idx,o1 in enumerate(matrices): i,mat = o1 if is_in_Gamma0loc(embelt * mat, det_condition = False): reps[i] = set_immutable(elt) del matrices[idx] verbose('%s, len = %s/%s'%(n_iters,self.p+1-len(matrices),self.p+1)) if len(matrices) == 0: return reps break
def transition_matrix(self, basis, n): r""" Returns the transitions matrix between ``self`` and ``basis`` for the homogeneous component of degree ``n``. INPUT: - ``self`` -- a Hall-Littlewood symmetric function basis - ``basis`` -- another symmetric function basis - ``n`` -- a non-negative integer representing the degree OUTPUT: - Returns a `r \times r` matrix of elements of the base ring of ``self`` where `r` is the number of partitions of ``n``. The entry corresponding to row `\mu`, column `\nu` is the coefficient of ``basis`` `(\nu)` in ``self`` `(\mu)` EXAMPLES:: sage: Sym = SymmetricFunctions(FractionField(QQ['t'])) sage: HLP = Sym.hall_littlewood().P() sage: s = Sym.schur() sage: HLP.transition_matrix(s, 4) [ 1 -t 0 t^2 -t^3] [ 0 1 -t -t t^3 + t^2] [ 0 0 1 -t t^3] [ 0 0 0 1 -t^3 - t^2 - t] [ 0 0 0 0 1] sage: HLQ = Sym.hall_littlewood().Q() sage: HLQ.transition_matrix(s,3) [ -t + 1 t^2 - t -t^3 + t^2] [ 0 t^2 - 2*t + 1 -t^4 + t^3 + t^2 - t] [ 0 0 -t^6 + t^5 + t^4 - t^2 - t + 1] sage: HLQp = Sym.hall_littlewood().Qp() sage: HLQp.transition_matrix(s,3) [ 1 0 0] [ t 1 0] [ t^3 t^2 + t 1] """ P = sage.combinat.partition.Partitions_n(n) Plist = P.list() m = [] for row_part in Plist: z = basis(self(row_part)) m.append( [z.coefficient(col_part) for col_part in Plist] ) return matrix(m)
def degeneracy_matrix(self, p=None): """ Map from self to QuaterniocModule of level self/p. EXAMPLES:: sage: from sage.modular.hilbert.sqrt5_hmf import F, QuaternionicModule sage: H = QuaternionicModule(2*F.prime_above(31)); H Quaternionic module of dimension 4, level 10*a-4 (of norm 124=2^2*31) over QQ(sqrt(5)) sage: H.degeneracy_matrix(2) [1 0] [0 1] [0 1] [0 1] sage: H.degeneracy_matrix(F.prime_above(31)) [1] [1] [1] [1] sage: H.degeneracy_matrix() [1 0 1] [0 1 1] [0 1 1] [0 1 1] sage: H.degeneracy_matrix() is H.degeneracy_matrix() False sage: H.degeneracy_matrix(2) is H.degeneracy_matrix(2) True """ if self.level().is_prime(): return matrix(QQ, self.dimension(), 0, sparse=True) if self._degeneracy_matrices.has_key(p): return self._degeneracy_matrices[p] if p is None: A = None for p in prime_divisors(self._level): A = self.degeneracy_matrix(p) if A is None else A.augment(self.degeneracy_matrix(p)) A.set_immutable() self._degeneracy_matrices[None] = A return A p = sqrt5_ideal(p) if self._degeneracy_matrices.has_key(p): return self._degeneracy_matrices[p] d = self._icosians_mod_p1.degeneracy_matrix(p) d.set_immutable() self._degeneracy_matrices[p] = d return d
def transition_matrix(self, basis, n): r""" Returns the transitions matrix between ``self`` and ``basis`` for the homogenous component of degree ``n``. INPUT: - ``self`` -- a Hall-Littlewood symmetric function basis - ``basis`` -- another symmetric function basis - ``n`` -- a non-negative integer representing the degree OUTPUT: - Returns a `r \times r` matrix of elements of the base ring of ``self`` where `r` is the number of partitions of ``n``. The entry corresponding to row `\mu`, column `\nu` is the coefficient of ``basis`` `(\nu)` in ``self`` `(\mu)` EXAMPLES:: sage: Sym = SymmetricFunctions(FractionField(QQ['t'])) sage: HLP = Sym.hall_littlewood().P() sage: s = Sym.schur() sage: HLP.transition_matrix(s, 4) [ 1 -t 0 t^2 -t^3] [ 0 1 -t -t t^3 + t^2] [ 0 0 1 -t t^3] [ 0 0 0 1 -t^3 - t^2 - t] [ 0 0 0 0 1] sage: HLQ = Sym.hall_littlewood().Q() sage: HLQ.transition_matrix(s,3) [ -t + 1 t^2 - t -t^3 + t^2] [ 0 t^2 - 2*t + 1 -t^4 + t^3 + t^2 - t] [ 0 0 -t^6 + t^5 + t^4 - t^2 - t + 1] sage: HLQp = Sym.hall_littlewood().Qp() sage: HLQp.transition_matrix(s,3) [ 1 0 0] [ t 1 0] [ t^3 t^2 + t 1] """ P = sage.combinat.partition.Partitions_n(n) Plist = P.list() m = [] for row_part in Plist: z = basis(self(row_part)) m.append( map( lambda col_part: z.coefficient(col_part), Plist ) ) return matrix(m)
def _make_CPRFanoToricVariety(self, name, coordinate_names, base_ring): """ Construct a (crepant partially resolved) Fano toric variety and cache the result. INPUT: - ``name`` -- string. One of the pre-defined names in the ``toric_varieties_rays_cones`` data structure. - ``coordinate_names`` -- A string describing the names of the homogeneous coordinates of the toric variety. - ``base_ring`` -- a ring (default: `\QQ`). The base ring for the toric variety. OUTPUT: A :class:`CPR-Fano toric variety <sage.schemes.toric.fano_variety.CPRFanoToricVariety_field>`. EXAMPLES:: sage: toric_varieties.P2() # indirect doctest 2-d CPR-Fano toric variety covered by 3 affine patches """ rays, cones = toric_varieties_rays_cones[name] if coordinate_names is None: dict_key = (name, base_ring) else: coordinate_names = normalize_names(coordinate_names, len(rays), DEFAULT_PREFIX) dict_key = (name, base_ring) + tuple(coordinate_names) if dict_key not in self.__dict__: polytope = LatticePolytope( matrix(rays).transpose() ) points = map(tuple, polytope.points().columns()) ray2point = [points.index(r) for r in rays] charts = [ [ray2point[i] for i in c] for c in cones ] self.__dict__[dict_key] = \ CPRFanoToricVariety(Delta_polar=polytope, coordinate_points=ray2point, charts=charts, coordinate_names=coordinate_names, base_ring=base_ring, check=self._check) return self.__dict__[dict_key]
def _dft_seminormal(self): """ Returns the seminormal form of the discrete Fourier for self. EXAMPLES:: sage: QS3 = SymmetricGroupAlgebra(QQ, 3) sage: QS3._dft_seminormal() [ 1 1 1 1 1 1] [ 1 1/2 -1 -1/2 -1/2 1/2] [ 0 3/4 0 3/4 -3/4 -3/4] [ 0 1 0 -1 1 -1] [ 1 -1/2 1 -1/2 -1/2 -1/2] [ 1 -1 -1 1 1 -1] """ snb = self.seminormal_basis() return matrix( [vector(b) for b in snb] ).inverse().transpose()
def matrix_identity_multiply_scalar(scal,nrows,ncols): r""" Currently this method only returns for the same number of rows and columns. """ if nrows!=ncols: raise ValueError, "check dimensions" else: L = list() for i in range(nrows): L.append(list()) for j in range(ncols): if i == j: L[i].append(scal) else: L[i].append(CombinatorialScalarWrapper(set())) return matrix(CombinatorialScalarRing(),nrows,ncols,L)