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

fieker-DuValspielwiese
Last change on this file since c38460 was 788018, checked in by Hans Schönemann <hannes@…>, 17 years ago
*hannes: example weightKB git-svn-id: file:///usr/local/Singular/svn/trunk@10024 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.92 2007-05-04 07:59:31 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: 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 Heruristik, 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        (order=="simple" && (method==",par2var" && npars_P==0 )) ||
1013         (conversion=="no" && partovar=="no" &&
1014           (algorithm=="std" || algorithm=="slimgb" ||
1015            (find(method,"std") && find(method,"slimgb")) ) ) )
1016  {
1017    direct = "yes";
1018  }
1019  else
1020  {
1021    direct = "no";
1022  }
1023
1024  //order=="simple" means that the ordering of the variables consists of one
1025  //block which is not a matrix ordering and not a lexicographical ordering.
1026  //(Note:Singular counts always least 2 blocks, one is for module component):
1027  //Call a method "direct" if conversion=="no" && partovar="no" which means
1028  //that we apply std or slimgb dircet in the basering (exception
1029  //as long as slimgb does not know qrings: in a qring of a ring P
1030  //the ideal Qideal is added to the ideal and slimgb is applied in P).
1031  //We apply a direct method if we have a simple monomial ordering, if no
1032  //conversion (fglm or hilb) is specified and if the parameters shall
1033  //not be made to variables
1034
1035//---------------------------- direct methods -----------------------------
1036  if ( direct == "yes" )
1037  {
1038    if ( algorithm=="std" || (algorithm=="stdorslimgb" && char(P)>0) )
1039    {
1040      if (p_opt) { "std in " + string(P); }
1041      return(std(i));
1042    }
1043    if ( algorithm=="slimgb" || (algorithm=="stdorslimgb" && char(P)==0) )
1044    {
1045      return(qslimgb(i));
1046    }
1047  }
1048
1049//--------------------------- indirect methods -----------------------------
1050//indirect methods are methods where a conversion is used with a ring change
1051//We are in the following situation:
1052//direct=="no" (i.e. "hilb" or "fglm" or "par2var" is given)
1053//or no method is given and we have a complicated monomial ordering
1054//Note thar "par2var" is not a default strategy, it must be explicitely
1055//given in order to be performed.
1056
1057//------------ case where no parameters are made to variables  -------------
1058  if (  partovar == "no" && conversion == "hilb"
1059    || (partovar == "no" && conversion == "fglm" )
1060    || (partovar == "no" && conversion == "hilborfglm" )
1061    || (partovar == "no" && conversion == "no" && direct == "no") )
1062  //last case: heuristic
1063  {
1064    if ( conversion=="fglm" )
1065    {
1066      if ( algorithm=="std" || (algorithm=="stdorslimgb" && char(P)>0) )
1067      {
1068        return (stdfglm(i,"std"));
1069      }
1070      if ( algorithm=="slimgb" || (algorithm=="stdorslimgb" && char(P)==0) )
1071      {
1072        return (stdfglm(i,"slimgb"));
1073      }
1074    }
1075    else
1076    {
1077      if ( algorithm=="std" || (algorithm=="stdorslimgb" && char(P)>0) )
1078      {
1079        return (stdhilb(i,"std"));
1080      }
1081      if ( algorithm=="slimgb" || (algorithm=="stdorslimgb" && char(P)==0) )
1082      {
1083        return (stdhilb(i,"slimgb"));
1084      }
1085    }
1086  }
1087
1088//------------ case where parameters are made to variables  ----------------
1089//define a ring Phelp via par2varRing in which the parameters are variables
1090
1091  else
1092  {
1093    // reset options
1094    option(none);
1095    // turn on options prot, mem, redSB, intStrategy if previously set
1096    if ( find(s_opt, "prot") )
1097      { option(prot); }
1098    if ( find(s_opt, "mem") )
1099      { option(mem); }
1100    if ( find(s_opt, "redSB") )
1101      { option(redSB); }
1102    if ( find(s_opt, "intStrategy") )
1103      { option(intStrategy); }
1104
1105    //first clear denominators of parameters
1106    if (npars_P > 0)
1107    {
1108      for( k=ncols(i); k>0; k-- )
1109      { i[k]=cleardenom(i[k]); }
1110    }
1111
1112    def Phelp = par2varRing(i)[1];   //minpoly is mapped with i
1113    setring Phelp;
1114    def i = Id(1);
1115    //is_homog = homog(i);
1116
1117    //If parameters are converted to ring variables, they appear in an extra
1118    //block. Therefore we use always hilb for this block ordering:
1119    if ( conversion=="fglm" )
1120    {
1121      i = (stdfglm(i));       //only uesful for 1 parameter with minpoly
1122    }
1123    else
1124    {
1125      if ( algorithm=="std" || (algorithm=="stdorslimgb" && char(P)>0) )
1126      {
1127        i = stdhilb(i,"std");
1128      }
1129      if ( algorithm=="slimgb" || (algorithm=="stdorslimgb" && char(P)==0) )
1130      {
1131        i = stdhilb(i,"slimgb");
1132      }
1133    }
1134  }
1135
1136//-------------------- go back to original ring ---------------------------
1137//The main computation is done. However, the SB coming from a ring with
1138//extra variables is in general too big. We simplify it befor mapping it
1139//to the basering.
1140
1141  if (p_opt) { "//simplification"; }
1142
1143  if (was_minpoly)
1144  {
1145    ideal Minpoly = imap(P,Minpoly);
1146    attrib(Minpoly,"isSB",1);
1147    i = simplify(NF(i,Minpoly),2);
1148  }
1149
1150  def Li = lead(i);
1151  setring P;
1152  def Li = imap(Phelp,Li);
1153  Li = simplify(Li,32);
1154  intvec vi;
1155  for (k=1; k<=ncols(Li); k++)
1156  {
1157    vi[k] = Li[k]==0;
1158  }
1159
1160  setring Phelp;
1161  for (k=1;  k<=size(i) ;k++)
1162  {
1163    if(vi[k]==1)
1164    {
1165      i[k]=0;
1166    }
1167  }
1168  i = simplify(i,2);
1169
1170  setring P;
1171  if (p_opt) { "//imap to original ring"; }
1172  i = imap(Phelp,i);
1173  kill Phelp;
1174  i = simplify(i,34);
1175
1176  // clean-up time
1177  option(set, opt);
1178  if (find(s_opt, "redSB") > 0)
1179  {
1180    if (p_opt) { "//interreduction"; }
1181    i=interred(i);
1182  }
1183  attrib(i, "isSB", 1);
1184  return (i);
1185}
1186example
1187{ "EXAMPLE: "; echo=2;
1188  intvec opt = option(get);
1189  option(prot);
1190  ring r  = 0,(a,b,c,d),dp;
1191  ideal i = a+b+c+d,ab+ad+bc+cd,abc+abd+acd+bcd,abcd-1;
1192  groebner(i);
1193
1194  ring s  = 0,(a,b,c,d),lp;
1195  ideal i = imap(r,i);
1196  groebner(i,"hilb");
1197
1198  ring R  = (0,a),(b,c,d),lp;
1199  minpoly = a2+1;
1200  ideal i = a+b+c+d,ab+ad+bc+cd,abc+abd+acd+bcd,d2-c2b2;
1201  groebner(i,"par2var","slimgb");
1202
1203  groebner(i,"fglm");          //computes a reduced standard basis
1204
1205  if (system("with","MP")) {groebner(i,10,"std");}
1206  defined(Standard::groebner_error);
1207  option(set,opt);
1208}
1209
1210//////////////////////////////////////////////////////////////////////////
1211
1212proc res(list #)
1213"@c we do texinfo here:
1214@cindex resolution, computation of
1215@table @code
1216@item @strong{Syntax:}
1217@code{res (} ideal_expression@code{,} int_expression @code{[,} any_expression @code{])}
1218@*@code{res (} module_expression@code{,} int_expression @code{[,} any_expression @code{])}
1219@item @strong{Type:}
1220resolution
1221@item @strong{Purpose:}
1222computes a (possibly minimal) free resolution of an ideal or module using
1223a heuristically chosen method.
1224@* The second (int) argument (say, @code{k}) specifies the length of
1225the resolution. If it is not positive then @code{k} is assumed to be the
1226number of variables of the basering.
1227@* If a third argument is given, the returned resolution is minimized.
1228
1229Depending on the input, the returned resolution is computed using the
1230following methods:
1231@table @asis
1232@item @strong{quotient rings:}
1233@code{nres} (classical method using syzygies) , see @ref{nres}.
1234
1235@item @strong{homogeneous ideals and k=0:}
1236@code{lres} (La'Scala's method), see @ref{lres}.
1237
1238@item @strong{not minimized resolution and (homogeneous input with k not 0, or local rings):}
1239@code{sres} (Schreyer's method), see @ref{sres}.
1240
1241@item @strong{all other inputs:}
1242@code{mres} (classical method), see @ref{mres}.
1243@end table
1244@item @strong{Note:}
1245Accessing single elements of a resolution may require that some partial
1246computations have to be finished and may therefore take some time.
1247@end table
1248@c ref
1249See also
1250@ref{betti};
1251@ref{ideal};
1252@ref{minres};
1253@ref{module};
1254@ref{mres};
1255@ref{nres};
1256@ref{lres};
1257@ref{hres};
1258@ref{sres}.
1259@ref{resolution}
1260@c ref
1261"
1262{
1263   def P=basering;
1264   if (size(#) < 2)
1265   {
1266     ERROR("res: need at least two arguments: ideal/module, int");
1267   }
1268
1269   def m=#[1]; //the ideal or module
1270   int i=#[2]; //the length of the resolution
1271   if (i< 0) { i=0;}
1272
1273   string varstr_P = varstr(P);
1274
1275   int p_opt;
1276   string s_opt = option();
1277   // set p_opt, if option(prot) is set
1278   if (find(s_opt, "prot"))
1279   {
1280     p_opt = 1;
1281   }
1282
1283   if(size(ideal(basering)) > 0)
1284   {
1285     // the quick hack for qrings - seems to fit most needs
1286     // (lres is not implemented for qrings, sres is not so efficient)
1287     if (p_opt) { "using nres";}
1288     return(nres(m,i));
1289   }
1290
1291   if(homog(m)==1)
1292   {
1293      resolution re;
1294      if (((i==0) or (i>=nvars(basering))) && typeof(m) != "module")
1295      {
1296        //LaScala for the homogeneous case and i == 0
1297        if (p_opt) { "using lres";}
1298        re=lres(m,i);
1299        if(size(#)>2)
1300        {
1301           re=minres(re);
1302        }
1303      }
1304      else
1305      {
1306        if(size(#)>2)
1307        {
1308          if (p_opt) { "using mres";}
1309          re=mres(m,i);
1310        }
1311        else
1312        {
1313          if (p_opt) { "using sres";}
1314          re=sres(std(m),i);
1315        }
1316      }
1317      return(re);
1318   }
1319
1320   //mres for the global non homogeneous case
1321   if(find(ordstr(P),"s")==0)
1322   {
1323      string ri= "ring Phelp ="
1324                  +string(char(P))+",("+varstr_P+"),(dp,C);";
1325      execute(ri);
1326      def m=imap(P,m);
1327      if (p_opt) { "using mres in another ring";}
1328      list re=mres(m,i);
1329      setring P;
1330      resolution result=imap(Phelp,re);
1331      if (size(#) > 2) {result = minres(result);}
1332      return(result);
1333   }
1334
1335   //sres for the local case and not minimal resolution
1336   if(size(#)<=2)
1337   {
1338      string ri= "ring Phelp ="
1339                  +string(char(P))+",("+varstr_P+"),(ls,c);";
1340      execute(ri);
1341      def m=imap(P,m);
1342      m=std(m);
1343      if (p_opt) { "using sres in another ring";}
1344      list re=sres(m,i);
1345      setring P;
1346      resolution result=imap(Phelp,re);
1347      return(result);
1348   }
1349
1350   //mres for the local case and minimal resolution
1351   string ri= "ring Phelp ="
1352                  +string(char(P))+",("+varstr_P+"),(ls,C);";
1353   execute(ri);
1354   def m=imap(P,m);
1355    if (p_opt) { "using mres in another ring";}
1356   list re=mres(m,i);
1357   setring P;
1358   resolution result=imap(Phelp,re);
1359   result = minres(result);
1360   return(result);
1361}
1362example
1363{"EXAMPLE:"; echo = 2;
1364  ring r=0,(x,y,z),dp;
1365  ideal i=xz,yz,x3-y3;
1366  def l=res(i,0); // homogeneous ideal: uses lres
1367  l;
1368  print(betti(l), "betti"); // input to betti may be of type resolution
1369  l[2];         // element access may take some time
1370  i=i,x+1;
1371  l=res(i,0);   // inhomogeneous ideal: uses mres
1372  l;
1373  ring rs=0,(x,y,z),ds;
1374  ideal i=imap(r,i);
1375  def l=res(i,0); // local ring not minimized: uses sres
1376  l;
1377  res(i,0,0);     // local ring and minimized: uses mres
1378}
1379/////////////////////////////////////////////////////////////////////////
1380
1381proc quot (m1,m2,list #)
1382"SYNTAX: @code{quot (} module_expression@code{,} module_expression @code{)}
1383         @*@code{quot (} module_expression@code{,} module_expression@code{,}
1384            int_expression @code{)}
1385         @*@code{quot (} ideal_expression@code{,} ideal_expression @code{)}
1386         @*@code{quot (} ideal_expression@code{,} ideal_expression@code{,}
1387            int_expression @code{)}
1388TYPE:    ideal
1389SYNTAX:  @code{quot (} module_expression@code{,} ideal_expression @code{)}
1390TYPE:    module
1391PURPOSE: computes the quotient of the 1st and the 2nd argument.
1392         If a 3rd argument @code{n} is given the @code{n}-th method is used
1393         (@code{n}=1...5).
1394SEE ALSO: quotient
1395EXAMPLE: example quot; shows an example"
1396{
1397  if (((typeof(m1)!="ideal") and (typeof(m1)!="module"))
1398     or ((typeof(m2)!="ideal") and (typeof(m2)!="module")))
1399  {
1400    "USAGE:   quot(m1, m2[, n]); m1, m2 two submodules of k^s,";
1401    "         n (optional) integer (1<= n <=5)";
1402    "RETURN:  the quotient of m1 and m2";
1403    "EXAMPLE: example quot; shows an example";
1404    return();
1405  }
1406  if (typeof(m1)!=typeof(m2))
1407  {
1408    return(quotient(m1,m2));
1409  }
1410  if (size(#)>0)
1411  {
1412    if (typeof(#[1])=="int" )
1413    {
1414      return(quot1(m1,m2,#[1]));
1415    }
1416  }
1417  else
1418  {
1419    return(quot1(m1,m2,2));
1420  }
1421}
1422example
1423{ "EXAMPLE:"; echo = 2;
1424  ring r=181,(x,y,z),(c,ls);
1425  ideal id1=maxideal(4);
1426  ideal id2=x2+xyz,y2-z3y,z3+y5xz;
1427  option(prot);
1428  ideal id3=quotient(id1,id2);
1429  id3;
1430  ideal id4=quot(id1,id2,1);
1431  id4;
1432  ideal id5=quot(id1,id2,2);
1433  id5;
1434}
1435
1436static proc quot1 (module m1, module m2,int n)
1437"USAGE:   quot1(m1, m2, n); m1, m2 two submodules of k^s,
1438         n integer (1<= n <=5)
1439RETURN:  the quotient of m1 and m2
1440EXAMPLE: example quot1; shows an example"
1441{
1442  if (n==1)
1443  {
1444    return(quotient1(m1,m2));
1445  }
1446  else
1447  {
1448    if (n==2)
1449    {
1450      return(quotient2(m1,m2));
1451    }
1452    else
1453    {
1454      if (n==3)
1455      {
1456        return(quotient3(m1,m2));
1457      }
1458      else
1459      {
1460        if (n==4)
1461        {
1462          return(quotient4(m1,m2));
1463        }
1464        else
1465        {
1466          if (n==5)
1467          {
1468            return(quotient5(m1,m2));
1469          }
1470          else
1471          {
1472            return(quotient(m1,m2));
1473          }
1474        }
1475      }
1476    }
1477  }
1478}
1479example
1480{ "EXAMPLE:"; echo = 2;
1481  ring r=181,(x,y,z),(c,ls);
1482  ideal id1=maxideal(4);
1483  ideal id2=x2+xyz,y2-z3y,z3+y5xz;
1484  option(prot);
1485  ideal id6=quotient(id1,id2);
1486  id6;
1487  ideal id7=quot1(id1,id2,1);
1488  id7;
1489  ideal id8=quot1(id1,id2,2);
1490  id8;
1491}
1492
1493static proc quotient0(module a,module b)
1494{
1495  module mm=b+a;
1496  resolution rs=lres(mm,0);
1497  list I=list(rs);
1498  matrix M=I[2];
1499  matrix A[1][nrows(M)]=M[1..nrows(M),1];
1500  ideal i=A;
1501  return (i);
1502}
1503proc quotient1(module a,module b)  //17sec
1504"USAGE:   quotient1(m1, m2); m1, m2 two submodules of k^s,
1505RETURN:  the quotient of m1 and m2"
1506{
1507  int i;
1508  a=std(a);
1509  module dummy;
1510  module B=NF(b,a)+dummy;
1511  ideal re=quotient(a,module(B[1]));
1512  for(i=2;i<=ncols(B);i++)
1513  {
1514     re=intersect1(re,quotient(a,module(B[i])));
1515  }
1516  return(re);
1517}
1518proc quotient2(module a,module b)    //13sec
1519"USAGE:   quotient2(m1, m2); m1, m2 two submodules of k^s,
1520RETURN:  the quotient of m1 and m2"
1521{
1522  a=std(a);
1523  module dummy;
1524  module bb=NF(b,a)+dummy;
1525  int i=ncols(bb);
1526  ideal re=quotient(a,module(bb[i]));
1527  bb[i]=0;
1528  module temp;
1529  module temp1;
1530  module bbb;
1531  int mx;
1532  i=i-1;
1533  while (1)
1534  {
1535    if (i==0) break;
1536    temp = a+bb*re;
1537    temp1 = lead(interred(temp));
1538    mx=ncols(a);
1539    if (ncols(temp1)>ncols(a))
1540    {
1541      mx=ncols(temp1);
1542    }
1543    temp1 = matrix(temp1,1,mx)-matrix(lead(a),1,mx);
1544    temp1 = dummy+temp1;
1545    if (deg(temp1[1])<0) break;
1546    re=intersect1(re,quotient(a,module(bb[i])));
1547    bb[i]=0;
1548    i = i-1;
1549  }
1550  return(re);
1551}
1552proc quotient3(module a,module b)   //89sec
1553"USAGE:   quotient3(m1, m2); m1, m2 two submodules of k^s,
1554         only for global rings
1555RETURN:  the quotient of m1 and m2"
1556{
1557  string s="ring @newr=("+charstr(basering)+
1558           "),("+varstr(basering)+",@t,@w),dp;";
1559  def @newP=basering;
1560  execute(s);
1561  module b=imap(@newP,b);
1562  module a=imap(@newP,a);
1563  int i;
1564  int j=ncols(b);
1565  vector @b;
1566  for(i=1;i<=j;i++)
1567  {
1568     @b=@b+@t^(i-1)*@w^(j-i+1)*b[i];
1569  }
1570  ideal re=quotient(a,module(@b));
1571  setring @newP;
1572  ideal re=imap(@newr,re);
1573  return(re);
1574}
1575proc quotient5(module a,module b)   //89sec
1576"USAGE:   quotient5(m1, m2); m1, m2 two submodules of k^s,
1577         only for global rings
1578RETURN:  the quotient of m1 and m2"
1579{
1580  string s="ring @newr=("+charstr(basering)+
1581           "),("+varstr(basering)+",@t),dp;";
1582  def @newP=basering;
1583  execute(s);
1584  module b=imap(@newP,b);
1585  module a=imap(@newP,a);
1586  int i;
1587  int j=ncols(b);
1588  vector @b;
1589  for(i=1;i<=j;i++)
1590  {
1591     @b=@b+@t^(i-1)*b[i];
1592  }
1593  @b=homog(@b,@w);
1594  ideal re=quotient(a,module(@b));
1595  setring @newP;
1596  ideal re=imap(@newr,re);
1597  return(re);
1598}
1599proc quotient4(module a,module b)   //95sec
1600"USAGE:   quotient4(m1, m2); m1, m2 two submodules of k^s,
1601         only for global rings
1602RETURN:  the quotient of m1 and m2"
1603{
1604  string s="ring @newr=("+charstr(basering)+
1605           "),("+varstr(basering)+",@t),dp;";
1606  def @newP=basering;
1607  execute(s);
1608  module b=imap(@newP,b);
1609  module a=imap(@newP,a);
1610  int i;
1611  vector @b=b[1];
1612  for(i=2;i<=ncols(b);i++)
1613  {
1614     @b=@b+@t^(i-1)*b[i];
1615  }
1616  matrix sy=modulo(@b,a);
1617  ideal re=sy;
1618  setring @newP;
1619  ideal re=imap(@newr,re);
1620  return(re);
1621}
1622static proc intersect1(ideal i,ideal j)
1623{
1624  def R=basering;
1625  execute("ring gnir = ("+charstr(basering)+"),
1626                       ("+varstr(basering)+",@t),(C,dp);");
1627  ideal i=var(nvars(basering))*imap(R,i)+(var(nvars(basering))-1)*imap(R,j);
1628  ideal j=eliminate(i,var(nvars(basering)));
1629  setring R;
1630  map phi=gnir,maxideal(1);
1631  return(phi(j));
1632}
1633
1634//////////////////////////////////////////////////////////////////
1635///
1636/// sprintf, fprintf printf
1637///
1638proc sprintf(string fmt, list #)
1639"SYNTAX:  @code{sprintf (} string_expression @code{[,} any_expressions
1640               @code{] )}
1641RETURN:   string
1642PURPOSE:  @code{sprintf(fmt,...);} performs output formatting. The first
1643          argument is a format control string. Additional arguments may be
1644          required, depending on the content of the control string. A series
1645          of output characters is generated as directed by the control string;
1646          these characters are returned as a string. @*
1647          The control string @code{fmt} is simply text to be copied,
1648          except that the string may contain conversion specifications.@*
1649          Do @code{help print;} for a listing of valid conversion
1650          specifications. As an addition to the conversions of @code{print},
1651          the @code{%n} and @code{%2} conversion specification does not
1652          consume an additional argument, but simply generates a newline
1653          character.
1654NOTE:     If one of the additional arguments is a list, then it should be
1655          enclosed once more into a @code{list()} command, since passing a list
1656          as an argument flattens the list by one level.
1657SEE ALSO: fprintf, printf, print, string
1658EXAMPLE : example sprintf; shows an example
1659"
1660{
1661  int sfmt = size(fmt);
1662  if (sfmt  <= 1)
1663  {
1664    return (fmt);
1665  }
1666  int next, l, nnext;
1667  string ret;
1668  list formats = "%l", "%s", "%2l", "%2s", "%t", "%;", "%p", "%b", "%n", "%2";
1669  while (1)
1670  {
1671    if (size(#) <= 0)
1672    {
1673      return (ret + fmt);
1674    }
1675    nnext = 0;
1676    while (nnext < sfmt)
1677    {
1678      nnext = find(fmt, "%", nnext + 1);
1679      if (nnext == 0)
1680      {
1681        next = 0;
1682        break;
1683      }
1684      l = 1;
1685      while (l <= size(formats))
1686      {
1687        next = find(fmt, formats[l], nnext);
1688        if (next == nnext) break;
1689        l++;
1690      }
1691      if (next == nnext) break;
1692    }
1693    if (next == 0)
1694    {
1695      return (ret + fmt);
1696    }
1697    if (formats[l] != "%2" && formats[l] != "%n")
1698    {
1699      ret = ret + fmt[1, next - 1] + print(#[1], formats[l]);
1700      # = delete(#, 1);
1701    }
1702    else
1703    {
1704      ret = ret + fmt[1, next - 1] + print("", "%2s");
1705    }
1706    if (size(fmt) <= (next + size(formats[l]) - 1))
1707    {
1708      return (ret);
1709    }
1710    fmt = fmt[next + size(formats[l]), size(fmt)-next-size(formats[l]) + 1];
1711  }
1712}
1713example
1714{ "EXAMPLE:"; echo=2;
1715  ring r=0,(x,y,z),dp;
1716  module m=[1,y],[0,x+z];
1717  intmat M=betti(mres(m,0));
1718  list l = r, m, M;
1719  string s = sprintf("s:%s,%n l:%l", 1, 2); s;
1720  s = sprintf("s:%n%s", l); s;
1721  s = sprintf("s:%2%s", list(l)); s;
1722  s = sprintf("2l:%n%2l", list(l)); s;
1723  s = sprintf("%p", list(l)); s;
1724  s = sprintf("%;", list(l)); s;
1725  s = sprintf("%b", M); s;
1726}
1727
1728proc printf(string fmt, list #)
1729"SYNTAX:  @code{printf (} string_expression @code{[,} any_expressions@code{] )}
1730RETURN:   none
1731PURPOSE:  @code{printf(fmt,...);} performs output formatting. The first
1732          argument is a format control string. Additional arguments may be
1733          required, depending on the content of the control string. A series
1734          of output characters is generated as directed by the control string;
1735          these characters are displayed (i.e., printed to standard out). @*
1736          The control string @code{fmt} is simply text to be copied, except
1737          that the string may contain conversion specifications. @*
1738          Do @code{help print;} for a listing of valid conversion
1739          specifications. As an addition to the conversions of @code{print},
1740          the @code{%n} and @code{%2} conversion specification does not
1741          consume an additional argument, but simply generates a newline
1742          character.
1743NOTE:     If one of the additional arguments is a list, then it should be
1744          enclosed once more into a @code{list()} command, since passing a
1745          list as an argument flattens the list by one level.
1746SEE ALSO: sprintf, fprintf, print, string
1747EXAMPLE : example printf; shows an example
1748"
1749{
1750  write("", sprintf(fmt, #));
1751}
1752example
1753{ "EXAMPLE:"; echo=2;
1754  ring r=0,(x,y,z),dp;
1755  module m=[1,y],[0,x+z];
1756  intmat M=betti(mres(m,0));
1757  list l=r,m,matrix(M);
1758  printf("s:%s,l:%l",1,2);
1759  printf("s:%s",l);
1760  printf("s:%s",list(l));
1761  printf("2l:%2l",list(l));
1762  printf("%p",matrix(M));
1763  printf("%;",matrix(M));
1764  printf("%b",M);
1765}
1766
1767
1768proc fprintf(link l, string fmt, list #)
1769"SYNTAX:  @code{fprintf (} link_expression@code{,} string_expression @code{[,}
1770                any_expressions@code{] )}
1771RETURN:   none
1772PURPOSE:  @code{fprintf(l,fmt,...);} performs output formatting.
1773          The second argument is a format control string. Additional
1774          arguments may be required, depending on the content of the
1775          control string. A series of output characters is generated as
1776          directed by the control string; these characters are
1777          written to the link l.
1778          The control string @code{fmt} is simply text to be copied, except
1779          that the string may contain conversion specifications.@*
1780          Do @code{help print;} for a listing of valid conversion
1781          specifications. As an addition to the conversions of @code{print},
1782          the @code{%n} and @code{%2} conversion specification does not
1783          consume an additional argument, but simply generates a newline
1784          character.
1785NOTE:     If one of the additional arguments is a list, then it should be
1786          enclosed once more into a @code{list()} command, since passing
1787          a list as an argument flattens the list by one level.
1788SEE ALSO: sprintf, printf, print, string
1789EXAMPLE : example fprintf; shows an example
1790"
1791{
1792  write(l, sprintf(fmt, #));
1793}
1794example
1795{ "EXAMPLE:"; echo=2;
1796  ring r=0,(x,y,z),dp;
1797  module m=[1,y],[0,x+z];
1798  intmat M=betti(mres(m,0));
1799  list l=r,m,M;
1800  link li="";   // link to stdout
1801  fprintf(li,"s:%s,l:%l",1,2);
1802  fprintf(li,"s:%s",l);
1803  fprintf(li,"s:%s",list(l));
1804  fprintf(li,"2l:%2l",list(l));
1805  fprintf(li,"%p",list(l));
1806  fprintf(li,"%;",list(l));
1807  fprintf(li,"%b",M);
1808}
1809
1810//////////////////////////////////////////////////////////////////////////
1811
1812/*
1813proc minres(list #)
1814{
1815  if (size(#) == 2)
1816  {
1817    if (typeof(#[1]) == "ideal" || typeof(#[1]) == "module")
1818    {
1819      if (typeof(#[2] == "int"))
1820      {
1821        return (res(#[1],#[2],1));
1822      }
1823    }
1824  }
1825
1826  if (typeof(#[1]) == "resolution")
1827  {
1828    return minimizeres(#[1]);
1829  }
1830  else
1831  {
1832    return minimizeres(#);
1833  }
1834
1835}
1836*/
1837///////////////////////////////////////////////////////////////////////////////
1838
1839proc weightKB(def stc, int dd, list wim)
1840"SYNTAX: @code{weightKB (} module_expression@code{,} int_expression @code{,}
1841            list_expression @code{)}@*
1842         @code{weightKB (} ideal_expression@code{,} int_expression@code{,}
1843            list_expression @code{)}
1844RETURN:  the same as the input type of the first argument
1845PURPOSE: If @code{I,d,wim} denotes the three arguments then weightKB
1846         computes the weighted degree- @code{d} part of a vector space basis
1847         (consisting of monomials) of the quotient ring, resp. of the
1848         quotient module, modulo @code{I} w.r.t. weights given by @code{wim}
1849         The information about the weights is given as a list of two intvec:
1850            @code{wim[1]} weights for all variables (positive),
1851            @code{wim[2]} weights for the module generators.
1852NOTE:    This is a generalisation for the command @code{kbase} with the same
1853         first two arguments.
1854SEE ALSO: kbase
1855EXAMPLE: example weightKB; shows an example
1856"
1857{
1858  if(checkww(wim)){ERROR("wrong weights";);}
1859  kbclass();
1860  wwtop=wim[1];
1861  stc=interred(lead(stc));
1862  if(typeof(stc)=="ideal")
1863  {
1864    stdtop=stc;
1865    ideal out=widkbase(dd);
1866    delkbclass();
1867    return(out);
1868  }
1869  list mbase=kbprepare(stc);
1870  module mout;
1871  int im,ii;
1872  if(size(wim)>1){mmtop=wim[2];}
1873  else{mmtop=0;}
1874  for(im=size(mbase);im>0;im--)
1875  {
1876    stdtop=mbase[im];
1877    if(im>size(mmtop)){ii=dd;}
1878    else{ii=dd-mmtop[im];}
1879    mout=mout+widkbase(ii)*gen(im);
1880  }
1881  delkbclass();
1882  return(mout);
1883}
1884example
1885{ "EXAMPLE:"; echo=2;
1886  ring R=0, (x,y), wp(1,2);
1887  weightKB(ideal(0),3,intvec(1,2));
1888}
1889
1890///////////////////////////////////////////////////////////////////////////////
1891// construct global values
1892static proc kbclass()
1893{
1894  intvec wwtop,mmtop;
1895  export (wwtop,mmtop);
1896  ideal stdtop,kbtop;
1897  export (stdtop,kbtop);
1898}
1899// delete global values
1900static proc delkbclass()
1901{
1902  kill wwtop,mmtop;
1903  kill stdtop,kbtop;
1904}
1905//  select parts of the modul
1906static proc kbprepare(module mstc)
1907{
1908  list rr;
1909  ideal kk;
1910  int i1,i2;
1911  mstc=transpose(mstc);
1912  for(i1=ncols(mstc);i1>0;i1--)
1913  {
1914    kk=0;
1915    for(i2=nrows(mstc[i1]);i2>0;i2--)
1916    {
1917      kk=kk+mstc[i1][i2];
1918    }
1919    rr[i1]=kk;
1920  }
1921  return(rr);
1922}
1923//  check for weights
1924static proc checkww(list vv)
1925{
1926  if(typeof(vv[1])!="intvec"){return(1);}
1927  intvec ww=vv[1];
1928  int mv=nvars(basering);
1929  if(size(ww)<mv){return(1);}
1930  while(mv>0)
1931  {
1932    if(ww[mv]<=0){return(1);}
1933    mv--;
1934  }
1935  if(size(vv)>1)
1936  {
1937    if(typeof(vv[2])!="intvec"){return(1);}
1938  }
1939  return(0);
1940}
1941// The "Caller" for ideals
1942//    dd   - the degree of the result
1943static proc widkbase(int dd)
1944{
1945  if((size(stdtop)==1)&&(deg(stdtop[1])==0)){return(0);}
1946  if(dd<=0)
1947  {
1948    if(dd<0){return(0);}
1949    else{return(1);}
1950  }
1951  int m1,m2;
1952  m1=nvars(basering);
1953  while(wwtop[m1]>dd)
1954  {
1955    m1--;
1956    if(m1==0){return(0);}
1957  }
1958  attrib(stdtop,"isSB",1);
1959  poly mo=1;
1960  if(m1==1)
1961  {
1962    m2=dd/wwtop[1];
1963    if((m2*wwtop[1])==dd)
1964    {
1965      mo=var(1)^m2;
1966      if(reduce(mo,stdtop)==mo){return(mo);}
1967      else{return(0);}
1968    }
1969  }
1970  kbtop=0;
1971  m2=dd;
1972  weightmon(m1-1,m2,mo);
1973  while(m2>=wwtop[m1])
1974  {
1975    m2=m2-wwtop[m1];
1976    mo=mo*var(m1);
1977    if(m2==0)
1978    {
1979      if(reduce(mo,stdtop)==mo)
1980      {
1981        kbtop=kbtop+mo;
1982        return(kbtop);
1983      }
1984    }
1985    weightmon(m1-1,m2,mo);
1986  }
1987  return(kbtop);
1988}
1989// the recursive prozedur
1990//    va     - number of the variable
1991//    drest  - rest of the degree
1992//    mm     - the candidate
1993static proc weightmon(int va, int drest, poly mm)
1994{
1995  while(wwtop[va]>drest)
1996  {
1997    va--;
1998    if(va==0){return();}
1999  }
2000  int m2;
2001  if(va==1)
2002  {
2003    m2=drest/wwtop[1];
2004    if((m2*wwtop[1])==drest)
2005    {
2006      mm=mm*var(1)^m2;
2007      if(reduce(mm,stdtop)==mm){kbtop=kbtop+mm;}
2008    }
2009    return();
2010  }
2011  m2=drest;
2012  weightmon(va-1,m2,mm);
2013  while(m2>=wwtop[va])
2014  {
2015    m2=m2-wwtop[va];
2016    mm=mm*var(va);
2017    if(m2==0)
2018    {
2019      if(reduce(mm,stdtop)==mm)
2020      {
2021        kbtop=kbtop+mm;
2022        return();
2023      }
2024    }
2025    weightmon(va-1,m2,mm);
2026  }
2027  return();
2028}
2029example
2030{ "EXAMPLE:"; echo=2;
2031  ring r=0,(x,y,z),dp;
2032  ideal i = x6,y4,xyz;
2033  intvec w = 2,3,6;
2034  weightKB(i, 12, list(w));
2035}
2036//////////////////////////////////////////////////////////////////////////////
2037
2038/*
2039Versuche:
2040///////////////////////////////////////////////////////////////////////////////
2041proc downsizeSB (I, list #)
2042"USAGE:   downsizeSB(I [,l]); I ideal, l list of integers [default: l=0]
2043RETURN:  intvec, say v, with v[j] either 1 or 0. We have v[j]=1 if
2044         leadmonom(I[j]) is divisible by some leadmonom(I[k]) or if
2045         leadmonom(i[j]) == leadmonom(i[k]) and l[j] >= l[k], with k!=j.
2046PURPOSE: The procedure is applied in a situation where the standard basis
2047         computation in the basering R is done via a conversion through an
2048         overring Phelp with additional variables and where a direct
2049         imap from Phelp to R is too expensive.
2050         Assume Phelp is created by the procedure @code{par2varRing} or
2051         @code{hilbRing} and IPhelp is a SB in Phelp [ with l[j]=
2052         length(IPhelp(j)) or any other integer reflecting the complexity
2053         of a IPhelp[j] ]. Let I = lead(IPhelp) mapped to R and compute
2054         v = downsizeSB(imap(Phelp,I),l) in R. Then, if Ihelp[j] is deleted
2055         for all j with v[j]=1, we can apply imap to the remaining generators
2056         of Ihelp and still get SB in R  (in general not minimal).
2057EXAMPLE: example downsizeSB; shows an example"
2058{
2059   int k,j;
2060   intvec v,l;
2061   poly M,N,W;
2062   int c=size(I);
2063   if( size(#) != 0 )
2064   {
2065     if ( typeof(#[1]) == "intvec" )
2066     {
2067       l = #[1];
2068     }
2069     else
2070     {
2071        ERROR("// 2nd argument must be an intvec");
2072     }
2073   }
2074
2075   l[c+1]=0;
2076   v[c]=0;
2077
2078   j=0;
2079   while(j<c-1)
2080   {
2081     j++;
2082     M = leadmonom(I[j]);
2083     if( M != 0 )
2084     {
2085        for( k=j+1; k<=c; k++ )
2086        {
2087          N = leadmonom(I[k]);
2088          if( N != 0 )
2089          {
2090             if( (M==N) && (l[j]>l[k]) )
2091             {
2092               I[j]=0;
2093               v[j]=1;
2094               break;
2095             }
2096             if( (M==N) && (l[j]<=l[k]) || N/M != 0 )
2097             {
2098               I[k]=0;
2099               v[k]=1;
2100             }
2101          }
2102        }
2103      }
2104   }
2105   return(v);
2106}
2107example
2108{ "EXAMPLE:"; echo = 2;
2109   ring  r = 0,(x,y,z,t),(dp(3),dp);
2110   ideal i = x+y+z+t,xy+yz+xt+zt,xyz+xyt+xzt+yzt,xyzt-t4;
2111   ideal Id = std(i);
2112   ideal I = lead(Id);  I;
2113   ring S = (0,t),(x,y,z),dp;
2114   downsizeSB(imap(r,I));
2115   //Id[5] can be deleted, we still have a SB of i in the ring S
2116
2117   ring R = (0,x),(y,z,u),lp;
2118   ideal i = x+y+z+u,xy+xu+yz+zu,xyz+xyu+xzu+yzu,xyzu-1;
2119   def Phelp = par2varRing()[1];
2120   setring Phelp;
2121   ideal IPhelp = std(imap(R,i));
2122   ideal I = lead(IPhelp);
2123   setring R;
2124   ideal I = imap(Phelp,I); I;
2125   intvec v = downsizeSB(I); v;
2126}
2127///////////////////////////////////////////////////////////////////////////
2128// PROBLEM: Die Prozedur funktioniert nur fuer Ringe die global bekannt
2129//          sind, also interaktiv, aber nicht aus einer Prozedur.
2130//          Z.B. funktioniert example imapDownsize; nicht
2131
2132proc imapDownsize (string R, string I)
2133"SYNTAX: @code{imapDownsize (} string @code{,} string @code{)} *@
2134         First string must be the string of the name of a ring, second
2135         string must be the string of the name of an object in the ring.
2136TYPE:    same type as the object with name the second string
2137PURPOSE: maps the object given by the second string to the basering.
2138         If R resp. I are the first resp. second string, then
2139         imapDownsize(R,I) is equivalent to simplify(imap(`R`,`I`),34).
2140NOTE:    imapDownsize is usually faster than imap if `I` is large and if
2141         simplify has a great effect, since the procedure maps only those
2142         generators from `I` which are not killed by simplify( - ,34).
2143         This is useful if `I` is a standard bases for a block ordering of
2144         `R` and if some variables from the last block in `R` are mapped
2145         to parameters. Then the returned result is a standard basis in
2146         the basering.
2147SEE ALSO: imap, fetch, map
2148EXAMPLE: example imapDownsize; shows an example"
2149{
2150       def BR = basering;
2151       int k;
2152
2153       setring `R`;
2154       def @leadI@ = lead(`I`);
2155       int s = ncols(@leadI@);
2156       setring BR;
2157       ideal @leadI@ = simplify(imap(`R`,@leadI@),32);
2158       intvec vi;
2159       for (k=1; k<=s; k++)
2160       {
2161         vi[k] = @leadI@[k]==0;
2162       }
2163       kill @leadI@;
2164
2165       setring `R`;
2166       kill @leadI@;
2167       for (k=1;  k<=s; k++)
2168       {
2169           if( vi[k]==1 )
2170           {
2171              `I`[k]=0;
2172           }
2173       }
2174       `I` = simplify(`I`,2);
2175
2176       setring BR;
2177       return(imap(`R`,`I`));
2178}
2179example
2180{ "EXAMPLE:"; echo = 2;
2181   ring  r = 0,(x,y,z,t),(dp(3),dp);
2182   ideal i = x+y+z+t,xy+yz+xt+zt,xyz+xyt+xzt+yzt,xyzt-1;
2183   i = std(i); i;
2184
2185   ring s = (0,t),(x,y,z),dp;
2186   imapDownsize("r","i");     //i[5] is omitted since lead(i[2]) | lead(i[5])
2187}
2188///////////////////////////////////////////////////////////////////////////////
2189//die folgende proc war fuer groebner mit fglm vorgesehen
2190//um die projektive Dimension korrekt zu berechnen, muss man aber
2191//voerher ein SB bzgl. einer Gradordnung berechnen und dann homogenisieren.
2192//Sonst koennen hoeherdimensionale Komponenten in Unendlich entstehen
2193
2194proc projInvariants(ideal i,list #)
2195"SYNTAX: @code{projInvariants (} ideal_expression @code{)} @*
2196         @code{projInvariants (} ideal_expression@code{,} list of string_expres          sions@code{)}
2197TYPE:    list, say L, with L[1] and L[2] of type int and L[3] of type intvec
2198PURPOSE: Computes the (projective) dimension (L[1]), degree (L[2]) and the
2199         first Hilbert series (L[3], as intvec) of the homogenized ideal
2200         in the ring given by the procedure @code{hilbRing} with global
2201         ordering dp (resp. wp if the variables have weights >1)
2202         If an argument of type string @code{\"std\"} resp. @code{\"slimgb\"}
2203         is given, the standard basis computatuion uses @code{std} or
2204         @code{slimgb}, otherwise a heuristically chosen method (default)
2205NOTE:    Homogenized means weighted homogenized with respect to the weights
2206         w[i] of the variables var(i) of the basering. The returned dimension,
2207         degree and Hilbertseries are the respective invariants of the
2208         projective variety defined by the homogenized ideal. The dimension
2209         is equal to the (affine) dimension of the ideal in the basering
2210         (degree and Hilbert series make only sense for homogeneous ideals).
2211SEE ALSO: dim, dmult, hilb
2212KEYWORDS: dimension, degree, Hilbert function
2213EXAMPLE: example projInvariants;  shows an example"
2214{
2215  def P = basering;
2216  int p_opt;
2217  string s_opt = option();
2218  if (find(option(), "prot"))  { p_opt = 1; }
2219
2220//---------------- check method and clear denomintors --------------------
2221  int k;
2222  string method;
2223  for (k=1; k<=size(#); k++)
2224  {
2225     if (typeof(#[k]) == "string")
2226     {
2227       method = method + "," + #[k];
2228     }
2229  }
2230
2231  if (npars(P) > 0)             //clear denominators of parameters
2232  {
2233    for( k=ncols(i); k>0; k-- )
2234    {
2235       i[k]=cleardenom(i[k]);
2236    }
2237  }
2238
2239//------------------------ change to hilbRing ----------------------------
2240     list hiRi = hilbRing(i);
2241     intvec W = hiRi[2];
2242     def Philb = hiRi[1];      //note: Philb is no qring and the predefined
2243     setring Philb;            //ideal Id(1) in Philb is homogeneous
2244     int di, de;               //for dimension, degree
2245     intvec hi;                //for hilbert series
2246
2247//-------- compute Hilbert function of homogenized ideal in Philb ---------
2248//Philb has only 1 block. There are three cases
2249
2250     string algorithm;       //possibilities: std, slimgb, stdorslimgb
2251     //define algorithm:
2252     if( find(method,"std") && !find(method,"slimgb") )
2253     {
2254        algorithm = "std";
2255     }
2256     if( find(method,"slimgb") && !find(method,"std") )
2257     {
2258         algorithm = "slimgb";
2259     }
2260     if( find(method,"std") && find(method,"slimgb") ||
2261         (!find(method,"std") && !find(method,"slimgb")) )
2262     {
2263         algorithm = "stdorslimgb";
2264     }
2265
2266     if ( algorithm=="std" || ( algorithm=="stdorslimgb" && char(P)>0 ) )
2267     {
2268        if (p_opt) {"std in ring " + string(Philb);}
2269        Id(1) = std(Id(1));
2270        di = dim(Id(1))-1;
2271        de = mult(Id(1));
2272        hi = hilb( Id(1),1,W );
2273     }
2274     if ( algorithm=="slimgb" || ( algorithm=="stdorslimgb" && char(P)==0 ) )
2275     {
2276        if (p_opt) {"slimgb in ring " + string(Philb);}
2277        Id(1) = slimgb(Id(1));
2278        di = dim( Id(1) );
2279        if (di > -1)
2280        {
2281           di = di-1;
2282        }
2283        de = mult( Id(1) );
2284        hi = hilb( Id(1),1,W );
2285     }
2286     kill Philb;
2287     list L = di,de,hi;
2288     return(L);
2289}
2290example
2291{ "EXAMPLE:"; echo = 2;
2292   ring r = 32003,(x,y,z),lp;
2293   ideal i = y2-xz,x2-z;
2294   projInvariants(i);
2295
2296   ring R = (0),(x,y,z,u,v),lp;
2297   //minpoly = x2+1;
2298   ideal i = x2+1,x2+y+z+u+v,xyzuv-1;
2299   projInvariants(i);
2300   qring S =std(x2+1);
2301   ideal i = imap(R,i);
2302   projInvariants(i);
2303}
2304
2305*/
2306
Note: See TracBrowser for help on using the repository browser.