[c91bb9] | 1 | /////////////////////////////////////////////////////////////////////////////// |
---|
[341696] | 2 | version="$Id$"; |
---|
[fd3fb7] | 3 | category="Symbolic-numerical solving"; |
---|
[5480da] | 4 | info=" |
---|
[8942a5] | 5 | LIBRARY: presolve.lib Pre-Solving of Polynomial Equations |
---|
[091424] | 6 | AUTHOR: Gert-Martin Greuel, email: greuel@mathematik.uni-kl.de, |
---|
[c91bb9] | 7 | |
---|
[f34c37c] | 8 | PROCEDURES: |
---|
[faed79] | 9 | degreepart(id,d1,d2); elements of id of total degree >= d1 and <= d2, and rest |
---|
[c91bb9] | 10 | elimlinearpart(id); linear part eliminated from id |
---|
[9173792] | 11 | elimpart(id[,n]); partial elimination of vars [among first n vars] |
---|
[c91bb9] | 12 | elimpartanyr(i,p); factors of p partially eliminated from i in any ring |
---|
| 13 | fastelim(i,p[..]); fast elimination of factors of p from i [options] |
---|
| 14 | findvars(id[..]); ideal of variables occuring in id [more information] |
---|
| 15 | hilbvec(id[,c,o]); intvec of Hilberseries of id [in char c and ord o] |
---|
| 16 | linearpart(id); elements of id of total degree <=1 |
---|
| 17 | tolessvars(id[,]); maps id to new basering having only vars occuring in id |
---|
| 18 | solvelinearpart(id); reduced std-basis of linear part of id |
---|
[faed79] | 19 | sortandmap(id[..]); map to new basering with vars sorted w.r.t. complexity |
---|
[c91bb9] | 20 | sortvars(id[n1,p1..]); sort vars w.r.t. complexity in id [different blocks] |
---|
[82716e] | 21 | valvars(id[..]); valuation of vars w.r.t. to their complexity in id |
---|
[3c4dcc] | 22 | idealSplit(id,tF,fS); a list of ideals such that their intersection |
---|
[8b87364] | 23 | has the same radical as id |
---|
| 24 | ( parameters in square brackets [] are optional) |
---|
[5480da] | 25 | "; |
---|
[c91bb9] | 26 | |
---|
| 27 | LIB "inout.lib"; |
---|
| 28 | LIB "general.lib"; |
---|
| 29 | LIB "matrix.lib"; |
---|
| 30 | LIB "ring.lib"; |
---|
| 31 | LIB "elim.lib"; |
---|
| 32 | /////////////////////////////////////////////////////////////////////////////// |
---|
[35ceb0] | 33 | proc shortid (id,int n,list #) |
---|
| 34 | "USAGE: shortid(id,n[,e]); id= ideal/module, n,e=integers |
---|
| 35 | RETURN: - if called with two arguments or e=0: |
---|
| 36 | @* same type as id, containing generators of id having <= n terms. |
---|
| 37 | @* - if called with three arguments and e!=0: |
---|
| 38 | @* a list L: |
---|
| 39 | @* L[1]: same type as id, containing generators of id having <= n terms. |
---|
| 40 | @* L[2]: number of corresponding generator of id |
---|
| 41 | NOTE: May be used to compute partial standard basis in case id is to hard |
---|
[3c4dcc] | 42 | EXAMPLE: example shortid; shows an example |
---|
[35ceb0] | 43 | " |
---|
| 44 | { |
---|
| 45 | intvec v; |
---|
| 46 | int ii; |
---|
| 47 | for(ii=1; ii<=ncols(id); ii++) |
---|
| 48 | { |
---|
| 49 | if (size(id[ii]) <=n and id[ii]!=0 ) |
---|
| 50 | { |
---|
| 51 | v=v,ii; |
---|
| 52 | } |
---|
| 53 | if (size(id[ii]) > n ) |
---|
| 54 | { |
---|
| 55 | id[ii]=0; |
---|
| 56 | } |
---|
| 57 | } |
---|
| 58 | if( size(v)>1 ) |
---|
[3c4dcc] | 59 | { |
---|
[35ceb0] | 60 | v = v[2..size(v)]; |
---|
| 61 | } |
---|
| 62 | id = simplify(id,2); |
---|
| 63 | list L = id,v; |
---|
| 64 | if ( size(#)==0 ) |
---|
| 65 | { |
---|
| 66 | return(id); |
---|
| 67 | } |
---|
| 68 | if ( size(#)!=0 ) |
---|
| 69 | { |
---|
| 70 | if(#[1]==0) |
---|
| 71 | { |
---|
| 72 | return(id); |
---|
| 73 | } |
---|
| 74 | if(#[1]!=0) |
---|
| 75 | { |
---|
| 76 | return(L); |
---|
| 77 | } |
---|
| 78 | } |
---|
| 79 | } |
---|
| 80 | example |
---|
| 81 | { "EXAMPLE:"; echo = 2; |
---|
| 82 | ring s=0,(x,y,z,w),dp; |
---|
[3c4dcc] | 83 | ideal i = (x3+y2+yw2)^2,(xz+z2)^2,xyz-w2-xzw; |
---|
[35ceb0] | 84 | shortid(i,3); |
---|
| 85 | } |
---|
| 86 | /////////////////////////////////////////////////////////////////////////////// |
---|
[c91bb9] | 87 | |
---|
| 88 | proc degreepart (id,int d1,int d2,list #) |
---|
[d2b2a7] | 89 | "USAGE: degreepart(id,d1,d2[,v]); id=ideal/module, d1,d1=integers, v=intvec |
---|
[faed79] | 90 | RETURN: list of size 2, |
---|
| 91 | _[1]: generators of id of [v-weighted] total degree >= d1 and <= d2 |
---|
| 92 | (default: v = 1,...,1) |
---|
| 93 | _[2]: remaining generators of id |
---|
[30bb07] | 94 | NOTE: if id is of type int/number/poly it is converted to ideal, if id is |
---|
| 95 | of type intmat/matrix/vector to module and then the corresponding |
---|
| 96 | generators are computed |
---|
[c91bb9] | 97 | EXAMPLE: example degreepart; shows an example |
---|
[d2b2a7] | 98 | " |
---|
[c91bb9] | 99 | { |
---|
[b21c4a] | 100 | if( typeof(id)=="int" or typeof(id)=="number" |
---|
| 101 | or typeof(id)=="ideal" or typeof(id)=="poly" ) |
---|
[faed79] | 102 | { |
---|
| 103 | ideal dpart = ideal(id); |
---|
| 104 | } |
---|
[b21c4a] | 105 | if( typeof(id)=="intmat" or typeof(id)=="matrix" |
---|
| 106 | or typeof(id)=="module" or typeof(id)=="vector") |
---|
[faed79] | 107 | { |
---|
| 108 | module dpart = module(id); |
---|
| 109 | } |
---|
| 110 | |
---|
| 111 | def epart = dpart; |
---|
| 112 | int s,ii = ncols(id),0; |
---|
[c91bb9] | 113 | if ( size(#)==0 ) |
---|
| 114 | { |
---|
[faed79] | 115 | for ( ii=1; ii<=s; ii++ ) |
---|
[82716e] | 116 | { |
---|
| 117 | dpart[ii] = (jet(id[ii],d1-1)==0)*(id[ii]==jet(id[ii],d2))*id[ii]; |
---|
[faed79] | 118 | epart[ii] = (size(dpart[ii])==0) * id[ii]; |
---|
[c91bb9] | 119 | } |
---|
| 120 | } |
---|
| 121 | else |
---|
[82716e] | 122 | { |
---|
[c91bb9] | 123 | for ( ii=1; ii<=s; ii=ii+1 ) |
---|
[82716e] | 124 | { |
---|
[faed79] | 125 | dpart[ii]=(jet(id[ii],d1-1,#[1])==0)*(id[ii]==jet(id[ii],d2,#[1]))*id[ii]; |
---|
| 126 | epart[ii] = (size(dpart[ii])==0)*id[ii]; |
---|
[c91bb9] | 127 | } |
---|
| 128 | } |
---|
[faed79] | 129 | list L = simplify(dpart,2),simplify(epart,2); |
---|
| 130 | return(L); |
---|
[c91bb9] | 131 | } |
---|
[82716e] | 132 | example |
---|
[c91bb9] | 133 | { "EXAMPLE:"; echo = 2; |
---|
| 134 | ring r=0,(x,y,z),dp; |
---|
[9173792] | 135 | ideal i=1+x+x2+x3+x4,3,xz+y3+z8; |
---|
[c91bb9] | 136 | degreepart(i,0,4); |
---|
[faed79] | 137 | |
---|
[c91bb9] | 138 | module m=[x,y,z],x*[x3,y2,z],[1,x2,z3,0,1]; |
---|
| 139 | intvec v=2,3,6; |
---|
| 140 | show(degreepart(m,8,8,v)); |
---|
| 141 | } |
---|
| 142 | /////////////////////////////////////////////////////////////////////////////// |
---|
| 143 | |
---|
[faed79] | 144 | proc linearpart (id) |
---|
| 145 | "USAGE: linearpart(id); id=ideal/module |
---|
| 146 | RETURN: list of size 2, |
---|
| 147 | _[1]: generators of id of total degree <= 1 |
---|
| 148 | _[2]: remaining generators of id |
---|
[30bb07] | 149 | NOTE: all variables have degree 1 (independent of ordering of basering) |
---|
[faed79] | 150 | EXAMPLE: example linearpart; shows an example |
---|
| 151 | " |
---|
| 152 | { |
---|
| 153 | return(degreepart(id,0,1)); |
---|
| 154 | } |
---|
| 155 | example |
---|
| 156 | { "EXAMPLE:"; echo = 2; |
---|
| 157 | ring r=0,(x,y,z),dp; |
---|
| 158 | ideal i=1+x+x2+x3,3,x+3y+5z; |
---|
| 159 | linearpart(i); |
---|
| 160 | |
---|
| 161 | module m=[x,y,z],x*[x3,y2,z],[1,x2,z3,0,1]; |
---|
| 162 | show(linearpart(m)); |
---|
| 163 | } |
---|
| 164 | /////////////////////////////////////////////////////////////////////////////// |
---|
| 165 | |
---|
[c91bb9] | 166 | proc elimlinearpart (ideal i,list #) |
---|
[9173792] | 167 | "USAGE: elimlinearpart(i[,n]); i=ideal, n=integer,@* |
---|
| 168 | default: n=nvars(basering) |
---|
| 169 | RETURN: list L with 5 entries: |
---|
| 170 | @format |
---|
[faed79] | 171 | L[1]: ideal obtained from i by substituting from the first n variables those |
---|
[0bc582c] | 172 | which appear in a linear part of i, by putting this part into triangular |
---|
[faed79] | 173 | form |
---|
[9173792] | 174 | L[2]: ideal of variables which have been substituted |
---|
| 175 | L[3]: ideal, j-th element defines substitution of j-th var in [2] |
---|
| 176 | L[4]: ideal of variables of basering, eliminated ones are set to 0 |
---|
| 177 | L[5]: ideal, describing the map from the basering to itself such that |
---|
| 178 | L[1] is the image of i |
---|
| 179 | @end format |
---|
[faed79] | 180 | NOTE: the procedure always interreduces the ideal i internally w.r.t. |
---|
[9173792] | 181 | ordering dp. |
---|
[c91bb9] | 182 | EXAMPLE: example elimlinearpart; shows an example |
---|
[d2b2a7] | 183 | " |
---|
[c91bb9] | 184 | { |
---|
[30bb07] | 185 | int ii,n,k,ringchange; |
---|
| 186 | string o; |
---|
[c91bb9] | 187 | intvec getoption = option(get); |
---|
| 188 | option(redSB); |
---|
[faed79] | 189 | def BAS = basering; |
---|
| 190 | n = nvars(BAS); |
---|
| 191 | list gnirlist = ringlist(basering); |
---|
| 192 | list g3 = gnirlist[3]; |
---|
| 193 | list g32 = g3[size(g3)]; |
---|
| 194 | |
---|
[091424] | 195 | //---------------------------------- start ------------------------------------ |
---|
[c91bb9] | 196 | if ( size(#)!=0 ) { n=#[1]; } |
---|
[de63d0] | 197 | ideal maxi,rest = maxideal(1),0; |
---|
[b21c4a] | 198 | if ( n < nvars(BAS) ) |
---|
| 199 | { |
---|
[30bb07] | 200 | rest = maxi[n+1..nvars(BAS)]; //variables which are not substituted |
---|
[faed79] | 201 | } |
---|
[82716e] | 202 | attrib(rest,"isSB",1); |
---|
[faed79] | 203 | |
---|
| 204 | //-------------------- find linear part and reduce rest ---------------------- |
---|
| 205 | // Perhaps for big systems, check only those generators of id |
---|
[c91bb9] | 206 | // which do not contain elements not to be eliminated |
---|
| 207 | |
---|
[b21c4a] | 208 | //ideal id = interred(i); |
---|
[0610f0e] | 209 | //## gmg, geaendert 9/2008: interred sehr lange z.B. bei Leonard1 in normal, |
---|
[faed79] | 210 | //daher interred ersetzt durch: std nur auf linearpart angewendet |
---|
[30bb07] | 211 | //Wechsel zu dp Ordnung (da Lin affin linear) |
---|
[faed79] | 212 | |
---|
[30bb07] | 213 | //--------------- replace ordering different from dp by dp ------------------- |
---|
| 214 | o = "dp("+string(n)+")"; |
---|
| 215 | if( ! find(ordstr(BAS),o) or find(ordstr(BAS),"a") ) |
---|
[b21c4a] | 216 | { |
---|
[30bb07] | 217 | ringchange = 1; //remember change of ring |
---|
[b21c4a] | 218 | intvec V; |
---|
[faed79] | 219 | V[n]=0; V=V+1; //weights for dp ordering |
---|
| 220 | gnirlist[3] = list("dp",V), g32; |
---|
| 221 | def newBAS = ring(gnirlist); //change of ring to dp ordering |
---|
| 222 | setring newBAS; |
---|
[28d306] | 223 | ideal rest = imap(BAS,rest); |
---|
| 224 | attrib(rest,"isSB",1); |
---|
[faed79] | 225 | ideal i = imap(BAS,i); |
---|
| 226 | } |
---|
[b21c4a] | 227 | |
---|
[faed79] | 228 | list Lin = linearpart(i); |
---|
| 229 | ideal lin = std(Lin[1]); //SB of ideal generated by polys of i |
---|
| 230 | //having at most degree 1 |
---|
| 231 | ideal id = Lin[2]; //remaining polys from i, of deg > 1 |
---|
| 232 | id = simplify(NF(id,lin),2); //instead of subst |
---|
| 233 | ideal id1 = linearpart(id)[1]; |
---|
| 234 | while( size(id1) != 0 ) //repeat to find linear parts |
---|
| 235 | { |
---|
| 236 | lin = lin,id1; |
---|
| 237 | lin = std(lin); |
---|
[30bb07] | 238 | id = simplify(NF(id,lin),2); //instead of subst, (### is faster) |
---|
[faed79] | 239 | id1 = linearpart(id)[1]; |
---|
| 240 | } |
---|
| 241 | //------------- check for special case of unit ideal and return --------------- |
---|
| 242 | int check; |
---|
[b21c4a] | 243 | if( lin[1] == 1 ) |
---|
| 244 | { |
---|
| 245 | check = 1; |
---|
[faed79] | 246 | } |
---|
[b21c4a] | 247 | else |
---|
[faed79] | 248 | { |
---|
| 249 | for (ii=1; ii<=size(id); ii++ ) |
---|
| 250 | { |
---|
| 251 | if ( id[ii] == 1 ) |
---|
[b21c4a] | 252 | { |
---|
[faed79] | 253 | check = 1; break; |
---|
| 254 | } |
---|
| 255 | } |
---|
| 256 | } |
---|
[de63d0] | 257 | |
---|
[faed79] | 258 | if (check == 1) //case of a unit ideal |
---|
[de63d0] | 259 | { |
---|
[faed79] | 260 | setring BAS; |
---|
[de63d0] | 261 | list L = ideal(1), ideal(0), ideal(0), maxideal(1), maxideal(1); |
---|
| 262 | option(set,getoption); |
---|
| 263 | return(L); |
---|
| 264 | } |
---|
[c91bb9] | 265 | //----- remove generators from lin containing vars not to be eliminated ------ |
---|
[faed79] | 266 | if ( n < nvars(BAS) ) |
---|
[c91bb9] | 267 | { |
---|
[82716e] | 268 | for ( ii=1; ii<=size(lin); ii++ ) |
---|
[c91bb9] | 269 | { |
---|
[82716e] | 270 | if ( reduce(lead(lin[ii]),rest) == 0 ) |
---|
| 271 | { |
---|
[c91bb9] | 272 | id=lin[ii],id; |
---|
[82716e] | 273 | lin[ii] = 0; |
---|
[c91bb9] | 274 | } |
---|
| 275 | } |
---|
| 276 | } |
---|
[faed79] | 277 | lin = simplify(lin,1); |
---|
| 278 | ideal eva = lead(lin); //vars to be eliminated |
---|
[82716e] | 279 | attrib(eva,"isSB",1); |
---|
[faed79] | 280 | ideal neva = NF(maxideal(1),eva); //vars not to be eliminated |
---|
[091424] | 281 | //------------------ go back to original ring end return --------------------- |
---|
[faed79] | 282 | |
---|
[30bb07] | 283 | if ( ringchange ) //i.e there was a ring change |
---|
[c91bb9] | 284 | { |
---|
[faed79] | 285 | setring BAS; |
---|
| 286 | ideal id = imap(newBAS,id); |
---|
| 287 | ideal eva = imap(newBAS,eva); |
---|
| 288 | ideal lin = imap(newBAS,lin); |
---|
| 289 | ideal neva = imap(newBAS,neva); |
---|
[c91bb9] | 290 | } |
---|
[b9b906] | 291 | |
---|
[c91bb9] | 292 | eva = eva[ncols(eva)..1]; // sorting according to variables in basering |
---|
| 293 | lin = lin[ncols(lin)..1]; |
---|
[faed79] | 294 | ideal phi = neva; |
---|
[c91bb9] | 295 | k = 1; |
---|
| 296 | for( ii=1; ii<=n; ii++ ) |
---|
| 297 | { |
---|
| 298 | if( neva[ii] == 0 ) |
---|
[82716e] | 299 | { |
---|
[c91bb9] | 300 | phi[ii] = eva[k]-lin[k]; |
---|
| 301 | k=k+1; |
---|
| 302 | } |
---|
| 303 | } |
---|
[faed79] | 304 | |
---|
[c91bb9] | 305 | list L = id, eva, lin, neva, phi; |
---|
| 306 | option(set,getoption); |
---|
| 307 | return(L); |
---|
| 308 | } |
---|
[82716e] | 309 | example |
---|
[c91bb9] | 310 | { "EXAMPLE:"; echo = 2; |
---|
[faed79] | 311 | ring s=0,(u,x,y,z),dp; |
---|
| 312 | ideal i = u3+y3+z-x,x2y2+z3,y+z+1,y+u; |
---|
| 313 | elimlinearpart(i); |
---|
[c91bb9] | 314 | } |
---|
| 315 | /////////////////////////////////////////////////////////////////////////////// |
---|
| 316 | proc elimpart (ideal i,list #) |
---|
[9173792] | 317 | "USAGE: elimpart(i [,n,e] ); i=ideal, n,e=integers |
---|
| 318 | n : only the first n vars are considered for substitution,@* |
---|
| 319 | e =0: substitute from linear part of i (same as elimlinearpart)@* |
---|
| 320 | e!=0: eliminate also by direct substitution@* |
---|
[c91bb9] | 321 | (default: n = nvars(basering), e = 1) |
---|
[9173792] | 322 | RETURN: list of 5 objects: |
---|
| 323 | @format |
---|
| 324 | [1]: ideal obtained by substituting from the first n variables those |
---|
| 325 | from i, which appear in the linear part of i (or, if e!=0, which |
---|
| 326 | can be expressed directly in the remaining vars) |
---|
| 327 | [2]: ideal, variables which have been substituted |
---|
| 328 | [3]: ideal, i-th element defines substitution of i-th var in [2] |
---|
| 329 | [4]: ideal of variables of basering, substituted ones are set to 0 |
---|
| 330 | [5]: ideal, describing the map from the basering, say k[x(1..m)], to |
---|
[dd73043] | 331 | itself onto k[..variables from [4]..] and [1] is the image of i |
---|
[9173792] | 332 | @end format |
---|
| 333 | The ideal i is generated by [1] and [3] in k[x(1..m)], the map [5] |
---|
| 334 | maps [3] to 0, hence induces an isomorphism |
---|
| 335 | @format |
---|
[dd73043] | 336 | k[x(1..m)]/i -> k[..variables from [4]..]/[1] |
---|
[9173792] | 337 | @end format |
---|
[0bc582c] | 338 | NOTE: Applying elimpart to interred(i) may result in more substitutions. |
---|
[faed79] | 339 | However, interred may be more expansive than elimpart for big ideals |
---|
[c91bb9] | 340 | EXAMPLE: example elimpart; shows an example |
---|
[d2b2a7] | 341 | " |
---|
[c91bb9] | 342 | { |
---|
[faed79] | 343 | def BAS = basering; |
---|
| 344 | int n,e = nvars(BAS),1; |
---|
[c91bb9] | 345 | if ( size(#)==1 ) { n=#[1]; } |
---|
| 346 | if ( size(#)==2 ) { n=#[1]; e=#[2];} |
---|
[091424] | 347 | //----------- interreduce linear part with proc elimlinearpart ---------------- |
---|
[faed79] | 348 | // lin = ideal i after interreduction with linear part |
---|
[c91bb9] | 349 | // eva = eliminated (substituted) variables |
---|
| 350 | // sub = polynomials defining substitution |
---|
| 351 | // neva= not eliminated variables |
---|
| 352 | // phi = map describing substitution |
---|
[faed79] | 353 | |
---|
[c91bb9] | 354 | list L = elimlinearpart(i,n); |
---|
[30bb07] | 355 | ideal lin, eva, sub, neva, phi = L[1], L[2], L[3], L[4], L[5]; |
---|
[faed79] | 356 | if ( e == 0 ) |
---|
| 357 | { |
---|
| 358 | return(L); |
---|
| 359 | } |
---|
[30bb07] | 360 | |
---|
[091424] | 361 | //-------- direct substitution of variables if possible and if e!=0 ----------- |
---|
[3754ca] | 362 | // first find terms lin1 in lin of pure degree 1 in each polynomial of lin |
---|
[faed79] | 363 | // k1 = pure degree 1 part, i.e. nonzero elts of lin1, renumbered |
---|
| 364 | // k2 = lin2 (=matrix(lin) - matrix(lin2)), renumbered |
---|
| 365 | // kin = matrix(k1)+matrix(k2) = those polys of lin which contained a pure |
---|
[82716e] | 366 | // degree 1 part. |
---|
[faed79] | 367 | /* |
---|
| 368 | Alte Version mit interred: |
---|
[b21c4a] | 369 | // Then go to ring newBAS with ordering c,dp(n) and create a matrix with |
---|
| 370 | // size(k1) colums and 2 rows, such that if [f1,f2] is a column of M then f1+f2 |
---|
| 371 | // is one of the polys of lin containing a pure degree 1 part and f1 is this |
---|
| 372 | // part interreduce this matrix (i.e. Gauss elimination on linear part, with |
---|
[faed79] | 373 | // rest transformed accordingly). |
---|
| 374 | //Ist jetzt durch direkte Substitution gemacht (schneller!) |
---|
| 375 | //Variante falls wieder interred angewendet werden soll: |
---|
| 376 | //ideal k12 = k1,k2; |
---|
| 377 | //matrix M = matrix(k12,2,kk); //degree 1 part is now in row 1 |
---|
[b21c4a] | 378 | //M = interred(M); |
---|
| 379 | //### interred zu teuer, muss nicht sein. Wenn interred angewendet |
---|
[faed79] | 380 | //werden soll, vorher in Ring mit Ordnung (c,dp) wechseln! |
---|
| 381 | //Abfrage: if( ordstr(BAS) != "c,dp("+string(n)+")" ) |
---|
| 382 | //auf KEINEN Fall std (wird zu gross) |
---|
| 383 | //l = ncols(M); |
---|
| 384 | //k1 = M[1,1..l]; |
---|
| 385 | //k2 = M[2,1..l]; |
---|
| 386 | Interred ist jetzt ganz weggelassen. Aber es gibt Beispiele wo interred polys |
---|
| 387 | mit Grad 1 Teilen produziert, die vorher nicht da waren (aus polys, die einen konstanten Term haben). |
---|
| 388 | z.B. i=xy2-xu4-x+y2,x2y2+z3+zy,y+z2+1,y+u2;, interred(i)=z2+y+1,y2-x,u2+y,x3-z |
---|
| 389 | -z ergibt ich auch i[2]-z*i[3] mit option(redThrough) |
---|
| 390 | statt interred kann man hier auch NF(i,i[3])+i[3] verwenden |
---|
[30bb07] | 391 | hier lifert elimpart(i) 2 Substitutionen (x,y) elimpart(interred(i)) |
---|
[faed79] | 392 | aber 3 (x,y,z) |
---|
| 393 | Da interred oder NF aber die Laenge der polys vergroessern kann, nicht gemacht |
---|
| 394 | */ |
---|
[9c35ef] | 395 | int ii, kk; |
---|
[faed79] | 396 | ideal k1, k2, lin2; |
---|
[b21c4a] | 397 | int l = ncols(lin); // lin=i after applying elimlinearpart |
---|
[867e1a3] | 398 | ideal lin1 = ideal(matrix(jet(lin,1))-matrix(jet(lin,0))); // part of pure degree 1 |
---|
[faed79] | 399 | //Note: If i,i1,i2 are ideals, then i = i1 - i2 is equivalent to |
---|
| 400 | //i = ideal(matrix(i1) - matrix(i2)) |
---|
| 401 | |
---|
| 402 | if (size(lin1) == 0 ) |
---|
[c91bb9] | 403 | { |
---|
[faed79] | 404 | return(L); |
---|
| 405 | } |
---|
[c91bb9] | 406 | |
---|
[faed79] | 407 | //-------- check candidates for direct substitution of variables ---------- |
---|
| 408 | //since lin1 != 0 there are candidates for substituting variables |
---|
| 409 | |
---|
[867e1a3] | 410 | lin2 = matrix(lin) - matrix(lin1); //difference as matrix |
---|
[faed79] | 411 | // rest of lin, part of pure degree 1 substracted from each generator of lin |
---|
[c91bb9] | 412 | |
---|
[faed79] | 413 | for( ii=1; ii<=l; ii++ ) |
---|
| 414 | { |
---|
| 415 | if( lin1[ii] != 0 ) |
---|
[c91bb9] | 416 | { |
---|
[faed79] | 417 | kk = kk+1; |
---|
| 418 | k1[kk] = lin1[ii]; // part of pure degree 1, renumbered |
---|
| 419 | k2[kk] = lin2[ii]; // rest of those polys which had a degree 1 part |
---|
| 420 | lin2[ii] = 0; |
---|
| 421 | } |
---|
| 422 | } |
---|
[b21c4a] | 423 | //Now each !=0 generator of lin2 contains only constant terms or terms of |
---|
[faed79] | 424 | //degree >= 2, hence lin 2 can never be used for further substitutions |
---|
| 425 | //We have: lin = ideal(matrix(k1)+matrix(k2)), lin2 |
---|
| 426 | |
---|
[b21c4a] | 427 | ideal kin = matrix(k1)+matrix(k2); |
---|
[faed79] | 428 | //kin = polys of lin which contained a pure degree 1 part. |
---|
| 429 | kin = simplify(kin,2); |
---|
[30bb07] | 430 | l = size(kin); //l != 0 since lin1 != 0 |
---|
[faed79] | 431 | poly p,kip,vip, cand; |
---|
| 432 | int count=1; |
---|
| 433 | while ( count != 0 ) |
---|
[b21c4a] | 434 | { |
---|
[faed79] | 435 | count = 0; |
---|
| 436 | for ( ii=1; ii<=n; ii++ ) //start direct substitution of var(ii) |
---|
[82716e] | 437 | { |
---|
[c91bb9] | 438 | for (kk=1; kk<=l; kk++ ) |
---|
| 439 | { |
---|
[82716e] | 440 | p = kin[kk]/var(ii); |
---|
[30bb07] | 441 | //if ( deg(p) == 0 ) |
---|
| 442 | //old test, does not work if some var has deg 0 |
---|
| 443 | //geaendert Mai 09 gmg |
---|
| 444 | |
---|
| 445 | if( p!=0 & p == jet(p,0) ) |
---|
| 446 | //this means that kin[kk]= p*var(ii) + h, |
---|
| 447 | //with p=const !=0 and h not depending on var(ii) |
---|
[c91bb9] | 448 | { |
---|
[faed79] | 449 | //we look for the shortest candidate to substitute var(ii) |
---|
[b21c4a] | 450 | if ( cand == 0 ) |
---|
| 451 | { |
---|
[faed79] | 452 | cand = kin[kk]; //candidate for substituting var(ii) |
---|
[b21c4a] | 453 | } |
---|
[faed79] | 454 | else |
---|
| 455 | { |
---|
[b21c4a] | 456 | if ( size(kin[kk]) < size(cand) ) |
---|
| 457 | { |
---|
| 458 | cand = kin[kk]; |
---|
[faed79] | 459 | } |
---|
| 460 | } |
---|
| 461 | } |
---|
[30bb07] | 462 | } |
---|
[faed79] | 463 | if ( cand != 0 ) |
---|
| 464 | { |
---|
| 465 | p = cand/var(ii); |
---|
[30bb07] | 466 | kip = cand/p; //normalized polynomial of kin w.r.t var(ii) |
---|
[faed79] | 467 | eva = eva+var(ii); //var(ii) added to list of elimin. vars |
---|
[c91bb9] | 468 | neva[ii] = 0; |
---|
[3754ca] | 469 | sub = sub+kip; //polynomial defining substituion |
---|
[0610f0e] | 470 | //## gmg: geaendert 08/2008, map durch subst ersetzt |
---|
[faed79] | 471 | //(viel schneller) |
---|
[3754ca] | 472 | vip = var(ii) - kip; //polynomial to be substituted |
---|
[faed79] | 473 | lin = subst(lin, var(ii), vip); //subst in rest |
---|
| 474 | lin = simplify(lin,2); |
---|
| 475 | kin = subst(kin, var(ii), vip); //subst in pure dgree 1 part |
---|
| 476 | kin = simplify(kin,2); |
---|
[c91bb9] | 477 | l = size(kin); |
---|
[faed79] | 478 | count = 1; |
---|
[c91bb9] | 479 | } |
---|
[faed79] | 480 | cand=0; |
---|
[c91bb9] | 481 | } |
---|
| 482 | } |
---|
[b21c4a] | 483 | |
---|
[faed79] | 484 | lin = kin+lin; |
---|
[b21c4a] | 485 | |
---|
[c91bb9] | 486 | for( ii=1; ii<=size(lin); ii++ ) |
---|
| 487 | { |
---|
| 488 | lin[ii] = cleardenom(lin[ii]); |
---|
| 489 | } |
---|
[faed79] | 490 | |
---|
[b21c4a] | 491 | for( ii=1; ii<=n; ii++ ) |
---|
[c91bb9] | 492 | { |
---|
| 493 | for( kk=1; kk<=size(eva); kk++ ) |
---|
| 494 | { |
---|
| 495 | if (phi[ii] == eva[kk] ) |
---|
| 496 | { phi[ii] = eva[kk]-sub[kk]; break; } |
---|
| 497 | } |
---|
| 498 | } |
---|
[faed79] | 499 | map psi = BAS,phi; |
---|
| 500 | ideal phi1 = maxideal(1); |
---|
| 501 | for(ii=1; ii<=size(eva); ii++) |
---|
| 502 | { |
---|
| 503 | phi1=psi(phi1); |
---|
| 504 | } |
---|
[35ceb0] | 505 | L = lin, eva, sub, neva, phi1; |
---|
[faed79] | 506 | return(L); |
---|
[c91bb9] | 507 | } |
---|
[82716e] | 508 | example |
---|
[c91bb9] | 509 | { "EXAMPLE:"; echo = 2; |
---|
[faed79] | 510 | ring s=0,(u,x,y,z),dp; |
---|
| 511 | ideal i = xy2-xu4-x+y2,x2y2+z3+zy,y+z2+1,y+u2; |
---|
| 512 | elimpart(i); |
---|
| 513 | |
---|
| 514 | i = interred(i); i; |
---|
| 515 | elimpart(i); |
---|
| 516 | |
---|
| 517 | elimpart(i,2); |
---|
[c91bb9] | 518 | } |
---|
| 519 | |
---|
| 520 | /////////////////////////////////////////////////////////////////////////////// |
---|
| 521 | |
---|
| 522 | proc elimpartanyr (ideal i, list #) |
---|
[9173792] | 523 | "USAGE: elimpartanyr(i [,p,e] ); i=ideal, p=polynomial, e=integer@* |
---|
| 524 | p: product of vars to be eliminated,@* |
---|
| 525 | e =0: substitute from linear part of i (same as elimlinearpart)@* |
---|
| 526 | e!=0: eliminate also by direct substitution@* |
---|
| 527 | (default: p=product of all vars, e=1) |
---|
| 528 | RETURN: list of 6 objects: |
---|
| 529 | @format |
---|
| 530 | [1]: (interreduced) ideal obtained by substituting from i those vars |
---|
| 531 | appearing in p, which occur in the linear part of i (or which can |
---|
| 532 | be expressed directly in the remaining variables, if e!=0) |
---|
| 533 | [2]: ideal, variables which have been substituted |
---|
| 534 | [3]: ideal, i-th element defines substitution of i-th var in [2] |
---|
| 535 | [4]: ideal of variables of basering, substituted ones are set to 0 |
---|
| 536 | [5]: ideal, describing the map from the basering, say k[x(1..m)], to |
---|
| 537 | itself onto k[..variables fom [4]..] and [1] is the image of i |
---|
| 538 | [6]: int, # of vars considered for substitution (= # of factors of p) |
---|
| 539 | @end format |
---|
| 540 | The ideal i is generated by [1] and [3] in k[x(1..m)], the map [5] |
---|
| 541 | maps [3] to 0, hence induces an isomorphism |
---|
| 542 | @format |
---|
| 543 | k[x(1..m)]/i -> k[..variables fom [4]..]/[1] |
---|
| 544 | @end format |
---|
[dd73043] | 545 | NOTE: the procedure uses @code{execute} to create a ring with ordering dp |
---|
| 546 | and vars placed correctly and then applies @code{elimpart}. |
---|
[c91bb9] | 547 | EXAMPLE: example elimpartanyr; shows an example |
---|
[d2b2a7] | 548 | " |
---|
[c91bb9] | 549 | { |
---|
| 550 | def P = basering; |
---|
[82716e] | 551 | int j,n,e = 0,0,1; |
---|
[c91bb9] | 552 | poly p = product(maxideal(1)); |
---|
| 553 | if ( size(#)==1 ) { p=#[1]; } |
---|
| 554 | if ( size(#)==2 ) { p=#[1]; e=#[2]; } |
---|
| 555 | string a,b; |
---|
[82716e] | 556 | for ( j=1; j<=nvars(P); j++ ) |
---|
| 557 | { |
---|
[c91bb9] | 558 | if (deg(p/var(j))>=0) { a = a+varstr(j)+","; n = n+1; } |
---|
| 559 | else { b = b+varstr(j)+","; } |
---|
| 560 | } |
---|
| 561 | if ( size(b) != 0 ) { b = b[1,size(b)-1]; } |
---|
| 562 | else { a = a[1,size(a)-1]; } |
---|
[38c165] | 563 | execute("ring gnir ="+charstr(P)+",("+a+b+"),dp;"); |
---|
[c91bb9] | 564 | ideal i = imap(P,i); |
---|
[82716e] | 565 | list L = elimpart(i,n,e)+list(n); |
---|
[c91bb9] | 566 | setring P; |
---|
| 567 | list L = imap(gnir,L); |
---|
| 568 | return(L); |
---|
| 569 | } |
---|
[82716e] | 570 | example |
---|
[c91bb9] | 571 | { "EXAMPLE:"; echo = 2; |
---|
[9173792] | 572 | ring s=0,(x,y,z),dp; |
---|
| 573 | ideal i = x3+y2+z,x2y2+z3,y+z+1; |
---|
| 574 | elimpartanyr(i,z); |
---|
[c91bb9] | 575 | } |
---|
| 576 | /////////////////////////////////////////////////////////////////////////////// |
---|
[82716e] | 577 | |
---|
[c91bb9] | 578 | proc fastelim (ideal i, poly p, list #) |
---|
[0bc582c] | 579 | "USAGE: fastelim(i,p[h,o,a,b,e,m]); i=ideal, p=polynomial; h,o,a,b,e=integers@* |
---|
[9173792] | 580 | p: product of variables to be eliminated;@* |
---|
| 581 | Optional parameters: |
---|
| 582 | @format |
---|
| 583 | - h !=0: use Hilbert-series driven std-basis computation |
---|
| 584 | - o !=0: use proc @code{valvars} for a - hopefully - optimal ordering of vars |
---|
| 585 | - a !=0: order vars to be eliminated w.r.t. increasing complexity |
---|
| 586 | - b !=0: order vars not to be eliminated w.r.t. increasing complexity |
---|
| 587 | - e !=0: use @code{elimpart} first to eliminate easy part |
---|
| 588 | - m !=0: compute a minimal system of generators |
---|
| 589 | @end format |
---|
| 590 | (default: h,o,a,b,e,m = 0,1,0,0,0,0) |
---|
| 591 | RETURN: ideal obtained from i by eliminating those variables, which occur in p |
---|
[c91bb9] | 592 | EXAMPLE: example fastelim; shows an example. |
---|
[d2b2a7] | 593 | " |
---|
[c91bb9] | 594 | { |
---|
| 595 | def P = basering; |
---|
| 596 | int h,o,a,b,e,m = 0,1,0,0,0,0; |
---|
| 597 | if ( size(#) == 1 ) { h=#[1]; } |
---|
| 598 | if ( size(#) == 2 ) { h=#[1]; o=#[2]; } |
---|
| 599 | if ( size(#) == 3 ) { h=#[1]; o=#[2]; a=#[3]; } |
---|
| 600 | if ( size(#) == 4 ) { h=#[1]; o=#[2]; a=#[3]; b=#[4];} |
---|
| 601 | if ( size(#) == 5 ) { h=#[1]; o=#[2]; a=#[3]; b=#[4]; e=#[5]; } |
---|
| 602 | if ( size(#) == 6 ) { h=#[1]; o=#[2]; a=#[3]; b=#[4]; e=#[5]; m=#[6]; } |
---|
[82716e] | 603 | list L = elimpartanyr(i,p,e); |
---|
[c91bb9] | 604 | poly q = product(L[2]); //product of vars which are already eliminated |
---|
| 605 | if ( q==0 ) { q=1; } |
---|
| 606 | p = p/q; //product of vars which must still be eliminated |
---|
[9c35ef] | 607 | int nu = size(L[5])-size(L[2]); //number of vars which must still be eliminated |
---|
[c91bb9] | 608 | if ( p==1 ) //ready if no vars are left |
---|
| 609 | { //compute minbase if 3-rd argument !=0 |
---|
[82716e] | 610 | if ( m != 0 ) { L[1]=minbase(L[1]); } |
---|
[c91bb9] | 611 | return(L); |
---|
| 612 | } |
---|
| 613 | //---------------- create new ring with remaining variables ------------------- |
---|
| 614 | string newvar = string(L[4]); |
---|
| 615 | L = L[1],p; |
---|
[38c165] | 616 | execute("ring r1=("+charstr(P)+"),("+newvar+"),"+"dp;"); |
---|
[c91bb9] | 617 | list L = imap(P,L); |
---|
| 618 | //------------------- find "best" ordering of variables ---------------------- |
---|
| 619 | newvar = string(maxideal(1)); |
---|
| 620 | if ( o != 0 ) |
---|
| 621 | { |
---|
| 622 | list ordevar = valvars(L[1],a,L[2],b); |
---|
| 623 | intvec v = ordevar[1]; |
---|
| 624 | newvar=string(sort(maxideal(1),v)[1]); |
---|
| 625 | //------------ create new ring with "best" ordering of variables -------------- |
---|
[daa83b] | 626 | def r0=changevar(newvar); |
---|
| 627 | setring r0; |
---|
[c91bb9] | 628 | list L = imap(r1,L); |
---|
| 629 | kill r1; |
---|
| 630 | def r1 = r0; |
---|
| 631 | kill r0; |
---|
| 632 | } |
---|
| 633 | //----------------- h==0: eliminate remaining vars directly ------------------- |
---|
[82716e] | 634 | if ( h == 0 ) |
---|
[c91bb9] | 635 | { |
---|
| 636 | L[1] = eliminate(L[1],L[2]); |
---|
| 637 | def r2 = r1; |
---|
[82716e] | 638 | } |
---|
| 639 | else |
---|
[6ed15c] | 640 | //------- h!=0: homogenize and compute Hilbert series using hilbvec ---------- |
---|
[82716e] | 641 | { |
---|
[6ed15c] | 642 | intvec hi = hilbvec(L[1]); // Hilbert series of i |
---|
[38c165] | 643 | execute("ring r2=("+charstr(P)+"),("+varstr(basering)+",@homo),dp;"); |
---|
[c91bb9] | 644 | list L = imap(r1,L); |
---|
| 645 | L[1] = homog(L[1],@homo); // @homo = homogenizing var |
---|
| 646 | //---- use Hilbert-series to eliminate variables with Hilbert-driven std ----- |
---|
| 647 | L[1] = eliminate(L[1],L[2],hi); |
---|
| 648 | L[1]=subst(L[1],@homo,1); // dehomogenize by setting @homo=1 |
---|
[82716e] | 649 | } |
---|
[c91bb9] | 650 | if ( m != 0 ) // compute minbase |
---|
[82716e] | 651 | { |
---|
| 652 | if ( #[1] != 0 ) { L[1] = minbase(L[1]); } |
---|
[c91bb9] | 653 | } |
---|
| 654 | def id = L[1]; |
---|
| 655 | setring P; |
---|
| 656 | return(imap(r2,id)); |
---|
| 657 | } |
---|
[82716e] | 658 | example |
---|
[c91bb9] | 659 | { "EXAMPLE:"; echo = 2; |
---|
| 660 | ring s=31991,(e,f,x,y,z,t,u,v,w,a,b,c,d),dp; |
---|
| 661 | ideal i = w2+f2-1, x2+t2+a2-1, y2+u2+b2-1, z2+v2+c2-1, |
---|
[82716e] | 662 | d2+e2-1, f4+2u, wa+tf, xy+tu+ab; |
---|
[9173792] | 663 | fastelim(i,xytua,1,1); //with hilb,valvars |
---|
| 664 | fastelim(i,xytua,1,0,1); //with hilb,minbase |
---|
[c91bb9] | 665 | } |
---|
| 666 | /////////////////////////////////////////////////////////////////////////////// |
---|
| 667 | |
---|
[6ed15c] | 668 | proc faststd (@id, list #) |
---|
| 669 | "USAGE: faststd(id [,\"hilb\",\"sort\",\"dec\",o,\"blocks\"]); |
---|
| 670 | id=ideal/module, o=string (allowed:\"lp\",\"dp\",\"Dp\",\"ls\", |
---|
[3c4dcc] | 671 | \"ds\",\"Ds\"), \"hilb\",\"sort\",\"dec\",\"block\" options for |
---|
[6ed15c] | 672 | Hilbert-driven std, and the procedure sortandmap |
---|
| 673 | RETURN: a ring R, in which an ideal STD_id is stored: @* |
---|
[3c4dcc] | 674 | - the ring R differs from the active basering only in the choice |
---|
[6ed15c] | 675 | of monomial ordering and in the sorting of the variables. |
---|
[3c4dcc] | 676 | - STD_id is a standard basis for the image (under imap) of the input |
---|
[6ed15c] | 677 | ideal/module id with respect to the new monomial ordering. @* |
---|
| 678 | NOTE: Using the optional input parameters, we may modify the computations |
---|
| 679 | performed: @* |
---|
| 680 | - \"hilb\" : use Hilbert-driven standard basis computation@* |
---|
| 681 | - \"sort\" : use 'sortandmap' for a best sorting of the variables@* |
---|
| 682 | - \"dec\" : order vars w.r.t. decreasing complexity (with \"sort\")@* |
---|
| 683 | - \"block\" : create block ordering, each block having ordstr=o, s.t. |
---|
| 684 | vars of same complexity are in one block (with \"sort\")@* |
---|
| 685 | - o : defines the basic ordering of the resulting ring@* |
---|
| 686 | [default: o=ordering of 1st block of basering (if allowed, else o=\"dp\"], |
---|
| 687 | \"sort\", if none of the optional parameters is given @* |
---|
[dd73043] | 688 | This procedure is only useful for hard problems where other methods fail.@* |
---|
[6ed15c] | 689 | \"hilb\" is useful for hard orderings (as \"lp\") or for characteristic 0,@* |
---|
| 690 | it is correct for \"lp\",\"dp\",\"Dp\" (and for block orderings combining |
---|
| 691 | these) but not for s-orderings or if the vars have different weights.@* |
---|
[dd73043] | 692 | There seem to be only few cases in which \"dec\" is fast. |
---|
| 693 | SEE ALSO: groebner |
---|
[c91bb9] | 694 | EXAMPLE: example faststd; shows an example. |
---|
[d2b2a7] | 695 | " |
---|
[c91bb9] | 696 | { |
---|
| 697 | def @P = basering; |
---|
| 698 | int @h,@s,@n,@m,@ii = 0,0,0,0,0; |
---|
| 699 | string @o,@va,@c = ordstr(basering),"",""; |
---|
| 700 | //-------------------- prepare ordering and set options ----------------------- |
---|
[82716e] | 701 | if ( @o[1]=="c" or @o[1]=="C") |
---|
[c91bb9] | 702 | { @o = @o[3,2]; } |
---|
[82716e] | 703 | else |
---|
[c91bb9] | 704 | { @o = @o[1,2]; } |
---|
[82716e] | 705 | if( @o[1]!="d" and @o[1]!="D" and @o[1]!="l") |
---|
[c91bb9] | 706 | { @o="dp"; } |
---|
| 707 | |
---|
[82716e] | 708 | if (size(#) == 0 ) |
---|
[c91bb9] | 709 | { @s = 1; } |
---|
| 710 | for ( @ii=1; @ii<=size(#); @ii++ ) |
---|
| 711 | { |
---|
[82716e] | 712 | if ( typeof(#[@ii]) != "string" ) |
---|
| 713 | { |
---|
| 714 | "// wrong syntax! type: help faststd"; |
---|
[c91bb9] | 715 | return(); |
---|
| 716 | } |
---|
| 717 | else |
---|
| 718 | { |
---|
| 719 | if ( #[@ii] == "hilb" ) { @h = 1; } |
---|
| 720 | if ( #[@ii] == "dec" ) { @n = 1; } |
---|
| 721 | if ( #[@ii] == "block" ) { @m = 1; } |
---|
| 722 | if ( #[@ii] == "sort" ) { @s = 1; } |
---|
| 723 | if ( #[@ii]=="lp" or #[@ii]=="dp" or #[@ii]=="Dp" or #[@ii]=="ls" |
---|
| 724 | or #[@ii]=="ds" or #[@ii]=="Ds" ) { @o = #[@ii]; } |
---|
| 725 | } |
---|
| 726 | } |
---|
[6ed15c] | 727 | if( voice==2 ) { "// chosen options, hilb sort dec block:",@h,@s,@n,@m; } |
---|
[c91bb9] | 728 | |
---|
| 729 | //-------------------- nosort: create ring with new name ---------------------- |
---|
[82716e] | 730 | if ( @s==0 ) |
---|
| 731 | { |
---|
[6ed15c] | 732 | execute("ring @S1 =("+charstr(@P)+"),("+varstr(@P)+"),("+@o+");"); |
---|
| 733 | def STD_id = imap(@P,@id); |
---|
| 734 | if ( @h==0 ) { STD_id = std(STD_id); } |
---|
[c91bb9] | 735 | } |
---|
[6ed15c] | 736 | |
---|
[c91bb9] | 737 | //---------------------- no hilb: compute SB directly ------------------------- |
---|
| 738 | if ( @s != 0 and @h == 0 ) |
---|
| 739 | { |
---|
[6ed15c] | 740 | intvec getoption = option(get); |
---|
| 741 | option(redSB); |
---|
| 742 | @id = interred(sort(@id)[1]); |
---|
| 743 | poly @p = product(maxideal(1),1..nvars(@P)); |
---|
| 744 | def @S1=sortandmap(@id,@n,@p,0,@o,@m); |
---|
| 745 | setring @S1; |
---|
| 746 | option(set,getoption); |
---|
| 747 | def STD_id=imap(@S1,IMAG); |
---|
| 748 | STD_id = std(STD_id); |
---|
[c91bb9] | 749 | } |
---|
| 750 | //------- hilb: homogenize and compute Hilbert-series using hilbvec ----------- |
---|
| 751 | // this uses another standardbasis computation |
---|
[82716e] | 752 | if ( @h != 0 ) |
---|
| 753 | { |
---|
[3c4dcc] | 754 | execute("ring @Q=("+charstr(@P)+"),("+varstr(@P)+",@homo),("+@o+");"); |
---|
[c91bb9] | 755 | def @id = imap(@P,@id); |
---|
| 756 | @id = homog(@id,@homo); // @homo = homogenizing var |
---|
[82716e] | 757 | if ( @s != 0 ) |
---|
[c91bb9] | 758 | { |
---|
[6ed15c] | 759 | intvec getoption = option(get); |
---|
| 760 | option(redSB); |
---|
| 761 | @id = interred(sort(@id)[1]); |
---|
| 762 | poly @p = product(maxideal(1),1..(nvars(@Q)-1)); |
---|
| 763 | def @S1=sortandmap(@id,@n,@p,0,@o,@m); |
---|
| 764 | setring @S1; |
---|
| 765 | option(set,getoption); |
---|
| 766 | kill @Q; |
---|
| 767 | def @Q= basering; |
---|
| 768 | def @id = IMAG; |
---|
[c91bb9] | 769 | } |
---|
[82716e] | 770 | intvec @hi; // encoding of Hilbert-series of i |
---|
| 771 | @hi = hilbvec(@id); |
---|
[c91bb9] | 772 | //if ( @s!=0 ) { @hi = hilbvec(@id,"32003",ordstr(@Q)); } |
---|
[82716e] | 773 | //else { @hi = hilbvec(@id); } |
---|
[c91bb9] | 774 | //-------------------------- use Hilbert-driven std -------------------------- |
---|
| 775 | @id = std(@id,@hi); |
---|
| 776 | @id = subst(@id,@homo,1); // dehomogenize by setting @homo=1 |
---|
| 777 | @va = varstr(@Q)[1,size(varstr(@Q))-6]; |
---|
| 778 | if ( @s!=0 ) |
---|
| 779 | { |
---|
| 780 | @o = ordstr(@Q); |
---|
| 781 | if ( @o[1]=="c" or @o[1]=="C") { @o = @o[1,size(@o)-6]; } |
---|
| 782 | else { @o = @o[1,size(@o)-8] + @o[size(@o)-1,2]; } |
---|
| 783 | } |
---|
[3c4dcc] | 784 | kill @S1; |
---|
[6ed15c] | 785 | execute("ring @S1=("+charstr(@Q)+"),("+@va+"),("+@o+");"); |
---|
| 786 | def STD_id = imap(@Q,@id); |
---|
[82716e] | 787 | } |
---|
[6ed15c] | 788 | attrib(STD_id,"isSB",1); |
---|
| 789 | export STD_id; |
---|
[3c4dcc] | 790 | if (defined(IMAG)) { kill IMAG; } |
---|
[6ed15c] | 791 | setring @P; |
---|
| 792 | dbprint(printlevel-voice+3," |
---|
[3c4dcc] | 793 | // 'faststd' created a ring, in which an object STD_id is stored. |
---|
[6ed15c] | 794 | // To access the object, type (if the name R was assigned to the return value): |
---|
| 795 | setring R; STD_id; "); |
---|
| 796 | return(@S1); |
---|
[c91bb9] | 797 | } |
---|
[82716e] | 798 | example |
---|
[c91bb9] | 799 | { "EXAMPLE:"; echo = 2; |
---|
[9d06efc] | 800 | system("--ticks-per-sec",100); // show time in 1/100 sec |
---|
[c91bb9] | 801 | ring s = 0,(e,f,x,y,z,t,u,v,w,a,b,c,d),(c,lp); |
---|
| 802 | ideal i = w2+f2-1, x2+t2+a2-1, y2+u2+b2-1, z2+v2+c2-1, |
---|
| 803 | d2+e2-1, f4+2u, wa+tf, xy+tu+ab; |
---|
[6ed15c] | 804 | option(prot); timer=1; |
---|
[82716e] | 805 | int time = timer; |
---|
| 806 | ideal j=std(i); |
---|
[c91bb9] | 807 | timer-time; |
---|
[6ed15c] | 808 | dim(j),mult(j); |
---|
| 809 | |
---|
| 810 | time = timer; |
---|
| 811 | def R=faststd(i); // use "best" ordering of vars |
---|
[c91bb9] | 812 | timer-time; |
---|
[6ed15c] | 813 | show(R);setring R;dim(STD_id),mult(STD_id); |
---|
| 814 | |
---|
| 815 | setring s;kill R;time = timer; |
---|
| 816 | def R=faststd(i,"hilb"); // hilb-std only |
---|
[c91bb9] | 817 | timer-time; |
---|
[6ed15c] | 818 | show(R);setring R;dim(STD_id),mult(STD_id); |
---|
| 819 | |
---|
| 820 | setring s;kill R;time = timer; |
---|
| 821 | def R=faststd(i,"hilb","sort"); // hilb-std,"best" ordering |
---|
[c91bb9] | 822 | timer-time; |
---|
[6ed15c] | 823 | show(R);setring R;dim(STD_id),mult(STD_id); |
---|
| 824 | |
---|
| 825 | setring s;kill R;time = timer; |
---|
| 826 | def R=faststd(i,"hilb","sort","block","dec"); // hilb-std,"best",blocks |
---|
[c91bb9] | 827 | timer-time; |
---|
[6ed15c] | 828 | show(R);setring R;dim(STD_id),mult(STD_id); |
---|
| 829 | |
---|
| 830 | setring s;kill R;time = timer; |
---|
[c91bb9] | 831 | timer-time;time = timer; |
---|
[6ed15c] | 832 | def R=faststd(i,"sort","block","Dp"); //"best",decreasing,Dp-blocks |
---|
[c91bb9] | 833 | timer-time; |
---|
[6ed15c] | 834 | show(R);setring R;dim(STD_id),mult(STD_id); |
---|
[c91bb9] | 835 | } |
---|
| 836 | /////////////////////////////////////////////////////////////////////////////// |
---|
| 837 | |
---|
| 838 | proc findvars(id, list #) |
---|
[9173792] | 839 | "USAGE: findvars(id [,any] ); id=poly/ideal/vector/module/matrix, any=any type |
---|
| 840 | RETURN: if no second argument is present: ideal of variables occuring in id,@* |
---|
| 841 | if a second argument is given (of any type): list L with 4 entries: |
---|
| 842 | @format |
---|
| 843 | L[1]: ideal of variables occuring in id |
---|
| 844 | L[2]: intvec of variables occuring in id |
---|
| 845 | L[3]: ideal of variables not occuring in id |
---|
| 846 | L[4]: intvec of variables not occuring in id |
---|
| 847 | @end format |
---|
[c91bb9] | 848 | EXAMPLE: example findvars; shows an example |
---|
[d2b2a7] | 849 | " |
---|
[c91bb9] | 850 | { |
---|
| 851 | int ii,n; |
---|
| 852 | ideal found, notfound; |
---|
| 853 | intvec f,nf; |
---|
| 854 | n = nvars(basering); |
---|
| 855 | ideal i = simplify(ideal(matrix(id)),10); |
---|
| 856 | matrix M[ncols(i)][1] = i; |
---|
| 857 | vector v = module(M)[1]; |
---|
| 858 | ideal max = maxideal(1); |
---|
| 859 | |
---|
| 860 | for (ii=1; ii<=n; ii++) |
---|
| 861 | { |
---|
| 862 | if ( v != subst(v,var(ii),0) ) |
---|
| 863 | { |
---|
| 864 | found = found+var(ii); |
---|
| 865 | f = f,ii; |
---|
| 866 | } |
---|
| 867 | else |
---|
| 868 | { |
---|
| 869 | notfound = notfound+var(ii); |
---|
| 870 | nf = nf,ii; |
---|
| 871 | } |
---|
| 872 | } |
---|
| 873 | if ( size(f)>1 ) { f = f[2..size(f)]; } //intvec of found vars |
---|
[82716e] | 874 | if ( size(nf)>1 ) { nf = nf[2..size(nf)]; } //intvec of vars not found |
---|
[c91bb9] | 875 | if( size(#)==0 ) { return(found); } |
---|
| 876 | if( size(#)!=0 ) { list L = found,f,notfound,nf; return(L); } |
---|
| 877 | } |
---|
[82716e] | 878 | example |
---|
[c91bb9] | 879 | { "EXAMPLE:"; echo = 2; |
---|
| 880 | ring s = 0,(e,f,x,y,t,u,v,w,a,d),dp; |
---|
[82716e] | 881 | ideal i = w2+f2-1, x2+t2+a2-1; |
---|
[c91bb9] | 882 | findvars(i); |
---|
[82716e] | 883 | findvars(i,1); |
---|
[c91bb9] | 884 | } |
---|
| 885 | /////////////////////////////////////////////////////////////////////////////// |
---|
| 886 | |
---|
| 887 | proc hilbvec (@id, list #) |
---|
[9173792] | 888 | "USAGE: hilbvec(id[,c,o]); id=poly/ideal/vector/module/matrix, c,o=strings,@* |
---|
[0bc582c] | 889 | c=char, o=ordering used by @code{hilb} (default: c=\"32003\", o=\"dp\") |
---|
| 890 | RETURN: intvec of 1st Hilbert-series of id, computed in char c and ordering o |
---|
[9173792] | 891 | NOTE: id must be homogeneous (i.e. all vars have weight 1) |
---|
[c91bb9] | 892 | EXAMPLE: example hilbvec; shows an example |
---|
[d2b2a7] | 893 | " |
---|
[c91bb9] | 894 | { |
---|
| 895 | def @P = basering; |
---|
| 896 | string @c,@o = "32003", "dp"; |
---|
[82716e] | 897 | if ( size(#) == 1 ) { @c = #[1]; } |
---|
[c91bb9] | 898 | if ( size(#) == 2 ) { @c = #[1]; @o = #[2]; } |
---|
| 899 | string @si = typeof(@id)+" @i = "+string(@id)+";"; //** weg |
---|
[38c165] | 900 | execute("ring @r=("+@c+"),("+varstr(basering)+"),("+@o+");"); |
---|
[c91bb9] | 901 | //**def i = imap(P,@id); |
---|
[38c165] | 902 | execute(@si); //** weg |
---|
[c91bb9] | 903 | //show(basering); |
---|
[82716e] | 904 | @i = std(@i); |
---|
[c91bb9] | 905 | intvec @hi = hilb(@i,1); // intvec of 1-st Hilbert-series of id |
---|
| 906 | return(@hi); |
---|
| 907 | } |
---|
[82716e] | 908 | example |
---|
[c91bb9] | 909 | { "EXAMPLE:"; echo = 2; |
---|
| 910 | ring s = 0,(e,f,x,y,z,t,u,v,w,a,b,c,d,H),dp; |
---|
| 911 | ideal id = w2+f2-1, x2+t2+a2-1, y2+u2+b2-1, z2+v2+c2-1, |
---|
[82716e] | 912 | d2+e2-1, f4+2u, wa+tf, xy+tu+ab; |
---|
[c91bb9] | 913 | id = homog(id,H); |
---|
| 914 | hilbvec(id); |
---|
| 915 | } |
---|
| 916 | /////////////////////////////////////////////////////////////////////////////// |
---|
| 917 | |
---|
| 918 | proc tolessvars (id ,list #) |
---|
[9173792] | 919 | "USAGE: tolessvars(id [,s1,s2] ); id poly/ideal/vector/module/matrix, |
---|
[6ed15c] | 920 | s1=string (new ordering)@* |
---|
[3c4dcc] | 921 | [default: s1=\"dp\" or \"ds\" depending on whether the first block |
---|
[dd73043] | 922 | of the old ordering is a p- or an s-ordering, respectively] |
---|
[6ed15c] | 923 | RETURN: If id contains all vars of the basering: empty list. @* |
---|
| 924 | Else: ring R with the same char as the basering, but possibly less |
---|
| 925 | variables (only those variables which actually occur in id). In R |
---|
[3c4dcc] | 926 | an object IMAG (image of id under imap) is stored. |
---|
[dd73043] | 927 | DISPLAY: If printlevel >=0, display ideal of vars, which have been omitted |
---|
[6ed15c] | 928 | from the old ring. |
---|
[c91bb9] | 929 | EXAMPLE: example tolessvars; shows an example |
---|
[d2b2a7] | 930 | " |
---|
[c91bb9] | 931 | { |
---|
| 932 | //---------------- initialisation and check occurence of vars ----------------- |
---|
| 933 | int s,ii,n,fp,fs; |
---|
[6ed15c] | 934 | string s2,newvar; |
---|
[c91bb9] | 935 | int pr = printlevel-voice+3; // p = printlevel+1 (default: p=1) |
---|
| 936 | def P = basering; |
---|
| 937 | s2 = ordstr(P); |
---|
| 938 | |
---|
| 939 | list L = findvars(id,1); |
---|
| 940 | newvar = string(L[1]); // string of new variables |
---|
| 941 | n = size(L[1]); // number of new variables |
---|
[82716e] | 942 | if( n == 0 ) |
---|
[c91bb9] | 943 | { |
---|
| 944 | dbprint( pr,"","// no variable occured in "+typeof(id)+", no change of ring!"); |
---|
| 945 | return(id); |
---|
| 946 | } |
---|
[82716e] | 947 | if( n == nvars(P) ) |
---|
| 948 | { |
---|
[6ed15c] | 949 | dbprint(printlevel-voice+3," |
---|
[3c4dcc] | 950 | // All variables appear in input object. |
---|
| 951 | // empty list returned. "); |
---|
[6ed15c] | 952 | return(list()); |
---|
[c91bb9] | 953 | } |
---|
| 954 | //----------------- prepare new ring, map to it and return -------------------- |
---|
[82716e] | 955 | if ( size(#) == 0 ) |
---|
| 956 | { |
---|
[c91bb9] | 957 | fp = find(s2,"p"); |
---|
| 958 | fs = find(s2,"s"); |
---|
| 959 | if( fs==0 or (fs>=fp && fp!=0) ) { s2="dp"; } |
---|
[82716e] | 960 | else { s2="ds"; } |
---|
[c91bb9] | 961 | } |
---|
[6ed15c] | 962 | if ( size(#) ==1 ) { s2=#[1]; } |
---|
[c91bb9] | 963 | dbprint( pr,"","// variables which did not occur:",L[3] ); |
---|
[6ed15c] | 964 | execute("ring S1=("+charstr(P)+"),("+newvar+"),("+s2+");"); |
---|
| 965 | def IMAG = imap(P,id); |
---|
| 966 | export IMAG; |
---|
| 967 | dbprint(printlevel-voice+3," |
---|
[3c4dcc] | 968 | // 'tolessvars' created a ring, in which an object IMAG is stored. |
---|
[6ed15c] | 969 | // To access the object, type (if the name R was assigned to the return value): |
---|
| 970 | setring R; IMAG; "); |
---|
| 971 | return(S1); |
---|
[c91bb9] | 972 | } |
---|
[82716e] | 973 | example |
---|
[c91bb9] | 974 | { "EXAMPLE:"; echo = 2; |
---|
| 975 | ring r = 0,(x,y,z),dp; |
---|
| 976 | ideal i = y2-x3,x-3,y-2x; |
---|
[6ed15c] | 977 | def R_r = tolessvars(i,"lp"); |
---|
| 978 | setring R_r; |
---|
[c91bb9] | 979 | show(basering); |
---|
[6ed15c] | 980 | IMAG; |
---|
[9173792] | 981 | kill R_r; |
---|
[c91bb9] | 982 | } |
---|
| 983 | /////////////////////////////////////////////////////////////////////////////// |
---|
| 984 | |
---|
| 985 | proc solvelinearpart (id,list #) |
---|
[0bc582c] | 986 | "USAGE: solvelinearpart(id [,n] ); id=ideal/module, n=integer (default: n=0) |
---|
[c91bb9] | 987 | RETURN: (interreduced) generators of id of degree <=1 in reduced triangular |
---|
[9173792] | 988 | form if n=0 [non-reduced triangular form if n!=0] |
---|
[c91bb9] | 989 | ASSUME: monomial ordering is a global ordering (p-ordering) |
---|
[0bc582c] | 990 | NOTE: may be used to solve a system of linear equations, |
---|
[dd73043] | 991 | see @code{gauss_row} from 'matrix.lib' for a different method |
---|
[82716e] | 992 | WARNING: the result is very likely to be false for 'real' coefficients, use |
---|
[c91bb9] | 993 | char 0 instead! |
---|
| 994 | EXAMPLE: example solvelinearpart; shows an example |
---|
[d2b2a7] | 995 | " |
---|
[c91bb9] | 996 | { |
---|
| 997 | intvec getoption = option(get); |
---|
| 998 | option(redSB); |
---|
[82716e] | 999 | if ( size(#)!=0 ) |
---|
| 1000 | { |
---|
[c91bb9] | 1001 | if(#[1]!=0) { option(noredSB); } |
---|
| 1002 | } |
---|
[faed79] | 1003 | def lin = interred(degreepart(id,0,1)[1]); |
---|
[82716e] | 1004 | if ( size(#)!=0 ) |
---|
| 1005 | { |
---|
| 1006 | if(#[1]!=0) |
---|
| 1007 | { |
---|
[c91bb9] | 1008 | return(lin); |
---|
| 1009 | } |
---|
| 1010 | } |
---|
| 1011 | option(set,getoption); |
---|
| 1012 | return(simplify(lin,1)); |
---|
| 1013 | } |
---|
[82716e] | 1014 | example |
---|
[c91bb9] | 1015 | { "EXAMPLE:"; echo = 2; |
---|
| 1016 | // Solve the system of linear equations: |
---|
| 1017 | // 3x + y + z - u = 2 |
---|
| 1018 | // 3x + 8y + 6z - 7u = 1 |
---|
| 1019 | // 14x + 10y + 6z - 7u = 0 |
---|
| 1020 | // 7x + 4y + 3z - 3u = 3 |
---|
| 1021 | ring r = 0,(x,y,z,u),lp; |
---|
| 1022 | ideal i= 3x + y + z - u, |
---|
| 1023 | 13x + 8y + 6z - 7u, |
---|
| 1024 | 14x + 10y + 6z - 7u, |
---|
| 1025 | 7x + 4y + 3z - 3u; |
---|
| 1026 | ideal j= 2,1,0,3; |
---|
[867e1a3] | 1027 | j = matrix(i)-matrix(j); // difference of 1x4 matrices |
---|
[82716e] | 1028 | // compute reduced triangular form, setting |
---|
[c91bb9] | 1029 | solvelinearpart(j); // the RHS equal 0 gives the solutions! |
---|
| 1030 | solvelinearpart(j,1); ""; // triangular form, not reduced |
---|
| 1031 | } |
---|
| 1032 | /////////////////////////////////////////////////////////////////////////////// |
---|
| 1033 | |
---|
[6ed15c] | 1034 | proc sortandmap (@id, list #) |
---|
| 1035 | "USAGE: sortandmap(id [,n1,p1,n2,p2...,o1,m1,o2,m2...]);@* |
---|
[9173792] | 1036 | id=poly/ideal/vector/module,@* |
---|
| 1037 | p1,p2,...= polynomials (product of variables),@* |
---|
| 1038 | n1,n2,...= integers,@* |
---|
| 1039 | o1,o2,...= strings,@* |
---|
| 1040 | m1,m2,...= integers@* |
---|
[d2b2a7] | 1041 | (default: p1=product of all vars, n1=0, o1=\"dp\",m1=0) |
---|
[c91bb9] | 1042 | the last pi (containing the remaining vars) may be omitted |
---|
[6ed15c] | 1043 | RETURN: a ring R, in which a poly/ideal/vector/module IMAG is stored: @* |
---|
[3c4dcc] | 1044 | - the ring R differs from the active basering only in the choice |
---|
[6ed15c] | 1045 | of monomial ordering and in the sorting of the variables.@* |
---|
| 1046 | - IMAG is the image (under imap) of the input ideal/module id @* |
---|
| 1047 | The new monomial ordering and sorting of vars is as follows: |
---|
[9173792] | 1048 | @format |
---|
[50cbdc] | 1049 | - each block of vars occuring in pi is sorted w.r.t. its complexity in id, |
---|
[9173792] | 1050 | - ni controls the sorting in i-th block (= vars occuring in pi): |
---|
[dd73043] | 1051 | ni=0 (resp. ni!=0) means that least complex (resp. most complex) vars come |
---|
[0bc582c] | 1052 | first |
---|
[9173792] | 1053 | - oi and mi define the monomial ordering of the i-th block: |
---|
| 1054 | if mi =0, oi=ordstr(i-th block) |
---|
| 1055 | if mi!=0, the ordering of the i-th block itself is a blockordering, |
---|
| 1056 | each subblock having ordstr=oi, such that vars of same complexity are |
---|
| 1057 | in one block |
---|
| 1058 | @end format |
---|
[6ed15c] | 1059 | Note that only simple ordstrings oi are allowed: \"lp\",\"dp\",\"Dp\", |
---|
| 1060 | \"ls\",\"ds\",\"Ds\". @* |
---|
[c91bb9] | 1061 | NOTE: We define a variable x to be more complex than y (with respect to id) |
---|
[82716e] | 1062 | if val(x) > val(y) lexicographically, where val(x) denotes the |
---|
[50cbdc] | 1063 | valuation vector of x:@* |
---|
[9173792] | 1064 | consider id as list of polynomials in x with coefficients in the |
---|
| 1065 | remaining variables. Then:@* |
---|
| 1066 | val(x) = (maximal occuring power of x, # of all monomials in leading |
---|
| 1067 | coefficient, # of all monomials in coefficient of next smaller power |
---|
| 1068 | of x,...). |
---|
[c91bb9] | 1069 | EXAMPLE: example sortandmap; shows an example |
---|
[d2b2a7] | 1070 | " |
---|
[c91bb9] | 1071 | { |
---|
| 1072 | def @P = basering; |
---|
| 1073 | int @ii,@jj; |
---|
| 1074 | intvec @v; |
---|
| 1075 | string @o; |
---|
| 1076 | //----------------- find o in # and split # into 2 lists --------------------- |
---|
| 1077 | # = # +list("dp",0); |
---|
[82716e] | 1078 | for ( @ii=1; @ii<=size(#); @ii++) |
---|
| 1079 | { |
---|
| 1080 | if ( typeof(#[@ii])=="string" ) break; |
---|
[c91bb9] | 1081 | } |
---|
| 1082 | if ( @ii==1 ) { list @L1 = list(); } |
---|
| 1083 | else { list @L1 = #[1..@ii-1]; } |
---|
| 1084 | list @L2 = #[@ii..size(#)]; |
---|
| 1085 | list @L = sortvars(@id,@L1); |
---|
| 1086 | string @va = string(@L[1]); |
---|
| 1087 | list @l = @L[2]; //e.g. @l[4]=intvec describing permutation of 1-st block |
---|
| 1088 | //----------------- construct correct ordering with oi and mi ---------------- |
---|
| 1089 | for ( @ii=4; @ii<=size(@l); @ii=@ii+4 ) |
---|
| 1090 | { |
---|
| 1091 | @L2=@L2+list("dp",0); |
---|
[1f9a84] | 1092 | if ( @L2[@ii div 2] != 0) |
---|
[c91bb9] | 1093 | { |
---|
| 1094 | @v = @l[@ii]; |
---|
| 1095 | for ( @jj=1; @jj<=size(@v); @jj++ ) |
---|
| 1096 | { |
---|
[1f9a84] | 1097 | @o = @o+@L2[@ii div 2 -1]+"("+string(@v[@jj])+"),"; |
---|
[c91bb9] | 1098 | } |
---|
| 1099 | } |
---|
[82716e] | 1100 | else |
---|
| 1101 | { |
---|
[1f9a84] | 1102 | @o = @o+@L2[@ii div 2 -1]+"("+string(size(@l[@ii div 2]))+"),"; |
---|
[82716e] | 1103 | } |
---|
[c91bb9] | 1104 | } |
---|
| 1105 | @o=@o[1..size(@o)-1]; |
---|
[6ed15c] | 1106 | execute("ring @S1 =("+charstr(@P)+"),("+@va+"),("+@o+");"); |
---|
| 1107 | def IMAG = imap(@P,@id); |
---|
| 1108 | export IMAG; |
---|
| 1109 | dbprint(printlevel-voice+3," |
---|
[3c4dcc] | 1110 | // 'sortandmap' created a ring, in which an object IMAG is stored. |
---|
[6ed15c] | 1111 | // To access the object, type (if the name R was assigned to the return value): |
---|
| 1112 | setring R; IMAG; "); |
---|
| 1113 | return(@S1); |
---|
[c91bb9] | 1114 | } |
---|
[82716e] | 1115 | example |
---|
[c91bb9] | 1116 | { "EXAMPLE:"; echo = 2; |
---|
[9173792] | 1117 | ring s = 32003,(x,y,z),dp; |
---|
[50cbdc] | 1118 | ideal i=x3+y2,xz+z2; |
---|
[3c4dcc] | 1119 | def R_r=sortandmap(i); |
---|
[c91bb9] | 1120 | show(R_r); |
---|
[6ed15c] | 1121 | setring R_r; IMAG; |
---|
[c91bb9] | 1122 | kill R_r; setring s; |
---|
[6ed15c] | 1123 | def R_r=sortandmap(i,1,xy,0,z,0,"ds",0,"lp",0); |
---|
[82716e] | 1124 | show(R_r); |
---|
[6ed15c] | 1125 | setring R_r; IMAG; |
---|
[c91bb9] | 1126 | kill R_r; |
---|
| 1127 | } |
---|
| 1128 | /////////////////////////////////////////////////////////////////////////////// |
---|
| 1129 | |
---|
| 1130 | proc sortvars (id, list #) |
---|
[9173792] | 1131 | "USAGE: sortvars(id[,n1,p1,n2,p2,...]);@* |
---|
| 1132 | id=poly/ideal/vector/module,@* |
---|
| 1133 | p1,p2,...= polynomials (product of vars),@* |
---|
[0bc582c] | 1134 | n1,n2,...= integers@* |
---|
[c91bb9] | 1135 | (default: p1=product of all vars, n1=0) |
---|
| 1136 | the last pi (containing the remaining vars) may be omitted |
---|
| 1137 | COMPUTE: sort variables with respect to their complexity in id |
---|
| 1138 | RETURN: list of two elements, an ideal and a list: |
---|
[9173792] | 1139 | @format |
---|
| 1140 | [1]: ideal, variables of basering sorted w.r.t their complexity in id |
---|
| 1141 | ni controls the ordering in i-th block (= vars occuring in pi): |
---|
[dd73043] | 1142 | ni=0 (resp. ni!=0) means that less (resp. more) complex vars come first |
---|
[9173792] | 1143 | [2]: a list with 4 entries for each pi: |
---|
[0bc582c] | 1144 | _[1]: ideal ai : vars of pi in correct order, |
---|
| 1145 | _[2]: intvec vi: permutation vector describing the ordering in ai, |
---|
| 1146 | _[3]: intmat Mi: valuation matrix of ai, the columns of Mi being the |
---|
[9173792] | 1147 | valuation vectors of the vars in ai |
---|
[0bc582c] | 1148 | _[4]: intvec wi: size of 1-st, 2-nd,... block of identical columns of Mi |
---|
[9173792] | 1149 | (vars with same valuation) |
---|
| 1150 | @end format |
---|
| 1151 | NOTE: We define a variable x to be more complex than y (with respect to id) |
---|
[82716e] | 1152 | if val(x) > val(y) lexicographically, where val(x) denotes the |
---|
[50cbdc] | 1153 | valuation vector of x:@* |
---|
[9173792] | 1154 | consider id as list of polynomials in x with coefficients in the |
---|
| 1155 | remaining variables. Then:@* |
---|
| 1156 | val(x) = (maximal occuring power of x, # of all monomials in leading |
---|
| 1157 | coefficient, # of all monomials in coefficient of next smaller power |
---|
| 1158 | of x,...). |
---|
[c91bb9] | 1159 | EXAMPLE: example sortvars; shows an example |
---|
[d2b2a7] | 1160 | " |
---|
[c91bb9] | 1161 | { |
---|
| 1162 | int ii,jj,n,s; |
---|
| 1163 | list L = valvars(id,#); |
---|
[82716e] | 1164 | list L2, L3 = L[2], L[3]; |
---|
[c91bb9] | 1165 | list K; intmat M; intvec v1,v2,w; |
---|
| 1166 | ideal i = sort(maxideal(1),L[1])[1]; |
---|
| 1167 | for ( ii=1; ii<=size(L2); ii++ ) |
---|
| 1168 | { |
---|
| 1169 | M = transpose(L3[2*ii]); |
---|
| 1170 | M = M[L2[ii],1..nrows(L3[2*ii])]; |
---|
[82716e] | 1171 | w = 0; s = 0; |
---|
[c91bb9] | 1172 | for ( jj=1; jj<=nrows(M)-1; jj++ ) |
---|
| 1173 | { |
---|
| 1174 | v1 = M[jj,1..ncols(M)]; |
---|
| 1175 | v2 = M[jj+1,1..ncols(M)]; |
---|
| 1176 | if ( v1 != v2 ) { n=jj-s; s=s+n; w = w,n; } |
---|
| 1177 | } |
---|
| 1178 | w=w,nrows(M)-s; w=w[2..size(w)]; |
---|
| 1179 | K = K+sort(L3[2*ii-1],L2[ii])+list(transpose(M))+list(w); |
---|
| 1180 | } |
---|
[82716e] | 1181 | L = i,K; |
---|
[c91bb9] | 1182 | return(L); |
---|
| 1183 | } |
---|
[82716e] | 1184 | example |
---|
[c91bb9] | 1185 | { "EXAMPLE:"; echo = 2; |
---|
[9173792] | 1186 | ring s=0,(x,y,z,w),dp; |
---|
[50cbdc] | 1187 | ideal i = x3+y2+yw2,xz+z2,xyz-w2; |
---|
[9173792] | 1188 | sortvars(i,0,xy,1,zw); |
---|
[c91bb9] | 1189 | } |
---|
| 1190 | /////////////////////////////////////////////////////////////////////////////// |
---|
| 1191 | |
---|
| 1192 | proc valvars (id, list #) |
---|
[9173792] | 1193 | "USAGE: valvars(id[,n1,p1,n2,p2,...]);@* |
---|
| 1194 | id=poly/ideal/vector/module,@* |
---|
| 1195 | p1,p2,...= polynomials (product of vars),@* |
---|
| 1196 | n1,n2,...= integers, |
---|
| 1197 | |
---|
[dd73043] | 1198 | ni controls the ordering of vars occuring in pi: ni=0 (resp. ni!=0) |
---|
[0bc582c] | 1199 | means that less (resp. more) complex vars come first (default: p1=product of all vars, n1=0),@* |
---|
[c91bb9] | 1200 | the last pi (containing the remaining vars) may be omitted |
---|
[9173792] | 1201 | COMPUTE: valuation (complexity) of variables with respect to id.@* |
---|
| 1202 | ni controls the ordering of vars occuring in pi:@* |
---|
[dd73043] | 1203 | ni=0 (resp. ni!=0) means that less (resp. more) complex vars come first. |
---|
[9173792] | 1204 | RETURN: list with 3 entries: |
---|
| 1205 | @format |
---|
| 1206 | [1]: intvec, say v, describing the permutation such that the permuted |
---|
[dd73043] | 1207 | ring variables are ordered with respect to their complexity in id |
---|
[9173792] | 1208 | [2]: list of intvecs, i-th intvec, say v(i) describing permutation |
---|
| 1209 | of vars in a(i) such that v=v(1),v(2),... |
---|
| 1210 | [3]: list of ideals and intmat's, say a(i) and M(i), where |
---|
| 1211 | a(i): factors of pi, |
---|
| 1212 | M(i): valuation matrix of a(i), such that the j-th column of M(i) |
---|
| 1213 | is the valuation vector of j-th generator of a(i) |
---|
| 1214 | @end format |
---|
| 1215 | NOTE: Use @code{sortvars} in order to actually sort the variables! |
---|
[c91bb9] | 1216 | We define a variable x to be more complex than y (with respect to id) |
---|
[82716e] | 1217 | if val(x) > val(y) lexicographically, where val(x) denotes the |
---|
[50cbdc] | 1218 | valuation vector of x:@* |
---|
[9173792] | 1219 | consider id as list of polynomials in x with coefficients in the |
---|
| 1220 | remaining variables. Then:@* |
---|
| 1221 | val(x) = (maximal occuring power of x, # of all monomials in leading |
---|
| 1222 | coefficient, # of all monomials in coefficient of next smaller power |
---|
| 1223 | of x,...). |
---|
[c91bb9] | 1224 | EXAMPLE: example valvars; shows an example |
---|
[d2b2a7] | 1225 | " |
---|
[c91bb9] | 1226 | { |
---|
| 1227 | //---------------------------- initialization --------------------------------- |
---|
| 1228 | int ii,jj,kk,n; |
---|
| 1229 | list L; // list of valuation vectors in one block |
---|
| 1230 | intvec vec; // describes permutation of vars (in one block) |
---|
| 1231 | list blockvec; // i-th element = vec of i-th block |
---|
| 1232 | intvec varvec; // result intvector |
---|
| 1233 | list Li; // result list of ideals |
---|
| 1234 | list LM; // result list of intmat's |
---|
| 1235 | intvec v,w,s; // w valuation vector for one variable |
---|
| 1236 | matrix C; // coefficient matrix for different variables |
---|
| 1237 | ideal i = simplify(ideal(matrix(id)),10); |
---|
| 1238 | |
---|
| 1239 | //---- for each pii in # create ideal a(ii) intvec v(ii) and list L(ii) ------- |
---|
[82716e] | 1240 | // a(ii) = ideal of vars in product, v(ii)[j]=k <=> a(ii)[j]=var(k) |
---|
[c91bb9] | 1241 | |
---|
| 1242 | v = 1..nvars(basering); |
---|
| 1243 | int l = size(#); |
---|
| 1244 | if ( l >= 2 ) |
---|
| 1245 | { |
---|
| 1246 | ideal m=maxideal(1); |
---|
| 1247 | for ( ii=2; ii<=l; ii=ii+2 ) |
---|
| 1248 | { |
---|
| 1249 | int n(ii) = #[ii-1]; |
---|
| 1250 | ideal a(ii); |
---|
| 1251 | intvec v(ii); |
---|
| 1252 | for ( jj=1; jj<=nvars(basering); jj++ ) |
---|
| 1253 | { |
---|
[82716e] | 1254 | if ( #[ii]/var(jj) != 0) |
---|
| 1255 | { |
---|
| 1256 | a(ii) = a(ii) + var(jj); |
---|
[c91bb9] | 1257 | v(ii)=v(ii),jj; |
---|
| 1258 | m[jj]=0; |
---|
| 1259 | v[jj]=0; |
---|
| 1260 | } |
---|
| 1261 | } |
---|
| 1262 | v(ii)=v(ii)[2..size(v(ii))]; |
---|
[82716e] | 1263 | } |
---|
| 1264 | if ( size(m)!=0 ) |
---|
| 1265 | { |
---|
[1f9a84] | 1266 | l = 2*(l div 2)+2; |
---|
[82716e] | 1267 | ideal a(l) = simplify(m,2); |
---|
[c91bb9] | 1268 | intvec v(l) = compress(v); |
---|
| 1269 | int n(l); |
---|
| 1270 | if ( size(#)==l-1 ) { n(l) = #[l-1]; } |
---|
| 1271 | } |
---|
| 1272 | } |
---|
[82716e] | 1273 | else |
---|
| 1274 | { |
---|
| 1275 | l = 2; |
---|
| 1276 | ideal a(2) = maxideal(1); |
---|
| 1277 | intvec v(2) = v; |
---|
| 1278 | int n(2); |
---|
[c91bb9] | 1279 | if ( size(#)==1 ) { n(2) = #[1]; } |
---|
| 1280 | } |
---|
| 1281 | //------------- start loop to order variables in each a(ii) ------------------- |
---|
| 1282 | |
---|
| 1283 | for ( kk=2; kk<=l; kk=kk+2 ) |
---|
| 1284 | { |
---|
| 1285 | L = list(); |
---|
| 1286 | n = 0; |
---|
| 1287 | //---------------- get valuation of all variables in a(kk) -------------------- |
---|
| 1288 | for ( ii=1; ii<=size(a(kk)); ii++ ) |
---|
| 1289 | { |
---|
| 1290 | C = coeffs(i,a(kk)[ii]); |
---|
[9173792] | 1291 | w = nrows(C); // =(maximal occuring power of a(kk)[ii])+1 |
---|
[82716e] | 1292 | for ( jj=w[1]; jj>1; jj-- ) |
---|
[c91bb9] | 1293 | { |
---|
| 1294 | s = size(C[jj,1..ncols(C)]); |
---|
[82716e] | 1295 | w[w[1]-jj+2] = sum(s); |
---|
[c91bb9] | 1296 | } |
---|
[9173792] | 1297 | // w[1] should represent the maximal occuring power of a(kk)[ii] so it |
---|
| 1298 | // has to be decreased by 1 since otherwise the constant term is also |
---|
| 1299 | // counted |
---|
| 1300 | w[1]=w[1]-1; |
---|
| 1301 | |
---|
[c91bb9] | 1302 | L[ii]=w; |
---|
| 1303 | n = size(w)*(size(w) > n) + n*(size(w) <= n); |
---|
| 1304 | } |
---|
| 1305 | intmat M(kk)[size(a(kk))][n]; |
---|
[82716e] | 1306 | for ( ii=1; ii<=size(a(kk)); ii++ ) |
---|
| 1307 | { |
---|
| 1308 | if ( n==1 ) { w = L[ii]; M(kk)[ii,1] = w[1]; } |
---|
| 1309 | else { M(kk)[ii,1..n] = L[ii]; } |
---|
[c91bb9] | 1310 | } |
---|
| 1311 | LM[kk-1] = a(kk); |
---|
| 1312 | LM[kk] = transpose(compress(M(kk))); |
---|
| 1313 | //------------------- compare valuation and insert in vec --------------------- |
---|
| 1314 | vec = sort(L)[2]; |
---|
| 1315 | if ( n(kk) != 0 ) { vec = vec[size(vec)..1]; } |
---|
[1f9a84] | 1316 | blockvec[kk div 2] = vec; |
---|
[c91bb9] | 1317 | vec = sort(v(kk),vec)[1]; |
---|
[82716e] | 1318 | varvec = varvec,vec; |
---|
[c91bb9] | 1319 | } |
---|
| 1320 | varvec = varvec[2..size(varvec)]; |
---|
| 1321 | list result = varvec,blockvec,LM; |
---|
| 1322 | return(result); |
---|
| 1323 | } |
---|
[82716e] | 1324 | example |
---|
[c91bb9] | 1325 | { "EXAMPLE:"; echo = 2; |
---|
[9173792] | 1326 | ring s=0,(x,y,z,a,b),dp; |
---|
| 1327 | ideal i=ax2+ay3-b2x,abz+by2; |
---|
| 1328 | valvars (i,0,xyz); |
---|
[c91bb9] | 1329 | } |
---|
| 1330 | /////////////////////////////////////////////////////////////////////////////// |
---|
[8b87364] | 1331 | proc idealSplit(ideal I,list #) |
---|
[3c4dcc] | 1332 | "USAGE: idealSplit(id,timeF,timeS); id ideal and optional |
---|
[dd73043] | 1333 | timeF, timeS integers to bound the time which can be used |
---|
[8b87364] | 1334 | for factorization resp. standard basis computation |
---|
[3c4dcc] | 1335 | RETURN: a list of ideals such that their intersection |
---|
[8b87364] | 1336 | has the same radical as id |
---|
| 1337 | EXAMPLE: example idealSplit; shows an example |
---|
| 1338 | " |
---|
| 1339 | { |
---|
| 1340 | option(redSB); |
---|
| 1341 | int j,k,e; |
---|
| 1342 | int i=1; |
---|
| 1343 | int l=attrib(I,"isSB"); |
---|
| 1344 | ideal J; |
---|
| 1345 | int timeF; |
---|
| 1346 | int timeS; |
---|
| 1347 | list re,fac,te; |
---|
| 1348 | |
---|
| 1349 | if(size(#)==1) |
---|
| 1350 | { |
---|
| 1351 | if(typeof(#[1])=="ideal") |
---|
| 1352 | { |
---|
| 1353 | re=#; |
---|
| 1354 | } |
---|
| 1355 | else |
---|
| 1356 | { |
---|
| 1357 | timeF=#[1]; |
---|
| 1358 | } |
---|
| 1359 | } |
---|
| 1360 | if(size(#)==2) |
---|
| 1361 | { |
---|
| 1362 | if(typeof(#[1])=="list") |
---|
| 1363 | { |
---|
| 1364 | re=#[1]; |
---|
| 1365 | timeF=#[2]; |
---|
| 1366 | } |
---|
| 1367 | else |
---|
| 1368 | { |
---|
| 1369 | timeF=#[1]; |
---|
| 1370 | timeS=#[2]; |
---|
| 1371 | } |
---|
| 1372 | } |
---|
| 1373 | if(size(#)==3){re=#[1];timeF=#[2];timeS=#[3];} |
---|
| 1374 | |
---|
| 1375 | fac=timeFactorize(I[1],timeF); |
---|
| 1376 | |
---|
| 1377 | while((size(fac[1])==2)&&(i<size(I))) |
---|
[3c4dcc] | 1378 | { |
---|
| 1379 | i++; |
---|
[8b87364] | 1380 | fac=timeFactorize(I[i],timeF); |
---|
| 1381 | } |
---|
| 1382 | if(size(fac[1])>2) |
---|
| 1383 | { |
---|
| 1384 | for(j=2;j<=size(fac[1]);j++) |
---|
| 1385 | { |
---|
| 1386 | I[i]=fac[1][j]; |
---|
| 1387 | attrib(I,"isSB",1); |
---|
| 1388 | e=1; |
---|
| 1389 | k=0; |
---|
| 1390 | while(k<size(re)) |
---|
| 1391 | { |
---|
| 1392 | k++; |
---|
| 1393 | if(size(reduce(re[k],I))==0){e=0;break;} |
---|
| 1394 | attrib(re[k],"isSB",1); |
---|
| 1395 | if(size(reduce(I,re[k]))==0){re=delete(re,k);k--;} |
---|
| 1396 | } |
---|
| 1397 | if(e) |
---|
| 1398 | { |
---|
| 1399 | if(l) |
---|
| 1400 | { |
---|
| 1401 | J=I; |
---|
| 1402 | J[i]=0; |
---|
| 1403 | J=simplify(J,2); |
---|
| 1404 | attrib(J,"isSB",1); |
---|
| 1405 | re=idealSplit(std(J,fac[1][j]),re,timeF,timeS); |
---|
| 1406 | } |
---|
| 1407 | else |
---|
| 1408 | { |
---|
| 1409 | re=idealSplit(timeStd(I,timeS),re,timeF,timeS); |
---|
| 1410 | } |
---|
| 1411 | } |
---|
[3c4dcc] | 1412 | } |
---|
| 1413 | return(re); |
---|
[8b87364] | 1414 | } |
---|
| 1415 | J=timeStd(I,timeS); |
---|
| 1416 | attrib(I,"isSB",1); |
---|
| 1417 | if(size(reduce(J,I))==0){return(re+list(I));} |
---|
| 1418 | return(re+idealSplit(J,re,timeF,timeS)); |
---|
| 1419 | } |
---|
| 1420 | example |
---|
| 1421 | { "EXAMPLE:"; echo = 2; |
---|
| 1422 | ring r=32003,(b,s,t,u,v,w,x,y,z),dp; |
---|
| 1423 | ideal i= |
---|
| 1424 | bv+su, |
---|
| 1425 | bw+tu, |
---|
| 1426 | sw+tv, |
---|
| 1427 | by+sx, |
---|
| 1428 | bz+tx, |
---|
| 1429 | sz+ty, |
---|
| 1430 | uy+vx, |
---|
| 1431 | uz+wx, |
---|
| 1432 | vz+wy, |
---|
| 1433 | bvz; |
---|
| 1434 | idealSplit(i); |
---|
| 1435 | } |
---|
| 1436 | /////////////////////////////////////////////////////////////////////////////// |
---|
| 1437 | proc idealSimplify(ideal J,list #) |
---|
| 1438 | "USAGE: idealSimplify(id); id ideal |
---|
| 1439 | RETURN: ideal I = eliminate(Id,m) m is a product of variables |
---|
| 1440 | which are only linearly involved in the generators of id |
---|
| 1441 | EXAMPLE: example idealSimplify; shows an example |
---|
| 1442 | " |
---|
| 1443 | { |
---|
| 1444 | ideal I=J; |
---|
| 1445 | if(size(#)!=0){I=#[1];} |
---|
| 1446 | def R=basering; |
---|
| 1447 | matrix M=jacob(I); |
---|
| 1448 | ideal ma=maxideal(1); |
---|
| 1449 | int i,j,k; |
---|
| 1450 | map phi; |
---|
| 1451 | |
---|
| 1452 | for(i=1;i<=nrows(M);i++) |
---|
| 1453 | { |
---|
| 1454 | for(j=1;j<=ncols(M);j++) |
---|
[3c4dcc] | 1455 | { |
---|
[8b87364] | 1456 | if(deg(M[i,j])==0) |
---|
| 1457 | { |
---|
| 1458 | ma[j]=(-1/M[i,j])*(I[i]-M[i,j]*var(j)); |
---|
| 1459 | phi=R,ma; |
---|
| 1460 | I=phi(I); |
---|
| 1461 | J=phi(J); |
---|
| 1462 | for(k=1;k<=ncols(I);k++){I[k]=cleardenom(I[k]);} |
---|
| 1463 | M=jacob(I); |
---|
| 1464 | } |
---|
| 1465 | } |
---|
| 1466 | } |
---|
| 1467 | J=simplify(J,2); |
---|
| 1468 | for(i=1;i<=size(J);i++){J[i]=cleardenom(J[i]);} |
---|
| 1469 | return(J); |
---|
| 1470 | } |
---|
| 1471 | example |
---|
| 1472 | { "EXAMPLE:"; echo = 2; |
---|
| 1473 | ring r=0,(x,y,z,w,t),dp; |
---|
| 1474 | ideal i= |
---|
| 1475 | t, |
---|
| 1476 | x3+y2+2z, |
---|
| 1477 | x2+3y, |
---|
| 1478 | x2+y2+z2, |
---|
| 1479 | w2+z; |
---|
| 1480 | ideal j=idealSimplify(i); |
---|
| 1481 | ideal k=eliminate(i,zyt); |
---|
| 1482 | reduce(k,std(j)); |
---|
| 1483 | reduce(j,std(k)); |
---|
| 1484 | } |
---|
| 1485 | |
---|
| 1486 | /////////////////////////////////////////////////////////////////////////////// |
---|
| 1487 | |
---|
[75089b] | 1488 | /* |
---|
[c91bb9] | 1489 | |
---|
| 1490 | ring s=31991,(e,f,x,y,z,t,u,v,w,a,b,c,d),dp; |
---|
| 1491 | ring s=31991,(x,y,z,t,u,v,w,a,b,c,d,f,e,h),dp; //standard |
---|
| 1492 | ring s1=31991,(y,u,b,c,a,z,t,x,v,d,w,e,f,h),dp; //gut |
---|
| 1493 | v; |
---|
| 1494 | 13,12,11,10,8,7,6,5,4,3,2,1,9,14 |
---|
| 1495 | print(matrix(sort(maxideal(1),v))); |
---|
| 1496 | f,e,w,d,x,t,z,a,c,b,u,y,v,h |
---|
| 1497 | print(matrix(maxideal(1))); |
---|
| 1498 | y,u,b,c,a,z,t,x,v,d,w,e,f,h |
---|
| 1499 | v0; |
---|
[82716e] | 1500 | 14,9,12,11,10,8,7,6,5,4,3,2,1,13 |
---|
[c91bb9] | 1501 | print(matrix(sort(maxideal(1),v0))); |
---|
| 1502 | h,v,e,w,d,x,t,z,a,c,b,u,y,f |
---|
| 1503 | v1;v2; |
---|
[82716e] | 1504 | 9,12,11,10,8,7,6,5,4,3,2,1,13,14 |
---|
| 1505 | 13,12,11,10,8,7,6,5,4,3,2,1,9,14 |
---|
[c91bb9] | 1506 | |
---|
| 1507 | Ev. Gute Ordnung fuer i: |
---|
| 1508 | ======================== |
---|
| 1509 | i=ad*x^d+ad-1*x^(d-1)+...+a1*x+a0, ad!=0 |
---|
| 1510 | mit ar=(ar1,...,ark), k=size(i) |
---|
| 1511 | arj in K[..x^..] |
---|
| 1512 | d=deg_x(i) := max{deg_x(i[k]) | k=1..size(i)} |
---|
| 1513 | size_x(i,deg_x(i)..0) := size(ad),...,size(a0) |
---|
[82716e] | 1514 | x>y <== |
---|
| 1515 | 1. deg_x(i)>deg_y(i) |
---|
[c91bb9] | 1516 | 2. "=" in 1. und size_x lexikographisch |
---|
| 1517 | |
---|
| 1518 | hier im Beispiel: |
---|
| 1519 | f: 5,1,0,1,2 |
---|
| 1520 | |
---|
| 1521 | u: 3,1,4 |
---|
| 1522 | |
---|
| 1523 | y: 3,1,3 |
---|
| 1524 | b: 3,1,3 |
---|
| 1525 | c: 3,1,3 |
---|
| 1526 | a: 3,1,3 |
---|
| 1527 | z: 3,1,3 |
---|
| 1528 | t: 3,1,3 |
---|
| 1529 | |
---|
| 1530 | x: 3,1,2 |
---|
| 1531 | v: 3,1,2 |
---|
| 1532 | d: 3,1,2 |
---|
| 1533 | w: 3,1,2 |
---|
| 1534 | e: 3,1,2 |
---|
| 1535 | probier mal: |
---|
| 1536 | ring s=31991,(f,u,y,z,t,a,b,c,v,w,d,e,h),dp; //standard |
---|
| 1537 | |
---|
[75089b] | 1538 | */ |
---|