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