Ticket #8614: trac-8614-optimize-modular-symbol-relations-rebase.patch
| File trac-8614-optimize-modular-symbol-relations-rebase.patch, 8.7 KB (added by mraum, 2 years ago) |
|---|
-
module_list.py
# HG changeset patch # User Martin Raum <Martin.Raum@matha.rwth-aachen.de> # Date 1300754596 -3600 # Node ID 14d5de3ffc211021f81b0a4416b2a3a426718a0c # Parent cefe7ffc4322f0dc727cf001d09a6e7dd6659d83 #Trac 8614: Optimize creation of modular symbols spaces by speeding up quotienting out by 2-term relations diff -r cefe7ffc4322 -r 14d5de3ffc21 module_list.py
a b 1028 1028 extra_compile_args=["-std=c99", "-D_XPG6"], 1029 1029 depends = flint_depends), 1030 1030 1031 Extension('sage.modular.modsym.relation_matrix_pyx', 1032 sources = ['sage/modular/modsym/relation_matrix_pyx.pyx']), 1033 1031 1034 Extension('sage.modular.modsym.heilbronn', 1032 1035 sources = ['sage/modular/modsym/heilbronn.pyx'], 1033 1036 libraries = ["csage", "flint", "gmp", "gmpxx", "m", "stdc++"], -
sage/modular/modsym/manin_symbols.py
diff -r cefe7ffc4322 -r 14d5de3ffc21 sage/modular/modsym/manin_symbols.py
a b 182 182 183 183 """ 184 184 raise NotImplementedError, "Only implemented in derived classes" 185 186 def _apply_S_only_0pm1(self): 187 """ 188 Return True if the coefficient when applying the S relation is 189 always 0, 1, or -1. This is useful for optimizing code in 190 relation_matrix.py. 191 192 EXAMPLES:: 193 194 sage: eps = DirichletGroup(4).gen(0) 195 sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character 196 sage: ManinSymbolList_character(eps,2)._apply_S_only_0pm1() 197 True 198 sage: eps = DirichletGroup(7).gen(0) 199 sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character 200 sage: ManinSymbolList_character(eps,2)._apply_S_only_0pm1() 201 False 202 """ 203 return False # derived classes could overload and put True 185 204 186 205 def apply_S(self, j): 187 206 """ … … 501 520 else: 502 521 return k, -1 503 522 523 def _apply_S_only_0pm1(self): 524 """ 525 Return True if the coefficient when applying the S relation is 526 always 0, 1, or -1. This is useful for optimizing code in 527 relation_matrix.py. 528 529 EXAMPLES:: 530 531 sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0 532 sage: ManinSymbolList_gamma0(5,8)._apply_S_only_0pm1() 533 True 534 """ 535 return True 536 504 537 def apply_I(self, j): 505 538 """ 506 539 Apply the matrix `I=[-1,0,0,1]` to the `j`-th Manin symbol. … … 1047 1080 else: 1048 1081 return k, -s 1049 1082 1083 def _apply_S_only_0pm1(self): 1084 """ 1085 Return True if the coefficient when applying the S relation is 1086 always 0, 1, or -1. This is useful for optimizing code in 1087 relation_matrix.py. 1088 1089 EXAMPLES:: 1090 1091 sage: eps = DirichletGroup(4).gen(0) 1092 sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character 1093 sage: ManinSymbolList_character(eps,2)._apply_S_only_0pm1() 1094 True 1095 sage: ManinSymbolList_character(DirichletGroup(13).0,2)._apply_S_only_0pm1() 1096 False 1097 """ 1098 return self.__character.order() <= 2 1099 1050 1100 def apply_I(self, j): 1051 1101 """ 1052 1102 Apply the matrix `I=[-1,0,0,1]` to the `j`-th Manin symbol. -
sage/modular/modsym/p1list.pyx
diff -r cefe7ffc4322 -r 14d5de3ffc21 sage/modular/modsym/p1list.pyx
a b 678 678 sage: L 679 679 The projective line over the integers modulo 120 680 680 """ 681 cdef int i 682 681 683 self.__N = N 682 684 if N <= 46340: 683 685 self.__list = p1list_int(N) … … 700 702 if not self.t: raise MemoryError 701 703 702 704 # Initialize xgcd table 703 cdef int i704 705 cdef llong ll_s, ll_t, ll_N = N 705 706 706 707 if N <= 46340: -
sage/modular/modsym/relation_matrix.py
diff -r cefe7ffc4322 -r 14d5de3ffc21 sage/modular/modsym/relation_matrix.py
a b 459 459 if sign != 0: 460 460 # Let rels = rels union I relations. 461 461 rels.update(modI_relations(syms,sign)) 462 mod = sparse_2term_quotient(rels, len(syms), field) 462 463 if syms._apply_S_only_0pm1() and rings.is_RationalField(field): 464 import relation_matrix_pyx 465 mod = relation_matrix_pyx.sparse_2term_quotient_only_pm1(rels, len(syms)) 466 else: 467 mod = sparse_2term_quotient(rels, len(syms), field) 468 463 469 R = T_relation_matrix_wtk_g0(syms, mod, field, sparse) 464 470 return R, mod 465 471 -
new file sage/modular/modsym/relation_matrix_pyx.pyx
diff -r cefe7ffc4322 -r 14d5de3ffc21 sage/modular/modsym/relation_matrix_pyx.pyx
- + 1 """ 2 Optimized Cython code for computing relation matrices in certain cases. 3 """ 4 5 ############################################################################# 6 # Copyright (C) 2010 William Stein <wstein@gmail.com> 7 # Distributed under the terms of the GNU General Public License (GPL) v2+. 8 # The full text of the GPL is available at: 9 # http://www.gnu.org/licenses/ 10 ############################################################################# 11 12 import sage.misc.misc as misc 13 from sage.rings.rational cimport Rational 14 15 def sparse_2term_quotient_only_pm1(rels, n): 16 r""" 17 Performs Sparse Gauss elimination on a matrix all of whose columns 18 have at most 2 nonzero entries with relations all 1 or -1. 19 20 This algorithm is more subtle than just "identify symbols in pairs", 21 since complicated relations can cause generators to equal 0. 22 23 NOTE: Note the condition on the s,t coefficients in the relations 24 being 1 or -1 for this optimized function. There is a more 25 general function in relation_matrix.py, which is much, much 26 slower. 27 28 INPUT: 29 30 - ``rels`` - set of pairs ((i,s), (j,t)). The pair represents 31 the relation s*x_i + t*x_j = 0, where the i, j must be 32 Python int's, and the s,t must all be 1 or -1. 33 34 - ``n`` - int, the x_i are x_0, ..., x_n-1. 35 36 OUTPUT: 37 38 - ``mod`` - list such that mod[i] = (j,s), which means 39 that x_i is equivalent to s*x_j, where the x_j are a basis for 40 the quotient. 41 42 EXAMPLES:: 43 44 sage: v = [((0,1), (1,-1)), ((1,1), (3,1)), ((2,1),(3,1)), ((4,1),(5,-1))] 45 sage: rels = set(v) 46 sage: n = 6 47 sage: from sage.modular.modsym.relation_matrix_pyx import sparse_2term_quotient_only_pm1 48 sage: sparse_2term_quotient_only_pm1(rels, n) 49 [(3, -1), (3, -1), (3, -1), (3, 1), (5, 1), (5, 1)] 50 """ 51 if not isinstance(rels, set): 52 raise TypeError, "rels must be a set" 53 54 n = int(n) 55 56 tm = misc.verbose("Starting optimized integer sparse 2-term quotient...") 57 58 cdef int c0, c1, i, die 59 free = range(n) 60 coef = [1]*n 61 related_to_me = [[] for i in range(n)] 62 63 for v0, v1 in rels: 64 c0 = coef[v0[0]] * v0[1] 65 c1 = coef[v1[0]] * v1[1] 66 67 # Mod out by the following relation: 68 # 69 # c0*free[v0[0]] + c1*free[v1[0]] = 0. 70 # 71 die = -1 72 if c0 == 0 and c1 == 0: 73 pass 74 elif c0 == 0 and c1 != 0: # free[v1[0]] --> 0 75 die = free[v1[0]] 76 elif c1 == 0 and c0 != 0: 77 die = free[v0[0]] 78 elif free[v0[0]] == free[v1[0]]: 79 if c0 + c1 != 0: 80 # all xi equal to free[v0[0]] must now equal to zero. 81 die = free[v0[0]] 82 else: # x1 = -c1/c0 * x2. 83 x = free[v0[0]] 84 free[x] = free[v1[0]] 85 if c0 != 1 and c0 != -1: 86 raise ValueError, "coefficients must all be -1 or 1." 87 coef[x] = -c1/c0 88 for i in related_to_me[x]: 89 free[i] = free[x] 90 coef[i] *= coef[x] 91 related_to_me[free[v1[0]]].append(i) 92 related_to_me[free[v1[0]]].append(x) 93 if die != -1: 94 for i in related_to_me[die]: 95 free[i] = 0 96 coef[i] = 0 97 free[die] = 0 98 coef[die] = 0 99 100 # Special casing the rationals leads to a huge speedup, 101 # actually. (All the code above is slower than just this line 102 # without this special case.) 103 mod = [(free[i], Rational(coef[i])) for i in range(len(free))] 104 105 misc.verbose("finished",tm) 106 return mod 107
