source: git/Singular/LIB/presolve.lib @ b7b65ee

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