source: git/Singular/LIB/presolve.lib @ 33b509

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