Ticket #11316: trac_11316.3.patch
File trac_11316.3.patch, 76.2 KB (added by , 10 years ago) |
---|
-
sage/crypto/mq/sr.py
# HG changeset patch # User Kwankyu Lee <ekwankyu@gmail.com> # Date 1305014300 -32400 # Node ID c14df15c273dd4d2707c69a24c5ee3fa5ff1d008 # Parent ce324e28c3334398d3552640e2cb1520d22465a3 #11316: added weighted degree term orders diff -r ce324e28c333 -r c14df15c273d sage/crypto/mq/sr.py
a b 1665 1665 1666 1666 sage: sr = mq.SR(2, 1, 1, 4) 1667 1667 sage: sr.block_order() 1668 degrevlex(16),degrevlex(16),degrevlex(4) term order 1668 Block term order with blocks: 1669 (Degree reverse lexicographic term order of length 16, 1670 Degree reverse lexicographic term order of length 16, 1671 Degree reverse lexicographic term order of length 4) 1669 1672 1670 1673 :: 1671 1674 -
sage/libs/singular/ring.pyx
diff -r ce324e28c333 -r c14df15c273d sage/libs/singular/ring.pyx
a b 22 22 from sage.libs.singular.decl cimport number, lnumber, napoly, ring, currRing 23 23 from sage.libs.singular.decl cimport rChangeCurrRing, rCopy0, rComplete, rDelete 24 24 from sage.libs.singular.decl cimport omAlloc0, omStrDup, omAlloc, omAlloc0Bin, sip_sring_bin, rnumber_bin 25 from sage.libs.singular.decl cimport ringorder_dp, ringorder_Dp, ringorder_lp, ringorder_rp, ringorder_ds, ringorder_Ds, ringorder_ls, ringorder_M, ringorder_C 25 from sage.libs.singular.decl cimport ringorder_dp, ringorder_Dp, ringorder_lp, ringorder_rp, ringorder_ds, ringorder_Ds, ringorder_ls, ringorder_M, ringorder_C, ringorder_wp, ringorder_Wp, ringorder_ws, ringorder_Ws 26 26 from sage.libs.singular.decl cimport p_Copy 27 27 28 28 from sage.rings.integer cimport Integer … … 41 41 42 42 43 43 # mapping str --> SINGULAR representation 44 order_dict = {"dp":ringorder_dp, 45 "Dp":ringorder_Dp, 46 "lp":ringorder_lp, 47 "rp":ringorder_rp, 48 "ds":ringorder_ds, 49 "Ds":ringorder_Ds, 50 "ls":ringorder_ls, 51 } 44 order_dict = { 45 "dp": ringorder_dp, 46 "Dp": ringorder_Dp, 47 "lp": ringorder_lp, 48 "rp": ringorder_rp, 49 "ds": ringorder_ds, 50 "Ds": ringorder_Ds, 51 "ls": ringorder_ls, 52 "wp": ringorder_wp, 53 "Wp": ringorder_Wp, 54 "ws": ringorder_ws, 55 "Ws": ringorder_Ws, 56 } 52 57 53 58 cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: 54 59 """ … … 236 241 237 242 _ring.minpoly=<number*>nmp 238 243 239 nblcks = len(order.blocks )244 nblcks = len(order.blocks()) 240 245 offset = 0 241 246 242 247 _ring.wvhdl = <int **>omAlloc0((nblcks + 2) * sizeof(int *)) … … 250 255 _ring.OrdSgn = 1 251 256 252 257 for i from 0 <= i < nblcks: 253 if order[i].singular_str()[0] == 'M': 258 s = order[i].singular_str() 259 if s[0] == 'M': # matrix order 254 260 _ring.order[i] = ringorder_M 255 261 mtx = order[i].matrix().list() 256 m= <int *>omAlloc0(len(mtx)*sizeof(int))262 wv = <int *>omAlloc0(len(mtx)*sizeof(int)) 257 263 for j in range(len(mtx)): 258 m[j] = int(mtx[j]) 259 _ring.wvhdl[i] = m 260 else: 261 _ring.order[i] = order_dict.get(order[i].singular_str(), ringorder_dp) 264 wv[j] = int(mtx[j]) 265 _ring.wvhdl[i] = wv 266 elif s[0] == 'w' or s[0] == 'W': # weighted degree orders 267 _ring.order[i] = order_dict.get(s[:2], ringorder_dp) 268 wts = order[i].weights() 269 wv = <int *>omAlloc0(len(wts)*sizeof(int)) 270 for j in range(len(wts)): 271 wv[j] = int(wts[j]) 272 _ring.wvhdl[i] = wv 273 else: # ordinary orders 274 _ring.order[i] = order_dict.get(s, ringorder_dp) 262 275 _ring.block0[i] = offset + 1 263 276 if len(order[i]) == 0: # may be zero in some cases 264 277 _ring.block1[i] = offset + n -
sage/rings/polynomial/multi_polynomial_ring.py
diff -r ce324e28c333 -r c14df15c273d sage/rings/polynomial/multi_polynomial_ring.py
a b 468 468 c = self.base_ring()(x) 469 469 return MPolynomial_polydict(self, {self._zero_tuple:c}) 470 470 471 472 473 471 class MPolynomialRing_polydict_domain(integral_domain.IntegralDomain, 474 472 MPolynomialRing_polydict, 475 473 MPolynomialRing_macaulay2_repr): 476 474 def __init__(self, base_ring, n, names, order): 477 order = TermOrder(order, n)475 order = TermOrder(order,n) 478 476 MPolynomialRing_polydict.__init__(self, base_ring, n, names, order) 479 477 480 478 def is_integral_domain(self, proof = True): … … 513 511 gens = [self(x) for x in gens] # this will even coerce from singular ideals correctly! 514 512 return multi_polynomial_ideal.MPolynomialIdeal(self, gens, **kwds) 515 513 516 517 514 def monomial_quotient(self,f, g, coeff=False): 518 515 """ 519 516 Return f/g, where both f and g are treated as monomials. … … 716 713 return 0,0 717 714 return 0,0 718 715 719 720 716 def monomial_divides(self, a, b): 721 717 """ 722 718 Return False if a does not divide b and True otherwise. -
sage/rings/polynomial/multi_polynomial_ring_generic.pyx
diff -r ce324e28c333 -r c14df15c273d sage/rings/polynomial/multi_polynomial_ring_generic.pyx
a b 48 48 sage: A1(a) in A2 49 49 True 50 50 """ 51 order = TermOrder(order,n) 51 order = TermOrder(order,n) 52 52 53 if not base_ring.is_commutative(): 53 54 raise TypeError, "Base ring must be a commutative ring." 54 55 n = int(n) … … 252 253 _repr += " Size : %d Variables\n"%(n,) 253 254 offset = 0 254 255 i = 0 255 for order in T.blocks :256 for order in T.blocks(): 256 257 _repr += " Block % 2d : Ordering : %s\n"%(i,inv_singular_name_mapping.get(order.singular_str(), order.singular_str())) 257 258 _repr += " Names : %s\n"%(", ".join(names[offset:offset + len(order)])) 258 259 offset += len(order) -
sage/rings/polynomial/pbori.pyx
diff -r ce324e28c333 -r c14df15c273d sage/rings/polynomial/pbori.pyx
a b 263 263 264 264 sage: R = BooleanPolynomialRing(5,'x',order='deglex(3),deglex(2)') 265 265 sage: R.term_order() 266 deglex(3),deglex(2) term order 266 Block term order with blocks: 267 (Degree lexicographic term order of length 3, 268 Degree lexicographic term order of length 2) 267 269 268 270 :: 269 271 … … 326 328 except KeyError: 327 329 raise ValueError, "Only lex, deglex, degrevlex orders are supported." 328 330 329 if len(order.blocks) > 1:331 if order.is_block_order(): 330 332 if pb_order_code is pblp: 331 333 raise ValueError, "Only deglex and degrevlex are supported for block orders." 332 334 elif pb_order_code is pbdlex: 333 335 pb_order_code = pbblock_dlex 334 336 elif pb_order_code is pbdp_asc: 335 337 pb_order_code = pbblock_dp_asc 336 for i in range(1, len(order.blocks )):337 if order[0] != order[i]:338 raise ValueError, "Each block must have the same order type (deglex or degrevlex) for block order ings."338 for i in range(1, len(order.blocks())): 339 if order[0].name() != order[i].name(): 340 raise ValueError, "Each block must have the same order type (deglex or degrevlex) for block orders." 339 341 340 342 if (pb_order_code is pbdlex) or (pb_order_code is pblp) or \ 341 343 (pb_order_code is pbblock_dlex): … … 347 349 else: 348 350 # pb_order_code is block_dp_asc: 349 351 bstart = 0 350 for i from 0 <= i < len(order.blocks ):352 for i from 0 <= i < len(order.blocks()): 351 353 bsize = len(order[i]) 352 354 for j from 0 <= j < bsize: 353 355 self.pbind[bstart + j] = bstart + bsize - j -1 … … 357 359 MPolynomialRing_generic.__init__(self, GF(2), n, names, order) 358 360 359 361 counter = 0 360 for i in range(len(order.blocks )-1):362 for i in range(len(order.blocks())-1): 361 363 counter += len(order[i]) 362 364 pb_append_block(counter) 363 365 … … 7056 7058 sage: change_ordering(block_dp_asc) 7057 7059 sage: append_ring_block(5) 7058 7060 sage: get_cring().term_order() 7059 deglex_asc(5),deglex_asc(5) term order 7061 Block term order with blocks: 7062 (deglex_asc term order of length 5, 7063 deglex_asc term order of length 5) 7060 7064 sage: change_ordering(lp) 7061 7065 7062 7066 sage: from polybori.blocks import * … … 7129 7133 else: 7130 7134 # pb_order_code is block_dp_asc: 7131 7135 bstart = 0 7132 for i from 0 <= i < len(T.blocks ):7136 for i from 0 <= i < len(T.blocks()): 7133 7137 bsize = len(T[i]) 7134 7138 for j from 0 <= j < bsize: 7135 7139 self.pbind[bstart + j] = bstart + j -
sage/rings/polynomial/polynomial_ring.py
diff -r ce324e28c333 -r c14df15c273d sage/rings/polynomial/polynomial_ring.py
a b 688 688 except AttributeError: 689 689 return self.base_ring() 690 690 691 692 691 def characteristic(self): 693 692 """ 694 693 Return the characteristic of this polynomial ring, which is the -
sage/rings/polynomial/polynomial_ring_constructor.py
diff -r ce324e28c333 -r c14df15c273d sage/rings/polynomial/polynomial_ring_constructor.py
a b 494 494 495 495 sage: R = BooleanPolynomialRing(5,'x',order='deglex(3),deglex(2)') 496 496 sage: R.term_order() 497 deglex(3),deglex(2) term order 497 Block term order with blocks: 498 (Degree lexicographic term order of length 3, 499 Degree lexicographic term order of length 2) 498 500 499 501 sage: R = BooleanPolynomialRing(3,'x',order='degrevlex') 500 502 sage: R.term_order() … … 531 533 532 534 from sage.rings.polynomial.term_order import TermOrder 533 535 from sage.rings.polynomial.pbori import set_cring 536 534 537 order = TermOrder(order, n) 535 538 536 539 key = ("pbori", names, n, order) -
sage/rings/polynomial/term_order.py
diff -r ce324e28c333 -r c14df15c273d sage/rings/polynomial/term_order.py
a b 1 1 r""" 2 Term Orderings2 Term orders 3 3 4 Sage supports the following term order ings:4 Sage supports the following term orders: 5 5 6 Lexicographic (*lex*) 7 `x^a < x^b \Leftrightarrow \exists\; 0 \le i < n : a_0 = b_0, \ldots, a_{i-1} = b_{i-1}, a_i < b_i` 6 Lexicographic (lex) 7 `x^a < x^b` if and only if there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i < b_i`. 8 This term order is called 'lp' in Singular. 8 9 9 10 EXAMPLES: 10 11 … … 22 23 sage: x^3*y^2*z^4 < x^3*y^2*z^1 23 24 False 24 25 25 This term ordering is called 'lp' in Singular. 26 27 Degree reverse lexicographic (*degrevlex*) 28 Let `deg(x^a) = a_0 + \cdots + a_{n-1},` then 29 `x^a < x^b \Leftrightarrow deg(x^a) < deg(x^b)` or 30 `deg(x^a) = deg(x^b)` and 31 `\exists\ 0 \le i < n: a_{n-1} = b_{n-1}, \ldots, a_{i+1} = b_{i+1}, a_i > b_i.` 26 Degree reverse lexicographic (degrevlex) 27 Let `\deg(x^a) = a_1 + a_2 + \dots + a_n`, then 28 `x^a < x^b` if and only if `\deg(x^a) < \deg(x^b)` or `\deg(x^a) = \deg(x^b)` and 29 there exists `1 \le i \le n` such that `a_n = b_n, \dots, a_{i+1} = b_{i+1}, a_i > b_i`. 30 This term order is called 'dp' in Singular. 32 31 33 32 EXAMPLES: 34 33 … … 46 45 sage: x^2*y*z^2 > x*y^3*z 47 46 False 48 47 49 This term ordering is called 'dp' in Singular. 50 51 Degree lexicographic (*deglex*) 52 Let `deg(x^a) = a_0 + \cdots + a_{n-1},` then 53 `x^a < x^b \Leftrightarrow deg(x^a) < deg(x^b)` or 54 `deg(x^a) = deg(x^b)` and 55 `\exists\ 0 \le i < n:a_0 = b_0, \ldots, a_{i-1} = b_{i-1}, a_i < b_i.` 48 Degree lexicographic (deglex) 49 Let `\deg(x^a) = a_1 + a_2 + \dots + a_n`, then 50 `x^a < x^b` if and only if `\deg(x^a) < \deg(x^b)` or `\deg(x^a) = \deg(x^b)` and 51 there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i < b_i`. 52 This term order is called 'Dp' in Singular. 56 53 57 54 EXAMPLES: 58 55 … … 70 67 sage: x^2*y*z^2 > x*y^3*z 71 68 True 72 69 73 This term order is called 'Dp' in Singular. 74 75 Inverse lexicographic (*invlex*) 76 `x^a < x^b \Leftrightarrow \exists\; 0 \le i < n : a_{n-1} = b_{n-1}, \ldots, a_{i+1} = b_{i+1}, a_i < b_i.` 70 Inverse lexicographic (invlex) 71 `x^a < x^b` if and only if there exists `1 \le i \le n` such that `a_n = b_n, \dots, a_{i+1} = b_{i+1}, a_i < b_i`. 72 This order is called 'rp' in Singular. 77 73 78 74 EXAMPLES: 79 75 … … 89 85 sage: x*y > z 90 86 False 91 87 92 This term order ingonly makes sense in a non-commutative setting88 This term order only makes sense in a non-commutative setting 93 89 because if P is the ring `k[x_1, \dots, x_n]` and term 94 order ing'invlex' then it is equivalent to the ring95 `k[x_n, \dots, x_1]` with term order ing'lex'.90 order 'invlex' then it is equivalent to the ring 91 `k[x_n, \dots, x_1]` with term order 'lex'. 96 92 97 This ordering is called 'rp' in Singular. 98 99 Negative lexicographic (*neglex*) 100 `x^a < x^b \Leftrightarrow \exists\; 0 \le i < n : a_0 = b_0, \ldots, a_{i-1} = b_{i-1}, a_i > b_i` 93 Negative lexicographic (neglex) 94 `x^a < x^b` if and only if there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i > b_i`. 95 This term order is called 'ls' in Singular. 101 96 102 97 EXAMPLES: 103 98 … … 115 110 sage: x*y > z 116 111 False 117 112 118 This term ordering is called 'ls' in Singular. 119 120 Negative degree reverse lexicographic (*negdegrevlex*) 121 Let `deg(x^a) = a_0 + \cdots + a_{n-1},` then 122 `x^a < x^b \Leftrightarrow deg(x^a) > deg(x^b)` or 123 `deg(x^a) = deg(x^b)` and 124 `\exists\ 0 \le i < n: a_{n-1} = b_{n-1}, \ldots, a_{i+1} = b_{i+1}, a_i > b_i.` 113 Negative degree reverse lexicographic (negdegrevlex) 114 Let `\deg(x^a) = a_1 + a_2 + \dots + a_n`, then 115 `x^a < x^b` if and only if `\deg(x^a) > \deg(x^b)` or `\deg(x^a) = \deg(x^b)` and 116 there exists `1 \le i \le n` such that `a_n = b_n, \dots, a_{i+1} = b_{i+1}, a_i > b_i`. 117 This term order is called 'ds' in Singular. 125 118 126 119 EXAMPLES: 127 120 … … 139 132 sage: x^2*y*z^2 > x*y^3*z 140 133 False 141 134 142 This term ordering is called 'ds' in Singular. 143 144 Negative degree lexicographic (*negdeglex*) 145 Let `deg(x^a) = a_0 + \cdots + a_{n-1},` then 146 `x^a < x^b \Leftrightarrow deg(x^a) > deg(x^b)` or 147 `deg(x^a) = deg(x^b)` and 148 `\exists\ 0 \le i < n: a_0 = b_0, \ldots, a_{i-1} = b_{i-1}, a_i < b_i.` 135 Negative degree lexicographic (negdeglex) 136 Let `\deg(x^a) = a_1 + a_2 + \dots + a_n`, then 137 `x^a < x^b` if and only if `\deg(x^a) > \deg(x^b)` or `\deg(x^a) = \deg(x^b)` and 138 there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i < b_i`. 139 This term order is called 'Ds' in Singular. 149 140 150 141 EXAMPLES: 151 142 … … 163 154 sage: x^2*y*z^2 > x*y^3*z 164 155 True 165 156 166 This term ordering is called 'Ds' in Singular. 157 Weighted degree reverse lexicographic (wdegrevlex) 158 Let `\deg_w(x^a) = a_1w_1 + a_2w_2 + \dots + a_nw_n` with weights `w`, then 159 `x^a < x^b` if and only if `\deg_w(x^a) < \deg_w(x^b)` or `\deg_w(x^a) = \deg_w(x^b)` and 160 there exists `1 \le i \le n` such that `a_n = b_n, \dots, a_{i+1} = b_{i+1}, a_i > b_i`. 161 This term order is called 'wp' in Singular. 167 162 163 EXAMPLES: 168 164 169 Of these, only 'degrevlex', 'deglex', 'invlex' and 'lex' are global 170 orderings. 165 :: 171 166 172 Additionally all these monomial orderings may be combined to 173 product or block orderings, defined as: 167 sage: P.<x,y,z> = PolynomialRing(QQ, 3, order=TermOrder('wdegrevlex',(1,2,3))) 168 sage: x > y 169 False 170 sage: x > x^2 171 False 172 sage: x > 1 173 True 174 sage: x^1*y^2 > x^2*z 175 True 176 sage: y*z > x^3*y 177 False 174 178 175 Let `x = (x_0, \ldots, x_{n-1})` and 176 `y = (y_0, \ldots, y_{m-1})` be two ordered sets of 177 variables, `<_1` a monomial ordering on `k[x]` and 178 `<_2` a monomial ordering on `k[y]`. 179 Weighted degree lexicographic (wdeglex) 180 Let `\deg_w(x^a) = a_1w_1 + a_2w_2 + \dots + a_nw_n` with weights `w`, then 181 `x^a < x^b` if and only if `\deg_w(x^a) < \deg_w(x^b)` or `\deg_w(x^a) = \deg_w(x^b)` and 182 there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i < b_i`. 183 This term order is called 'Wp' in Singular. 179 184 180 The product ordering (or block ordering) 181 `<\ := (<_1,<_2)` on `k[x,y]` is defined as: 182 `x^a y^b < x^A y^B \Leftrightarrow x^a <_1 x^A` or 183 `(x^a =x^A \textrm{ and } y^b <_2 y^B)`. 185 EXAMPLES: 184 186 185 These block orderings are constructed in Sage by giving a comma 186 separated list of monomial orderings with the length of each block 187 attached to them. 187 :: 188 189 sage: P.<x,y,z> = PolynomialRing(QQ, 3, order=TermOrder('wdeglex',(1,2,3))) 190 sage: x > y 191 False 192 sage: x > x^2 193 False 194 sage: x > 1 195 True 196 sage: x^1*y^2 > x^2*z 197 False 198 sage: y*z > x^3*y 199 False 200 201 Negative weighted degree reverse lexicographic (negwdegrevlex) 202 Let `\deg_w(x^a) = a_1w_1 + a_2w_2 + \dots + a_nw_n` with weights `w`, then 203 `x^a < x^b` if and only if `\deg_w(x^a) > \deg_w(x^b)` or `\deg_w(x^a) = \deg_w(x^b)` and 204 there exists `1 \le i \le n` such that `a_n = b_n, \dots, a_{i+1} = b_{i+1}, a_i > b_i`. 205 This term order is called 'ws' in Singular. 206 207 EXAMPLES: 208 209 :: 210 211 sage: P.<x,y,z> = PolynomialRing(QQ, 3, order=TermOrder('negwdegrevlex',(1,2,3))) 212 sage: x > y 213 True 214 sage: x > x^2 215 True 216 sage: x > 1 217 False 218 sage: x^1*y^2 > x^2*z 219 True 220 sage: y*z > x^3*y 221 False 222 223 Negative weighted degree lexicographic (negwdeglex) 224 Let `\deg_w(x^a) = a_1w_1 + a_2w_2 + \dots + a_nw_n` with weights `w`, then 225 `x^a < x^b` if and only if `\deg_w(x^a) > \deg_w(x^b)` or `\deg_w(x^a) = \deg_w(x^b)` and 226 there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i < b_i`. 227 This term order is called 'Ws' in Singular. 228 229 EXAMPLES: 230 231 :: 232 233 sage: P.<x,y,z> = PolynomialRing(QQ, 3, order=TermOrder('negwdeglex',(1,2,3))) 234 sage: x > y 235 True 236 sage: x > x^2 237 True 238 sage: x > 1 239 False 240 sage: x^1*y^2 > x^2*z 241 False 242 sage: y*z > x^3*y 243 False 244 245 Of these, only 'degrevlex', 'deglex', 'wdegrevlex', 'wdeglex', 'invlex' and 'lex' are global 246 orders. 247 248 Sage also supports matrix term order. Given a square matrix `A`, 249 250 `x^a <_A x^b` if and only if `Aa < Ab` 251 252 where `<` is the lexicographic term order. 253 254 EXAMPLE:: 255 256 sage: m = matrix(2,[2,3,0,1]); m 257 [2 3] 258 [0 1] 259 sage: T = TermOrder(m); T 260 Matrix term order with matrix 261 [2 3] 262 [0 1] 263 sage: P.<a,b> = PolynomialRing(QQ,2,order=T) 264 sage: P 265 Multivariate Polynomial Ring in a, b over Rational Field 266 sage: a > b 267 False 268 sage: a^3 < b^2 269 True 270 sage: S = TermOrder('M(2,3,0,1)') 271 sage: T == S 272 True 273 274 Additionally all these monomial orders may be combined to product or block orders, defined as: 275 276 Let `x = (x_1, x_2, \dots, x_n)` and `y = (y_1, y_2, \dots, y_m)` be two ordered sets of 277 variables, `<_1` a monomial order on `k[x]` and `<_2` a monomial order on `k[y]`. 278 279 The product order (or block order) `<` `:=` `(<_1,<_2)` on `k[x,y]` is defined as: 280 `x^a y^b < x^A y^B` if and only if `x^a <_1 x^A` or (`x^a =x^A` and `y^b <_2 y^B`). 281 282 These block orders are constructed in Sage by giving a comma separated list of monomial orders 283 with the length of each block attached to them. 188 284 189 285 EXAMPLE: 190 286 191 As an example, consider constructing a block order ingwhere the287 As an example, consider constructing a block order where the 192 288 first four variables are compared using the degree reverse 193 lexicographical order ingwhile the last two variables in the second194 block are compared using negative lexicographical order ing.289 lexicographical order while the last two variables in the second 290 block are compared using negative lexicographical order. 195 291 196 292 :: 197 293 … … 214 310 sage: a > e^4 215 311 True 216 312 217 Finally Sage supports matrix term order. Given a square matrix `A`, 313 If any other unsupported term order is given the provided string 314 can be forced to be passed through as is to Singular, Macaulay2, and Magma. 315 This ensures that it is for example possible to calculate a Groebner 316 basis with respect to some term order Singular supports but Sage 317 doesn't:: 218 318 219 `x^a < x^b \Leftrightarrow x^{Aa} <_{\mathrm{lex}} x^{Ab}` 220 221 where `<_{\mathrm{lex}}` is the lexicographic term order. 222 223 EXAMPLE:: 224 225 sage: m = matrix(2,[2,3,0,1]); m 226 [2 3] 227 [0 1] 228 sage: T = TermOrder(m); T 229 Matrix term order with matrix 230 [2 3] 231 [0 1] 232 sage: P.<a,b> = PolynomialRing(QQ,2,order=T) 233 sage: P 234 Multivariate Polynomial Ring in a, b over Rational Field 235 sage: a > b 236 False 237 sage: a^3 < b^2 238 True 239 sage: S = TermOrder('M(2,3,0,1)') 240 sage: T == S 241 True 242 243 A matrix term ordering is not allowed in block ordering yet:: 244 245 sage: T+S 319 sage: T = TermOrder("royalorder") 246 320 Traceback (most recent call last): 247 321 ... 248 NotImplementedError: Cannot use a matrix term order as a block. 249 250 If any other unsupported term ordering is given the provided string 251 is passed through as is to Singular, Macaulay2, and Magma. This 252 ensures that it is for example possible to calculate a Groebner 253 basis with respect to some term ordering Singular supports but Sage 254 doesn't. However a warning is issued to make the user aware of the 255 situation and potential typos:: 256 257 sage: T = TermOrder("royalorder") 258 verbose 0 (...: term_order.py, __init__) Term ordering 'royalorder' unknown. 259 322 TypeError: Unknown term order 'royalorder' 323 sage: T = TermOrder("royalorder",force=True) 324 sage: T 325 royalorder term order 326 sage: T.singular_str() 327 'royalorder' 328 260 329 AUTHORS: 261 330 262 - David Joyner and William Stein: initial version 263 multi_polynomial_ring 331 - David Joyner and William Stein: initial version of multi_polynomial_ring 264 332 265 333 - Kiran S. Kedlaya: added macaulay2 interface 266 334 267 - Martin Albrecht: implemented native term order ings, refactoring335 - Martin Albrecht: implemented native term orders, refactoring 268 336 269 - Kwankyu Lee (2010-06): implemented matrix term ordering337 - Kwankyu Lee: implemented matrix and weighted degree term orders, refactoring 270 338 """ 271 339 272 import re 273 from sage.structure.sage_object import SageObject 340 import re 341 from sage.structure.sage_object import SageObject 274 342 275 343 print_name_mapping = { 276 'lex' :'Lexicographic', 277 'invlex' :'Inverse Lexicographic', 278 'degrevlex' :'Degree reverse lexicographic', 279 'deglex' :'Degree lexicographic', 280 'neglex' :'Negative lexicographic', 281 'negdegrevlex' :'Negative degree reverse lexicographic', 282 'negdeglex' :'Negative degree lexicographic'} 344 'lex' : 'Lexicographic', 345 'invlex' : 'Inverse lexicographic', 346 'degrevlex' : 'Degree reverse lexicographic', 347 'deglex' : 'Degree lexicographic', 348 'neglex' : 'Negative lexicographic', 349 'negdegrevlex' : 'Negative degree reverse lexicographic', 350 'negdeglex' : 'Negative degree lexicographic', 351 'wdegrevlex' : 'Weighted degree reverse lexicographic', 352 'wdeglex' : 'Weighted degree lexicographic', 353 'negwdegrevlex' : 'Negative weighted degree reverse lexicographic', 354 'negwdeglex' : 'Negative weighted degree lexicographic', 355 } 283 356 284 357 singular_name_mapping = { 285 'lex' :'lp', 286 'invlex' :'rp', 287 'degrevlex' :'dp', 288 'deglex' :'Dp', 289 'neglex' :'ls', 290 'negdegrevlex' :'ds', 291 'negdeglex' :'Ds'} 358 'lex' : 'lp', 359 'invlex' : 'rp', 360 'degrevlex' : 'dp', 361 'deglex' : 'Dp', 362 'neglex' : 'ls', 363 'negdegrevlex' : 'ds', 364 'negdeglex' : 'Ds', 365 'wdegrevlex' : 'wp', 366 'wdeglex' : 'Wp', 367 'negwdegrevlex' : 'ws', 368 'negwdeglex' : 'Ws', 369 } 292 370 293 inv_singular_name_mapping = { 294 'lp' :'lex', 295 'rp' :'invlex', 296 'dp' :'degrevlex', 297 'Dp' :'deglex', 298 'ls' :'neglex', 299 'ds' :'negdegrevlex', 300 'Ds' :'negdeglex'} 371 inv_singular_name_mapping = dict(zip(singular_name_mapping.values(),singular_name_mapping.keys())) 301 372 302 373 macaulay2_name_mapping = { 303 'lex' :'Lex', 304 'revlex' :'RevLex, Global=>false', 305 'degrevlex' :'GRevLex', 306 'deglex' :'GLex'} 374 'lex' : 'Lex', 375 'revlex' : 'RevLex, Global=>false', 376 'degrevlex' : 'GRevLex', 377 'deglex' : 'GLex', 378 } 307 379 308 inv_macaulay2_name_mapping = { 309 'Lex' :'lex', 310 'RevLex,Global=>false' :'revlex', 311 'GRevLex' :"degrevlex", 312 'GLex' :'deglex'} 380 inv_macaulay2_name_mapping = dict(zip(macaulay2_name_mapping.values(),macaulay2_name_mapping.keys())) 313 381 314 magma_name_mapping = { 315 'lex' :'"lex"', 316 'degrevlex' :'"grevlex"', 317 'deglex' :'"glex"'} 382 magma_name_mapping = { 383 'lex' : '"lex"', 384 'degrevlex' : '"grevlex"', 385 'deglex' : '"glex"', 386 } 318 387 319 lp_description = """ 320 Lexicographic (lex) term ordering. 388 inv_magma_name_mapping = dict(zip(magma_name_mapping.values(),magma_name_mapping.keys())) 321 389 322 $x^a < x^b <=> \exists\; 0 <= i < n : a_0 = b_0, ..., a_{i-1} = b_{i-1}, a_i < b_i$ 390 lex_description = """ 391 Lexicographic (lex) term order. 392 393 `x^a < x^b` if and only if there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i < b_i`. 323 394 """ 324 395 325 dp_description = """326 Degree reverse lexicographic (degrevlex) term ordering.396 invlex_description = """ 397 Inverse lexicographic (invlex) term order. 327 398 328 Let $deg(x^a) = a_0 + ... + a_{n-1},$ then $x^a < x^b <=> deg(x^a) < deg(x^b)$ or 329 $deg(x^a) = deg(x^b)$ and $\exists\ 0 <= i < n: a_{n-1} = b_{n-1}, ..., a_{i+1} = b_{i+1}, a_i > b_i.$ 399 `x^a < x^b` if and only if there exists `1 \le i \le n` such that `a_n = b_n, \dots, a_{i+1} = b_{i+1}, a_i < b_i`. 400 """ 401 402 degrevlex_description = """ 403 Degree reverse lexicographic (degrevlex) term order. 404 405 Let `\deg(x^a) = a_1 + a_2 + \dots + a_n`, then 406 `x^a < x^b` if and only if `\deg(x^a) < \deg(x^b)` or `\deg(x^a) = \deg(x^b)` and 407 there exists `1 \le i \le n` such that `a_n = b_n, \dots, a_{i+1} = b_{i+1}, a_i > b_i`. 330 408 """ 331 409 332 Dp_description = """333 Degree lexicographic (deglex) term order ing.410 deglex_description = """ 411 Degree lexicographic (deglex) term order. 334 412 335 Let $deg(x^a) = a_0 + \cdots + a_{n-1},$ then $x^a < x^b \Leftrightarrow deg(x^a) < deg(x^b)$ or 336 $deg(x^a) = deg(x^b)$ and $\exists\ 0 \le i < n:a_0 = b_0, \ldots, a_{i-1} = b_{i-1}, a_i < b_i.$ 413 Let `\deg(x^a) = a_1 + a_2 + \dots + a_n`, then 414 `x^a < x^b` if and only if `\deg(x^a) < \deg(x^b)` or `\deg(x^a) = \deg(x^b)` and 415 there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i < b_i`. 337 416 """ 338 417 339 rp_description = """340 Inverse lexicographic (invlex) term ordering.418 neglex_description = """ 419 Negative lexicographic (neglex) term order. 341 420 342 $x^a < x^b \Leftrightarrow \exists\; 0 \le i < n : a_{n-1} = b_{n-1}, \ldots, a_{i+1} = b_{i+1}, a_i < b_i.$ 421 `x^a < x^b` if and only if there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i > b_i`. 343 422 """ 344 423 345 ls_description = """346 Negative lexicographic (neglex) term ordering.424 negdegrevlex_description = """ 425 Negative degree reverse lexicographic (negdegrevlex) term order. 347 426 348 $x^a < x^b \Leftrightarrow \exists\; 0 \le i < n : a_0 = b_0, \ldots, a_{i-1} = b_{i-1}, a_i > b_i$ 427 Let `\deg(x^a) = a_1 + a_2 + \dots + a_n`, then 428 `x^a < x^b` if and only if `\deg(x^a) > \deg(x^b)` or `\deg(x^a) = \deg(x^b)` and 429 there exists `1 \le i \le n` such that `a_n = b_n, \dots, a_{i+1} = b_{i+1}, a_i > b_i`. 430 """ 431 432 negdeglex_description = """ 433 Negative degree lexicographic (negdeglex) term order. 434 435 Let `\deg(x^a) = a_1 + a_2 + \dots + a_n`, then 436 `x^a < x^b` if and only if `\deg(x^a) > \deg(x^b)` or `\deg(x^a) = \deg(x^b)` and 437 there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i < b_i`. 438 """ 439 440 wdegrevlex_description = """ 441 Weighted degree reverse lexicographic (wdegrevlex) term order. 442 443 Let `\deg_w(x^a) = a_1w_1 + a_2w_2 + \dots + a_nw_n` with weights `w`, then 444 `x^a < x^b` if and only if `\deg_w(x^a) < \deg_w(x^b)` or `\deg_w(x^a) = \deg_w(x^b)` and 445 there exists `1 \le i \le n` such that `a_n = b_n, \dots, a_{i+1} = b_{i+1}, a_i > b_i`. 349 446 """ 447 448 wdeglex_description = r""" 449 Weighted degree lexicographic (wdeglex) term order. 350 450 351 ds_description = """ 352 Negative degree reverse lexicographic (negdegrevlex) term ordering. 451 Let `\deg_w(x^a) = a_1w_1 + a_2w_2 + \dots + a_nw_n` with weights `w`, then 452 `x^a < x^b` if and only if `\deg_w(x^a) < \deg_w(x^b)` or `\deg_w(x^a) = \deg_w(x^b)` and 453 there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i < b_i`. 454 """ 353 455 354 Let $deg(x^a) = a_0 + \cdots + a_{n-1},$ then $x^a < x^b \Leftrightarrow deg(x^a) > deg(x^b)$ or 355 $deg(x^a) = deg(x^b)$ and $\exists\ 0 \le i < n: a_{n-1} = b_{n-1}, \ldots, a_{i+1} = b_{i+1}, a_i > b_i.$ 456 negwdegrevlex_description = """ 457 Negative weighted degree reverse lexicographic (negwdegrevlex) term order. 458 459 Let `\deg_w(x^a) = a_1w_1 + a_2w_2 + \dots + a_nw_n` with weights `w`, then 460 `x^a < x^b` if and only if `\deg_w(x^a) > \deg_w(x^b)` or `\deg_w(x^a) = \deg_w(x^b)` and 461 there exists `1 \le i \le n` such that `a_n = b_n, \dots, a_{i+1} = b_{i+1}, a_i > b_i`. 356 462 """ 463 464 negwdeglex_description = """ 465 Negative weighted degree lexicographic (negwdeglex) term order. 357 466 358 Ds_description = """ 359 Negative degree lexicographic (negdeglex) term ordering. 467 Let `\deg_w(x^a) = a_1w_1 + a_2w_2 + \dots + a_nw_n` with weights `w`, then 468 `x^a < x^b` if and only if `\deg_w(x^a) > \deg_w(x^b)` or `\deg_w(x^a) = \deg_w(x^b)` and 469 there exists `1 \le i \le n` such that `a_1 = b_1, \dots, a_{i-1} = b_{i-1}, a_i < b_i`. 470 """ 360 471 361 Let $deg(x^a) = a_0 + \cdots + a_{n-1},$ then $x^a < x^b \Leftrightarrow deg(x^a) > deg(x^b)$ or 362 $deg(x^a) = deg(x^b)$ and $\exists\ 0 \le i < n: a_0 = b_0, \ldots, a_{i-1} = b_{i-1}, a_i < b_i.$ 363 """ 472 matrix_description = """ 473 Matrix term order defined by a matrix A. 474 475 `x^a < x^b` if and only if `x^{Aa} < x^{Ab}` where `<` is the lexicographic term order. 476 """ 477 478 block_description = """ 479 Block term order defined by term orders `<_1, <_2, \dots, <_n`. 480 481 `x^a < x^b` if and only if `a = b` with respect to the first `n-1` term orders and `a <_n b` 482 with respect to the `n`th term order `<_n`. 483 """ 364 484 365 485 description_mapping = { 366 "lp":lp_description, 367 "dp":dp_description, 368 "Dp":Dp_description, 369 "rp":rp_description, 370 "ls":ls_description, 371 "Ds":Ds_description, 372 "ds":ds_description} 486 'lex' : lex_description, 487 'invlex' : invlex_description, 488 'degrevlex' : degrevlex_description, 489 'deglex' : deglex_description, 490 'neglex' : neglex_description, 491 'negdegrevlex' : negdegrevlex_description, 492 'negdeglex' : negdeglex_description, 493 'wdeglex' : wdeglex_description, 494 'wdegrevlex' : wdegrevlex_description, 495 'negwdegrevlex' : negwdegrevlex_description, 496 'negwdeglex' : negwdeglex_description, 497 'matrix' : matrix_description, 498 'block' : block_description, 373 499 374 M_description = """ 375 Matrix term ordering defined by a matrix A. 376 377 $x^a < x^b \Leftrightarrow x^{Aa} <_{\mathrm{lex}} x^{Ab}$ 378 where $<_{\mathrm{lex}}$ is the lexicographic term ordering 379 """ 500 } 380 501 381 502 class TermOrder(SageObject): 382 503 r""" 383 504 A term order. 384 505 385 506 See ``sage.rings.polynomial.term_order`` for details 386 on supported term order ings.507 on supported term orders. 387 508 """ 388 def __ init__(self, name='lex', n = 0, blocks=True, force=False):509 def __setstate__(self, dict): 389 510 """ 390 Construct a new term ordering object. 511 Translate pickled TermOrder objects with old data structure. 512 513 EXAMPLE:: 514 515 sage: t = TermOrder('lex') 516 sage: t2 = loads(dumps(t)) 517 sage: t2._weights is None 518 True 519 """ 520 if not dict.has_key('_weights'): 521 name = dict['_TermOrder__name'] 522 n = dict['_TermOrder__length'] 523 t = TermOrder(name,n) 524 self.__dict__.update(t.__dict__) 525 else: 526 self.__dict__.update(dict) 527 528 def __init__(self, name='lex', n=0, blocks=True, force=False): 529 """ 530 Construct a new term order object. 391 531 392 532 INPUT: 393 533 394 - ``name`` - name of the term order ing(default: lex)534 - ``name`` - name of the term order (default: lex) 395 535 396 - ``n`` - number of variables in the polynomial ring 397 (default: 0) 536 - ``n`` - number of variables (default is `0`) or weights for 537 weighted degree orders 538 539 - ``blocks`` - this is deprecated. 398 540 399 - ``blocks`` - controls whether a list of blocks is 400 maintained (internal use only, default:True) 401 402 - ``force`` - ignore unknown term orderings. 541 - ``force`` - ignore unknown term orders. 403 542 404 543 See the ``sage.rings.polynomial.term_order`` module 405 for help which names and order ings are available.544 for help which names and orders are available. 406 545 407 546 EXAMPLES:: 408 547 … … 412 551 sage: loads(dumps(t)) == t 413 552 True 414 553 415 We can construct block order ings directly as554 We can construct block orders directly as 416 555 417 556 :: 418 557 419 558 sage: TermOrder('degrevlex(3),neglex(2)') 420 degrevlex(3),neglex(2) term order 559 Block term order with blocks: 560 (Degree reverse lexicographic term order of length 3, 561 Negative lexicographic term order of length 2) 421 562 422 563 or by adding together the blocks:: 423 564 424 565 sage: t1 = TermOrder('degrevlex',3) 425 566 sage: t2 = TermOrder('neglex',2) 426 567 sage: t1 + t2 427 degrevlex(3),neglex(2) term order 428 sage: t2 + t1 429 neglex(2),degrevlex(3) term order 568 Block term order with blocks: 569 (Degree reverse lexicographic term order of length 3, 570 Negative lexicographic term order of length 2) 571 sage: t3 = TermOrder('wdeglex',(1,2)) 572 sage: t1 + t3 573 Block term order with blocks: 574 (Degree reverse lexicographic term order of length 3, 575 Weighted degree lexicographic term order with weights (1, 2)) 430 576 431 577 .. note:: 432 578 433 579 The optional `n` parameter is not necessary if only 434 non-block order ings like `deglex` are435 constructed. However, it is useful if block order ings are580 non-block orders like `deglex` are 581 constructed. However, it is useful if block orders are 436 582 to be constructed from this ``TermOrder`` object later. 437 """ 583 """ 438 584 if isinstance(name, TermOrder): 439 if n == 0 and len(name) > 0: 440 n = len(name) 585 self.__copy(name) 586 if n > 0 and not name.is_block_order() and not name.is_weighted_degree_order(): 587 self._length = n 588 return 589 590 if isinstance(name, str): 591 name = name.lower() 592 else: 441 593 try: 442 force = name.__force 443 except AttributeError: # pickled old TermOrders don't have this field 444 force = False 445 name = name.name() 446 else: 447 try: # name is a matrix 448 name = 'M('+','.join(["%i"%(i,) for i in name.list()])+')' 594 if not isinstance(name, (tuple,list)): 595 name = name.list() # name may be a matrix 596 name = tuple(name) 449 597 except: 450 pass 451 name = name.lower() 598 raise TypeError, "%s is not a valid term order"%(name,) 452 599 453 split_pattern = "([^(),]+(?:\([^()]*\)[^(),]*)*)" # split by outermost commas 454 length_pattern = re.compile("\(([0-9]+)\)$") # match with parenthesized block length at end 455 matrix_pattern = "([0-9,]+)" # match with list of integers 456 457 self.__force = force 458 self.__length = 0 459 self.__name = "" 460 self.__singular_str = "" 461 self.__macaulay2_str = "" 462 self.__magma_str = "" 463 self.__matrix = None # only for matrix ordering 464 465 block_names = re.findall(split_pattern,name) 600 self._blocks = tuple() 601 self._weights = None 602 self._matrix = None 466 603 467 if len(block_names) == 0: 468 raise TypeError, "No term ordering specified" 469 elif len(block_names) == 1: 470 name = block_names[0] 471 if re.match('m\(([0-9,]+)\)$',name) != None: # matrix ordering 472 integers_str = re.search(matrix_pattern,name).group() 473 integers = map(int,integers_str.split(',')) 474 475 if n == 0: 476 from math import sqrt 477 n = int(sqrt(len(integers))) 478 479 if len(integers) != n**2: 480 raise TypeError, "%s does not specify a square matrix"%(name,) 481 482 self.__matrix = [] 483 for idx in range(0,len(integers),n): 484 self.__matrix.append(integers[idx:idx+n]) 485 486 self.__length = n 487 self.__name = "M(%s)"%(integers_str,) 488 self.__singular_str = "M(%s)"%(integers_str,) 489 self.__macaulay2_str = "" # Macaulay2 does not support matrix term order directly 490 self.__magma_str = '"weight",[%s]'%(integers_str,) 491 self.__doc__ = M_description 492 493 else: # simple ordering 494 self.__length = n 495 self.__name = name 496 self.__singular_str = singular_name_mapping.get(name,name) 497 self.__macaulay2_str = macaulay2_name_mapping.get(name,name) 498 self.__magma_str = magma_name_mapping.get(name,name) 499 500 if self.__singular_str in description_mapping: 501 self.__doc__ = description_mapping[self.__singular_str] 502 503 from sage.misc.misc import verbose 504 if blocks: 505 # we allow deglex_asc here which is used by PolyBoRi 506 if self.__matrix == None and \ 507 name not in singular_name_mapping.keys() and \ 508 name not in singular_name_mapping.values() and not force: 509 verbose("Term ordering '%s' unknown."%name,level=0) 510 self.blocks = (TermOrder(self.__name,n,blocks=False,force=force),) 511 else: 512 self.blocks = tuple() 513 514 else: # block ordering 604 if name == "block": # block term order with blocks in a list 515 605 length = 0 516 606 blocks = [] 517 607 name_str = [] 518 608 singular_str = [] 519 609 macaulay2_str = [] 520 610 521 for block in block_names: 522 try: 523 block_name, block_length, _ = re.split(length_pattern,block) 524 except ValueError: 525 raise TypeError, "%s is not a valid term ordering"%(name,) 611 for t in n: 612 if not isinstance(t, TermOrder): 613 try: 614 t = TermOrder(t,force=True) 615 except: 616 raise TypeError 617 if t.name() == 'block': 618 blocks = blocks + list(t.blocks()) 619 singular_str.append("%s"%(t.singular_str()[1:-1],)) # [1:-1] is needed to remove parenthesis 620 macaulay2_str.append("%s"%(t.macaulay2_str()[1:-1],)) 621 else: 622 if len(t) == 0: 623 raise ArithmeticError, "Can only concatenate term orders with length attribute." 624 blocks.append(t) 625 if t.is_weighted_degree_order(): # true if t is a matrix order as well 626 singular_str.append("%s"%(t.singular_str(),)) 627 else: 628 singular_str.append("%s(%d)"%(t.singular_str(), len(t))) 629 macaulay2_str.append("%s => %d"%(t.macaulay2_str(), len(t))) 630 length += len(t) 526 631 527 block_length = int(block_length) 632 self._length = length 633 self._name = "block" 634 self._singular_str = "(" + ",".join(singular_str) + ")" 635 self._macaulay2_str = "{" + ",".join(macaulay2_str) + "}" 636 self._magma_str = "" # Magma does not support block order 637 self._blocks = tuple(blocks) 638 elif isinstance(name, str) and not (isinstance(n, tuple) or isinstance(n,list)): # string representation of simple or block orders 639 split_pattern = "([^(),]+(?:\([^()]*\)[^(),]*)*)" # split by outermost commas 640 block_names = re.findall(split_pattern,name) 528 641 529 blocks.append( TermOrder(block_name,block_length,force=force) ) 530 name_str.append("%s(%d)"%(block_name,block_length)) 531 singular_str.append("%s(%d)"%(singular_name_mapping.get(block_name, block_name), block_length)) 532 macaulay2_str.append("%s => %d"%(macaulay2_name_mapping.get(block_name, block_name), block_length)) 642 if len(block_names) == 0: 643 raise TypeError, "No term order specified" 644 elif len(block_names) == 1: 645 name = block_names[0] 646 match = re.match('m\(([-+0-9,]+)\)$',name) 647 if match: # matrix term order 648 m = map(int,match.groups()[0].split(',')) # replace match.groups()[0] with match.group(1) later 649 self.__copy(TermOrder(m)) 650 else: # simple order 651 if name not in print_name_mapping.keys() and name not in singular_name_mapping.values() and not force: 652 raise TypeError, "Unknown term order '%s'"%(name,) 653 self._length = n 654 self._name = name 655 self._singular_str = singular_name_mapping.get(name,name) 656 self._macaulay2_str = macaulay2_name_mapping.get(name,name) 657 self._magma_str = magma_name_mapping.get(name,name) 658 else: # len(block_names) > 1, and hence block order represented by a string 659 length = 0 660 blocks = [] 661 name_str = [] 662 singular_str = [] 663 macaulay2_str = [] 533 664 534 length += block_length 665 for block in block_names: 666 try: 667 length_pattern = re.compile("\(([0-9]+)\)$") # match with parenthesized block length at end 668 block_name, block_length, _ = re.split(length_pattern,block) 669 block_length = int(block_length) 670 blocks.append( TermOrder(block_name,block_length,force=force) ) 671 except: 672 raise TypeError, "%s is not a valid term order"%(name,) 673 length += block_length 535 674 536 self.blocks = tuple(blocks) 537 self.__length = length 538 self.__name = ",".join(name_str) 539 self.__singular_str = "(" + ",".join(singular_str) + ")" 540 self.__macaulay2_str = "(" + ",".join(macaulay2_str) + ")" 541 self.__magma_str = "" # Magma does not support block order 675 if n != 0 and length != n: 676 raise TypeError, "Term order length does not match the number of generators" 677 self.__copy(TermOrder('block', blocks)) 678 elif isinstance(name, str) and (isinstance(n, tuple) or isinstance(n,list)): # weighted degree term orders 679 if name not in print_name_mapping.keys() and name not in singular_name_mapping.values() and not force: 680 raise TypeError, "Unknown term order '%s'"%(name,) 681 weights = tuple(n) # n is a tuple of weights 682 683 self._length = len(weights) 684 self._name = name 685 self._singular_str = singular_name_mapping.get(name,name) + '(' + ','.join([str(w) for w in weights]) + ')' 686 self._macaulay2_str = "" 687 self._magma_str = "" 688 self._weights = weights # defined only for weighted degree orders 689 elif isinstance(name, tuple): # name represents a matrix 690 if n == 0: 691 from math import sqrt 692 n = int(sqrt(len(name))) 693 if n**2 != len(name): 694 raise TypeError, "%s does not specify a square matrix"%(name,) 542 695 543 if n != 0 and self.__length != n: 544 raise TypeError, "Term order length does not match the number of generators" 696 int_str = ','.join([str(int(e)) for e in name]) 697 698 self._length = n 699 self._name = "matrix" 700 self._singular_str = "M(%s)"%(int_str,) 701 self._macaulay2_str = "" # Macaulay2 does not support matrix term order directly 702 self._magma_str = '"weight",[%s]'%(int_str,) 703 704 from sage.matrix.constructor import matrix 705 self._matrix = matrix(n,name) # defined only for matrix term order 706 self._weights = name[:n] # the first row of the matrix gives weights 707 else: 708 raise TypeError, "%s is not a valid term order"%(name,) 709 710 self.__doc__ = description_mapping.get(self._name, "No description available") 711 712 def __copy(self, other): 713 """ 714 Copy other term order to self. 715 716 EXAMPLE:: 717 718 sage: t = TermOrder('lex') 719 sage: s = TermOrder(t) 720 sage: t == s # indirect test 721 True 722 """ 723 self.__dict__ = other.__dict__.copy() 545 724 546 725 def __getattr__(self,name): 547 726 """ … … 550 729 EXAMPLE:: 551 730 552 731 sage: TermOrder('lex').compare_tuples 553 <bound method TermOrder.compare_tuples_l pof Lexicographic term order>732 <bound method TermOrder.compare_tuples_lex of Lexicographic term order> 554 733 555 734 :: 556 735 557 736 sage: TermOrder('deglex').compare_tuples 558 <bound method TermOrder.compare_tuples_ Dpof Degree lexicographic term order>737 <bound method TermOrder.compare_tuples_deglex of Degree lexicographic term order> 559 738 """ 560 739 if name == 'compare_tuples': 561 if len(self.blocks) <= 1: 562 if self.__matrix != None: 563 return self.compare_tuples_matrix 564 else: 565 return getattr(self,'compare_tuples_'+self.__singular_str) 566 else: 567 return self.compare_tuples_block 740 return getattr(self,'compare_tuples_'+self._name) 568 741 elif name == 'greater_tuple': 569 if len(self.blocks) <= 1: 570 if self.__matrix != None: 571 return self.greater_tuple_matrix 572 else: 573 return getattr(self,'greater_tuple_'+self.__singular_str) 574 else: 575 return self.greater_tuple_block 742 return getattr(self,'greater_tuple_'+self._name) 576 743 else: 577 744 raise AttributeError,name 578 745 … … 595 762 sage: y > x^3 596 763 False 597 764 """ 598 for row in self._ _matrix:599 mf = sum(l*r for (l,r) in zip(row,f))600 mg = sum(l*r for (l,r) in zip(row,g))765 for row in self._matrix: 766 sf = sum(l*r for (l,r) in zip(row,f)) 767 sg = sum(l*r for (l,r) in zip(row,g)) 601 768 602 if mf > mg:769 if sf > sg: 603 770 return 1 604 elif mf < mg:771 elif sf < sg: 605 772 return -1 606 773 return 0 607 774 608 def compare_tuples_l p(self,f,g):775 def compare_tuples_lex(self,f,g): 609 776 """ 610 777 Compares two exponent tuples with respect to the lexicographical 611 778 term order. … … 624 791 sage: x > 1 625 792 True 626 793 """ 627 628 if f>g: 794 if f > g: 629 795 return 1 630 elif f <g:796 elif f < g: 631 797 return -1 632 798 else: 633 799 return 0 634 800 635 def compare_tuples_ rp(self,f,g):801 def compare_tuples_invlex(self,f,g): 636 802 """ 637 803 Compares two exponent tuples with respect to the inversed 638 804 lexicographical term order. … … 651 817 sage: x > 1 652 818 True 653 819 """ 654 return self.compare_tuples_l p(f.reversed(),g.reversed())820 return self.compare_tuples_lex(f.reversed(),g.reversed()) 655 821 656 def compare_tuples_ Dp(self,f,g):822 def compare_tuples_deglex(self,f,g): 657 823 """ 658 824 Compares two exponent tuples with respect to the degree 659 825 lexicographical term order. … … 676 842 sg = sum(g.nonzero_values(sort=False)) 677 843 if sf > sg: 678 844 return 1 679 elif sf <sg:845 elif sf < sg: 680 846 return -1 681 847 elif sf == sg: 682 return self.compare_tuples_l p(f,g)848 return self.compare_tuples_lex(f,g) 683 849 684 def compare_tuples_d p(self,f,g):850 def compare_tuples_degrevlex(self,f,g): 685 851 """ 686 852 Compares two exponent tuples with respect to the degree reversed 687 853 lexicographical term order. … … 704 870 sg = sum(g.nonzero_values(sort=False)) 705 871 if sf > sg: 706 872 return 1 707 elif sf <sg:873 elif sf < sg: 708 874 return -1 709 875 elif sf == sg: 710 return (-1)*self.compare_tuples_lp(f.reversed(),g.reversed())876 return -self.compare_tuples_lex(f.reversed(),g.reversed()) 711 877 712 def compare_tuples_ ls(self,f,g):878 def compare_tuples_neglex(self,f,g): 713 879 """ 714 880 Compares two exponent tuples with respect to the negative 715 881 lexicographical term order. … … 728 894 sage: x > 1 729 895 False 730 896 """ 731 return -self.compare_tuples_l p(f,g)897 return -self.compare_tuples_lex(f,g) 732 898 733 def compare_tuples_ ds(self,f,g):899 def compare_tuples_negdegrevlex(self,f,g): 734 900 """ 735 901 Compares two exponent tuples with respect to the negative degree 736 902 reverse lexicographical term order. … … 753 919 sg = sum(g.nonzero_values(sort=False)) 754 920 if sf > sg: 755 921 return -1 756 elif sf <sg:922 elif sf < sg: 757 923 return 1 758 924 elif sf == sg: 759 return (-1)*self.compare_tuples_l p(f.reversed(),g.reversed())925 return (-1)*self.compare_tuples_lex(f.reversed(),g.reversed()) 760 926 761 def compare_tuples_ Ds(self,f,g):927 def compare_tuples_negdeglex(self,f,g): 762 928 """ 763 929 Compares two exponent tuples with respect to the negative degree 764 930 lexicographical term order. … … 781 947 sg = sum(g.nonzero_values(sort=False)) 782 948 if sf > sg: 783 949 return -1 784 elif sf <sg:950 elif sf < sg: 785 951 return 1 786 952 elif sf == sg: 787 return self.compare_tuples_lp(f,g) 953 return self.compare_tuples_lex(f,g) 954 955 def compare_tuples_wdegrevlex(self,f,g): 956 """ 957 Compares two exponent tuples with respect to the weighted degree reverse 958 lexicographical term order. 959 960 INPUT: 961 962 - ``f`` - exponent tuple 963 964 - ``g`` - exponent tuple 965 966 EXAMPLE:: 967 968 sage: t = TermOrder('wdegrevlex',(3,2)) 969 sage: P.<x,y> = PolynomialRing(QQbar, 2, order=t) 970 sage: x > y^2 # indirect doctest 971 False 972 sage: x^2 > y^3 973 True 974 """ 975 sf = sum(l*r for (l,r) in zip(f,self._weights)) 976 sg = sum(l*r for (l,r) in zip(g,self._weights)) 977 if sf > sg: 978 return 1 979 elif sf < sg: 980 return -1 981 elif sf == sg: 982 return -self.compare_tuples_lex(f.reversed(),g.reversed()) 983 984 def compare_tuples_wdeglex(self,f,g): 985 """ 986 Compares two exponent tuples with respect to the weighted degree 987 lexicographical term order. 988 989 INPUT: 990 991 - ``f`` - exponent tuple 992 993 - ``g`` - exponent tuple 994 995 EXAMPLE:: 996 997 sage: t = TermOrder('wdeglex',(3,2)) 998 sage: P.<x,y> = PolynomialRing(QQbar, 2, order=t) 999 sage: x > y^2 # indirect doctest 1000 False 1001 sage: x > y 1002 True 1003 """ 1004 sf = sum(l*r for (l,r) in zip(f,self._weights)) 1005 sg = sum(l*r for (l,r) in zip(g,self._weights)) 1006 if sf > sg: 1007 return 1 1008 elif sf < sg: 1009 return -1 1010 elif sf == sg: 1011 return self.compare_tuples_lex(f,g) 1012 1013 def compare_tuples_negwdeglex(self,f,g): 1014 """ 1015 Compares two exponent tuples with respect to the negative weighted 1016 degree lexicographical term order. 1017 1018 INPUT: 1019 1020 - ``f`` - exponent tuple 1021 1022 - ``g`` - exponent tuple 1023 1024 EXAMPLE:: 1025 1026 sage: t = TermOrder('negwdeglex',(3,2)) 1027 sage: P.<x,y> = PolynomialRing(QQbar, 2, order=t) 1028 sage: x > y^2 # indirect doctest 1029 True 1030 sage: x^2 > y^3 1031 True 1032 """ 1033 sf = sum(l*r for (l,r) in zip(f,self._weights)) 1034 sg = sum(l*r for (l,r) in zip(g,self._weights)) 1035 if sf > sg: 1036 return -1 1037 elif sf < sg: 1038 return 1 1039 elif sf == sg: 1040 return self.compare_tuples_lex(f,g) 1041 1042 def compare_tuples_negwdegrevlex(self,f,g): 1043 """ 1044 Compares two exponent tuples with respect to the negative weighted 1045 degree reverse lexicographical term order. 1046 1047 INPUT: 1048 1049 - ``f`` - exponent tuple 1050 1051 - ``g`` - exponent tuple 1052 1053 EXAMPLE:: 1054 1055 sage: t = TermOrder('negwdegrevlex',(3,2)) 1056 sage: P.<x,y> = PolynomialRing(QQbar, 2, order=t) 1057 sage: x > y^2 # indirect doctest 1058 True 1059 sage: x^2 > y^3 1060 True 1061 """ 1062 sf = sum(l*r for (l,r) in zip(f,self._weights)) 1063 sg = sum(l*r for (l,r) in zip(g,self._weights)) 1064 if sf > sg: 1065 return -1 1066 elif sf < sg: 1067 return 1 1068 elif sf == sg: 1069 return (-1)*self.compare_tuples_lex(f.reversed(),g.reversed()) 788 1070 789 1071 def compare_tuples_block(self, f,g): 790 1072 """ 791 Compares two exponent tuples with respect to the block order ingas1073 Compares two exponent tuples with respect to the block order as 792 1074 specified when constructing this element. 793 1075 794 1076 INPUT: … … 806 1088 True 807 1089 """ 808 1090 n = 0 809 for orderin self:810 r = getattr( self,"compare_tuples_"+order.singular_str())(f[n:n+len(order)],g[n:n+len(order)])1091 for block in self: 1092 r = getattr(block,"compare_tuples_" + block.name())(f[n:n+len(block)],g[n:n+len(block)]) 811 1093 if r != 0: 812 1094 return r 813 n += len( order)1095 n += len(block) 814 1096 return 0 815 1097 816 1098 def greater_tuple_matrix(self,f,g): … … 832 1114 sage: y > x^3 833 1115 False 834 1116 """ 835 for row in self._ _matrix:836 mf = sum(l*r for (l,r) in zip(row,f))837 mg = sum(l*r for (l,r) in zip(row,g))1117 for row in self._matrix: 1118 sf = sum(l*r for (l,r) in zip(row,f)) 1119 sg = sum(l*r for (l,r) in zip(row,g)) 838 1120 839 if mf>mg:1121 if sf > sg: 840 1122 return f 841 elif mf<mg:1123 elif sf < sg: 842 1124 return g 843 1125 return g 844 1126 845 def greater_tuple_l p(self,f,g):1127 def greater_tuple_lex(self,f,g): 846 1128 """ 847 Return sthe greater exponent tuple with respect to the1129 Return the greater exponent tuple with respect to the 848 1130 lexicographical term order. 849 1131 850 1132 INPUT: … … 864 1146 """ 865 1147 return f > g and f or g 866 1148 867 def greater_tuple_ rp(self,f,g):1149 def greater_tuple_invlex(self,f,g): 868 1150 """ 869 Return sthe greater exponent tuple with respect to the inversed1151 Return the greater exponent tuple with respect to the inversed 870 1152 lexicographical term order. 871 1153 872 1154 INPUT: … … 886 1168 This method is called by the lm/lc/lt methods of 887 1169 ``MPolynomial_polydict``. 888 1170 """ 889 return f.reversed() > g.reversed() 1171 return f.reversed() > g.reversed() and f or g 890 1172 891 def greater_tuple_ Dp(self,f,g):1173 def greater_tuple_deglex(self,f,g): 892 1174 """ 893 Return sthe greater exponent tuple with respect to the total degree1175 Return the greater exponent tuple with respect to the total degree 894 1176 lexicographical term order. 895 1177 896 1178 INPUT: … … 910 1192 This method is called by the lm/lc/lt methods of 911 1193 ``MPolynomial_polydict``. 912 1194 """ 913 return (sum(f.nonzero_values(sort=False))>sum(g.nonzero_values(sort=False)) 914 or (sum(f.nonzero_values(sort=False))==sum(g.nonzero_values(sort=False)) and f > g )) and f or g 1195 sf = sum(f.nonzero_values(sort=False)) 1196 sg = sum(g.nonzero_values(sort=False)) 1197 return ( sf > sg or ( sf == sg and f > g )) and f or g 915 1198 916 def greater_tuple_d p(self,f,g):1199 def greater_tuple_degrevlex(self,f,g): 917 1200 """ 918 Return sthe greater exponent tuple with respect to the total degree1201 Return the greater exponent tuple with respect to the total degree 919 1202 reversed lexicographical term order. 920 1203 921 1204 INPUT: … … 935 1218 This method is called by the lm/lc/lt methods of 936 1219 ``MPolynomial_polydict``. 937 1220 """ 938 return (sum(f.nonzero_values(sort=False))>sum(g.nonzero_values(sort=False))939 or (sum(f.nonzero_values(sort=False))==sum(g.nonzero_values(sort=False))940 and f.reversed() < g.reversed())) and f or g1221 sf = sum(f.nonzero_values(sort=False)) 1222 sg = sum(g.nonzero_values(sort=False)) 1223 return ( sf > sg or ( sf == sg and f.reversed() < g.reversed() )) and f or g 941 1224 942 def greater_tuple_ ds(self,f,g):1225 def greater_tuple_negdegrevlex(self,f,g): 943 1226 """ 944 Return sthe greater exponent tuple with respect to the negative1227 Return the greater exponent tuple with respect to the negative 945 1228 degree reverse lexicographical term order. 946 1229 947 1230 INPUT: … … 963 1246 This method is called by the lm/lc/lt methods of 964 1247 ``MPolynomial_polydict``. 965 1248 """ 966 if self.compare_tuples_ds(f,g) >= 0: 967 return f 968 else: 969 return g 1249 sf = sum(f.nonzero_values(sort=False)) 1250 sg = sum(g.nonzero_values(sort=False)) 1251 return ( sf < sg or ( sf == sg and f.reversed() < g.reversed() )) and f or g 970 1252 971 def greater_tuple_ Ds(self,f,g):1253 def greater_tuple_negdeglex(self,f,g): 972 1254 """ 973 Return sthe greater exponent tuple with respect to the negative1255 Return the greater exponent tuple with respect to the negative 974 1256 degree lexicographical term order. 975 1257 976 1258 INPUT: … … 992 1274 This method is called by the lm/lc/lt methods of 993 1275 ``MPolynomial_polydict``. 994 1276 """ 995 if self.compare_tuples_Ds(f,g) >= 0: 996 return f 997 else: 998 return g 1277 sf = sum(f.nonzero_values(sort=False)) 1278 sg = sum(g.nonzero_values(sort=False)) 1279 return ( sf < sg or ( sf == sg and f > g )) and f or g 999 1280 1000 def greater_tuple_ ls(self,f,g):1281 def greater_tuple_neglex(self,f,g): 1001 1282 """ 1002 Return sthe greater exponent tuple with respect to the negative1283 Return the greater exponent tuple with respect to the negative 1003 1284 lexicographical term order. 1004 1285 1005 1286 This method is called by the lm/lc/lt methods of … … 1019 1300 sage: g = a + e^4; g.lm() 1020 1301 a 1021 1302 """ 1022 if self.greater_tuple_lp(f,g) is f: 1023 return g 1024 else: 1025 return f 1303 return (f < g) and f or g 1026 1304 1305 def greater_tuple_wdeglex(self,f,g): 1306 """ 1307 Return the greater exponent tuple with respect to the weighted degree 1308 lexicographical term order. 1309 1310 INPUT: 1311 1312 - ``f`` - exponent tuple 1313 1314 - ``g`` - exponent tuple 1315 1316 EXAMPLE:: 1317 1318 sage: t = TermOrder('wdeglex',(1,2,3)) 1319 sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order=t) 1320 sage: f = x + y; f.lm() # indirect doctest 1321 y 1322 sage: f = x*y + z; f.lm() 1323 x*y 1324 1325 This method is called by the lm/lc/lt methods of 1326 ``MPolynomial_polydict``. 1327 """ 1328 sf = sum(l*r for (l,r) in zip(f,self._weights)) 1329 sg = sum(l*r for (l,r) in zip(g,self._weights)) 1330 return (sf > sg or ( sf == sg and f > g )) and f or g 1331 1332 def greater_tuple_wdegrevlex(self,f,g): 1333 """ 1334 Return the greater exponent tuple with respect to the weighted degree 1335 reverse lexicographical term order. 1336 1337 INPUT: 1338 1339 - ``f`` - exponent tuple 1340 1341 - ``g`` - exponent tuple 1342 1343 EXAMPLES:: 1344 1345 sage: t = TermOrder('wdegrevlex',(1,2,3)) 1346 sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order=t) 1347 sage: f = x + y; f.lm() # indirect doctest 1348 y 1349 sage: f = x + y^2*z; f.lm() 1350 y^2*z 1351 1352 This method is called by the lm/lc/lt methods of 1353 ``MPolynomial_polydict``. 1354 """ 1355 sf = sum(l*r for (l,r) in zip(f,self._weights)) 1356 sg = sum(l*r for (l,r) in zip(g,self._weights)) 1357 return (sf > sg or ( sf == sg and f.reversed() < g.reversed())) and f or g 1358 1359 def greater_tuple_negwdeglex(self,f,g): 1360 """ 1361 Return the greater exponent tuple with respect to the negative 1362 weighted degree lexicographical term order. 1363 1364 INPUT: 1365 1366 - ``f`` - exponent tuple 1367 1368 - ``g`` - exponent tuple 1369 1370 EXAMPLE:: 1371 1372 sage: t = TermOrder('negwdeglex',(1,2,3)) 1373 sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order=t) 1374 sage: f = x + y; f.lm() # indirect doctest 1375 x 1376 sage: f = x + x^2; f.lm() 1377 x 1378 sage: f = x^3 + z; f.lm() 1379 x^3 1380 1381 This method is called by the lm/lc/lt methods of 1382 ``MPolynomial_polydict``. 1383 """ 1384 sf = sum(l*r for (l,r) in zip(f,self._weights)) 1385 sg = sum(l*r for (l,r) in zip(g,self._weights)) 1386 return (sf < sg or ( sf == sg and f > g )) and f or g 1387 1388 def greater_tuple_negwdegrevlex(self,f,g): 1389 """ 1390 Return the greater exponent tuple with respect to the negative 1391 weighted degree reverse lexicographical term order. 1392 1393 INPUT: 1394 1395 - ``f`` - exponent tuple 1396 1397 - ``g`` - exponent tuple 1398 1399 EXAMPLE:: 1400 1401 sage: t = TermOrder('negwdegrevlex',(1,2,3)) 1402 sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order=t) 1403 sage: f = x + y; f.lm() # indirect doctest 1404 x 1405 sage: f = x + x^2; f.lm() 1406 x 1407 sage: f = x^3 + z; f.lm() 1408 x^3 1409 1410 This method is called by the lm/lc/lt methods of 1411 ``MPolynomial_polydict``. 1412 """ 1413 sf = sum(l*r for (l,r) in zip(f,self._weights)) 1414 sg = sum(l*r for (l,r) in zip(g,self._weights)) 1415 return (sf < sg or ( sf == sg and f.reversed() < g.reversed() )) and f or g 1416 1027 1417 def greater_tuple_block(self, f,g): 1028 1418 """ 1029 Return sthe greater exponent tuple with respect to the block1030 order ingas specified when constructing this element.1419 Return the greater exponent tuple with respect to the block 1420 order as specified when constructing this element. 1031 1421 1032 1422 This method is called by the lm/lc/lt methods of 1033 1423 ``MPolynomial_polydict``. … … 1047 1437 a 1048 1438 """ 1049 1439 n = 0 1050 for orderin self:1051 r = getattr( self,"compare_tuples_"+order.singular_str())(f[n:n+len(order)],g[n:n+len(order)])1440 for block in self: 1441 r = getattr(block,"compare_tuples_" + block.name())(f[n:n+len(block)],g[n:n+len(block)]) 1052 1442 if r != 0: 1053 1443 if r < 0: 1054 1444 return g 1055 1445 else: 1056 1446 return f 1057 n += len( order)1447 n += len(block) 1058 1448 return f 1059 1449 1450 def tuple_weight(self, f): 1451 """ 1452 Return the weight of tuple f. 1453 1454 INPUT: 1455 1456 - ``f`` - exponent tuple 1457 1458 EXAMPLE:: 1459 1460 sage: t=TermOrder('wdeglex',(1,2,3)) 1461 sage: P.<a,b,c>=PolynomialRing(QQbar, order=t) 1462 sage: P.term_order().tuple_weight([3,2,1]) 1463 10 1464 """ 1465 return sum(l*r for (l,r) in zip(f,self._weights)) 1466 1060 1467 def name(self): 1061 1468 """ 1062 1469 EXAMPLE:: … … 1064 1471 sage: TermOrder('lex').name() 1065 1472 'lex' 1066 1473 """ 1067 return self._ _name1474 return self._name 1068 1475 1069 1476 def _repr_(self): 1070 1477 """ … … 1073 1480 sage: TermOrder('lex') # indirect doctest 1074 1481 Lexicographic term order 1075 1482 """ 1076 if self.__name[0] == 'M': 1077 return 'Matrix term order with matrix\n%s'%self.matrix() 1483 if self._name == 'matrix': 1484 return 'Matrix term order with matrix\n%s'%(self._matrix,) 1485 elif self._name == 'block': 1486 s = [] 1487 for t in self._blocks: 1488 if not t.is_weighted_degree_order(): 1489 s.append('%s of length %d'%(t,len(t))) 1490 else: # includes matrix order 1491 s.append('%s'%(t,)) 1492 return 'Block term order with blocks:\n(%s)'%(',\n '.join(s),) 1078 1493 else: 1079 s = print_name_mapping.get(self.__name,self.__name) 1080 return '%s term order'%s 1494 s = print_name_mapping.get(self._name,self._name) + ' term order' 1495 if self.is_weighted_degree_order(): 1496 s = s + ' with weights %s'%(self._weights,) 1497 return s 1081 1498 1082 1499 def singular_str(self): 1083 1500 """ … … 1102 1519 // : names x8 x9 1103 1520 // block 4 : ordering C 1104 1521 """ 1105 return self._ _singular_str1522 return self._singular_str 1106 1523 1107 1524 def macaulay2_str(self): 1108 1525 """ … … 1116 1533 sage: P = PolynomialRing(GF(127), 8,names='x',order='degrevlex(3),lex(5)') 1117 1534 sage: T = P.term_order() 1118 1535 sage: T.macaulay2_str() 1119 ' (GRevLex => 3,Lex => 5)'1536 '{GRevLex => 3,Lex => 5}' 1120 1537 sage: P._macaulay2_() # optional - macaulay2 1121 1538 ZZ/127 [x0, x1, x2, x3, x4, x5, x6, x7, MonomialOrder => {GRevLex => 3, Lex => 5}, MonomialSize => 16] 1122 1539 """ 1123 return self._ _macaulay2_str1540 return self._macaulay2_str 1124 1541 1125 1542 def magma_str(self): 1126 1543 """ … … 1142 1559 sage: T.magma_str() 1143 1560 '"grevlex"' 1144 1561 """ 1145 return self.__magma_str 1562 return self._magma_str 1563 1564 def blocks(self): 1565 """ 1566 Return the term order blocks of self. 1567 1568 EXAMPLE:: 1569 1570 sage: t=TermOrder('deglex',2)+TermOrder('lex',2) 1571 sage: t.blocks() 1572 (Degree lexicographic term order, Lexicographic term order) 1573 """ 1574 if self._blocks: # self is a block order 1575 return self._blocks 1576 else: 1577 return [self] 1146 1578 1147 1579 def matrix(self): 1148 1580 """ 1149 Return the matrix defining matrix ordering.1581 Return the matrix defining matrix term order. 1150 1582 1151 1583 EXAMPLE:: 1152 1584 … … 1156 1588 [0 1] 1157 1589 1158 1590 """ 1159 from sage.matrix.constructor import matrix 1160 return matrix(self.__matrix) 1591 return self._matrix 1161 1592 1162 def __cmp__(self, other):1593 def weights(self): 1163 1594 """ 1164 Only equality testing makes sense here. 1165 1595 Return the weights for weighted term orders. 1596 1597 EXAMPLE:: 1598 1599 sage: t=TermOrder('wdeglex',(2,3)) 1600 sage: t.weights() 1601 (2, 3) 1602 """ 1603 return self._weights 1604 1605 def __eq__(self, other): 1606 """ 1607 Return true if self and other are equal. 1608 1166 1609 EXAMPLE:: 1167 1610 1168 1611 sage: TermOrder('lex') == TermOrder('lex',3) … … 1178 1621 sage: T1 = TermOrder('lex',2)+TermOrder('lex',3) 1179 1622 sage: T2 = TermOrder('lex',3)+TermOrder('lex',2) 1180 1623 sage: T1 == T2 1181 False1624 True 1182 1625 1183 1626 :: 1184 1627 … … 1188 1631 True 1189 1632 """ 1190 1633 if not isinstance(other, TermOrder): 1191 if isinstance(other, str):1634 try: 1192 1635 other = TermOrder(other, force=True) 1193 else: 1194 return cmp(type(self), type(other)) 1195 return cmp(self.singular_str(), other.singular_str()) 1636 except: 1637 return False 1638 1639 return (self._name == other._name # note that length is not considered. 1640 and self._blocks == other._blocks 1641 and self._weights == other._weights 1642 and self._matrix == other._matrix) 1643 1644 def __ne__(self, other): 1645 """ 1646 Return true if self and other are not equal. 1647 1648 EXAMPLE:: 1649 1650 sage: T1 = TermOrder('lex',2)+TermOrder('lex',3) 1651 sage: T2 = TermOrder('lex',3)+TermOrder('lex',2) 1652 sage: T1 != T2 1653 False 1654 """ 1655 return not self.__eq__(other) 1196 1656 1197 1657 def __add__(self, other): 1198 1658 """ 1199 Block ordering constructor.1659 Construct a block order combining self and other. 1200 1660 1201 1661 INPUT: 1202 1662 1203 1663 - ``other`` - a term order 1204 1664 1205 OUTPUT: a block order ing1665 OUTPUT: a block order 1206 1666 1207 1667 EXAMPLE:: 1208 1668 1209 1669 sage: from sage.rings.polynomial.term_order import TermOrder 1210 1670 sage: TermOrder('deglex',2) + TermOrder('degrevlex(3),neglex(3)') 1211 deglex(2),degrevlex(3),neglex(3) term order 1212 """ 1213 if other is None: 1671 Block term order with blocks: 1672 (Degree lexicographic term order of length 2, 1673 Degree reverse lexicographic term order of length 3, 1674 Negative lexicographic term order of length 3) 1675 """ 1676 if isinstance(other, TermOrder): 1677 return TermOrder('block',[self,other]) 1678 else: 1214 1679 return self 1215 1216 if not isinstance(other,TermOrder):1217 other = TermOrder(other, force = self.__force)1218 if len(self) == 0 or len(other) == 0:1219 raise ArithmeticError, "Can only concatenate term orders with length attribute."1220 1221 name = []1222 for block_order in self.blocks + other.blocks:1223 if 'M' in block_order.singular_str():1224 raise NotImplementedError, "Cannot use a matrix term order as a block."1225 nom = block_order.singular_str()1226 name.append("%s(%d)"%(inv_singular_name_mapping.get(nom,nom), len(block_order)))1227 1228 name = ",".join(name)1229 return TermOrder(name, len(self)+len(other), force=self.__force)1230 1680 1231 1681 def __len__(self): 1232 1682 """ 1233 Return the length of this term order ing, i.e. the number of1683 Return the length of this term order, i.e. the number of 1234 1684 variables it covers. This may be zero for indefinitely many 1235 1685 variables. 1236 1686 … … 1243 1693 sage: len(T) 1244 1694 5 1245 1695 """ 1246 return self._ _length1696 return self._length 1247 1697 1248 1698 def __getitem__(self, i): 1249 1699 r""" 1250 Return the i-th block of this term order ing.1700 Return the i-th block of this term order. 1251 1701 1252 1702 INPUT: 1253 1703 … … 1273 1723 sage: T = TermOrder('lex', 2) + TermOrder('degrevlex', 3) 1274 1724 sage: T[len(T)-1] 1275 1725 Traceback (most recent call last): 1276 ...1726 \dots 1277 1727 IndexError: tuple index out of range 1278 1728 """ 1279 return self.blocks [i]1729 return self.blocks()[i] 1280 1730 1281 1731 def __iter__(self): 1282 1732 r""" 1283 Iterate over the blocks of this term order ing.1733 Iterate over the blocks of this term order. 1284 1734 1285 1735 EXAMPLE:: 1286 1736 … … 1299 1749 the number of variables in ``self`` while the latter 1300 1750 counts the number of blocks. 1301 1751 """ 1302 return iter(self.blocks )1752 return iter(self.blocks()) 1303 1753 1304 1754 def is_global(self): 1305 1755 r""" 1306 Return ``True`` if this term orderingis definitely1307 global. Return ``False``otherwise, which includes1308 unknown term order ings.1756 Return true if this term order is definitely 1757 global. Return false otherwise, which includes 1758 unknown term orders. 1309 1759 1310 1760 EXAMPLE:: 1311 1761 … … 1319 1769 sage: T.is_global() 1320 1770 False 1321 1771 """ 1322 if len(self.blocks) == 1: 1323 if self.singular_str() in ('lp','dp','Dp'): 1324 return True 1325 else: 1326 return False 1772 if self.name() in ('lex','degrevlex','deglex','wdegrevlex','wdeglex'): 1773 return True 1774 elif self.name() is 'block': 1775 return all([t.is_global() for t in self.blocks()]) 1327 1776 else: 1328 return all([t.is_global() for t in self.blocks])1329 1777 return False 1778 1330 1779 def is_local(self): 1331 1780 r""" 1332 Return ``True`` if this term orderingis definitely1333 local. Return ``False``otherwise, which includes1334 unknown term order ings.1781 Return true if this term order is definitely 1782 local. Return false otherwise, which includes 1783 unknown term orders. 1335 1784 1336 1785 EXAMPLE:: 1337 1786 … … 1345 1794 sage: T.is_local() 1346 1795 False 1347 1796 """ 1348 if len(self.blocks) == 1:1349 if self.singular_str() in ('rp', 'ls','ds','Ds'):1350 1351 else:1352 return False1797 if (self.name() in ('neglex','negdegrevlex','negdeglex','negwdegrevlex','negwdeglex') or 1798 self.singular_str() in ('ls','ds','Ds','ws','Ws')): 1799 return True 1800 elif self.name() is 'block': 1801 return all([t.is_local() for t in self.blocks()]) 1353 1802 else: 1354 return all([t.is_local() for t in self.blocks]) 1803 return False 1804 1805 def is_block_order(self): 1806 """ 1807 Return true if self is a block term order. 1808 1809 EXAMPLE:: 1810 1811 sage: t=TermOrder('deglex',2)+TermOrder('lex',2) 1812 sage: t.is_block_order() 1813 True 1814 """ 1815 return self._name == 'block' 1816 1817 def is_weighted_degree_order(self): 1818 """ 1819 Return true if self is a weighted degree term order. 1820 1821 EXAMPLE:: 1822 1823 sage: t=TermOrder('wdeglex',(2,3)) 1824 sage: t.is_weighted_degree_order() 1825 True 1826 """ 1827 return self._weights is not None