source: git/Singular/LIB/standard.lib @ d41b423

spielwiese
Last change on this file since d41b423 was d41b423, checked in by Hans Schönemann <hannes@…>, 17 years ago
*hannes: colon operator git-svn-id: file:///usr/local/Singular/svn/trunk@9945 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 66.4 KB
Line 
1//////////////////////////////////////////////////////////////////////////////
2//major revision Jan/Feb. 2007, GMG
3//groebner mit Optionen versehen
4//////////////////////////////////////////////////////////////////////////////
5version="$Id: standard.lib,v 1.89 2007-03-14 18:17:34 Singular Exp $";
6category="Miscellaneous";
7info="
8LIBRARY: standard.lib   Procedures which are always loaded at Start-up
9
10PROCEDURES:
11 stdfglm(ideal[,ord])   standard basis of ideal via fglm [and ordering ord]
12 stdhilb(ideal[,h])     Hilbert driven Groebner basis of ideal
13 groebner(ideal,...)    standard basis using a heuristically chosen method
14 res(ideal/module,[i])  free resolution of ideal or module
15 sprintf(fmt,...)       returns fomatted string
16 fprintf(link,fmt,..)   writes formatted string to link
17 printf(fmt,...)        displays formatted string
18 weightKB(stc,dd,vl)    degree dd part of a kbase wrt. some weigths
19";
20// qslimgb(i)             computes a standard basis with slimgb in a qring
21// hilbRing([i])          create a ring containing the homogenized i
22// par2varRing([i])       create a ring with pars to vars together with i
23// quotientList(L,...)    a list, say QL, s.t. ring(QL) creates a correct qring
24
25//////////////////////////////////////////////////////////////////////////////
26
27proc stdfglm (i, list #)
28"SYNTAX: @code{stdfglm (} ideal_expression @code{)} @*
29         @code{stdfglm (} ideal_expression@code{,} string_expression @code{)}
30TYPE:    ideal
31PURPOSE: computes the standard basis of the ideal in the basering
32         via @code{fglm} from the ordering given as the second argument
33         to the ordering of the basering. If no second argument is given,
34         \"dp\" is used. The standard basis for the given ordering (resp. for
35         \"dp\") is computed via the command groebner except if a further
36         argument \"std\" or \"slimgb\" is given in which case std resp.
37         slimgb is used.
38SEE ALSO: fglm, groebner, std, slimgb, stdhilb
39KEYWORDS: fglm
40EXAMPLE: example stdfglm; shows an example"
41{
42   if (nrows(i) > 1)
43   {
44      ERROR("first argument of 'stdfglm' must be an ideal");
45   }
46   string os;
47   int s = size(#);
48   def P= basering;
49   string algorithm;
50   int ii;
51   for( ii=1; ii<=s; ii++)
52   {
53      if ( typeof(#[ii])== "string" )
54      {
55         if ( #[ii]=="std" || #[ii]=="slimgb" )
56         {
57            algorithm =  #[ii];
58            # = delete(#,ii);
59            s = s-1;
60            ii--;
61         }
62      }
63   }
64
65   if( s > 0 && (typeof(#[1]) == "string") )
66   {
67      os = #[1];
68      ideal Qideal = ideal(P);
69      int sQ = size(Qideal);
70      int sM = size(minpoly);
71      if ( sM!=0 )
72      {
73         string mpoly = string(minpoly);
74      }
75      if (sQ!=0 )
76      {
77        execute("ring Rfglm=("+charstr(P)+"),("+varstr(P)+"),"+os+";");
78        ideal Qideal = fetch(P,Qideal);
79        qring Pfglm = groebner(Qideal,"std","slimgb");
80      }
81      else
82      {
83        execute("ring Pfglm=("+charstr(P)+"),("+varstr(P)+"),"+os+";");
84      }
85      if ( sM!=0 )
86      {
87        execute("minpoly="+mpoly+";");
88      }
89    }
90    else
91    {
92      list BRlist = ringlist(P);
93      int nvarP = nvars(P);
94      intvec w;                       //for ringweights of basering P
95      int k;
96      for(k=1;  k <= nvarP; k++)
97      {
98        w[k]=deg(var(k));
99      }
100
101      BRlist[3] = list();
102      if( s==0 or (typeof(#[1]) != "string") )
103      {
104        if( w==1 )
105        {
106           BRlist[3][1]=list("dp",w);
107        }
108        else
109        {
110           BRlist[3][1]=list("wp",w);
111        }
112        BRlist[3][2]=list("C",intvec(0));
113        def Pfglm = ring(quotientList(BRlist));
114        setring Pfglm;
115      }
116    }
117    ideal i = fetch(P,i);
118
119    intvec opt = option(get);            //save options
120    option(redSB);
121    if (size(algorithm) > 0)
122    {
123       i = groebner(i,algorithm);
124    }
125    else
126    {
127       i = groebner(i);
128    }
129    option(set,opt);
130    setring P;
131    return (fglm(Pfglm,i));
132}
133example
134{ "EXAMPLE:"; echo = 2;
135   ring r  = 0,(x,y,z),lp;
136   ideal i = y3+x2,x2y+x2,x3-x2,z4-x2-y;
137   stdfglm(i);                   //uses fglm from "dp" (with groebner) to "lp"
138   stdfglm(i,"std");             //uses fglm from "dp" (with std) to "lp"
139
140   ring s  = (0,x),(y,z,u,v),lp;
141   minpoly = x2+1;
142   ideal i = u5-v4,zv-u2,zu3-v3,z2u-v2,z3-uv,yv-zu,yu-z2,yz-v,y2-u,u-xy2;
143   weight(i);
144   stdfglm(i,"(a(2,3,4,5),dp)"); //uses fglm from "(a(2,3,4,5),dp)" to "lp"
145}
146
147/////////////////////////////////////////////////////////////////////////////
148
149proc stdhilb(i,list #)
150"SYNTAX: @code{stdhilb (} ideal_expression @code{)} @*
151         @code{stdhilb (} module_expression @code{)} @*
152         @code{stdhilb (} ideal_expression@code{,} intvec_expression @code{)}
153         @code{stdhilb (} ideal_expression@code{,} list of string_expressions
154               and intvec_expressin @code{)} @*
155TYPE:    type of the first argument
156PURPOSE: Compute a Groebner basis of the ideal/module in the basering by
157         using the Hilbert driven Groebner basis algorithm.
158         If an argument of type string @code{\"std\"} resp. @code{\"slimgb\"}
159         is given, the standard basis computation uses @code{std} or
160         @code{slimgb}, otherwise a heuristically chosen method (default)
161THEORY:  If the ideal is not homogeneous compute first a Groebner basis
162         of the homogenization of the ideal, then the Hilbert function and,
163         finally, a Groebner basis in the original ring by using the
164         computed Hilbert function.@*
165         If the ideal is homogeneous and a second argument of type intvec
166         is given it will be used as 1st Hilbert function in the Hilbert
167         driven algorithm.
168NOTE:    'homogeneous' means weighted homogeneous with respect to the weights
169         w[i] of the variables var(i) of the basering. Parameters are not
170         converted to variables.
171ASSUME:  The argument of type intvec is the 1st Hilbert series, computed
172         by @code{hilb} using an intvector w, w[i]=deg(var(i)), as third
173         argument
174SEE ALSO: stdfglm, std, slimgb, groebner
175KEYWORDS: Hilbert function
176EXAMPLE: example stdhilb;  shows an example"
177{
178
179//--------------------- save data from basering --------------------------
180  def P=basering;
181  int nr = nrows(i);            //nr=1 iff i is an ideal
182  ideal Qideal = ideal(P);      //defining the quotient ideal if P is a qring
183  int was_qring;                //remembers if basering was a qring
184  int is_homog = homog(Qideal); //remembers if Qideal was homog (homog(0)=1)
185  is_homog = is_homog*homog(i); //check for homogeneity of i and Qideal
186  if (size(Qideal) > 0)
187  {
188     was_qring = 1;
189  }
190
191  // save ordering of basering P for later use
192  list ord_P = ringlist(P)[3];     //ordering of basering in ringlist
193  string ordstr_P = ordstr(P);     //ordering of basering as string
194  int nvarP = nvars(P);
195  intvec w;                        //for ringweights of basering P
196  int k;
197  for(k=1;  k<=nvarP; k++)
198  {
199     w[k]=deg(var(k));
200  }
201  int neg=1-attrib (P,"global");
202
203  //save options:
204  int p_opt;
205  string s_opt = option();
206  if (find(s_opt, "prot"))  { p_opt = 1; }
207
208//--------------------- check the given method ---------------------------
209  string method;
210  for (k=1; k<=size(#); k++)
211  {
212     if (typeof(#[k]) == "intvec")
213     {
214        intvec hi = #[k];
215     }
216     if (typeof(#[k]) == "string")
217     {
218       method = method + "," + #[k];
219     }
220  }
221
222  if (npars(P) > 0)             //clear denominators of parameters
223  {
224    for( k=ncols(i); k>0; k-- )
225    {
226       i[k]=cleardenom(i[k]);
227    }
228  }
229
230//---------- exclude cases to which stdhilb should no be applied  ----------
231//Note that quotient ideal of qring must be homogeneous too
232
233   if( find(ordstr_P,"s") || find(ordstr_P,"M")
234       || find(ordstr_P,"a") || (neg > 0) )
235   {
236      if( defined(hi) && is_homog )
237      {
238         if (p_opt){"std with given Hilbert function in basering";}
239         return( std(i,hi,w) );
240      }
241      if (p_opt){"//--stdhilb not implemented, use std in basering";}
242      //if ( neg )
243      //{
244      //  "//*** WARNING: non-positive ring weights, computation may not finish";
245      //}
246      return( std(i) );
247   }
248
249//------------------------ change to hilbRing ----------------------------
250
251     list hiRi = hilbRing(i);  //The ground field of P and Philb coincide
252     intvec W = hiRi[2];       //Philb has an extra variable @ or @(k)
253     def Philb = hiRi[1];      //Philb is no qring and the predefined
254     setring Philb;            //ideal/module Id(1) in Philb is homogeneous
255                               //Parameters of P are not converted in Philb
256//-------- compute Hilbert function of homogenized ideal in Philb ---------
257//Philb has only 1 block. There are three cases
258
259     string algorithm;       //possibilities: std, slimgb, stdorslimgb
260     //define algorithm:
261     if( find(method,"std") && !find(method,"slimgb") )
262     {
263        algorithm = "std";
264     }
265     if( find(method,"slimgb") && !find(method,"std") )
266     {
267         algorithm = "slimgb";
268     }
269     if( find(method,"std") && find(method,"slimgb") ||
270         (!find(method,"std") && !find(method,"slimgb")) )
271     {
272        algorithm = "stdorslimgb";
273     }
274
275     if ( algorithm=="std" || ( algorithm=="stdorslimgb" && char(P)>0 ) )
276     {
277        if (p_opt) {"std in ring " + string(Philb);}
278        intvec hi = hilb( std(Id(1)),1,W );
279     }
280     if ( algorithm=="slimgb" || ( algorithm=="stdorslimgb" && char(P)==0 ) )
281     {
282        intvec hi = hilb(qslimgb(Id(1)),1,W);
283     }
284
285   //-------------- we need another intermediate ring Phelp ----------------
286   //In Phelp we change the ordering from Philb, otherwise it coincides with
287   //Philb, that is, it has in addition to P an extra homogenizing variable
288   //with name @, resp. @(i) if @ and @(1), ..., @(i-1) are defined.
289   //Phelp has the same ordering as P on common variables. In Phelp
290   //a quotient ideal from P is added to the input
291
292      list BRlist = ringlist(Philb);
293      BRlist[3] = list();
294      int so = size(ord_P);
295      if( ord_P[so][1] =="c" || ord_P[so][1] =="C" )
296      {
297         list moduleord = ord_P[so];
298         so = so-1;
299      }
300      for (k=1; k<=so; k++)
301      {
302         BRlist[3][k] = ord_P[k];
303      }
304
305      BRlist[3][so+1] = list("dp",1);
306      w = w,1;
307
308      if( defined(moduleord) )
309      {
310        BRlist[3][so+2] = moduleord;
311      }
312
313//------ change to extended ring and compute std with hilbert series ------
314      def Phelp = ring(quotientList(BRlist));
315      setring Phelp;
316      def i = imap(Philb, Id(1));
317      kill Philb;
318
319      // compute std with Hilbert series
320      if (w ==1)
321      {
322         if (p_opt){ "std with hilb in " + string(Phelp);}
323         i = std(i, hi);
324      }
325      else
326      {
327         if(p_opt){"std with weighted hilb in "+string(Phelp);}
328         i = std(i, hi, w);
329      }
330
331//-------------------- go back to original ring ---------------------------
332 //The main computation is done. Do not forget to simplfy before maping.
333
334      // subst 1 for homogenizing var
335      if ( p_opt )
336      {
337          "dehomogenization";
338      }
339      i = subst(i, var(nvars(basering)), 1);
340
341       if (p_opt)
342       {
343         "simplification";
344       }
345       i= simplify(i,34);
346
347       setring P;
348       if (p_opt)
349       {
350         "imap to ring "+string(P);
351       }
352       i = imap(Phelp,i);
353       kill Phelp;
354       if( was_qring)
355       {
356         i = NF(i,std(0));
357       }
358       i = simplify(i,34);
359
360       // compute reduced SB
361       if (find(s_opt, "redSB") > 0)
362       {
363         if (p_opt)
364         {
365           "//interreduction";
366         }
367         i=interred(i);
368       }
369       attrib(i, "isSB", 1);
370       return (i);
371}
372example
373{ "EXAMPLE:"; echo = 2;
374   ring  r = 0,(x,y,z),lp;
375   ideal i = y3+x2,x2y+x2z2,x3-z9,z4-y2-xz;
376   ideal j = stdhilb(i); j;
377
378   ring  r1 = 0,(x,y,z),wp(3,2,1);
379   ideal  i = y3+x2,x2y+x2z2,x3-z9,z4-y2-xz;  //ideal is homogeneous
380   ideal j = stdhilb(i,"std"); j;
381   //this is equivalent to:
382   intvec v = hilb(std(i),1);
383   ideal j1 = std(i,v,intvec(3,2,1)); j1;
384   size(NF(j,j1))+size(NF(j1,j));            //j and j1 define the same ideal
385}
386
387///////////////////////////////////////////////////////////////////////////////
388proc quotientList (list RL, list #)
389"SYNTAX: @code{quotientList (} list_expression @code{)} @*
390         @code{quotientList (} list_expression @code{,} string_expression@code{)}
391TYPE:    list
392PURPOSE: define a ringlist, say QL, of the first argument, say RL, which is
393         assumed to be the ringlist of a qring, but where the quotient ideal
394         RL[4] is not a standard basis with respect to the given monomial
395         order in RL[3]. Then QL will be obtained from RL just by replacing
396         RL[4] by a standard of it with respect to this order. RL itself
397         will be returnd if size(RL[4]) <= 1 (in which case it is known to be
398         a standard basis w.r.t. any ordering) or if a second argument
399         \"isSB\" of type string is given.
400NOTE:    the command ring(quotientList(RL)) defines a quotient ring correctly
401         and should be used instead of ring(RL) if the quotient ideal RL[4]
402         is not (or not known to be) a standard basis with respect to the
403         monomial ordering specified in RL[3].
404SEE ALSO: ringlist, ring
405EXAMPLE: example quotientList; shows an example"
406{
407   def P = basering;
408   if( size(#) > 0 )
409   {
410      if ( #[1] == "isSB")
411      {
412         return (RL);
413      }
414   }
415   ideal Qideal  = RL[4];  //##Achtung: falls basering Nullteiler hat, kann
416                           //die SB eines Elements mehrere Elemente enthalten
417   if( size(Qideal) <= 0)
418   {
419      return (RL);
420   }
421
422   RL[4] = ideal(0);
423   def Phelp = ring(RL);
424   setring Phelp;
425   ideal Qideal = groebner(fetch(P,Qideal));
426   setring P;
427   RL[4]=fetch(Phelp,Qideal);
428   return (RL);
429}
430example
431{ "EXAMPLE:"; echo = 2;
432   ring P = 0,(y,z,u,v),lp;
433   ideal i = y+u2+uv3, z+uv3;            //i is an lp-SB but not a dp_SB
434   qring Q = std(i);
435   list LQ = ringlist(Q);
436   LQ[3][1][1]="dp";
437   def Q1 = ring(quotientList(LQ));
438   setring Q1;
439   Q1;
440
441   setring Q;
442   ideal q1 = uv3+z, u2+y-z, yv3-zv3-zu; //q1 is a dp-standard basis
443   LQ[4] = q1;
444   def Q2 = ring(quotientList(LQ,"isSB"));
445   setring Q2;
446   Q2;
447}
448
449///////////////////////////////////////////////////////////////////////////////
450proc par2varRing (list #)
451"USAGE:   par2varRing([l]); l list of ideals/modules [default:l=empty list]
452RETURN:  list, say L, with L[1] a ring where the parameters of the
453         basering have been converted to an additional last block of
454         variables, all of weight 1, and ordering dp.
455         If a list l with l[i] an ideal/module is given, then
456         l[i] + minpoly*freemodule(nrows(l[i])) is mapped to an ideal/module
457         in L[1] with name Id(i).
458         If the basering has no parameters then L[1] is the basering.
459EXAMPLE: example par2varRing; shows an example"
460{
461   def P = basering;
462   int npar = npars(P);  //number of parameters
463   int s = size(#);
464   int ii;
465   if ( npar == 0)
466   {
467     dbprint(printlevel-voice+3,"// ** no parameters, ring was not changed");
468     for( ii = 1; ii <= s; ii++)
469     {
470        def Id(ii) = #[ii];
471        export (Id(ii));
472     }
473     return(list(P));
474   }
475
476   list rlist = ringlist(P);
477   list parlist = rlist[1];
478   rlist[1] = parlist[1];
479   poly Minpoly = minpoly;     //check for minpoly:
480   int sm = size(Minpoly);
481
482   //now create new ring
483   for( ii = 1; ii <= s; ii++)
484   {
485      def Id(ii) = #[ii];
486   }
487   int nvar = size(rlist[2]);
488   int nblock = size(rlist[3]);
489   int k;
490   for (k=1; k<=npar; k++)
491   {
492      rlist[2][nvar+k] = parlist[2][k];   //change variable list
493   }
494
495   //converted parameters get one block dp. If module ordering was in front
496   //it stays in front, otherwise it will be moved to the end
497   intvec OW = 1:npar;
498   if( rlist[3][nblock][1] =="c" || rlist[3][nblock][1] =="C" )
499   {
500      rlist[3][nblock+1] = rlist[3][nblock];
501      rlist[3][nblock] = list("dp",OW);
502   }
503   else
504   {
505      rlist[3][nblock+1] = list("dp",OW);
506   }
507
508   def Ppar2var = ring(quotientList(rlist));
509   setring Ppar2var;
510   if ( sm == 0 )
511   {
512      for( ii = 1; ii <= s; ii++)
513      {
514        def Id(ii) = imap(P,Id(ii));
515        export (Id(ii));
516      }
517   }
518   else
519   {
520      if( find(option(),"prot") ){"//add minpoly to input";}
521      poly Minpoly = imap(P,Minpoly);
522      for( ii = 1; ii <= s; ii++)
523      {
524        def Id(ii) = imap(P,Id(ii));
525        Id(ii) = Id(ii),Minpoly*freemodule(nrows(Id(ii)));
526        export (Id(ii));
527      }
528   }
529   list Lpar2var = Ppar2var;
530   return(Lpar2var);
531}
532example
533{ "EXAMPLE:"; echo = 2;
534   ring R = (0,x),(y,z,u,v),lp;
535   minpoly = x2+1;
536   ideal i = x3,x2+y+z+u+v,xyzuv-1; i;
537   def P = par2varRing(i)[1]; P;
538   setring(P);
539   Id(1);
540
541   setring R;
542   module m = x3*[1,1,1], (xyzuv-1)*[1,0,1];
543   def Q = par2varRing(m)[1]; Q;
544   setring(Q);
545   print(Id(1));
546}
547
548//////////////////////////////////////////////////////////////////////////////
549proc hilbRing ( list # )
550"USAGE:   hilbRing([l]); l list of ideals/modules [default:l=empty list]
551RETURN:  list, say L: L[1] is a ring and L[2] an intvec
552         L[1] is a ring whith an extra homogenizing variable with name @,
553         resp. @(i) if @ and @(1), ..., @(i-1) are defined.
554         The monomial ordering of L[1] is 1 block dp if the
555         weights of the variables of the basering, say R, are all 1, resp.
556         wp(w,1) wehre w is the intvec of weights of the variables of R.
557         If R is a quotient ring P/Q, then L[1] is not a quotient ring but
558         contains the ideal @Qidealhilb@, the homogenized ideal Q of P.
559         (Parameters of R are not touched).
560         If a list l is given with l[i] an ideal, then l[i] is
561         mapped to the homogenized ideal Id(i) in L[1].
562         L[2] is the intvec (w,1)
563PURPOSE: Prepare a ring for computing the (weighted) hilbert series of
564         an ideal with an easy monomial ordering.
565EXAMPLE: example hilbRing; shows an example
566"
567{
568   def P = basering;
569   ideal Qideal = ideal(P);    //defining the quotient ideal if P is a qring
570   if( size(Qideal) != 0 )
571   {
572     int is_qring =1;
573   }
574   list BRlist = ringlist(P);
575   BRlist[4] = ideal(0);
576
577   int nvarP = nvars(P);
578   int s = size(#);
579   intvec w;                   //for ringweights of basering P
580   int k;
581   for(k=1;  k<=nvarP; k++)
582   {
583       w[k]=deg(var(k));
584   }
585
586   for(k = 1; k <= s; k++)
587   {
588      def Id(k) = #[k];
589      int nr(k) = nrows(Id(k));
590   }
591
592    // a homogenizing variable is added:
593    // call it @, resp. @(k) if @(1),...,@(k-1) are defined
594    string homvar;
595    if ( defined(@)==0 )
596    {
597       homvar = "@";
598    }
599    else
600    {
601       k=1;
602       while( defined(@(k)) != 0 )
603       {
604          k++;
605       }
606       homvar = "@("+string(k)+")";
607    }
608    BRlist[2][nvarP+1] = homvar;
609    w[nvarP +1]=1;
610
611    //ordering is set to (dp,C) if weights of all variables are 1
612    //resp. to (wp(w,1),C) where w are the ringweights of basering P
613    //homogenizing var gets weight 1:
614
615    BRlist[3] = list();
616    if(w==1)
617    {
618      BRlist[3][1]=list("dp",w);
619    }
620    else
621    {
622      BRlist[3][1]=list("wp",w);
623    }
624    BRlist[3][2]=list("C",intvec(0));
625
626    //change ring and get ideal from previous ring
627    def Philb = ring(quotientList(BRlist));
628    kill BRlist;
629    setring Philb;
630    if( defined(is_qring) )
631    {
632       ideal @Qidealhilb@ =  homog( imap(P,Qideal), `homvar` );
633       export(@Qidealhilb@);
634
635       if( find(option(),"prot") ){"add quotient ideal to input";}
636       for(k = 1; k <= s; k++)
637       {  //homogenize
638          def Id(k) =  homog( imap(P,Id(k)), `homvar` );
639              Id(k) =  Id(k),@Qidealhilb@*freemodule(nr(k)) ;
640          export(Id(k));
641       }
642    }
643    else
644    {
645        for(k = 1; k <= s; k++)
646        { //homogenize
647            def Id(k) =  homog( imap(P,Id(k)), `homvar` );
648            export(Id(k));
649        }
650    }
651    list Lhilb = Philb,w;
652    return(Lhilb);
653}
654example
655{ "EXAMPLE:"; echo = 2;
656   ring R = 0,(x,y,z,u,v),lp;
657   ideal i = x+y2+z3,xy+xv+yz+zu+uv,xyzuv-1;
658   def P = hilbRing(i)[1];  P;
659   setring P;
660   Id(1);
661   hilb(std(Id(1)),1);
662
663   ring S =  0,(x,y,z,u,v),lp;
664   qring T = std(x+y2+z3);
665   ideal i = xy+xv+yz+zu+uv,xyzuv-v5;
666   module m = i*[0,1,1] + (xyzuv-v5)*[1,1,0];
667   def Q = hilbRing(m)[1];  Q;
668   setring Q;
669   print(Id(1));
670}
671
672//////////////////////////////////////////////////////////////////////////////
673proc qslimgb (i)
674"USAGE:   qslimgb(i); i ideal or module
675RETURN:  same type as input, a standard basis of i computed with slimgb
676NOTE:    As long as slimgb does not know qrings qslimgb should be used in case
677         the basering is (possibly) a quotient ring. The quotient ideal is
678         added to the input and slimgb is applied.
679EXAMPLE: example qslimgb; shows an example"
680{
681    def P = basering;
682    ideal Qideal = ideal(P);      //defining the quotient ideal if P is a qring
683    int p_opt;
684    if( find(option(),"prot") )
685    {
686      p_opt=1;
687    }
688    if (size(Qideal) == 0)
689    {
690      if (p_opt)
691      {
692         "slimgb in ring " + string(P);
693      }
694      return(slimgb(i));
695    }
696
697    //case of a qring; since slimgb does not know qrings we
698    //delete the quotient ideal and add it to i
699
700    list BRlist = ringlist(P);
701    BRlist[4] = ideal(0);
702    def Phelp = ring(BRlist);
703    kill BRlist;
704    setring Phelp;
705    // module case:
706    def iq = imap(P,i);
707    iq = iq, imap(P,Qideal)*freemodule(nrows(iq));
708    if (p_opt)
709    {
710       "slimgb in ring " + string(Phelp);
711       "(with quotient ideal added to input)";
712    }
713    iq = slimgb(iq);
714
715    setring P;
716    if (p_opt)
717    {
718       "//imap to original ring";
719    }
720    i = imap(Phelp,iq);
721    kill Phelp;
722
723    if (find(option(),"redSB") > 0)
724    {
725       if (p_opt)
726       {
727         "//interreduction";
728       }
729       i=interred(i);
730    }
731    attrib(i, "isSB", 1);
732    return (i);
733}
734example
735{ "EXAMPLE:"; echo = 2;
736   ring R  = (0,v),(x,y,z,u),dp;
737   qring Q = std(x2-y3);
738   ideal i = x+y2,xy+yz+zu+u*v,xyzu*v-1;
739   ideal j = qslimgb(i); j;
740
741   module m = [x+y2,1,0], [1,1,x2+y2+xyz];
742   print(qslimgb(m));
743}
744
745//////////////////////////////////////////////////////////////////////////////
746proc groebner(def i_par, list #)
747"SYNTAX: @code{groebner (} ideal_expression @code{)} @*
748         @code{groebner (} module_expression @code{)} @*
749         @code{groebner (} ideal_expression@code{,} int_expression @code{)} @*
750         @code{groebner (} module_expression@code{,} int_expression @code{)}
751         @code{groebner (} ideal_expression@code{,} list of string_expressions
752               @code{)} @*
753         @code{groebner (} ideal_expression@code{,} list of string_expressions
754               and int_expression @code{)} @*
755         @code{groebner (} ideal_expression@code{,} int_expression @code{)} @*
756TYPE:    type of the first argument
757PURPOSE: computes a standard basis of the first argument @code{I}
758         (ideal or module), by a heuristically chosen method (default)
759         or by a method specified by further arguments of type string.
760         Possible methods are:  @*
761         - the direct methods @code{\"std\"} or @code{\"slimgb\"} without
762           conversion @*
763         - conversion methods @code{\"hilb\"} or @code{\"fglm\"} where
764           a Groebner basis is first computed with an \"easy\" ordering
765           and then converted to the ordering of the basering by the
766           Hilbert driven Groebner basis computation or by linear algebra.
767           The actual computation of the Groebner basis can be
768           specified by @code{\"std\"} or by @code{\"slimgb\"}
769           (not implemented for all orderings) @*
770         A further string @code{\"par2var\"} converts parameters to an extra
771         block of variables before a Groebner basis computation (and
772         afterwards back).
773         @code{option(prot)} tells about the chosen method.
774NOTE:    If a further argument, say @code{wait}, of type int is given,
775         then the computation proceeds at most @code{wait} seconds.
776         That is, if no result could be computed in @code{wait} seconds,
777         then the computation is interrupted, 0 is returned, a warning
778         message is displayed, and the global variable
779         @code{Standard::groebner_error} is defined.
780         This feature uses MP and is hence only available on UNIX platforms.
781HINT:    Since there exists no uniform best method for computing standard
782         bases, and since the difference in performance of a method on
783         different examples can be huge, it is recommended to test, for hard
784         examples, first various methods on a simplified example (e.g. use
785         characteristic 32003 instead of 0 or substitute a subset of
786         parameters/variables by integers, etc.). @*
787SEE ALSO: stdhilb, stdfglm, std, slimgb
788KEYWORDS: time limit on computations; MP, groebner basis computations
789EXAMPLE: example groebner;  shows an example"
790{
791
792//Vorgabe einer Teilmenge aus {hilb,fglm,par2var,std,slimgb}
793//Aktuelle Einstellungen (Jan 2007):
794//---------------------------------
795//0. Immer Aufruf von std unabhaengig von der Vorgabe:
796//   gemischte Ordnungen, extra Gewichtsvektor, Matrix Ordnungen
797
798//1. Keine Vorgabe: es wirkt die aktuelle Heuristk:
799//   - Char p: std
800//   - Char = 0: slimgb (im qring wird Quotientenideal zum Input addiert)
801//   - 1-Block-Ordnungen: direkt Aufruf von std oder slimgb
802//   - Komplizierte Ordnungen (lp oder > 1 Block): hilb
803//   - Parameter werden grundsaetzlich nicht in Variable umgewandelt
804//   ? alternativ: more than 1 parameter will be converted to ring variable ?
805//   - fglm is keine Heruristik, da sonst vorher dim==0 peprueft werden muss
806
807//2. Vorgabe aus {std,slimgb}: es wird wo immer moeglich das angegebene
808//   gewaehlt (da slimgb keine Hilbertfunktion kennt, wird std verwendet).
809//   Bei slimgb im qring, wird das Quotientenideal zum Ideal addiert.
810//   Bei Angabe von std zusammen mit slimgb (aequivalent zur Angabe von
811//   keinem von beidem) wirkt obige Heuristik.
812
813//3. Nichtleere Vorgabe aus {hilb,fglm,std,slimgb}:
814//   es wird nur das angegebene und moegliche sowie das notwendige verwendet
815//   und bei Wahlmoeglickeit je nach Heuristik.
816//   Z.B. Vorgabe von {hilb} ist aequivalent zu {hilb,std,slimgb} und es wird
817//   hilb und nach Heuristik std oder slimgb verwendet, aber nicht par2var;
818//   bei Vorgabe von {hilb,slimgb} wird hilb und wo moeglich slimgb verwendet.
819
820//4. Bei Vorgabe von {par2var} wird par2var immer mit hilb und nach Heuristik
821//   std oder slimgb verwendet. Zu Variablen konvertierte Parameter haben
822//   extra letzten Block und Gewichte 1.
823
824
825  def P=basering;
826  if ((typeof(i_par)=="vector")||(typeof(i_par)=="module")) {module i=i_par;}
827  else {ideal i=i_par; }
828  kill i_par;
829
830//----------------------- save the given method ---------------------------
831  string method;
832  list Method;
833  int k;
834  for (k=1; k<=size(#); k++)
835  {
836     if (typeof(#[k]) == "int")
837     {
838       int wait = #[k];
839     }
840     if (typeof(#[k]) == "string")
841     {
842       method = method + "," + #[k];
843       Method = Method + list(#[k]);
844     }
845  }
846
847 //======= we have an argument of type int -- try to use MPfork links =======
848  if ( defined(wait) == voice )
849  {
850    if ( system("with", "MP") )
851    {
852        int j = 10;
853        string bs = nameof(basering);
854        link l_fork = "MPtcp:fork";
855        open(l_fork);
856        write(l_fork, quote(system("pid")));
857        int pid = read(l_fork);
858//        write(l_fork, quote(groebner(eval(i))));
859        write(l_fork, quote(groebner(eval(i),eval(Method))));
860//###Fehlermeldung:
861// ***dError: undef. ringorder used
862// occured at:
863
864        // sleep in small intervalls for appr. one second
865        if (wait > 0)
866        {
867          while(j < 1000000)
868          {
869            if (status(l_fork, "read", "ready", j)) {break;}
870            j = j + j;
871          }
872        }
873
874        // sleep in intervalls of one second from now on
875        j = 1;
876        while (j < wait)
877        {
878          if (status(l_fork, "read", "ready", 1000000)) {break;}
879          j = j + 1;
880        }
881
882        if (status(l_fork, "read", "ready"))
883        {
884          def result = read(l_fork);
885          if (bs != nameof(basering))
886          {
887            def PP = basering;
888            setring P;
889            def result = imap(PP, result);
890            kill PP;
891          }
892          if (defined(groebner_error))
893          {
894            kill groebner_error;
895          }
896          kill l_fork;
897        }
898        else
899        {
900          ideal result;
901          if (! defined(groebner_error))
902          {
903            int groebner_error = 1;
904            export groebner_error;
905          }
906          "** groebner did not finish";
907          j = system("sh", "kill " + string(pid));
908        }
909        return (result);
910    }
911    else
912    {
913      "** groebner with a time limit on computation is not supported
914          in this configuration";
915    }
916  }
917
918 //=========== we are still here -- do the actual computation =============
919
920//--------------------- save data from basering ---------------------------
921  poly Minpoly = minpoly;      //minimal polynomial
922  int was_minpoly;             //remembers if there was a minpoly in P
923  if (size(Minpoly) > 0)
924  {
925     was_minpoly = 1;
926  }
927
928  ideal Qideal = ideal(P);      //defining the quotient ideal if P is a qring
929  int was_qring;                //remembers if basering was a qring
930  int is_homog = homog(Qideal); //remembers if Qideal was homog (homog(0)=1)
931  if (size(Qideal) > 0)
932  {
933     was_qring = 1;
934  }
935  list BRlist = ringlist(P);
936
937  // save ordering of basering P for later use
938  list ord_P = BRlist[3];       //should be available in all rings
939  string ordstr_P = ordstr(P);
940  int nvars_P = nvars(P);
941  int npars_P = npars(P);
942  intvec w;                     //for ringweights of basering P
943  for(k=1;  k<=nvars_P; k++)
944  {
945     w[k]=deg(var(k));
946  }
947  int neg=1-attrib (P,"global");
948
949  //save options:
950  intvec opt=option(get);
951  string s_opt = option();
952  int p_opt;
953  if (find(s_opt, "prot"))  { p_opt = 1; }
954
955//------------------ cases where std is always used ------------------------
956//If other methods are not implemented or do not make sense, i.e. for
957//local or mixed orderings, matrix orderings, extra weight vector and modules
958
959  if(  ( find(ordstr_P,"s") > 0 )
960    || ( find(ordstr_P,"M") > 0 )
961    || ( find(ordstr_P,"a") > 0 )
962    || ( neg>0 ) )
963  {
964    if (p_opt) { "std in basering"; }
965    return(std(i));
966  }
967
968//now we have:
969//ideal or module, global ordering, no matrix ordering, no extra weight vector
970//The interesting cases start now.
971
972 //------------------ classify the possible settings ---------------------
973 string algorithm;       //possibilities: std, slimgb, stdorslimgb
974 string conversion;      //possibilities: hilb, fglm, hilborfglm, no
975 string partovar;        //possibilities: yes, no
976 string order;           //possibilities: simple, !simple
977 string direct;          //possibilities: yes, no
978
979  //define algorithm:
980  if( find(method,"std") && !find(method,"slimgb") )
981  {
982     algorithm = "std";
983  }
984  if( find(method,"slimgb") && !find(method,"std") )
985  {
986     algorithm = "slimgb";
987  }
988  if( find(method,"std") && find(method,"slimgb") ||
989      (!find(method,"std") && !find(method,"slimgb")) )
990  {
991     algorithm = "stdorslimgb";
992  }
993
994  //define conversion:
995  if( find(method,"hilb") && !find(method,"fglm") )
996  {
997     conversion = "hilb";
998  }
999  if( find(method,"fglm") && !find(method,"hilb") )
1000  {
1001     conversion = "fglm";
1002  }
1003  if( find(method,"fglm") && find(method,"hilb") )
1004  {
1005     conversion = "hilborfglm";
1006  }
1007  if( !find(method,"fglm") && !find(method,"hilb") )
1008  {
1009     conversion = "no";
1010  }
1011
1012  //define partovar:
1013  if( find(method,"par2var") && npars_P > 0 )
1014  {
1015     partovar = "yes";
1016  }
1017  else
1018  {
1019     partovar = "no";
1020  }
1021
1022  //define order:
1023  if (system("nblocks") <= 2)
1024  {
1025    if ( find(ordstr_P,"M")+find(ordstr_P,"lp")+find(ordstr_P,"rp") <= 0 )
1026    {
1027      order = "simple";
1028    }
1029  }
1030
1031  //define direct:
1032  if ( (order=="simple" && (size(method)==0 )) ||
1033        (order=="simple" && (method==",par2var" && npars_P==0 )) ||
1034         (conversion=="no" && partovar=="no" &&
1035           (algorithm=="std" || algorithm=="slimgb" ||
1036            (find(method,"std") && find(method,"slimgb")) ) ) )
1037  {
1038     direct = "yes";
1039  }
1040  else
1041  {
1042     direct = "no";
1043  }
1044
1045  //order=="simple" means that the ordering of the variables consists of one
1046  //block which is not a matrix ordering and not a lexicographical ordering.
1047  //(Note:Singular counts always least 2 blocks, one is for module component):
1048  //Call a method "direct" if conversion=="no" && partovar="no" which means
1049  //that we apply std or slimgb dircet in the basering (exception
1050  //as long as slimgb does not know qrings: in a qring of a ring P
1051  //the ideal Qideal is added to the ideal and slimgb is applied in P).
1052  //We apply a direct method if we have a simple monomial ordering, if no
1053  //conversion (fglm or hilb) is specified and if the parameters shall
1054  //not be made to variables
1055
1056//---------------------------- direct methods -----------------------------
1057  if ( direct == "yes" )
1058  {
1059     if ( algorithm=="std" || (algorithm=="stdorslimgb" && char(P)>0) )
1060     {
1061           if (p_opt) { "std in " + string(P); }
1062           i = std(i);
1063           return(i);
1064     }
1065     if ( algorithm=="slimgb" || (algorithm=="stdorslimgb" && char(P)==0) )
1066     {
1067           i = qslimgb(i);
1068           return(i);
1069     }
1070  }
1071
1072//--------------------------- indirect methods -----------------------------
1073//indirect methods are methods where a conversion is used with a ring change
1074//We are in the following situation:
1075//direct=="no" (i.e. "hilb" or "fglm" or "par2var" is given)
1076//or no method is given and we have a complicated monomial ordering
1077//Note thar "par2var" is not a default strategy, it must be explicitely
1078//given in order to be performed.
1079
1080//------------ case where no parameters are made to variables  -------------
1081   if (  partovar == "no" && conversion == "hilb"
1082     || (partovar == "no" && conversion == "fglm" )
1083     || (partovar == "no" && conversion == "hilborfglm" )
1084     || (partovar == "no" && conversion == "no" && direct == "no") )
1085        //last case: heuristic
1086   {
1087     if ( conversion=="fglm" )
1088     {
1089       if ( algorithm=="std" || (algorithm=="stdorslimgb" && char(P)>0) )
1090       {
1091         return (stdfglm(i,"std"));
1092       }
1093       if ( algorithm=="slimgb" || (algorithm=="stdorslimgb" && char(P)==0) )
1094       {
1095         return (stdfglm(i,"slimgb"));
1096       }
1097     }
1098     else
1099     {
1100       if ( algorithm=="std" || (algorithm=="stdorslimgb" && char(P)>0) )
1101       {
1102         return (stdhilb(i,"std"));
1103       }
1104       if ( algorithm=="slimgb" || (algorithm=="stdorslimgb" && char(P)==0) )
1105       {
1106         return (stdhilb(i,"slimgb"));
1107       }
1108     }
1109   }
1110
1111//------------ case where parameters are made to variables  ----------------
1112//define a ring Phelp via par2varRing in which the parameters are variables
1113
1114   else
1115   {
1116      // reset options
1117      option(none);
1118      // turn on options prot, mem, redSB, intStrategy if previously set
1119      if ( find(s_opt, "prot") )
1120      { option(prot); }
1121      if ( find(s_opt, "mem") )
1122      { option(mem); }
1123      if ( find(s_opt, "redSB") )
1124      { option(redSB); }
1125      if ( find(s_opt, "intStrategy") )
1126      { option(intStrategy); }
1127
1128      is_homog = is_homog*homog(i); //check for homogeneity of i and Qideal
1129
1130     //first clear denominators of parameters
1131      if (npars_P > 0)
1132      {
1133         for( k=ncols(i); k>0; k-- )
1134         { i[k]=cleardenom(i[k]); }
1135      }
1136
1137      def Phelp = par2varRing(i)[1];   //minpoly is mapped with i
1138      setring Phelp;
1139      def i = Id(1);
1140      is_homog = homog(i);
1141
1142      //If parameters are converted to ring variables, they appear in an extra
1143      //block. Therefore we use always hilb for this block ordering:
1144      if ( conversion=="fglm" )
1145      {
1146         i = (stdfglm(i));       //only uesful for 1 parameter with minpoly
1147      }
1148      else
1149      {
1150        if ( algorithm=="std" || (algorithm=="stdorslimgb" && char(P)>0) )
1151        {
1152           i = stdhilb(i,"std");
1153        }
1154        if ( algorithm=="slimgb" || (algorithm=="stdorslimgb" && char(P)==0) )
1155        {
1156           i = stdhilb(i,"slimgb");
1157        }
1158      }
1159   }
1160
1161//-------------------- go back to original ring ---------------------------
1162//The main computation is done. However, the SB coming from a ring with
1163//extra variables is in general too big. We simplify it befor mapping it
1164//to the basering.
1165
1166       if (p_opt)
1167       {
1168         "//simplification";
1169       }
1170
1171       if (was_minpoly)
1172       {
1173          ideal Minpoly = imap(P,Minpoly);
1174          attrib(Minpoly,"isSB",1);
1175          i = simplify(NF(i,Minpoly),2);
1176       }
1177
1178       def Li = lead(i);
1179       setring P;
1180       def Li = imap(Phelp,Li);
1181       Li = simplify(Li,32);
1182       intvec vi;
1183       for (k=1; k<=ncols(Li); k++)
1184       {
1185         vi[k] = Li[k]==0;
1186       }
1187
1188       setring Phelp;
1189       for (k=1;  k<=size(i) ;k++)
1190       {
1191           if(vi[k]==1)
1192           {
1193              i[k]=0;
1194           }
1195       }
1196       i = simplify(i,2);
1197
1198       setring P;
1199       if (p_opt)
1200       {
1201         "//imap to original ring";
1202       }
1203       i = imap(Phelp,i);
1204       kill Phelp;
1205       i = simplify(i,34);
1206
1207       // clean-up time
1208       option(set, opt);
1209       if (find(s_opt, "redSB") > 0)
1210       {
1211         if (p_opt)
1212         {
1213           "//interreduction";
1214         }
1215         i=interred(i);
1216       }
1217       attrib(i, "isSB", 1);
1218       return (i);
1219}
1220example
1221{ "EXAMPLE: "; echo=2;
1222  intvec opt = option(get);
1223  option(prot);
1224  ring r  = 0,(a,b,c,d),dp;
1225  ideal i = a+b+c+d,ab+ad+bc+cd,abc+abd+acd+bcd,abcd-1;
1226  groebner(i);
1227
1228  ring s  = 0,(a,b,c,d),lp;
1229  ideal i = imap(r,i);
1230  groebner(i,"hilb");
1231
1232  ring R  = (0,a),(b,c,d),lp;
1233  minpoly = a2+1;
1234  ideal i = a+b+c+d,ab+ad+bc+cd,abc+abd+acd+bcd,d2-c2b2;
1235  groebner(i,"par2var","slimgb");
1236
1237  groebner(i,"fglm");          //computes a reduced standard basis
1238
1239  if (system("with","MP")) {groebner(i,10,"std");}
1240  defined(Standard::groebner_error);
1241  option(set,opt);
1242}
1243
1244//////////////////////////////////////////////////////////////////////////
1245
1246proc res(list #)
1247"@c we do texinfo here:
1248@cindex resolution, computation of
1249@table @code
1250@item @strong{Syntax:}
1251@code{res (} ideal_expression@code{,} int_expression @code{[,} any_expression @code{])}
1252@*@code{res (} module_expression@code{,} int_expression @code{[,} any_expression @code{])}
1253@item @strong{Type:}
1254resolution
1255@item @strong{Purpose:}
1256computes a (possibly minimal) free resolution of an ideal or module using
1257a heuristically chosen method.
1258@* The second (int) argument (say, @code{k}) specifies the length of
1259the resolution. If it is not positive then @code{k} is assumed to be the
1260number of variables of the basering.
1261@* If a third argument is given, the returned resolution is minimized.
1262
1263Depending on the input, the returned resolution is computed using the
1264following methods:
1265@table @asis
1266@item @strong{quotient rings:}
1267@code{nres} (classical method using syzygies) , see @ref{nres}.
1268
1269@item @strong{homogeneous ideals and k=0:}
1270@code{lres} (La'Scala's method), see @ref{lres}.
1271
1272@item @strong{not minimized resolution and (homogeneous input with k not 0, or local rings):}
1273@code{sres} (Schreyer's method), see @ref{sres}.
1274
1275@item @strong{all other inputs:}
1276@code{mres} (classical method), see @ref{mres}.
1277@end table
1278@item @strong{Note:}
1279Accessing single elements of a resolution may require that some partial
1280computations have to be finished and may therefore take some time.
1281@end table
1282@c ref
1283See also
1284@ref{betti};
1285@ref{ideal};
1286@ref{minres};
1287@ref{module};
1288@ref{mres};
1289@ref{nres};
1290@ref{lres};
1291@ref{hres};
1292@ref{sres}.
1293@ref{resolution}
1294@c ref
1295"
1296{
1297   def P=basering;
1298   if (size(#) < 2)
1299   {
1300     ERROR("res: need at least two arguments: ideal/module, int");
1301   }
1302
1303   def m=#[1]; //the ideal or module
1304   int i=#[2]; //the length of the resolution
1305   if (i< 0) { i=0;}
1306
1307   string varstr_P = varstr(P);
1308
1309   int p_opt;
1310   string s_opt = option();
1311   // set p_opt, if option(prot) is set
1312   if (find(s_opt, "prot"))
1313   {
1314     p_opt = 1;
1315   }
1316
1317   if(size(ideal(basering)) > 0)
1318   {
1319     // the quick hack for qrings - seems to fit most needs
1320     // (lres is not implemented for qrings, sres is not so efficient)
1321     if (p_opt) { "using nres";}
1322     return(nres(m,i));
1323   }
1324
1325   if(homog(m)==1)
1326   {
1327      resolution re;
1328      if (((i==0) or (i>=nvars(basering))) && typeof(m) != "module")
1329      {
1330        //LaScala for the homogeneous case and i == 0
1331        if (p_opt) { "using lres";}
1332        re=lres(m,i);
1333        if(size(#)>2)
1334        {
1335           re=minres(re);
1336        }
1337      }
1338      else
1339      {
1340        if(size(#)>2)
1341        {
1342          if (p_opt) { "using mres";}
1343          re=mres(m,i);
1344        }
1345        else
1346        {
1347          if (p_opt) { "using sres";}
1348          re=sres(std(m),i);
1349        }
1350      }
1351      return(re);
1352   }
1353
1354   //mres for the global non homogeneous case
1355   if(find(ordstr(P),"s")==0)
1356   {
1357      string ri= "ring Phelp ="
1358                  +string(char(P))+",("+varstr_P+"),(dp,C);";
1359      execute(ri);
1360      def m=imap(P,m);
1361      if (p_opt) { "using mres in another ring";}
1362      list re=mres(m,i);
1363      setring P;
1364      resolution result=imap(Phelp,re);
1365      if (size(#) > 2) {result = minres(result);}
1366      return(result);
1367   }
1368
1369   //sres for the local case and not minimal resolution
1370   if(size(#)<=2)
1371   {
1372      string ri= "ring Phelp ="
1373                  +string(char(P))+",("+varstr_P+"),(ls,c);";
1374      execute(ri);
1375      def m=imap(P,m);
1376      m=std(m);
1377      if (p_opt) { "using sres in another ring";}
1378      list re=sres(m,i);
1379      setring P;
1380      resolution result=imap(Phelp,re);
1381      return(result);
1382   }
1383
1384   //mres for the local case and minimal resolution
1385   string ri= "ring Phelp ="
1386                  +string(char(P))+",("+varstr_P+"),(ls,C);";
1387   execute(ri);
1388   def m=imap(P,m);
1389    if (p_opt) { "using mres in another ring";}
1390   list re=mres(m,i);
1391   setring P;
1392   resolution result=imap(Phelp,re);
1393   result = minres(result);
1394   return(result);
1395}
1396example
1397{"EXAMPLE:"; echo = 2;
1398  ring r=0,(x,y,z),dp;
1399  ideal i=xz,yz,x3-y3;
1400  def l=res(i,0); // homogeneous ideal: uses lres
1401  l;
1402  print(betti(l), "betti"); // input to betti may be of type resolution
1403  l[2];         // element access may take some time
1404  i=i,x+1;
1405  l=res(i,0);   // inhomogeneous ideal: uses mres
1406  l;
1407  ring rs=0,(x,y,z),ds;
1408  ideal i=imap(r,i);
1409  def l=res(i,0); // local ring not minimized: uses sres
1410  l;
1411  res(i,0,0);     // local ring and minimized: uses mres
1412}
1413/////////////////////////////////////////////////////////////////////////
1414
1415proc quot (m1,m2,list #)
1416"SYNTAX: @code{quot (} module_expression@code{,} module_expression @code{)}
1417         @*@code{quot (} module_expression@code{,} module_expression@code{,}
1418            int_expression @code{)}
1419         @*@code{quot (} ideal_expression@code{,} ideal_expression @code{)}
1420         @*@code{quot (} ideal_expression@code{,} ideal_expression@code{,}
1421            int_expression @code{)}
1422TYPE:    ideal
1423SYNTAX:  @code{quot (} module_expression@code{,} ideal_expression @code{)}
1424TYPE:    module
1425PURPOSE: computes the quotient of the 1st and the 2nd argument.
1426         If a 3rd argument @code{n} is given the @code{n}-th method is used
1427         (@code{n}=1...5).
1428SEE ALSO: quotient
1429EXAMPLE: example quot; shows an example"
1430{
1431  if (((typeof(m1)!="ideal") and (typeof(m1)!="module"))
1432     or ((typeof(m2)!="ideal") and (typeof(m2)!="module")))
1433  {
1434    "USAGE:   quot(m1, m2[, n]); m1, m2 two submodules of k^s,";
1435    "         n (optional) integer (1<= n <=5)";
1436    "RETURN:  the quotient of m1 and m2";
1437    "EXAMPLE: example quot; shows an example";
1438    return();
1439  }
1440  if (typeof(m1)!=typeof(m2))
1441  {
1442    return(quotient(m1,m2));
1443  }
1444  if (size(#)>0)
1445  {
1446    if (typeof(#[1])=="int" )
1447    {
1448      return(quot1(m1,m2,#[1]));
1449    }
1450  }
1451  else
1452  {
1453    return(quot1(m1,m2,2));
1454  }
1455}
1456example
1457{ "EXAMPLE:"; echo = 2;
1458  ring r=181,(x,y,z),(c,ls);
1459  ideal id1=maxideal(4);
1460  ideal id2=x2+xyz,y2-z3y,z3+y5xz;
1461  option(prot);
1462  ideal id3=quotient(id1,id2);
1463  id3;
1464  ideal id4=quot(id1,id2,1);
1465  id4;
1466  ideal id5=quot(id1,id2,2);
1467  id5;
1468}
1469
1470static proc quot1 (module m1, module m2,int n)
1471"USAGE:   quot1(m1, m2, n); m1, m2 two submodules of k^s,
1472         n integer (1<= n <=5)
1473RETURN:  the quotient of m1 and m2
1474EXAMPLE: example quot1; shows an example"
1475{
1476  if (n==1)
1477  {
1478    return(quotient1(m1,m2));
1479  }
1480  else
1481  {
1482    if (n==2)
1483    {
1484      return(quotient2(m1,m2));
1485    }
1486    else
1487    {
1488      if (n==3)
1489      {
1490        return(quotient3(m1,m2));
1491      }
1492      else
1493      {
1494        if (n==4)
1495        {
1496          return(quotient4(m1,m2));
1497        }
1498        else
1499        {
1500          if (n==5)
1501          {
1502            return(quotient5(m1,m2));
1503          }
1504          else
1505          {
1506            return(quotient(m1,m2));
1507          }
1508        }
1509      }
1510    }
1511  }
1512}
1513example
1514{ "EXAMPLE:"; echo = 2;
1515  ring r=181,(x,y,z),(c,ls);
1516  ideal id1=maxideal(4);
1517  ideal id2=x2+xyz,y2-z3y,z3+y5xz;
1518  option(prot);
1519  ideal id6=quotient(id1,id2);
1520  id6;
1521  ideal id7=quot1(id1,id2,1);
1522  id7;
1523  ideal id8=quot1(id1,id2,2);
1524  id8;
1525}
1526
1527static proc quotient0(module a,module b)
1528{
1529  module mm=b+a;
1530  resolution rs=lres(mm,0);
1531  list I=list(rs);
1532  matrix M=I[2];
1533  matrix A[1][nrows(M)]=M[1..nrows(M),1];
1534  ideal i=A;
1535  return (i);
1536}
1537proc quotient1(module a,module b)  //17sec
1538"USAGE:   quotient1(m1, m2); m1, m2 two submodules of k^s,
1539RETURN:  the quotient of m1 and m2"
1540{
1541  int i;
1542  a=std(a);
1543  module dummy;
1544  module B=NF(b,a)+dummy;
1545  ideal re=quotient(a,module(B[1]));
1546  for(i=2;i<=ncols(B);i++)
1547  {
1548     re=intersect1(re,quotient(a,module(B[i])));
1549  }
1550  return(re);
1551}
1552proc quotient2(module a,module b)    //13sec
1553"USAGE:   quotient2(m1, m2); m1, m2 two submodules of k^s,
1554RETURN:  the quotient of m1 and m2"
1555{
1556  a=std(a);
1557  module dummy;
1558  module bb=NF(b,a)+dummy;
1559  int i=ncols(bb);
1560  ideal re=quotient(a,module(bb[i]));
1561  bb[i]=0;
1562  module temp;
1563  module temp1;
1564  module bbb;
1565  int mx;
1566  i=i-1;
1567  while (1)
1568  {
1569    if (i==0) break;
1570    temp = a+bb*re;
1571    temp1 = lead(interred(temp));
1572    mx=ncols(a);
1573    if (ncols(temp1)>ncols(a))
1574    {
1575      mx=ncols(temp1);
1576    }
1577    temp1 = matrix(temp1,1,mx)-matrix(lead(a),1,mx);
1578    temp1 = dummy+temp1;
1579    if (deg(temp1[1])<0) break;
1580    re=intersect1(re,quotient(a,module(bb[i])));
1581    bb[i]=0;
1582    i = i-1;
1583  }
1584  return(re);
1585}
1586proc quotient3(module a,module b)   //89sec
1587"USAGE:   quotient3(m1, m2); m1, m2 two submodules of k^s,
1588         only for global rings
1589RETURN:  the quotient of m1 and m2"
1590{
1591  string s="ring @newr=("+charstr(basering)+
1592           "),("+varstr(basering)+",@t,@w),dp;";
1593  def @newP=basering;
1594  execute(s);
1595  module b=imap(@newP,b);
1596  module a=imap(@newP,a);
1597  int i;
1598  int j=ncols(b);
1599  vector @b;
1600  for(i=1;i<=j;i++)
1601  {
1602     @b=@b+@t^(i-1)*@w^(j-i+1)*b[i];
1603  }
1604  ideal re=quotient(a,module(@b));
1605  setring @newP;
1606  ideal re=imap(@newr,re);
1607  return(re);
1608}
1609proc quotient5(module a,module b)   //89sec
1610"USAGE:   quotient5(m1, m2); m1, m2 two submodules of k^s,
1611         only for global rings
1612RETURN:  the quotient of m1 and m2"
1613{
1614  string s="ring @newr=("+charstr(basering)+
1615           "),("+varstr(basering)+",@t),dp;";
1616  def @newP=basering;
1617  execute(s);
1618  module b=imap(@newP,b);
1619  module a=imap(@newP,a);
1620  int i;
1621  int j=ncols(b);
1622  vector @b;
1623  for(i=1;i<=j;i++)
1624  {
1625     @b=@b+@t^(i-1)*b[i];
1626  }
1627  @b=homog(@b,@w);
1628  ideal re=quotient(a,module(@b));
1629  setring @newP;
1630  ideal re=imap(@newr,re);
1631  return(re);
1632}
1633proc quotient4(module a,module b)   //95sec
1634"USAGE:   quotient4(m1, m2); m1, m2 two submodules of k^s,
1635         only for global rings
1636RETURN:  the quotient of m1 and m2"
1637{
1638  string s="ring @newr=("+charstr(basering)+
1639           "),("+varstr(basering)+",@t),dp;";
1640  def @newP=basering;
1641  execute(s);
1642  module b=imap(@newP,b);
1643  module a=imap(@newP,a);
1644  int i;
1645  vector @b=b[1];
1646  for(i=2;i<=ncols(b);i++)
1647  {
1648     @b=@b+@t^(i-1)*b[i];
1649  }
1650  matrix sy=modulo(@b,a);
1651  ideal re=sy;
1652  setring @newP;
1653  ideal re=imap(@newr,re);
1654  return(re);
1655}
1656static proc intersect1(ideal i,ideal j)
1657{
1658  def R=basering;
1659  execute("ring gnir = ("+charstr(basering)+"),
1660                       ("+varstr(basering)+",@t),(C,dp);");
1661  ideal i=var(nvars(basering))*imap(R,i)+(var(nvars(basering))-1)*imap(R,j);
1662  ideal j=eliminate(i,var(nvars(basering)));
1663  setring R;
1664  map phi=gnir,maxideal(1);
1665  return(phi(j));
1666}
1667
1668//////////////////////////////////////////////////////////////////
1669///
1670/// sprintf, fprintf printf
1671///
1672proc sprintf(string fmt, list #)
1673"SYNTAX:  @code{sprintf (} string_expression @code{[,} any_expressions
1674               @code{] )}
1675RETURN:   string
1676PURPOSE:  @code{sprintf(fmt,...);} performs output formatting. The first
1677          argument is a format control string. Additional arguments may be
1678          required, depending on the content of the control string. A series
1679          of output characters is generated as directed by the control string;
1680          these characters are returned as a string. @*
1681          The control string @code{fmt} is simply text to be copied,
1682          except that the string may contain conversion specifications.@*
1683          Do @code{help print;} for a listing of valid conversion
1684          specifications. As an addition to the conversions of @code{print},
1685          the @code{%n} and @code{%2} conversion specification does not
1686          consume an additional argument, but simply generates a newline
1687          character.
1688NOTE:     If one of the additional arguments is a list, then it should be
1689          enclosed once more into a @code{list()} command, since passing a list
1690          as an argument flattens the list by one level.
1691SEE ALSO: fprintf, printf, print, string
1692EXAMPLE : example sprintf; shows an example
1693"
1694{
1695  int sfmt = size(fmt);
1696  if (sfmt  <= 1)
1697  {
1698    return (fmt);
1699  }
1700  int next, l, nnext;
1701  string ret;
1702  list formats = "%l", "%s", "%2l", "%2s", "%t", "%;", "%p", "%b", "%n", "%2";
1703  while (1)
1704  {
1705    if (size(#) <= 0)
1706    {
1707      return (ret + fmt);
1708    }
1709    nnext = 0;
1710    while (nnext < sfmt)
1711    {
1712      nnext = find(fmt, "%", nnext + 1);
1713      if (nnext == 0)
1714      {
1715        next = 0;
1716        break;
1717      }
1718      l = 1;
1719      while (l <= size(formats))
1720      {
1721        next = find(fmt, formats[l], nnext);
1722        if (next == nnext) break;
1723        l++;
1724      }
1725      if (next == nnext) break;
1726    }
1727    if (next == 0)
1728    {
1729      return (ret + fmt);
1730    }
1731    if (formats[l] != "%2" && formats[l] != "%n")
1732    {
1733      ret = ret + fmt[1, next - 1] + print(#[1], formats[l]);
1734      # = delete(#, 1);
1735    }
1736    else
1737    {
1738      ret = ret + fmt[1, next - 1] + print("", "%2s");
1739    }
1740    if (size(fmt) <= (next + size(formats[l]) - 1))
1741    {
1742      return (ret);
1743    }
1744    fmt = fmt[next + size(formats[l]), size(fmt)-next-size(formats[l]) + 1];
1745  }
1746}
1747example
1748{ "EXAMPLE:"; echo=2;
1749  ring r=0,(x,y,z),dp;
1750  module m=[1,y],[0,x+z];
1751  intmat M=betti(mres(m,0));
1752  list l = r, m, M;
1753  string s = sprintf("s:%s,%n l:%l", 1, 2); s;
1754  s = sprintf("s:%n%s", l); s;
1755  s = sprintf("s:%2%s", list(l)); s;
1756  s = sprintf("2l:%n%2l", list(l)); s;
1757  s = sprintf("%p", list(l)); s;
1758  s = sprintf("%;", list(l)); s;
1759  s = sprintf("%b", M); s;
1760}
1761
1762proc printf(string fmt, list #)
1763"SYNTAX:  @code{printf (} string_expression @code{[,} any_expressions@code{] )}
1764RETURN:   none
1765PURPOSE:  @code{printf(fmt,...);} performs output formatting. The first
1766          argument is a format control string. Additional arguments may be
1767          required, depending on the content of the control string. A series
1768          of output characters is generated as directed by the control string;
1769          these characters are displayed (i.e., printed to standard out). @*
1770          The control string @code{fmt} is simply text to be copied, except
1771          that the string may contain conversion specifications. @*
1772          Do @code{help print;} for a listing of valid conversion
1773          specifications. As an addition to the conversions of @code{print},
1774          the @code{%n} and @code{%2} conversion specification does not
1775          consume an additional argument, but simply generates a newline
1776          character.
1777NOTE:     If one of the additional arguments is a list, then it should be
1778          enclosed once more into a @code{list()} command, since passing a
1779          list as an argument flattens the list by one level.
1780SEE ALSO: sprintf, fprintf, print, string
1781EXAMPLE : example printf; shows an example
1782"
1783{
1784  write("", sprintf(fmt, #));
1785}
1786example
1787{ "EXAMPLE:"; echo=2;
1788  ring r=0,(x,y,z),dp;
1789  module m=[1,y],[0,x+z];
1790  intmat M=betti(mres(m,0));
1791  list l=r,m,matrix(M);
1792  printf("s:%s,l:%l",1,2);
1793  printf("s:%s",l);
1794  printf("s:%s",list(l));
1795  printf("2l:%2l",list(l));
1796  printf("%p",matrix(M));
1797  printf("%;",matrix(M));
1798  printf("%b",M);
1799}
1800
1801
1802proc fprintf(link l, string fmt, list #)
1803"SYNTAX:  @code{fprintf (} link_expression@code{,} string_expression @code{[,}
1804                any_expressions@code{] )}
1805RETURN:   none
1806PURPOSE:  @code{fprintf(l,fmt,...);} performs output formatting.
1807          The second argument is a format control string. Additional
1808          arguments may be required, depending on the content of the
1809          control string. A series of output characters is generated as
1810          directed by the control string; these characters are
1811          written to the link l.
1812          The control string @code{fmt} is simply text to be copied, except
1813          that the string may contain conversion specifications.@*
1814          Do @code{help print;} for a listing of valid conversion
1815          specifications. As an addition to the conversions of @code{print},
1816          the @code{%n} and @code{%2} conversion specification does not
1817          consume an additional argument, but simply generates a newline
1818          character.
1819NOTE:     If one of the additional arguments is a list, then it should be
1820          enclosed once more into a @code{list()} command, since passing
1821          a list as an argument flattens the list by one level.
1822SEE ALSO: sprintf, printf, print, string
1823EXAMPLE : example fprintf; shows an example
1824"
1825{
1826  write(l, sprintf(fmt, #));
1827}
1828example
1829{ "EXAMPLE:"; echo=2;
1830  ring r=0,(x,y,z),dp;
1831  module m=[1,y],[0,x+z];
1832  intmat M=betti(mres(m,0));
1833  list l=r,m,M;
1834  link li="";   // link to stdout
1835  fprintf(li,"s:%s,l:%l",1,2);
1836  fprintf(li,"s:%s",l);
1837  fprintf(li,"s:%s",list(l));
1838  fprintf(li,"2l:%2l",list(l));
1839  fprintf(li,"%p",list(l));
1840  fprintf(li,"%;",list(l));
1841  fprintf(li,"%b",M);
1842}
1843
1844//////////////////////////////////////////////////////////////////////////
1845
1846/*
1847proc minres(list #)
1848{
1849  if (size(#) == 2)
1850  {
1851    if (typeof(#[1]) == "ideal" || typeof(#[1]) == "module")
1852    {
1853      if (typeof(#[2] == "int"))
1854      {
1855        return (res(#[1],#[2],1));
1856      }
1857    }
1858  }
1859
1860  if (typeof(#[1]) == "resolution")
1861  {
1862    return minimizeres(#[1]);
1863  }
1864  else
1865  {
1866    return minimizeres(#);
1867  }
1868
1869}
1870*/
1871///////////////////////////////////////////////////////////////////////////////
1872
1873proc weightKB(def stc, int dd, list wim)
1874"SYNTAX: @code{weightKB (} module_expression@code{,} int_expression @code{,}
1875            list_expression @code{)}@*
1876         @code{weightKB (} ideal_expression@code{,} int_expression@code{,}
1877            list_expression @code{)}
1878RETURN:  the same as the input type of the first argument
1879PURPOSE: If @code{I,d,wim} denotes the three arguments then weightKB
1880         computes the weighted degree- @code{d} part of a vector space basis
1881         (consisting of monomials) of the quotient ring, resp. of the
1882         quotient module, modulo @code{I} w.r.t. weights given by @code{wim}
1883         The information about the weights is given as a list of two intvec:
1884            @code{wim[1]} weights for all variables (positive),
1885            @code{wim[2]} weights for the module generators.
1886NOTE:    This is a generalisation for the command @code{kbase} with the same
1887         first two arguments.
1888SEE ALSO: kbase
1889EXAMPLE: example weightKB; shows an example
1890"
1891{
1892  if(checkww(wim)){ERROR("wrong weights";);}
1893  kbclass();
1894  wwtop=wim[1];
1895  stc=interred(lead(stc));
1896  if(typeof(stc)=="ideal")
1897  {
1898    stdtop=stc;
1899    ideal out=widkbase(dd);
1900    delkbclass();
1901    return(out);
1902  }
1903  list mbase=kbprepare(stc);
1904  module mout;
1905  int im,ii;
1906  if(size(wim)>1){mmtop=wim[2];}
1907  else{mmtop=0;}
1908  for(im=size(mbase);im>0;im--)
1909  {
1910    stdtop=mbase[im];
1911    if(im>size(mmtop)){ii=dd;}
1912    else{ii=dd-mmtop[im];}
1913    mout=mout+widkbase(ii)*gen(im);
1914  }
1915  delkbclass();
1916  return(mout);
1917}
1918///////////////////////////////////////////////////////////////////////////////
1919// construct global values
1920static proc kbclass()
1921{
1922  intvec wwtop,mmtop;
1923  export (wwtop,mmtop);
1924  ideal stdtop,kbtop;
1925  export (stdtop,kbtop);
1926  return();
1927}
1928// delete global values
1929static proc delkbclass()
1930{
1931  kill wwtop,mmtop;
1932  kill stdtop,kbtop;
1933  return();
1934}
1935//  select parts of the modul
1936static proc kbprepare(module mstc)
1937{
1938  list rr;
1939  ideal kk;
1940  int i1,i2;
1941  mstc=transpose(mstc);
1942  for(i1=ncols(mstc);i1>0;i1--)
1943  {
1944    kk=0;
1945    for(i2=nrows(mstc[i1]);i2>0;i2--)
1946    {
1947      kk=kk+mstc[i1][i2];
1948    }
1949    rr[i1]=kk;
1950  }
1951  return(rr);
1952}
1953//  check for weights
1954static proc checkww(list vv)
1955{
1956  if(typeof(vv[1])!="intvec"){return(1);}
1957  intvec ww=vv[1];
1958  int mv=nvars(basering);
1959  if(size(ww)<mv){return(1);}
1960  while(mv>0)
1961  {
1962    if(ww[mv]<=0){return(1);}
1963    mv--;
1964  }
1965  if(size(vv)>1)
1966  {
1967    if(typeof(vv[2])!="intvec"){return(1);}
1968  }
1969  return(0);
1970}
1971// The "Caller" for ideals
1972//    dd   - the degree of the result
1973static proc widkbase(int dd)
1974{
1975  if((size(stdtop)==1)&&(deg(stdtop[1])==0)){return(0);}
1976  if(dd<=0)
1977  {
1978    if(dd<0){return(0);}
1979    else{return(1);}
1980  }
1981  int m1,m2;
1982  m1=nvars(basering);
1983  while(wwtop[m1]>dd)
1984  {
1985    m1--;
1986    if(m1==0){return(0);}
1987  }
1988  attrib(stdtop,"isSB",1);
1989  poly mo=1;
1990  if(m1==1)
1991  {
1992    m2=dd/wwtop[1];
1993    if((m2*wwtop[1])==dd)
1994    {
1995      mo=var(1)^m2;
1996      if(reduce(mo,stdtop)==mo){return(mo);}
1997      else{return(0);}
1998    }
1999  }
2000  kbtop=0;
2001  m2=dd;
2002  weightmon(m1-1,m2,mo);
2003  while(m2>=wwtop[m1])
2004  {
2005    m2=m2-wwtop[m1];
2006    mo=mo*var(m1);
2007    if(m2==0)
2008    {
2009      if(reduce(mo,stdtop)==mo)
2010      {
2011        kbtop=kbtop+mo;
2012        return(kbtop);
2013      }
2014    }
2015    weightmon(m1-1,m2,mo);
2016  }
2017  return(kbtop);
2018}
2019// the recursive prozedur
2020//    va     - number of the variable
2021//    drest  - rest of the degree
2022//    mm     - the candidate
2023static proc weightmon(int va, int drest, poly mm)
2024{
2025  while(wwtop[va]>drest)
2026  {
2027    va--;
2028    if(va==0){return();}
2029  }
2030  int m2;
2031  if(va==1)
2032  {
2033    m2=drest/wwtop[1];
2034    if((m2*wwtop[1])==drest)
2035    {
2036      mm=mm*var(1)^m2;
2037      if(reduce(mm,stdtop)==mm){kbtop=kbtop+mm;}
2038    }
2039    return();
2040  }
2041  m2=drest;
2042  weightmon(va-1,m2,mm);
2043  while(m2>=wwtop[va])
2044  {
2045    m2=m2-wwtop[va];
2046    mm=mm*var(va);
2047    if(m2==0)
2048    {
2049      if(reduce(mm,stdtop)==mm)
2050      {
2051        kbtop=kbtop+mm;
2052        return();
2053      }
2054    }
2055    weightmon(va-1,m2,mm);
2056  }
2057  return();
2058}
2059example
2060{ "EXAMPLE:"; echo=2;
2061  ring r=0,(x,y,z),dp;
2062  ideal i = x6,y4,xyz;
2063  intvec w = 2,3,6;
2064  weightKB(i, 12, list(w));
2065}
2066//////////////////////////////////////////////////////////////////////////////
2067
2068/*
2069Versuche:
2070///////////////////////////////////////////////////////////////////////////////
2071proc downsizeSB (I, list #)
2072"USAGE:   downsizeSB(I [,l]); I ideal, l list of integers [default: l=0]
2073RETURN:  intvec, say v, with v[j] either 1 or 0. We have v[j]=1 if
2074         leadmonom(I[j]) is divisible by some leadmonom(I[k]) or if
2075         leadmonom(i[j]) == leadmonom(i[k]) and l[j] >= l[k], with k!=j.
2076PURPOSE: The procedure is applied in a situation where the standard basis
2077         computation in the basering R is done via a conversion through an
2078         overring Phelp with additional variables and where a direct
2079         imap from Phelp to R is too expensive.
2080         Assume Phelp is created by the procedure @code{par2varRing} or
2081         @code{hilbRing} and IPhelp is a SB in Phelp [ with l[j]=
2082         length(IPhelp(j)) or any other integer reflecting the complexity
2083         of a IPhelp[j] ]. Let I = lead(IPhelp) mapped to R and compute
2084         v = downsizeSB(imap(Phelp,I),l) in R. Then, if Ihelp[j] is deleted
2085         for all j with v[j]=1, we can apply imap to the remaining generators
2086         of Ihelp and still get SB in R  (in general not minimal).
2087EXAMPLE: example downsizeSB; shows an example"
2088{
2089   int k,j;
2090   intvec v,l;
2091   poly M,N,W;
2092   int c=size(I);
2093   if( size(#) != 0 )
2094   {
2095     if ( typeof(#[1]) == "intvec" )
2096     {
2097       l = #[1];
2098     }
2099     else
2100     {
2101        ERROR("// 2nd argument must be an intvec");
2102     }
2103   }
2104
2105   l[c+1]=0;
2106   v[c]=0;
2107
2108   j=0;
2109   while(j<c-1)
2110   {
2111     j++;
2112     M = leadmonom(I[j]);
2113     if( M != 0 )
2114     {
2115        for( k=j+1; k<=c; k++ )
2116        {
2117          N = leadmonom(I[k]);
2118          if( N != 0 )
2119          {
2120             if( (M==N) && (l[j]>l[k]) )
2121             {
2122               I[j]=0;
2123               v[j]=1;
2124               break;
2125             }
2126             if( (M==N) && (l[j]<=l[k]) || N/M != 0 )
2127             {
2128               I[k]=0;
2129               v[k]=1;
2130             }
2131          }
2132        }
2133      }
2134   }
2135   return(v);
2136}
2137example
2138{ "EXAMPLE:"; echo = 2;
2139   ring  r = 0,(x,y,z,t),(dp(3),dp);
2140   ideal i = x+y+z+t,xy+yz+xt+zt,xyz+xyt+xzt+yzt,xyzt-t4;
2141   ideal Id = std(i);
2142   ideal I = lead(Id);  I;
2143   ring S = (0,t),(x,y,z),dp;
2144   downsizeSB(imap(r,I));
2145   //Id[5] can be deleted, we still have a SB of i in the ring S
2146
2147   ring R = (0,x),(y,z,u),lp;
2148   ideal i = x+y+z+u,xy+xu+yz+zu,xyz+xyu+xzu+yzu,xyzu-1;
2149   def Phelp = par2varRing()[1];
2150   setring Phelp;
2151   ideal IPhelp = std(imap(R,i));
2152   ideal I = lead(IPhelp);
2153   setring R;
2154   ideal I = imap(Phelp,I); I;
2155   intvec v = downsizeSB(I); v;
2156}
2157///////////////////////////////////////////////////////////////////////////
2158// PROBLEM: Die Prozedur funktioniert nur fuer Ringe die global bekannt
2159//          sind, also interaktiv, aber nicht aus einer Prozedur.
2160//          Z.B. funktioniert example imapDownsize; nicht
2161
2162proc imapDownsize (string R, string I)
2163"SYNTAX: @code{imapDownsize (} string @code{,} string @code{)} *@
2164         First string must be the string of the name of a ring, second
2165         string must be the string of the name of an object in the ring.
2166TYPE:    same type as the object with name the second string
2167PURPOSE: maps the object given by the second string to the basering.
2168         If R resp. I are the first resp. second string, then
2169         imapDownsize(R,I) is equivalent to simplify(imap(`R`,`I`),34).
2170NOTE:    imapDownsize is usually faster than imap if `I` is large and if
2171         simplify has a great effect, since the procedure maps only those
2172         generators from `I` which are not killed by simplify( - ,34).
2173         This is useful if `I` is a standard bases for a block ordering of
2174         `R` and if some variables from the last block in `R` are mapped
2175         to parameters. Then the returned result is a standard basis in
2176         the basering.
2177SEE ALSO: imap, fetch, map
2178EXAMPLE: example imapDownsize; shows an example"
2179{
2180       def BR = basering;
2181       int k;
2182
2183       setring `R`;
2184       def @leadI@ = lead(`I`);
2185       int s = ncols(@leadI@);
2186       setring BR;
2187       ideal @leadI@ = simplify(imap(`R`,@leadI@),32);
2188       intvec vi;
2189       for (k=1; k<=s; k++)
2190       {
2191         vi[k] = @leadI@[k]==0;
2192       }
2193       kill @leadI@;
2194
2195       setring `R`;
2196       kill @leadI@;
2197       for (k=1;  k<=s; k++)
2198       {
2199           if( vi[k]==1 )
2200           {
2201              `I`[k]=0;
2202           }
2203       }
2204       `I` = simplify(`I`,2);
2205
2206       setring BR;
2207       return(imap(`R`,`I`));
2208}
2209example
2210{ "EXAMPLE:"; echo = 2;
2211   ring  r = 0,(x,y,z,t),(dp(3),dp);
2212   ideal i = x+y+z+t,xy+yz+xt+zt,xyz+xyt+xzt+yzt,xyzt-1;
2213   i = std(i); i;
2214
2215   ring s = (0,t),(x,y,z),dp;
2216   imapDownsize("r","i");     //i[5] is omitted since lead(i[2]) | lead(i[5])
2217}
2218///////////////////////////////////////////////////////////////////////////////
2219//die folgende proc war fuer groebner mit fglm vorgesehen
2220//um die projektive Dimension korrekt zu berechnen, muss man aber
2221//voerher ein SB bzgl. einer Gradordnung berechnen und dann homogenisieren.
2222//Sonst koennen hoeherdimensionale Komponenten in Unendlich entstehen
2223
2224proc projInvariants(ideal i,list #)
2225"SYNTAX: @code{projInvariants (} ideal_expression @code{)} @*
2226         @code{projInvariants (} ideal_expression@code{,} list of string_expres          sions@code{)}
2227TYPE:    list, say L, with L[1] and L[2] of type int and L[3] of type intvec
2228PURPOSE: Computes the (projective) dimension (L[1]), degree (L[2]) and the
2229         first Hilbert series (L[3], as intvec) of the homogenized ideal
2230         in the ring given by the procedure @code{hilbRing} with global
2231         ordering dp (resp. wp if the variables have weights >1)
2232         If an argument of type string @code{\"std\"} resp. @code{\"slimgb\"}
2233         is given, the standard basis computatuion uses @code{std} or
2234         @code{slimgb}, otherwise a heuristically chosen method (default)
2235NOTE:    Homogenized means weighted homogenized with respect to the weights
2236         w[i] of the variables var(i) of the basering. The returned dimension,
2237         degree and Hilbertseries are the respective invariants of the
2238         projective variety defined by the homogenized ideal. The dimension
2239         is equal to the (affine) dimension of the ideal in the basering
2240         (degree and Hilbert series make only sense for homogeneous ideals).
2241SEE ALSO: dim, dmult, hilb
2242KEYWORDS: dimension, degree, Hilbert function
2243EXAMPLE: example projInvariants;  shows an example"
2244{
2245  def P = basering;
2246  int p_opt;
2247  string s_opt = option();
2248  if (find(option(), "prot"))  { p_opt = 1; }
2249
2250//---------------- check method and clear denomintors --------------------
2251  int k;
2252  string method;
2253  for (k=1; k<=size(#); k++)
2254  {
2255     if (typeof(#[k]) == "string")
2256     {
2257       method = method + "," + #[k];
2258     }
2259  }
2260
2261  if (npars(P) > 0)             //clear denominators of parameters
2262  {
2263    for( k=ncols(i); k>0; k-- )
2264    {
2265       i[k]=cleardenom(i[k]);
2266    }
2267  }
2268
2269//------------------------ change to hilbRing ----------------------------
2270     list hiRi = hilbRing(i);
2271     intvec W = hiRi[2];
2272     def Philb = hiRi[1];      //note: Philb is no qring and the predefined
2273     setring Philb;            //ideal Id(1) in Philb is homogeneous
2274     int di, de;               //for dimension, degree
2275     intvec hi;                //for hilbert series
2276
2277//-------- compute Hilbert function of homogenized ideal in Philb ---------
2278//Philb has only 1 block. There are three cases
2279
2280     string algorithm;       //possibilities: std, slimgb, stdorslimgb
2281     //define algorithm:
2282     if( find(method,"std") && !find(method,"slimgb") )
2283     {
2284        algorithm = "std";
2285     }
2286     if( find(method,"slimgb") && !find(method,"std") )
2287     {
2288         algorithm = "slimgb";
2289     }
2290     if( find(method,"std") && find(method,"slimgb") ||
2291         (!find(method,"std") && !find(method,"slimgb")) )
2292     {
2293         algorithm = "stdorslimgb";
2294     }
2295
2296     if ( algorithm=="std" || ( algorithm=="stdorslimgb" && char(P)>0 ) )
2297     {
2298        if (p_opt) {"std in ring " + string(Philb);}
2299        Id(1) = std(Id(1));
2300        di = dim(Id(1))-1;
2301        de = mult(Id(1));
2302        hi = hilb( Id(1),1,W );
2303     }
2304     if ( algorithm=="slimgb" || ( algorithm=="stdorslimgb" && char(P)==0 ) )
2305     {
2306        if (p_opt) {"slimgb in ring " + string(Philb);}
2307        Id(1) = slimgb(Id(1));
2308        di = dim( Id(1) );
2309        if (di > -1)
2310        {
2311           di = di-1;
2312        }
2313        de = mult( Id(1) );
2314        hi = hilb( Id(1),1,W );
2315     }
2316     kill Philb;
2317     list L = di,de,hi;
2318     return(L);
2319}
2320example
2321{ "EXAMPLE:"; echo = 2;
2322   ring r = 32003,(x,y,z),lp;
2323   ideal i = y2-xz,x2-z;
2324   projInvariants(i);
2325
2326   ring R = (0),(x,y,z,u,v),lp;
2327   //minpoly = x2+1;
2328   ideal i = x2+1,x2+y+z+u+v,xyzuv-1;
2329   projInvariants(i);
2330   qring S =std(x2+1);
2331   ideal i = imap(R,i);
2332   projInvariants(i);
2333}
2334
2335*/
2336
Note: See TracBrowser for help on using the repository browser.