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

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