source: git/Singular/LIB/standard.lib @ 6e11a25

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