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

spielwiese
Last change on this file since 354684 was 354684, checked in by Hans Schönemann <hannes@…>, 17 years ago
*hannes: doc git-svn-id: file:///usr/local/Singular/svn/trunk@10251 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.95 2007-07-25 10:02:25 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 qslimgb(i)             computes a standard basis with slimgb in a qring
20 par2varRing([i])       create a ring with pars to vars together with i
21";
22// hilbRing([i])          create a ring containing the homogenized 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:    Only as long as slimgb does not know qrings qslimgb should be used
664         in case the basering is (possibly) a quotient ring.
665         The quotient ideal is 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=reduce(i,std(0));
708    i=interred(i);
709  }
710  attrib(i, "isSB", 1);
711  return (i);
712}
713example
714{ "EXAMPLE:"; echo = 2;
715   ring R  = (0,v),(x,y,z,u),dp;
716   qring Q = std(x2-y3);
717   ideal i = x+y2,xy+yz+zu+u*v,xyzu*v-1;
718   ideal j = qslimgb(i); j;
719
720   module m = [x+y2,1,0], [1,1,x2+y2+xyz];
721   print(qslimgb(m));
722}
723
724//////////////////////////////////////////////////////////////////////////////
725proc groebner(def i_par, list #)
726"SYNTAX: @code{groebner (} ideal_expression @code{)} @*
727         @code{groebner (} module_expression @code{)} @*
728         @code{groebner (} ideal_expression@code{,} int_expression @code{)} @*
729         @code{groebner (} module_expression@code{,} int_expression @code{)}
730         @code{groebner (} ideal_expression@code{,} list of string_expressions
731               @code{)} @*
732         @code{groebner (} ideal_expression@code{,} list of string_expressions
733               and int_expression @code{)} @*
734         @code{groebner (} ideal_expression@code{,} int_expression @code{)} @*
735TYPE:    type of the first argument
736PURPOSE: computes a standard basis of the first argument @code{I}
737         (ideal or module), by a heuristically chosen method (default)
738         or by a method specified by further arguments of type string.
739         Possible methods are:  @*
740         - the direct methods @code{\"std\"} or @code{\"slimgb\"} without
741           conversion @*
742         - conversion methods @code{\"hilb\"} or @code{\"fglm\"} where
743           a Groebner basis is first computed with an \"easy\" ordering
744           and then converted to the ordering of the basering by the
745           Hilbert driven Groebner basis computation or by linear algebra.
746           The actual computation of the Groebner basis can be
747           specified by @code{\"std\"} or by @code{\"slimgb\"}
748           (not implemented for all orderings) @*
749         A further string @code{\"par2var\"} converts parameters to an extra
750         block of variables before a Groebner basis computation (and
751         afterwards back).
752         @code{option(prot)} tells about the chosen method.
753NOTE:    If a further argument, say @code{wait}, of type int is given,
754         then the computation proceeds at most @code{wait} seconds.
755         That is, if no result could be computed in @code{wait} seconds,
756         then the computation is interrupted, 0 is returned, a warning
757         message is displayed, and the global variable
758         @code{Standard::groebner_error} is defined.
759         This feature uses MP and is hence only available on UNIX platforms.
760HINT:    Since there exists no uniform best method for computing standard
761         bases, and since the difference in performance of a method on
762         different examples can be huge, it is recommended to test, for hard
763         examples, first various methods on a simplified example (e.g. use
764         characteristic 32003 instead of 0 or substitute a subset of
765         parameters/variables by integers, etc.). @*
766SEE ALSO: stdhilb, stdfglm, std, slimgb
767KEYWORDS: time limit on computations; MP, groebner basis computations
768EXAMPLE: example groebner;  shows an example"
769
770{
771//Vorgabe einer Teilmenge aus {hilb,fglm,par2var,std,slimgb}
772//Aktuelle Einstellungen (Jan 2007):
773//---------------------------------
774//0. Immer Aufruf von std unabhaengig von der Vorgabe:
775//   gemischte Ordnungen, extra Gewichtsvektor, Matrix Ordnungen
776
777//1. Keine Vorgabe: es wirkt die aktuelle Heuristk:
778//   - Char p: std
779//   - Char = 0: slimgb (im qring wird Quotientenideal zum Input addiert)
780//   - 1-Block-Ordnungen/non-commutative: direkt Aufruf von std oder slimgb
781//   - Komplizierte Ordnungen (lp oder > 1 Block): hilb
782//   - Parameter werden grundsaetzlich nicht in Variable umgewandelt
783//   ? alternativ: more than 1 parameter will be converted to ring variable ?
784//   - fglm is keine Heuristik, da sonst vorher dim==0 peprueft werden muss
785
786//2. Vorgabe aus {std,slimgb}: es wird wo immer moeglich das angegebene
787//   gewaehlt (da slimgb keine Hilbertfunktion kennt, wird std verwendet).
788//   Bei slimgb im qring, wird das Quotientenideal zum Ideal addiert.
789//   Bei Angabe von std zusammen mit slimgb (aequivalent zur Angabe von
790//   keinem von beidem) wirkt obige Heuristik.
791
792//3. Nichtleere Vorgabe aus {hilb,fglm,std,slimgb}:
793//   es wird nur das angegebene und moegliche sowie das notwendige verwendet
794//   und bei Wahlmoeglickeit je nach Heuristik.
795//   Z.B. Vorgabe von {hilb} ist aequivalent zu {hilb,std,slimgb} und es wird
796//   hilb und nach Heuristik std oder slimgb verwendet, aber nicht par2var;
797//   bei Vorgabe von {hilb,slimgb} wird hilb und wo moeglich slimgb verwendet.
798
799//4. Bei Vorgabe von {par2var} wird par2var immer mit hilb und nach Heuristik
800//   std oder slimgb verwendet. Zu Variablen konvertierte Parameter haben
801//   extra letzten Block und Gewichte 1.
802
803
804  def P=basering;
805  if ((typeof(i_par)=="vector")||(typeof(i_par)=="module")) {module i=i_par;}
806  else {ideal i=i_par; }
807  kill i_par;
808
809//----------------------- save the given method ---------------------------
810  string method;
811  list Method;
812  int k;
813  for (k=1; k<=size(#); k++)
814  {
815     if (typeof(#[k]) == "int")
816     {
817       int wait = #[k];
818     }
819     if (typeof(#[k]) == "string")
820     {
821       method = method + "," + #[k];
822       Method = Method + list(#[k]);
823     }
824  }
825
826 //======= we have an argument of type int -- try to use MPfork links =======
827  if ( defined(wait) == voice )
828  {
829    if ( system("with", "MP") )
830    {
831        int j = 10;
832        string bs = nameof(basering);
833        link l_fork = "MPtcp:fork";
834        open(l_fork);
835        write(l_fork, quote(system("pid")));
836        int pid = read(l_fork);
837//        write(l_fork, quote(groebner(eval(i))));
838        write(l_fork, quote(groebner(eval(i),eval(Method))));
839//###Fehlermeldung:
840// ***dError: undef. ringorder used
841// occured at:
842
843        // sleep in small intervalls for appr. one second
844        if (wait > 0)
845        {
846          while(j < 1000000)
847          {
848            if (status(l_fork, "read", "ready", j)) {break;}
849            j = j + j;
850          }
851        }
852
853        // sleep in intervalls of one second from now on
854        j = 1;
855        while (j < wait)
856        {
857          if (status(l_fork, "read", "ready", 1000000)) {break;}
858          j = j + 1;
859        }
860
861        if (status(l_fork, "read", "ready"))
862        {
863          def result = read(l_fork);
864          if (bs != nameof(basering))
865          {
866            def PP = basering;
867            setring P;
868            def result = imap(PP, result);
869            kill PP;
870          }
871          if (defined(groebner_error))
872          {
873            kill groebner_error;
874          }
875          kill l_fork;
876        }
877        else
878        {
879          ideal result;
880          if (! defined(groebner_error))
881          {
882            int groebner_error = 1;
883            export groebner_error;
884          }
885          "** groebner did not finish";
886          j = system("sh", "kill " + string(pid));
887        }
888        return (result);
889    }
890    else
891    {
892      "** groebner with a time limit on computation is not supported
893          in this configuration";
894    }
895  }
896
897 //=========== we are still here -- do the actual computation =============
898
899//--------------------- save data from basering ---------------------------
900  poly Minpoly = minpoly;      //minimal polynomial
901  int was_minpoly;             //remembers if there was a minpoly in P
902  if (size(Minpoly) > 0)
903  {
904     was_minpoly = 1;
905  }
906
907  ideal Qideal = ideal(P);      //defining the quotient ideal if P is a qring
908  int was_qring;                //remembers if basering was a qring
909  //int is_homog = 1;
910  if (size(Qideal) > 0)
911  {
912     was_qring = 1;
913     //is_homog = homog(Qideal); //remembers if Qideal was homog (homog(0)=1)
914  }
915  list BRlist = ringlist(P);
916
917  // save ordering of basering P for later use
918  list ord_P = BRlist[3];       //should be available in all rings
919  string ordstr_P = ordstr(P);
920  int nvars_P = nvars(P);
921  int npars_P = npars(P);
922  intvec w;                     //for ringweights of basering P
923  for(k=1;  k<=nvars_P; k++)
924  {
925     w[k]=deg(var(k));
926  }
927  int neg=1-attrib (P,"global");
928
929  //save options:
930  intvec opt=option(get);
931  string s_opt = option();
932  int p_opt;
933  if (find(s_opt, "prot"))  { p_opt = 1; }
934
935//------------------ cases where std is always used ------------------------
936//If other methods are not implemented or do not make sense, i.e. for
937//local or mixed orderings, matrix orderings, extra weight vector and modules
938
939  if(  //( find(ordstr_P,"s") > 0 ) || // covered by neg
940       ( find(ordstr_P,"M") > 0 )
941    || ( find(ordstr_P,"a") > 0 )
942    || ( neg>0 ) )
943  {
944    if (p_opt) { "std in basering"; }
945    return(std(i));
946  }
947
948//now we have:
949//ideal or module, global ordering, no matrix ordering, no extra weight vector
950//The interesting cases start now.
951
952 //------------------ classify the possible settings ---------------------
953  string algorithm;       //possibilities: std, slimgb, stdorslimgb
954  string conversion;      //possibilities: hilb, fglm, hilborfglm, no
955  string partovar;        //possibilities: yes, no
956  string order;           //possibilities: simple, !simple
957  string direct;          //possibilities: yes, no
958
959  //define algorithm:
960  if( find(method,"std") && !find(method,"slimgb") )
961  {
962    algorithm = "std";
963  }
964  if( find(method,"slimgb") && !find(method,"std") )
965  {
966    algorithm = "slimgb";
967  }
968  if( find(method,"std") && find(method,"slimgb") ||
969      (!find(method,"std") && !find(method,"slimgb")) )
970  {
971    algorithm = "stdorslimgb";
972  }
973
974  //define conversion:
975  if( find(method,"hilb") && !find(method,"fglm") )
976  {
977     conversion = "hilb";
978  }
979  if( find(method,"fglm") && !find(method,"hilb") )
980  {
981    conversion = "fglm";
982  }
983  if( find(method,"fglm") && find(method,"hilb") )
984  {
985    conversion = "hilborfglm";
986  }
987  if( !find(method,"fglm") && !find(method,"hilb") )
988  {
989    conversion = "no";
990  }
991
992  //define partovar:
993  if( find(method,"par2var") && npars_P > 0 )
994  {
995     partovar = "yes";
996  }
997  else
998  {
999     partovar = "no";
1000  }
1001
1002  //define order:
1003  if (system("nblocks") <= 2)
1004  {
1005    if ( find(ordstr_P,"M")+find(ordstr_P,"lp")+find(ordstr_P,"rp") <= 0 )
1006    {
1007      order = "simple";
1008    }
1009  }
1010
1011  //define direct:
1012  if ( (order=="simple" && (size(method)==0)) ||
1013       (size(BRlist)>4) ||
1014        (order=="simple" && (method==",par2var" && npars_P==0 )) ||
1015         (conversion=="no" && partovar=="no" &&
1016           (algorithm=="std" || algorithm=="slimgb" ||
1017            (find(method,"std") && find(method,"slimgb")) ) ) )
1018  {
1019    direct = "yes";
1020  }
1021  else
1022  {
1023    direct = "no";
1024  }
1025
1026  //order=="simple" means that the ordering of the variables consists of one
1027  //block which is not a matrix ordering and not a lexicographical ordering.
1028  //(Note:Singular counts always least 2 blocks, one is for module component):
1029  //Call a method "direct" if conversion=="no" && partovar="no" which means
1030  //that we apply std or slimgb dircet in the basering (exception
1031  //as long as slimgb does not know qrings: in a qring of a ring P
1032  //the ideal Qideal is added to the ideal and slimgb is applied in P).
1033  //We apply a direct method if we have a simple monomial ordering, if no
1034  //conversion (fglm or hilb) is specified and if the parameters shall
1035  //not be made to variables
1036
1037//---------------------------- direct methods -----------------------------
1038  if ( direct == "yes" )
1039  {
1040    if ( algorithm=="std" || (algorithm=="stdorslimgb" && char(P)>0) )
1041    {
1042      if (p_opt) { "std in " + string(P); }
1043      return(std(i));
1044    }
1045    if ( algorithm=="slimgb" || (algorithm=="stdorslimgb" && char(P)==0) )
1046    {
1047      return(qslimgb(i));
1048    }
1049  }
1050
1051//--------------------------- indirect methods -----------------------------
1052//indirect methods are methods where a conversion is used with a ring change
1053//We are in the following situation:
1054//direct=="no" (i.e. "hilb" or "fglm" or "par2var" is given)
1055//or no method is given and we have a complicated monomial ordering
1056//Note thar "par2var" is not a default strategy, it must be explicitely
1057//given in order to be performed.
1058
1059//------------ case where no parameters are made to variables  -------------
1060  if (  partovar == "no" && conversion == "hilb"
1061    || (partovar == "no" && conversion == "fglm" )
1062    || (partovar == "no" && conversion == "hilborfglm" )
1063    || (partovar == "no" && conversion == "no" && direct == "no") )
1064  //last case: heuristic
1065  {
1066    if ( conversion=="fglm" )
1067    {
1068      if ( algorithm=="std" || (algorithm=="stdorslimgb" && char(P)>0) )
1069      {
1070        return (stdfglm(i,"std"));
1071      }
1072      if ( algorithm=="slimgb" || (algorithm=="stdorslimgb" && char(P)==0) )
1073      {
1074        return (stdfglm(i,"slimgb"));
1075      }
1076    }
1077    else
1078    {
1079      if ( algorithm=="std" || (algorithm=="stdorslimgb" && char(P)>0) )
1080      {
1081        return (stdhilb(i,"std"));
1082      }
1083      if ( algorithm=="slimgb" || (algorithm=="stdorslimgb" && char(P)==0) )
1084      {
1085        return (stdhilb(i,"slimgb"));
1086      }
1087    }
1088  }
1089
1090//------------ case where parameters are made to variables  ----------------
1091//define a ring Phelp via par2varRing in which the parameters are variables
1092
1093  else
1094  {
1095    // reset options
1096    option(none);
1097    // turn on options prot, mem, redSB, intStrategy if previously set
1098    if ( find(s_opt, "prot") )
1099      { option(prot); }
1100    if ( find(s_opt, "mem") )
1101      { option(mem); }
1102    if ( find(s_opt, "redSB") )
1103      { option(redSB); }
1104    if ( find(s_opt, "intStrategy") )
1105      { option(intStrategy); }
1106
1107    //first clear denominators of parameters
1108    if (npars_P > 0)
1109    {
1110      for( k=ncols(i); k>0; k-- )
1111      { i[k]=cleardenom(i[k]); }
1112    }
1113
1114    def Phelp = par2varRing(i)[1];   //minpoly is mapped with i
1115    setring Phelp;
1116    def i = Id(1);
1117    //is_homog = homog(i);
1118
1119    //If parameters are converted to ring variables, they appear in an extra
1120    //block. Therefore we use always hilb for this block ordering:
1121    if ( conversion=="fglm" )
1122    {
1123      i = (stdfglm(i));       //only uesful for 1 parameter with minpoly
1124    }
1125    else
1126    {
1127      if ( algorithm=="std" || (algorithm=="stdorslimgb" && char(P)>0) )
1128      {
1129        i = stdhilb(i,"std");
1130      }
1131      if ( algorithm=="slimgb" || (algorithm=="stdorslimgb" && char(P)==0) )
1132      {
1133        i = stdhilb(i,"slimgb");
1134      }
1135    }
1136  }
1137
1138//-------------------- go back to original ring ---------------------------
1139//The main computation is done. However, the SB coming from a ring with
1140//extra variables is in general too big. We simplify it befor mapping it
1141//to the basering.
1142
1143  if (p_opt) { "//simplification"; }
1144
1145  if (was_minpoly)
1146  {
1147    ideal Minpoly = imap(P,Minpoly);
1148    attrib(Minpoly,"isSB",1);
1149    i = simplify(NF(i,Minpoly),2);
1150  }
1151
1152  def Li = lead(i);
1153  setring P;
1154  def Li = imap(Phelp,Li);
1155  Li = simplify(Li,32);
1156  intvec vi;
1157  for (k=1; k<=ncols(Li); k++)
1158  {
1159    vi[k] = Li[k]==0;
1160  }
1161
1162  setring Phelp;
1163  for (k=1;  k<=size(i) ;k++)
1164  {
1165    if(vi[k]==1)
1166    {
1167      i[k]=0;
1168    }
1169  }
1170  i = simplify(i,2);
1171
1172  setring P;
1173  if (p_opt) { "//imap to original ring"; }
1174  i = imap(Phelp,i);
1175  kill Phelp;
1176  i = simplify(i,34);
1177
1178  // clean-up time
1179  option(set, opt);
1180  if (find(s_opt, "redSB") > 0)
1181  {
1182    if (p_opt) { "//interreduction"; }
1183    i=interred(i);
1184  }
1185  attrib(i, "isSB", 1);
1186  return (i);
1187}
1188example
1189{ "EXAMPLE: "; echo=2;
1190  intvec opt = option(get);
1191  option(prot);
1192  ring r  = 0,(a,b,c,d),dp;
1193  ideal i = a+b+c+d,ab+ad+bc+cd,abc+abd+acd+bcd,abcd-1;
1194  groebner(i);
1195
1196  ring s  = 0,(a,b,c,d),lp;
1197  ideal i = imap(r,i);
1198  groebner(i,"hilb");
1199
1200  ring R  = (0,a),(b,c,d),lp;
1201  minpoly = a2+1;
1202  ideal i = a+b+c+d,ab+ad+bc+cd,abc+abd+acd+bcd,d2-c2b2;
1203  groebner(i,"par2var","slimgb");
1204
1205  groebner(i,"fglm");          //computes a reduced standard basis
1206
1207  if (system("with","MP")) {groebner(i,10,"std");}
1208  defined(Standard::groebner_error);
1209  option(set,opt);
1210}
1211
1212//////////////////////////////////////////////////////////////////////////
1213
1214proc res(list #)
1215"@c we do texinfo here:
1216@cindex resolution, computation of
1217@table @code
1218@item @strong{Syntax:}
1219@code{res (} ideal_expression@code{,} int_expression @code{[,} any_expression @code{])}
1220@*@code{res (} module_expression@code{,} int_expression @code{[,} any_expression @code{])}
1221@item @strong{Type:}
1222resolution
1223@item @strong{Purpose:}
1224computes a (possibly minimal) free resolution of an ideal or module using
1225a heuristically chosen method.
1226@* The second (int) argument (say, @code{k}) specifies the length of
1227the resolution. If it is not positive then @code{k} is assumed to be the
1228number of variables of the basering.
1229@* If a third argument is given, the returned resolution is minimized.
1230
1231Depending on the input, the returned resolution is computed using the
1232following methods:
1233@table @asis
1234@item @strong{quotient rings:}
1235@code{nres} (classical method using syzygies) , see @ref{nres}.
1236
1237@item @strong{homogeneous ideals and k=0:}
1238@code{lres} (La'Scala's method), see @ref{lres}.
1239
1240@item @strong{not minimized resolution and (homogeneous input with k not 0, or local rings):}
1241@code{sres} (Schreyer's method), see @ref{sres}.
1242
1243@item @strong{all other inputs:}
1244@code{mres} (classical method), see @ref{mres}.
1245@end table
1246@item @strong{Note:}
1247Accessing single elements of a resolution may require that some partial
1248computations have to be finished and may therefore take some time.
1249@end table
1250@c ref
1251See also
1252@ref{betti};
1253@ref{ideal};
1254@ref{minres};
1255@ref{module};
1256@ref{mres};
1257@ref{nres};
1258@ref{lres};
1259@ref{hres};
1260@ref{sres}.
1261@ref{resolution}
1262@c ref
1263"
1264{
1265   def P=basering;
1266   if (size(#) < 2)
1267   {
1268     ERROR("res: need at least two arguments: ideal/module, int");
1269   }
1270
1271   def m=#[1]; //the ideal or module
1272   int i=#[2]; //the length of the resolution
1273   if (i< 0) { i=0;}
1274
1275   string varstr_P = varstr(P);
1276
1277   int p_opt;
1278   string s_opt = option();
1279   // set p_opt, if option(prot) is set
1280   if (find(s_opt, "prot"))
1281   {
1282     p_opt = 1;
1283   }
1284
1285   if(size(ideal(basering)) > 0)
1286   {
1287     // the quick hack for qrings - seems to fit most needs
1288     // (lres is not implemented for qrings, sres is not so efficient)
1289     if (p_opt) { "using nres";}
1290     return(nres(m,i));
1291   }
1292
1293   if(homog(m)==1)
1294   {
1295      resolution re;
1296      if (((i==0) or (i>=nvars(basering))) && typeof(m) != "module")
1297      {
1298        //LaScala for the homogeneous case and i == 0
1299        if (p_opt) { "using lres";}
1300        re=lres(m,i);
1301        if(size(#)>2)
1302        {
1303           re=minres(re);
1304        }
1305      }
1306      else
1307      {
1308        if(size(#)>2)
1309        {
1310          if (p_opt) { "using mres";}
1311          re=mres(m,i);
1312        }
1313        else
1314        {
1315          if (p_opt) { "using sres";}
1316          re=sres(std(m),i);
1317        }
1318      }
1319      return(re);
1320   }
1321
1322   //mres for the global non homogeneous case
1323   if(find(ordstr(P),"s")==0)
1324   {
1325      string ri= "ring Phelp ="
1326                  +string(char(P))+",("+varstr_P+"),(dp,C);";
1327      execute(ri);
1328      def m=imap(P,m);
1329      if (p_opt) { "using mres in another ring";}
1330      list re=mres(m,i);
1331      setring P;
1332      resolution result=imap(Phelp,re);
1333      if (size(#) > 2) {result = minres(result);}
1334      return(result);
1335   }
1336
1337   //sres for the local case and not minimal resolution
1338   if(size(#)<=2)
1339   {
1340      string ri= "ring Phelp ="
1341                  +string(char(P))+",("+varstr_P+"),(ls,c);";
1342      execute(ri);
1343      def m=imap(P,m);
1344      m=std(m);
1345      if (p_opt) { "using sres in another ring";}
1346      list re=sres(m,i);
1347      setring P;
1348      resolution result=imap(Phelp,re);
1349      return(result);
1350   }
1351
1352   //mres for the local case and minimal resolution
1353   string ri= "ring Phelp ="
1354                  +string(char(P))+",("+varstr_P+"),(ls,C);";
1355   execute(ri);
1356   def m=imap(P,m);
1357    if (p_opt) { "using mres in another ring";}
1358   list re=mres(m,i);
1359   setring P;
1360   resolution result=imap(Phelp,re);
1361   result = minres(result);
1362   return(result);
1363}
1364example
1365{"EXAMPLE:"; echo = 2;
1366  ring r=0,(x,y,z),dp;
1367  ideal i=xz,yz,x3-y3;
1368  def l=res(i,0); // homogeneous ideal: uses lres
1369  l;
1370  print(betti(l), "betti"); // input to betti may be of type resolution
1371  l[2];         // element access may take some time
1372  i=i,x+1;
1373  l=res(i,0);   // inhomogeneous ideal: uses mres
1374  l;
1375  ring rs=0,(x,y,z),ds;
1376  ideal i=imap(r,i);
1377  def l=res(i,0); // local ring not minimized: uses sres
1378  l;
1379  res(i,0,0);     // local ring and minimized: uses mres
1380}
1381/////////////////////////////////////////////////////////////////////////
1382
1383proc quot (m1,m2,list #)
1384"SYNTAX: @code{quot (} module_expression@code{,} module_expression @code{)}
1385         @*@code{quot (} module_expression@code{,} module_expression@code{,}
1386            int_expression @code{)}
1387         @*@code{quot (} ideal_expression@code{,} ideal_expression @code{)}
1388         @*@code{quot (} ideal_expression@code{,} ideal_expression@code{,}
1389            int_expression @code{)}
1390TYPE:    ideal
1391SYNTAX:  @code{quot (} module_expression@code{,} ideal_expression @code{)}
1392TYPE:    module
1393PURPOSE: computes the quotient of the 1st and the 2nd argument.
1394         If a 3rd argument @code{n} is given the @code{n}-th method is used
1395         (@code{n}=1...5).
1396SEE ALSO: quotient
1397EXAMPLE: example quot; shows an example"
1398{
1399  if (((typeof(m1)!="ideal") and (typeof(m1)!="module"))
1400     or ((typeof(m2)!="ideal") and (typeof(m2)!="module")))
1401  {
1402    "USAGE:   quot(m1, m2[, n]); m1, m2 two submodules of k^s,";
1403    "         n (optional) integer (1<= n <=5)";
1404    "RETURN:  the quotient of m1 and m2";
1405    "EXAMPLE: example quot; shows an example";
1406    return();
1407  }
1408  if (typeof(m1)!=typeof(m2))
1409  {
1410    return(quotient(m1,m2));
1411  }
1412  if (size(#)>0)
1413  {
1414    if (typeof(#[1])=="int" )
1415    {
1416      return(quot1(m1,m2,#[1]));
1417    }
1418  }
1419  else
1420  {
1421    return(quot1(m1,m2,2));
1422  }
1423}
1424example
1425{ "EXAMPLE:"; echo = 2;
1426  ring r=181,(x,y,z),(c,ls);
1427  ideal id1=maxideal(4);
1428  ideal id2=x2+xyz,y2-z3y,z3+y5xz;
1429  option(prot);
1430  ideal id3=quotient(id1,id2);
1431  id3;
1432  ideal id4=quot(id1,id2,1);
1433  id4;
1434  ideal id5=quot(id1,id2,2);
1435  id5;
1436}
1437
1438static proc quot1 (module m1, module m2,int n)
1439"USAGE:   quot1(m1, m2, n); m1, m2 two submodules of k^s,
1440         n integer (1<= n <=5)
1441RETURN:  the quotient of m1 and m2
1442EXAMPLE: example quot1; shows an example"
1443{
1444  if (n==1)
1445  {
1446    return(quotient1(m1,m2));
1447  }
1448  else
1449  {
1450    if (n==2)
1451    {
1452      return(quotient2(m1,m2));
1453    }
1454    else
1455    {
1456      if (n==3)
1457      {
1458        return(quotient3(m1,m2));
1459      }
1460      else
1461      {
1462        if (n==4)
1463        {
1464          return(quotient4(m1,m2));
1465        }
1466        else
1467        {
1468          if (n==5)
1469          {
1470            return(quotient5(m1,m2));
1471          }
1472          else
1473          {
1474            return(quotient(m1,m2));
1475          }
1476        }
1477      }
1478    }
1479  }
1480}
1481example
1482{ "EXAMPLE:"; echo = 2;
1483  ring r=181,(x,y,z),(c,ls);
1484  ideal id1=maxideal(4);
1485  ideal id2=x2+xyz,y2-z3y,z3+y5xz;
1486  option(prot);
1487  ideal id6=quotient(id1,id2);
1488  id6;
1489  ideal id7=quot1(id1,id2,1);
1490  id7;
1491  ideal id8=quot1(id1,id2,2);
1492  id8;
1493}
1494
1495static proc quotient0(module a,module b)
1496{
1497  module mm=b+a;
1498  resolution rs=lres(mm,0);
1499  list I=list(rs);
1500  matrix M=I[2];
1501  matrix A[1][nrows(M)]=M[1..nrows(M),1];
1502  ideal i=A;
1503  return (i);
1504}
1505proc quotient1(module a,module b)  //17sec
1506"USAGE:   quotient1(m1, m2); m1, m2 two submodules of k^s,
1507RETURN:  the quotient of m1 and m2"
1508{
1509  int i;
1510  a=std(a);
1511  module dummy;
1512  module B=NF(b,a)+dummy;
1513  ideal re=quotient(a,module(B[1]));
1514  for(i=2;i<=ncols(B);i++)
1515  {
1516     re=intersect1(re,quotient(a,module(B[i])));
1517  }
1518  return(re);
1519}
1520proc quotient2(module a,module b)    //13sec
1521"USAGE:   quotient2(m1, m2); m1, m2 two submodules of k^s,
1522RETURN:  the quotient of m1 and m2"
1523{
1524  a=std(a);
1525  module dummy;
1526  module bb=NF(b,a)+dummy;
1527  int i=ncols(bb);
1528  ideal re=quotient(a,module(bb[i]));
1529  bb[i]=0;
1530  module temp;
1531  module temp1;
1532  module bbb;
1533  int mx;
1534  i=i-1;
1535  while (1)
1536  {
1537    if (i==0) break;
1538    temp = a+bb*re;
1539    temp1 = lead(interred(temp));
1540    mx=ncols(a);
1541    if (ncols(temp1)>ncols(a))
1542    {
1543      mx=ncols(temp1);
1544    }
1545    temp1 = matrix(temp1,1,mx)-matrix(lead(a),1,mx);
1546    temp1 = dummy+temp1;
1547    if (deg(temp1[1])<0) break;
1548    re=intersect1(re,quotient(a,module(bb[i])));
1549    bb[i]=0;
1550    i = i-1;
1551  }
1552  return(re);
1553}
1554proc quotient3(module a,module b)   //89sec
1555"USAGE:   quotient3(m1, m2); m1, m2 two submodules of k^s,
1556         only for global rings
1557RETURN:  the quotient of m1 and m2"
1558{
1559  string s="ring @newr=("+charstr(basering)+
1560           "),("+varstr(basering)+",@t,@w),dp;";
1561  def @newP=basering;
1562  execute(s);
1563  module b=imap(@newP,b);
1564  module a=imap(@newP,a);
1565  int i;
1566  int j=ncols(b);
1567  vector @b;
1568  for(i=1;i<=j;i++)
1569  {
1570     @b=@b+@t^(i-1)*@w^(j-i+1)*b[i];
1571  }
1572  ideal re=quotient(a,module(@b));
1573  setring @newP;
1574  ideal re=imap(@newr,re);
1575  return(re);
1576}
1577proc quotient5(module a,module b)   //89sec
1578"USAGE:   quotient5(m1, m2); m1, m2 two submodules of k^s,
1579         only for global rings
1580RETURN:  the quotient of m1 and m2"
1581{
1582  string s="ring @newr=("+charstr(basering)+
1583           "),("+varstr(basering)+",@t),dp;";
1584  def @newP=basering;
1585  execute(s);
1586  module b=imap(@newP,b);
1587  module a=imap(@newP,a);
1588  int i;
1589  int j=ncols(b);
1590  vector @b;
1591  for(i=1;i<=j;i++)
1592  {
1593     @b=@b+@t^(i-1)*b[i];
1594  }
1595  @b=homog(@b,@w);
1596  ideal re=quotient(a,module(@b));
1597  setring @newP;
1598  ideal re=imap(@newr,re);
1599  return(re);
1600}
1601proc quotient4(module a,module b)   //95sec
1602"USAGE:   quotient4(m1, m2); m1, m2 two submodules of k^s,
1603         only for global rings
1604RETURN:  the quotient of m1 and m2"
1605{
1606  string s="ring @newr=("+charstr(basering)+
1607           "),("+varstr(basering)+",@t),dp;";
1608  def @newP=basering;
1609  execute(s);
1610  module b=imap(@newP,b);
1611  module a=imap(@newP,a);
1612  int i;
1613  vector @b=b[1];
1614  for(i=2;i<=ncols(b);i++)
1615  {
1616     @b=@b+@t^(i-1)*b[i];
1617  }
1618  matrix sy=modulo(@b,a);
1619  ideal re=sy;
1620  setring @newP;
1621  ideal re=imap(@newr,re);
1622  return(re);
1623}
1624static proc intersect1(ideal i,ideal j)
1625{
1626  def R=basering;
1627  execute("ring gnir = ("+charstr(basering)+"),
1628                       ("+varstr(basering)+",@t),(C,dp);");
1629  ideal i=var(nvars(basering))*imap(R,i)+(var(nvars(basering))-1)*imap(R,j);
1630  ideal j=eliminate(i,var(nvars(basering)));
1631  setring R;
1632  map phi=gnir,maxideal(1);
1633  return(phi(j));
1634}
1635
1636//////////////////////////////////////////////////////////////////
1637///
1638/// sprintf, fprintf printf
1639///
1640proc sprintf(string fmt, list #)
1641"SYNTAX:  @code{sprintf (} string_expression @code{[,} any_expressions
1642               @code{] )}
1643RETURN:   string
1644PURPOSE:  @code{sprintf(fmt,...);} performs output formatting. The first
1645          argument is a format control string. Additional arguments may be
1646          required, depending on the content of the control string. A series
1647          of output characters is generated as directed by the control string;
1648          these characters are returned as a string. @*
1649          The control string @code{fmt} is simply text to be copied,
1650          except that the string may contain conversion specifications.@*
1651          Do @code{help print;} for a listing of valid conversion
1652          specifications. As an addition to the conversions of @code{print},
1653          the @code{%n} and @code{%2} conversion specification does not
1654          consume an additional argument, but simply generates a newline
1655          character.
1656NOTE:     If one of the additional arguments is a list, then it should be
1657          enclosed once more into a @code{list()} command, since passing a list
1658          as an argument flattens the list by one level.
1659SEE ALSO: fprintf, printf, print, string
1660EXAMPLE : example sprintf; shows an example
1661"
1662{
1663  int sfmt = size(fmt);
1664  if (sfmt  <= 1)
1665  {
1666    return (fmt);
1667  }
1668  int next, l, nnext;
1669  string ret;
1670  list formats = "%l", "%s", "%2l", "%2s", "%t", "%;", "%p", "%b", "%n", "%2";
1671  while (1)
1672  {
1673    if (size(#) <= 0)
1674    {
1675      return (ret + fmt);
1676    }
1677    nnext = 0;
1678    while (nnext < sfmt)
1679    {
1680      nnext = find(fmt, "%", nnext + 1);
1681      if (nnext == 0)
1682      {
1683        next = 0;
1684        break;
1685      }
1686      l = 1;
1687      while (l <= size(formats))
1688      {
1689        next = find(fmt, formats[l], nnext);
1690        if (next == nnext) break;
1691        l++;
1692      }
1693      if (next == nnext) break;
1694    }
1695    if (next == 0)
1696    {
1697      return (ret + fmt);
1698    }
1699    if (formats[l] != "%2" && formats[l] != "%n")
1700    {
1701      ret = ret + fmt[1, next - 1] + print(#[1], formats[l]);
1702      # = delete(#, 1);
1703    }
1704    else
1705    {
1706      ret = ret + fmt[1, next - 1] + print("", "%2s");
1707    }
1708    if (size(fmt) <= (next + size(formats[l]) - 1))
1709    {
1710      return (ret);
1711    }
1712    fmt = fmt[next + size(formats[l]), size(fmt)-next-size(formats[l]) + 1];
1713  }
1714}
1715example
1716{ "EXAMPLE:"; echo=2;
1717  ring r=0,(x,y,z),dp;
1718  module m=[1,y],[0,x+z];
1719  intmat M=betti(mres(m,0));
1720  list l = r, m, M;
1721  string s = sprintf("s:%s,%n l:%l", 1, 2); s;
1722  s = sprintf("s:%n%s", l); s;
1723  s = sprintf("s:%2%s", list(l)); s;
1724  s = sprintf("2l:%n%2l", list(l)); s;
1725  s = sprintf("%p", list(l)); s;
1726  s = sprintf("%;", list(l)); s;
1727  s = sprintf("%b", M); s;
1728}
1729
1730proc printf(string fmt, list #)
1731"SYNTAX:  @code{printf (} string_expression @code{[,} any_expressions@code{] )}
1732RETURN:   none
1733PURPOSE:  @code{printf(fmt,...);} performs output formatting. The first
1734          argument is a format control string. Additional arguments may be
1735          required, depending on the content of the control string. A series
1736          of output characters is generated as directed by the control string;
1737          these characters are displayed (i.e., printed to standard out). @*
1738          The control string @code{fmt} is simply text to be copied, except
1739          that the string may contain conversion specifications. @*
1740          Do @code{help print;} for a listing of valid conversion
1741          specifications. As an addition to the conversions of @code{print},
1742          the @code{%n} and @code{%2} conversion specification does not
1743          consume an additional argument, but simply generates a newline
1744          character.
1745NOTE:     If one of the additional arguments is a list, then it should be
1746          enclosed once more into a @code{list()} command, since passing a
1747          list as an argument flattens the list by one level.
1748SEE ALSO: sprintf, fprintf, print, string
1749EXAMPLE : example printf; shows an example
1750"
1751{
1752  write("", sprintf(fmt, #));
1753}
1754example
1755{ "EXAMPLE:"; echo=2;
1756  ring r=0,(x,y,z),dp;
1757  module m=[1,y],[0,x+z];
1758  intmat M=betti(mres(m,0));
1759  list l=r,m,matrix(M);
1760  printf("s:%s,l:%l",1,2);
1761  printf("s:%s",l);
1762  printf("s:%s",list(l));
1763  printf("2l:%2l",list(l));
1764  printf("%p",matrix(M));
1765  printf("%;",matrix(M));
1766  printf("%b",M);
1767}
1768
1769
1770proc fprintf(link l, string fmt, list #)
1771"SYNTAX:  @code{fprintf (} link_expression@code{,} string_expression @code{[,}
1772                any_expressions@code{] )}
1773RETURN:   none
1774PURPOSE:  @code{fprintf(l,fmt,...);} performs output formatting.
1775          The second argument is a format control string. Additional
1776          arguments may be required, depending on the content of the
1777          control string. A series of output characters is generated as
1778          directed by the control string; these characters are
1779          written to the link l.
1780          The control string @code{fmt} is simply text to be copied, except
1781          that the string may contain conversion specifications.@*
1782          Do @code{help print;} for a listing of valid conversion
1783          specifications. As an addition to the conversions of @code{print},
1784          the @code{%n} and @code{%2} conversion specification does not
1785          consume an additional argument, but simply generates a newline
1786          character.
1787NOTE:     If one of the additional arguments is a list, then it should be
1788          enclosed once more into a @code{list()} command, since passing
1789          a list as an argument flattens the list by one level.
1790SEE ALSO: sprintf, printf, print, string
1791EXAMPLE : example fprintf; shows an example
1792"
1793{
1794  write(l, sprintf(fmt, #));
1795}
1796example
1797{ "EXAMPLE:"; echo=2;
1798  ring r=0,(x,y,z),dp;
1799  module m=[1,y],[0,x+z];
1800  intmat M=betti(mres(m,0));
1801  list l=r,m,M;
1802  link li="";   // link to stdout
1803  fprintf(li,"s:%s,l:%l",1,2);
1804  fprintf(li,"s:%s",l);
1805  fprintf(li,"s:%s",list(l));
1806  fprintf(li,"2l:%2l",list(l));
1807  fprintf(li,"%p",list(l));
1808  fprintf(li,"%;",list(l));
1809  fprintf(li,"%b",M);
1810}
1811
1812//////////////////////////////////////////////////////////////////////////
1813
1814/*
1815proc minres(list #)
1816{
1817  if (size(#) == 2)
1818  {
1819    if (typeof(#[1]) == "ideal" || typeof(#[1]) == "module")
1820    {
1821      if (typeof(#[2] == "int"))
1822      {
1823        return (res(#[1],#[2],1));
1824      }
1825    }
1826  }
1827
1828  if (typeof(#[1]) == "resolution")
1829  {
1830    return minimizeres(#[1]);
1831  }
1832  else
1833  {
1834    return minimizeres(#);
1835  }
1836
1837}
1838*/
1839///////////////////////////////////////////////////////////////////////////////
1840
1841proc weightKB(def stc, int dd, list wim)
1842"SYNTAX: @code{weightKB (} module_expression@code{,} int_expression @code{,}
1843            list_expression @code{)}@*
1844         @code{weightKB (} ideal_expression@code{,} int_expression@code{,}
1845            list_expression @code{)}
1846RETURN:  the same as the input type of the first argument
1847PURPOSE: If @code{I,d,wim} denotes the three arguments then weightKB
1848         computes the weighted degree- @code{d} part of a vector space basis
1849         (consisting of monomials) of the quotient ring, resp. of the
1850         quotient module, modulo @code{I} w.r.t. weights given by @code{wim}
1851         The information about the weights is given as a list of two intvec:
1852            @code{wim[1]} weights for all variables (positive),
1853            @code{wim[2]} weights for the module generators.
1854NOTE:    This is a generalisation for the command @code{kbase} with the same
1855         first two arguments.
1856SEE ALSO: kbase
1857EXAMPLE: example weightKB; shows an example
1858"
1859{
1860  if(checkww(wim)){ERROR("wrong weights";);}
1861  kbclass();
1862  wwtop=wim[1];
1863  stc=interred(lead(stc));
1864  if(typeof(stc)=="ideal")
1865  {
1866    stdtop=stc;
1867    ideal out=widkbase(dd);
1868    delkbclass();
1869    return(out);
1870  }
1871  list mbase=kbprepare(stc);
1872  module mout;
1873  int im,ii;
1874  if(size(wim)>1){mmtop=wim[2];}
1875  else{mmtop=0;}
1876  for(im=size(mbase);im>0;im--)
1877  {
1878    stdtop=mbase[im];
1879    if(im>size(mmtop)){ii=dd;}
1880    else{ii=dd-mmtop[im];}
1881    mout=mout+widkbase(ii)*gen(im);
1882  }
1883  delkbclass();
1884  return(mout);
1885}
1886example
1887{ "EXAMPLE:"; echo=2;
1888  ring R=0, (x,y), wp(1,2);
1889  weightKB(ideal(0),3,intvec(1,2));
1890}
1891
1892///////////////////////////////////////////////////////////////////////////////
1893// construct global values
1894static proc kbclass()
1895{
1896  intvec wwtop,mmtop;
1897  export (wwtop,mmtop);
1898  ideal stdtop,kbtop;
1899  export (stdtop,kbtop);
1900}
1901// delete global values
1902static proc delkbclass()
1903{
1904  kill wwtop,mmtop;
1905  kill stdtop,kbtop;
1906}
1907//  select parts of the modul
1908static proc kbprepare(module mstc)
1909{
1910  list rr;
1911  ideal kk;
1912  int i1,i2;
1913  mstc=transpose(mstc);
1914  for(i1=ncols(mstc);i1>0;i1--)
1915  {
1916    kk=0;
1917    for(i2=nrows(mstc[i1]);i2>0;i2--)
1918    {
1919      kk=kk+mstc[i1][i2];
1920    }
1921    rr[i1]=kk;
1922  }
1923  return(rr);
1924}
1925//  check for weights
1926static proc checkww(list vv)
1927{
1928  if(typeof(vv[1])!="intvec"){return(1);}
1929  intvec ww=vv[1];
1930  int mv=nvars(basering);
1931  if(size(ww)<mv){return(1);}
1932  while(mv>0)
1933  {
1934    if(ww[mv]<=0){return(1);}
1935    mv--;
1936  }
1937  if(size(vv)>1)
1938  {
1939    if(typeof(vv[2])!="intvec"){return(1);}
1940  }
1941  return(0);
1942}
1943// The "Caller" for ideals
1944//    dd   - the degree of the result
1945static proc widkbase(int dd)
1946{
1947  if((size(stdtop)==1)&&(deg(stdtop[1])==0)){return(0);}
1948  if(dd<=0)
1949  {
1950    if(dd<0){return(0);}
1951    else{return(1);}
1952  }
1953  int m1,m2;
1954  m1=nvars(basering);
1955  while(wwtop[m1]>dd)
1956  {
1957    m1--;
1958    if(m1==0){return(0);}
1959  }
1960  attrib(stdtop,"isSB",1);
1961  poly mo=1;
1962  if(m1==1)
1963  {
1964    m2=dd/wwtop[1];
1965    if((m2*wwtop[1])==dd)
1966    {
1967      mo=var(1)^m2;
1968      if(reduce(mo,stdtop)==mo){return(mo);}
1969      else{return(0);}
1970    }
1971  }
1972  kbtop=0;
1973  m2=dd;
1974  weightmon(m1-1,m2,mo);
1975  while(m2>=wwtop[m1])
1976  {
1977    m2=m2-wwtop[m1];
1978    mo=mo*var(m1);
1979    if(m2==0)
1980    {
1981      if(reduce(mo,stdtop)==mo)
1982      {
1983        kbtop=kbtop+mo;
1984        return(kbtop);
1985      }
1986    }
1987    weightmon(m1-1,m2,mo);
1988  }
1989  return(kbtop);
1990}
1991// the recursive prozedur
1992//    va     - number of the variable
1993//    drest  - rest of the degree
1994//    mm     - the candidate
1995static proc weightmon(int va, int drest, poly mm)
1996{
1997  while(wwtop[va]>drest)
1998  {
1999    va--;
2000    if(va==0){return();}
2001  }
2002  int m2;
2003  if(va==1)
2004  {
2005    m2=drest/wwtop[1];
2006    if((m2*wwtop[1])==drest)
2007    {
2008      mm=mm*var(1)^m2;
2009      if(reduce(mm,stdtop)==mm){kbtop=kbtop+mm;}
2010    }
2011    return();
2012  }
2013  m2=drest;
2014  weightmon(va-1,m2,mm);
2015  while(m2>=wwtop[va])
2016  {
2017    m2=m2-wwtop[va];
2018    mm=mm*var(va);
2019    if(m2==0)
2020    {
2021      if(reduce(mm,stdtop)==mm)
2022      {
2023        kbtop=kbtop+mm;
2024        return();
2025      }
2026    }
2027    weightmon(va-1,m2,mm);
2028  }
2029  return();
2030}
2031example
2032{ "EXAMPLE:"; echo=2;
2033  ring r=0,(x,y,z),dp;
2034  ideal i = x6,y4,xyz;
2035  intvec w = 2,3,6;
2036  weightKB(i, 12, list(w));
2037}
2038//////////////////////////////////////////////////////////////////////////////
2039
2040/*
2041Versuche:
2042///////////////////////////////////////////////////////////////////////////////
2043proc downsizeSB (I, list #)
2044"USAGE:   downsizeSB(I [,l]); I ideal, l list of integers [default: l=0]
2045RETURN:  intvec, say v, with v[j] either 1 or 0. We have v[j]=1 if
2046         leadmonom(I[j]) is divisible by some leadmonom(I[k]) or if
2047         leadmonom(i[j]) == leadmonom(i[k]) and l[j] >= l[k], with k!=j.
2048PURPOSE: The procedure is applied in a situation where the standard basis
2049         computation in the basering R is done via a conversion through an
2050         overring Phelp with additional variables and where a direct
2051         imap from Phelp to R is too expensive.
2052         Assume Phelp is created by the procedure @code{par2varRing} or
2053         @code{hilbRing} and IPhelp is a SB in Phelp [ with l[j]=
2054         length(IPhelp(j)) or any other integer reflecting the complexity
2055         of a IPhelp[j] ]. Let I = lead(IPhelp) mapped to R and compute
2056         v = downsizeSB(imap(Phelp,I),l) in R. Then, if Ihelp[j] is deleted
2057         for all j with v[j]=1, we can apply imap to the remaining generators
2058         of Ihelp and still get SB in R  (in general not minimal).
2059EXAMPLE: example downsizeSB; shows an example"
2060{
2061   int k,j;
2062   intvec v,l;
2063   poly M,N,W;
2064   int c=size(I);
2065   if( size(#) != 0 )
2066   {
2067     if ( typeof(#[1]) == "intvec" )
2068     {
2069       l = #[1];
2070     }
2071     else
2072     {
2073        ERROR("// 2nd argument must be an intvec");
2074     }
2075   }
2076
2077   l[c+1]=0;
2078   v[c]=0;
2079
2080   j=0;
2081   while(j<c-1)
2082   {
2083     j++;
2084     M = leadmonom(I[j]);
2085     if( M != 0 )
2086     {
2087        for( k=j+1; k<=c; k++ )
2088        {
2089          N = leadmonom(I[k]);
2090          if( N != 0 )
2091          {
2092             if( (M==N) && (l[j]>l[k]) )
2093             {
2094               I[j]=0;
2095               v[j]=1;
2096               break;
2097             }
2098             if( (M==N) && (l[j]<=l[k]) || N/M != 0 )
2099             {
2100               I[k]=0;
2101               v[k]=1;
2102             }
2103          }
2104        }
2105      }
2106   }
2107   return(v);
2108}
2109example
2110{ "EXAMPLE:"; echo = 2;
2111   ring  r = 0,(x,y,z,t),(dp(3),dp);
2112   ideal i = x+y+z+t,xy+yz+xt+zt,xyz+xyt+xzt+yzt,xyzt-t4;
2113   ideal Id = std(i);
2114   ideal I = lead(Id);  I;
2115   ring S = (0,t),(x,y,z),dp;
2116   downsizeSB(imap(r,I));
2117   //Id[5] can be deleted, we still have a SB of i in the ring S
2118
2119   ring R = (0,x),(y,z,u),lp;
2120   ideal i = x+y+z+u,xy+xu+yz+zu,xyz+xyu+xzu+yzu,xyzu-1;
2121   def Phelp = par2varRing()[1];
2122   setring Phelp;
2123   ideal IPhelp = std(imap(R,i));
2124   ideal I = lead(IPhelp);
2125   setring R;
2126   ideal I = imap(Phelp,I); I;
2127   intvec v = downsizeSB(I); v;
2128}
2129///////////////////////////////////////////////////////////////////////////
2130// PROBLEM: Die Prozedur funktioniert nur fuer Ringe die global bekannt
2131//          sind, also interaktiv, aber nicht aus einer Prozedur.
2132//          Z.B. funktioniert example imapDownsize; nicht
2133
2134proc imapDownsize (string R, string I)
2135"SYNTAX: @code{imapDownsize (} string @code{,} string @code{)} *@
2136         First string must be the string of the name of a ring, second
2137         string must be the string of the name of an object in the ring.
2138TYPE:    same type as the object with name the second string
2139PURPOSE: maps the object given by the second string to the basering.
2140         If R resp. I are the first resp. second string, then
2141         imapDownsize(R,I) is equivalent to simplify(imap(`R`,`I`),34).
2142NOTE:    imapDownsize is usually faster than imap if `I` is large and if
2143         simplify has a great effect, since the procedure maps only those
2144         generators from `I` which are not killed by simplify( - ,34).
2145         This is useful if `I` is a standard bases for a block ordering of
2146         `R` and if some variables from the last block in `R` are mapped
2147         to parameters. Then the returned result is a standard basis in
2148         the basering.
2149SEE ALSO: imap, fetch, map
2150EXAMPLE: example imapDownsize; shows an example"
2151{
2152       def BR = basering;
2153       int k;
2154
2155       setring `R`;
2156       def @leadI@ = lead(`I`);
2157       int s = ncols(@leadI@);
2158       setring BR;
2159       ideal @leadI@ = simplify(imap(`R`,@leadI@),32);
2160       intvec vi;
2161       for (k=1; k<=s; k++)
2162       {
2163         vi[k] = @leadI@[k]==0;
2164       }
2165       kill @leadI@;
2166
2167       setring `R`;
2168       kill @leadI@;
2169       for (k=1;  k<=s; k++)
2170       {
2171           if( vi[k]==1 )
2172           {
2173              `I`[k]=0;
2174           }
2175       }
2176       `I` = simplify(`I`,2);
2177
2178       setring BR;
2179       return(imap(`R`,`I`));
2180}
2181example
2182{ "EXAMPLE:"; echo = 2;
2183   ring  r = 0,(x,y,z,t),(dp(3),dp);
2184   ideal i = x+y+z+t,xy+yz+xt+zt,xyz+xyt+xzt+yzt,xyzt-1;
2185   i = std(i); i;
2186
2187   ring s = (0,t),(x,y,z),dp;
2188   imapDownsize("r","i");     //i[5] is omitted since lead(i[2]) | lead(i[5])
2189}
2190///////////////////////////////////////////////////////////////////////////////
2191//die folgende proc war fuer groebner mit fglm vorgesehen
2192//um die projektive Dimension korrekt zu berechnen, muss man aber
2193//voerher ein SB bzgl. einer Gradordnung berechnen und dann homogenisieren.
2194//Sonst koennen hoeherdimensionale Komponenten in Unendlich entstehen
2195
2196proc projInvariants(ideal i,list #)
2197"SYNTAX: @code{projInvariants (} ideal_expression @code{)} @*
2198         @code{projInvariants (} ideal_expression@code{,} list of string_expres          sions@code{)}
2199TYPE:    list, say L, with L[1] and L[2] of type int and L[3] of type intvec
2200PURPOSE: Computes the (projective) dimension (L[1]), degree (L[2]) and the
2201         first Hilbert series (L[3], as intvec) of the homogenized ideal
2202         in the ring given by the procedure @code{hilbRing} with global
2203         ordering dp (resp. wp if the variables have weights >1)
2204         If an argument of type string @code{\"std\"} resp. @code{\"slimgb\"}
2205         is given, the standard basis computatuion uses @code{std} or
2206         @code{slimgb}, otherwise a heuristically chosen method (default)
2207NOTE:    Homogenized means weighted homogenized with respect to the weights
2208         w[i] of the variables var(i) of the basering. The returned dimension,
2209         degree and Hilbertseries are the respective invariants of the
2210         projective variety defined by the homogenized ideal. The dimension
2211         is equal to the (affine) dimension of the ideal in the basering
2212         (degree and Hilbert series make only sense for homogeneous ideals).
2213SEE ALSO: dim, dmult, hilb
2214KEYWORDS: dimension, degree, Hilbert function
2215EXAMPLE: example projInvariants;  shows an example"
2216{
2217  def P = basering;
2218  int p_opt;
2219  string s_opt = option();
2220  if (find(option(), "prot"))  { p_opt = 1; }
2221
2222//---------------- check method and clear denomintors --------------------
2223  int k;
2224  string method;
2225  for (k=1; k<=size(#); k++)
2226  {
2227     if (typeof(#[k]) == "string")
2228     {
2229       method = method + "," + #[k];
2230     }
2231  }
2232
2233  if (npars(P) > 0)             //clear denominators of parameters
2234  {
2235    for( k=ncols(i); k>0; k-- )
2236    {
2237       i[k]=cleardenom(i[k]);
2238    }
2239  }
2240
2241//------------------------ change to hilbRing ----------------------------
2242     list hiRi = hilbRing(i);
2243     intvec W = hiRi[2];
2244     def Philb = hiRi[1];      //note: Philb is no qring and the predefined
2245     setring Philb;            //ideal Id(1) in Philb is homogeneous
2246     int di, de;               //for dimension, degree
2247     intvec hi;                //for hilbert series
2248
2249//-------- compute Hilbert function of homogenized ideal in Philb ---------
2250//Philb has only 1 block. There are three cases
2251
2252     string algorithm;       //possibilities: std, slimgb, stdorslimgb
2253     //define algorithm:
2254     if( find(method,"std") && !find(method,"slimgb") )
2255     {
2256        algorithm = "std";
2257     }
2258     if( find(method,"slimgb") && !find(method,"std") )
2259     {
2260         algorithm = "slimgb";
2261     }
2262     if( find(method,"std") && find(method,"slimgb") ||
2263         (!find(method,"std") && !find(method,"slimgb")) )
2264     {
2265         algorithm = "stdorslimgb";
2266     }
2267
2268     if ( algorithm=="std" || ( algorithm=="stdorslimgb" && char(P)>0 ) )
2269     {
2270        if (p_opt) {"std in ring " + string(Philb);}
2271        Id(1) = std(Id(1));
2272        di = dim(Id(1))-1;
2273        de = mult(Id(1));
2274        hi = hilb( Id(1),1,W );
2275     }
2276     if ( algorithm=="slimgb" || ( algorithm=="stdorslimgb" && char(P)==0 ) )
2277     {
2278        if (p_opt) {"slimgb in ring " + string(Philb);}
2279        Id(1) = slimgb(Id(1));
2280        di = dim( Id(1) );
2281        if (di > -1)
2282        {
2283           di = di-1;
2284        }
2285        de = mult( Id(1) );
2286        hi = hilb( Id(1),1,W );
2287     }
2288     kill Philb;
2289     list L = di,de,hi;
2290     return(L);
2291}
2292example
2293{ "EXAMPLE:"; echo = 2;
2294   ring r = 32003,(x,y,z),lp;
2295   ideal i = y2-xz,x2-z;
2296   projInvariants(i);
2297
2298   ring R = (0),(x,y,z,u,v),lp;
2299   //minpoly = x2+1;
2300   ideal i = x2+1,x2+y+z+u+v,xyzuv-1;
2301   projInvariants(i);
2302   qring S =std(x2+1);
2303   ideal i = imap(R,i);
2304   projInvariants(i);
2305}
2306
2307*/
2308
Note: See TracBrowser for help on using the repository browser.