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

spielwiese
Last change on this file since d939c1 was d939c1, checked in by Hans Schönemann <hannes@…>, 17 years ago
*hannes/gmg: new standard.lib git-svn-id: file:///usr/local/Singular/svn/trunk@9480 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 36.6 KB
Line 
1//////////////////////////////////////////////////////////////////////////////
2version="$Id: standard.lib,v 1.83 2006-11-13 10:15:34 Singular Exp $";
3category="Miscellaneous";
4info="
5LIBRARY: standard.lib   Procedures which are always loaded at Start-up
6
7PROCEDURES:
8 stdfglm(ideal[,ord])   standard basis of ideal via fglm [and ordering ord]
9 stdhilb(ideal[,h])     standard basis of ideal using the Hilbert function
10 hilbstd(ideal[,h])     standard basis using (weighted) Hilbert function
11 groebner(ideal/module) standard basis using a heuristically chosen method
12 res(ideal/module,[i])  free resolution of ideal or module
13 sprintf(fmt,...)       returns fomatted string
14 fprintf(link,fmt,..)   writes formatted string to link
15 printf(fmt,...)        displays formatted string
16 weightKB(stc,dd,vl)    degree dd part of a kbase wrt. some weigths
17";
18
19//////////////////////////////////////////////////////////////////////////////
20
21proc stdfglm (ideal i, list #)
22"SYNTAX: @code{stdfglm (} ideal_expression @code{)} @*
23         @code{stdfglm (} ideal_expression@code{,} string_expression @code{)}
24TYPE:    ideal
25PURPOSE: computes the standard basis of the ideal in the basering
26         via @code{fglm} (from the ordering given as the second argument
27         to the ordering of the basering).@*
28         If no second argument is given, \"dp\" is used.
29SEE ALSO: fglm, groebner, std, stdhilb
30KEYWORDS: fglm
31EXAMPLE: example stdfglm; shows an example"
32{
33   string os;
34   def dr= basering;
35   if( (size(#)==0) or (typeof(#[1]) != "string") )
36   {
37     os = "dp(" + string( nvars(dr) ) + ")";
38     if ( (find( ordstr(dr), os ) != 0) and (find( ordstr(dr), "a") == 0) )
39     {
40       os= "Dp";
41     }
42     else
43     {
44       os= "dp";
45     }
46   }
47   else { os = #[1]; }
48   execute("ring sr=("+charstr(dr)+"),("+varstr(dr)+"),"+os+";");
49   ideal i= fetch(dr,i);
50   intvec opt= option(get);
51   option(redSB);
52   i=std(i);
53   option(set,opt);
54   setring dr;
55   return (fglm(sr,i));
56}
57example
58{ "EXAMPLE:"; echo = 2;
59   ring r=0,(x,y,z),lp;
60   ideal i=y3+x2,x2y+x2,x3-x2,z4-x2-y;
61   ideal i1=stdfglm(i);         //uses fglm from "dp" to "lp"
62   i1;
63   ideal i2=stdfglm(i,"Dp");    //uses fglm from "Dp" to "lp"
64   i2;
65}
66/////////////////////////////////////////////////////////////////////////////
67
68proc stdhilb(ideal i,list #)
69"SYNTAX: @code{stdhilb (} ideal_expression @code{)} @*
70         @code{stdhilb (} ideal_expression@code{,} intvec_expression @code{)}
71TYPE:    ideal
72PURPOSE: computes the standard basis of the homogeneous ideal in the basering,
73         via a Hilbert driven standard basis computation.@*
74         An optional second argument will be used as 1st Hilbert function.
75ASSUME:  The optional second argument is the first Hilbert series as computed
76         by @code{hilb}.
77SEE ALSO: stdfglm, std, groebner
78KEYWORDS: Hilbert function
79EXAMPLE: example stdhilb;  shows an example"
80{
81   def R=basering;
82
83   if((homog(i)==1)||(ordstr(basering)[1]=="d"))
84   {
85      if ((size(#)!=0)&&(homog(i)==1))
86      {
87         return(std(i,#[1]));
88      }
89      return(std(i));
90   }
91
92   execute("ring S = ("+charstr(R)+"),("+varstr(R)+",@t),dp;");
93   ideal i=homog(imap(R,i),@t);
94   intvec v=hilb(std(i),1);
95   execute("ring T = ("+charstr(R)+"),("+varstr(R)+",@t),("+ordstr(R)+");");
96   ideal i=fetch(S,i);
97   ideal a=std(i,v);
98   setring R;
99   map phi=T,maxideal(1),1;
100   ideal a=phi(a);
101
102   int k,j;
103   poly m;
104   int c=ncols(i);
105
106   for(j=1;j<c;j++)
107   {
108     if(deg(a[j])==0)
109     {
110       a=ideal(1);
111       attrib(a,"isSB",1);
112       return(a);
113     }
114     if(deg(a[j])>0)
115     {
116       m=lead(a[j]);
117       for(k=j+1;k<=c;k++)
118       {
119          if(size(lead(a[k])/m)>0)
120          {
121            a[k]=0;
122          }
123       }
124     }
125   }
126   a=simplify(a,2);
127   attrib(a,"isSB",1);
128   return(a);
129}
130example
131{ "EXAMPLE:"; echo = 2;
132   ring  r=0,(x,y,z),dp;
133   ideal i=y3+x2,x2y+x2,x3-x2,z4-x2-y;
134   ideal i1=stdhilb(i); i1;
135   // the latter computation is equivalent to:
136   intvec v=hilb(i,1);
137   ideal i2=stdhilb(i,v); i2;
138}
139//////////////////////////////////////////////////////////////////////////
140
141proc hilbstd(ideal i,list #)
142"SYNTAX: @code{stdhilb (} ideal_expression @code{)} @*
143         @code{stdhilb (} ideal_expression@code{,} intvec_expression @code{)}
144TYPE:    ideal
145PURPOSE: Computes a Groebner basis of the homogeneous ideal in the basering.
146THEORY:  Compute first a standard basis of the (weighted) homogenization
147         of the ideal, then the (weighted) Hilbert function and finally
148         a Groebner basis in the original ring by using the computed Hilbert
149         function@*
150         An optional second argument will be used as 1st Hilbert function.
151ASSUME:  The optional second argument is the first Hilbert series as computed
152         by @code{hilb}.
153NOTE:    This procedure makes stdhilb obsolet since it is a generalization
154         to rings with some variables having weights >1. Parameters are kept.
155SEE ALSO: stdfglm, std, groebner
156KEYWORDS: Hilbert function
157EXAMPLE: example hilbstd;  shows an example"
158{
159   def R=basering;
160   list lR = ringlist(R);
161   intvec v = size(lR[1..size(lR)]);   //size of lists lR[i] in lR
162   int n = nvars(R);
163   intvec w;                 //ringweights
164   int ii, neg;
165   for(ii=1; ii<=n; ii++)
166   {
167     w[ii]=deg(var(ii));
168     if(w[ii] <= 0)
169     {neg = 1;}
170   }
171//---------- exclude cases to which hilbstd should no be applied  ----------
172   if( homog(i) || find(ordstr(R),"s") || find(ordstr(R),"M")
173       || find(ordstr(R),"a") || (neg > 0) )
174   {
175      if((size(#)!=0) && homog(i))
176      {
177         return(std(i,#[1]));
178      }
179      return(std(i));
180   }
181
182//----------- create ring for fast computation of hilbert series --------
183   list lS=lR;
184   lS[2]=insert(lR[2],"@t",v[2]);
185   lS[3]=lR[3][1],lR[3][size(lR[3])];
186   intvec ww=w,1;
187   if(w==1)
188   {
189     lS[3][1]=list("dp",ww);
190   }
191   else
192   {
193     lS[3][1]=list("wp",ww);
194   }
195
196   def S = ring(lS);              //ring with one weighted block of variables
197   setring S;
198   ideal i = homog(imap(R,i),@t); //weighted homog of i
199   string s_opt = option();
200   int p_opt=(find(s_opt, "prot"));
201   if (p_opt) {"std in " + string(S);}
202   intvec h = hilb(std(i),1);     //compute weighted hilbert series of i
203
204//------------- use hilbert driven std with original ordering  ------------
205   setring R;                     //can access to lR only in R
206   lR[2]=lS[2];
207   lR[3]=insert(lR[3],list("dp",1),v[3]-1);
208   //insert a last block for homogenizing variabble
209
210   def T = ring(lR);             //T = R with 1 homogenizing variable @t
211   setring T;                    //added to last block with weight 1
212   ideal i=fetch(S,i);           //homogenized i in T
213
214   if (p_opt) {"std with hilb in " + string(T);}
215   ideal a=std(i,h,ww);           //use h from S and Hilbert driven std in T
216
217//-------------------- dehomogenize and simplify -------------------------
218   a=subst(a,@t,1);              //dehomogenize in T (do not use map!)
219   a=simplify(a,34);             //keep only a[j] with different leading terms
220
221//-------------------- back to original ring -------------------------
222   setring R;
223   ideal a = fetch(T,a);
224   attrib(a,"isSB",1);
225   return(a);
226}
227example
228{ "EXAMPLE:"; echo = 2;
229   ring  r=0,(x,y,z),(wp(43),wp(49,56));
230   ideal i=y3+x2,x2y+x2,x3-x2,z4-x2-y;
231   ideal i1=hilbstd(i); i1;
232   // the latter computation is equivalent to:
233   ring r1=0,(x,y,z),wp(43,49,56);
234   ideal i = imap(r,i);
235   intvec v=hilb(std(i),1);
236   setring r;
237   ideal i2 = hilbstd(i,v);
238}
239//////////////////////////////////////////////////////////////////////////
240
241proc groebner(def i, list #)
242"SYNTAX: @code{groebner (} ideal_expression @code{)} @*
243         @code{groebner (} module_expression @code{)} @*
244         @code{groebner (} ideal_expression@code{,} int_expression @code{)} @*
245         @code{groebner (} module_expression@code{,} int_expression @code{)}
246TYPE:    type of the first argument
247PURPOSE: computes the standard basis of the first argument @code{I}
248         (ideal or module), by a heuristically chosen method:
249         possiblities are @code{std}, @code{slimgb} and/or conversions
250         based on @code{fglm}, @code{stdhilb} etc.
251         @code{option(prot)} tells about the chosen way.
252NOTE: If a 2nd argument @code{wait} is given, then the computation proceeds
253      at most @code{wait} seconds. That is, if no result could be computed in
254      @code{wait} seconds, then the computation is interrupted, 0 is returned,
255      a warning message is displayed, and the global variable
256      @code{Standard::groebner_error} is defined.
257SEE ALSO: stdhilb, stdfglm, std
258KEYWORDS: time limit on computations; MP, groebner basis computations
259EXAMPLE: example groebner;  shows an example"
260{
261  def P=basering;
262
263  // we have two arguments -- try to use MPfork links
264  if (size(#) > 0)
265  {
266    if (system("with", "MP"))
267    {
268      if (typeof(#[1]) == "int")
269      {
270        int wait = #[1];
271        int j = 10;
272
273        string bs = nameof(basering);
274        link l_fork = "MPtcp:fork";
275        open(l_fork);
276        write(l_fork, quote(system("pid")));
277        int pid = read(l_fork);
278        write(l_fork, quote(groebner(eval(i))));
279
280        // sleep in small intervalls for appr. one second
281        if (wait > 0)
282        {
283          while(j < 1000000)
284          {
285            if (status(l_fork, "read", "ready", j)) {break;}
286            j = j + j;
287          }
288        }
289
290        // sleep in intervalls of one second from now on
291        j = 1;
292        while (j < wait)
293        {
294          if (status(l_fork, "read", "ready", 1000000)) {break;}
295          j = j + 1;
296        }
297
298        if (status(l_fork, "read", "ready"))
299        {
300          def result = read(l_fork);
301          if (bs != nameof(basering))
302          {
303            def PP = basering;
304            setring P;
305            def result = imap(PP, result);
306            kill PP;
307          }
308          if (defined(groebner_error))
309          {
310            kill groebner_error;
311          }
312          kill l_fork;
313        }
314        else
315        {
316          ideal result;
317          if (! defined(groebner_error))
318          {
319            int groebner_error = 1;
320            export groebner_error;
321          }
322          "** groebner did not finish";
323          j = system("sh", "kill " + string(pid));
324        }
325        return (result);
326      }
327      else
328      {
329        "** groebner needs int as 2nd arg";
330      }
331    }
332    else
333    {
334      "** groebner with two args is not supported in this configuration";
335    }
336  }
337
338  // we are still here -- do the actual computation
339  string ordstr_P = ordstr(P);
340  int nvarP = nvars(P);
341  intvec w;                     //ringweights
342  int neg,k;
343  for(k=1;  k<=nvarP; k++)
344  {
345     w[k]=deg(var(k));
346     if(w[k] <= 0) {neg=1;}
347  }
348  if ( ( find(ordstr_P,"s") > 0)
349  ||(find(ordstr_P,"M") > 0)
350  ||(find(ordstr_P,"a") > 0)
351  ||(neg>0) )
352  {
353    //spaeter den lokalen fall ueber lp oder aehnlich behandeln
354    return(std(i));
355  }
356
357  if (typeof(basering)=="ring") // slimgb does not know qrings
358  {
359     //if ordering is global, there are parameters and minpoly is 0
360     if (((npars(basering)>0) &&(minpoly==0)))
361     { return(slimgb(i)); }
362     // ordering dp, char 0
363     if((char(P)==0) && (system("nblocks") <= 2) && (find(ordstr_P,"dp")>0))
364     { return(slimgb(i)); }
365  }
366  // for module case, not already hadled by slimgb:
367  if (nrows(i)>1)
368  { return(std(i)); }
369  int IsSimple_P;
370  if (system("nblocks") <= 2)
371  {
372    if (find(ordstr_P, "M") <= 0)
373    {
374      IsSimple_P = 1;
375    }
376  }
377  int npars_P = npars(P);
378
379  // return std if no parameters and (dp or wp)
380  if ((npars_P <= 1) && IsSimple_P)
381  {
382    if (find(ordstr_P, "d") > 0)
383    {
384      return (std(i));
385    }
386    if (find(ordstr_P,"w") > 0)
387    {
388      return (std(i));
389    }
390  }
391
392  // reset options
393  intvec opt=option(get);
394  int p_opt;
395  string s_opt = option();
396  option(none);
397  // turn on option(prot) and/or option(mem), if previously set
398  if (find(s_opt, "prot"))
399  {
400    option(prot);
401    p_opt = 1;
402  }
403  if (find(s_opt, "mem"))
404  { option(mem); }
405  if (find(s_opt, "intStrategy"))
406  { option(intStrategy); }
407
408  // construct ring in which first std computation is done
409  // CL: 21/09/05 for Singular 3-0 with ringlists....
410
411  list BRlist = ringlist(P);
412  int add_vars = 0;
413  ideal Qideal = ideal(P);
414
415  if (npars_P > 0)
416  {
417    for(k=ncols(i); k>0; k--) { i[k]=cleardenom(i[k]); }
418  }
419  // more than one parameters are converted to ring variables
420  if (npars_P > 1)
421  {
422    for (k=1; k<=npars_P; k++)
423    {
424      BRlist[2][nvarP+k] = BRlist[1][2][k];
425    }
426    BRlist[1]=BRlist[1][1];
427    add_vars = npars_P;
428  }
429
430
431  // for Hilbert driven approach, Qring structure is removed (defining ideal
432  // will be added to the ideal under consideration in the process).
433  if (size(BRlist[4])>0)
434  {
435    int was_qring = 1;
436    BRlist[4] = ideal(0);
437  }
438
439  // a homogenizing variable is added, if necessary
440  int is_homog = (homog(i) && (npars_P <= 1));
441  if (! is_homog)
442  {
443    add_vars = add_vars + 1;
444    BRlist[2][nvarP+add_vars] = "@t@";
445  }
446  // save ordering for later use
447  list ord_P = BRlist[3];   // should be ring independent
448
449  //ordering is set to (wp(w,1..1), C) where w are the ringweights
450    intvec weight_wp = w;
451  for(k=nvarP+1;  k<=nvarP+add_vars; k++)
452  {
453     weight_wp[k]=1;
454  }
455
456  BRlist[3] = list();
457  if(weight_wp==1)
458  {
459    BRlist[3][1]=list("dp",weight_wp);
460  }
461  else
462  {
463    BRlist[3][1]=list("wp",weight_wp);
464  }
465  BRlist[3][2]=list("C",intvec(0));
466
467  //------------ change the ring
468  def Phelp = ring(BRlist);
469  kill BRlist;
470  setring Phelp;
471
472  // get ideal from previous ring
473  if (is_homog)
474  {
475    ideal qh = imap(P, i), imap(P,Qideal);
476  }
477  else
478  {
479    // and homogenize
480    ideal qh = homog(imap(P,i),@t@), homog(imap(P,Qideal),@t@);
481  }
482
483  // compute std and hilbert series
484  if (p_opt)
485  {
486    "std in " + string(Phelp);
487  }
488  intvec hi=hilb(std(qh),1);
489
490  if (add_vars == 0)
491  {
492    // no additional variables were introduced
493    setring P;  // can immediately change to original ring
494                // simply compute std with hilbert series in original ring
495    if (p_opt)
496    {
497      "std with hilb in basering";
498    }
499    if ( w==1 ) { i = std(i,hi); }
500    else { i = std(i,hi,w); }
501
502  }
503  else
504  {
505    // additional variables were introduced
506    // need another intermediate ring
507    list BRlist = ringlist(Phelp);
508    BRlist[3] = list();
509    for (k=1; k<=size(ord_P)-1; k++)
510    {
511      BRlist[3][k] = ord_P[k];
512    }
513
514    if( IsSimple_P && (add_vars==1) && (size(ord_P)==2) && (ord_P[1][1]=="lp"))
515    {
516      // for lp with at most one parameter, we do not need a block ordering
517      intvec OW = BRlist[3][1][2];
518      OW = OW,1;
519      BRlist[3][1][2] = OW; // extend block1 by 1
520      BRlist[3][2]=ord_P[2]; // copy block 2
521    }
522    else
523    {
524      if( IsSimple_P && (add_vars==1) && (size(ord_P)==2)&&(ord_P[2][1]=="lp"))
525      {
526        // for lp with at most one parameter, we do not need a block ordering
527        intvec OW = ord_P[2][2];
528        OW = OW,1;
529        BRlist[3][2]=ord_P[2];
530        BRlist[3][2][2] = OW; // extend block 2 by 1
531      }
532      else
533      {
534        intvec OW = 1;
535        for (k=2; k<=add_vars; k++) { OW = OW,1; }
536        BRlist[3][size(ord_P)] = list("dp",OW);
537        BRlist[3][size(BRlist[3])+1]=ord_P[size(ord_P)];
538      }
539    }
540    // change to intermediate ring
541    def Phelp1 = ring(BRlist);
542    setring Phelp1;
543
544    ideal qh = imap(Phelp, qh);
545    kill Phelp;
546    if (p_opt)
547    {
548      "std with hilb in " + string(Phelp1);;
549    }
550    // compute std with Hilbert series
551    if (weight_wp==1) { qh = std(qh, hi);}
552    else { qh = std(qh, hi, weight_wp);}
553
554    // subst 1 for homogenizing var
555    if (!is_homog)
556    {
557      if (p_opt)
558      {
559        "dehomogenization";
560      }
561      qh = subst(qh, @t@, 1);
562    }
563
564    // go back to original ring
565    setring P;
566    // get ideal, delete zeros and clean SB
567    if (p_opt)
568    {
569      "imap to original ring";
570    }
571    i = imap(Phelp1,qh);
572    if (p_opt)
573    {
574      "simplification";
575    }
576    i = simplify(i, 34);
577    kill Phelp1;
578  }
579
580  // clean-up time
581  option(set, opt);
582  if (find(s_opt, "redSB") > 0)
583  {
584    if (p_opt)
585    {
586      "interreduction";
587    }
588    i=interred(i);
589  }
590  attrib(i, "isSB", 1);
591  return (i);
592}
593example
594{ "EXAMPLE: "; echo=2; // LIB "./standard.lib";
595  ring r=0,(a,b,c,d),lp;
596  option(prot);
597  ideal i=a+b+c+d,ab+ad+bc+cd,abc+abd+acd+bcd,abcd-1; // cyclic 4
598  groebner(i);
599  ring rp=(0,a,b),(c,d), lp;
600  ideal i=imap(r,i);
601  groebner(i);
602  option(noprot);
603  if (system("with","MP")) {groebner(i,0);}
604  defined(Standard::groebner_error);
605}
606
607//////////////////////////////////////////////////////////////////////////
608
609proc res(list #)
610"@c we do texinfo here:
611@cindex resolution, computation of
612@table @code
613@item @strong{Syntax:}
614@code{res (} ideal_expression@code{,} int_expression @code{[,} any_expression @code{])}
615@*@code{res (} module_expression@code{,} int_expression @code{[,} any_expression @code{])}
616@item @strong{Type:}
617resolution
618@item @strong{Purpose:}
619computes a (possibly minimal) free resolution of an ideal or module using
620a heuristically chosen method.
621@* The second (int) argument (say, @code{k}) specifies the length of
622the resolution. If it is not positive then @code{k} is assumed to be the
623number of variables of the basering.
624@* If a third argument is given, the returned resolution is minimized.
625
626Depending on the input, the returned resolution is computed using the
627following methods:
628@table @asis
629@item @strong{quotient rings:}
630@code{nres} (classical method using syzygies) , see @ref{nres}.
631
632@item @strong{homogeneous ideals and k=0:}
633@code{lres} (La'Scala's method), see @ref{lres}.
634
635@item @strong{not minimized resolution and (homogeneous input with k not 0, or local rings):}
636@code{sres} (Schreyer's method), see @ref{sres}.
637
638@item @strong{all other inputs:}
639@code{mres} (classical method), see @ref{mres}.
640@end table
641@item @strong{Note:}
642Accessing single elements of a resolution may require that some partial
643computations have to be finished and may therefore take some time.
644@end table
645@c ref
646See also
647@ref{betti};
648@ref{ideal};
649@ref{minres};
650@ref{module};
651@ref{mres};
652@ref{nres};
653@ref{lres};
654@ref{hres};
655@ref{sres}.
656@ref{resolution}
657@c ref
658"
659{
660   def P=basering;
661   if (size(#) < 2)
662   {
663     ERROR("res: need at least two arguments: ideal/module, int");
664   }
665
666   def m=#[1]; //the ideal or module
667   int i=#[2]; //the length of the resolution
668   if (i< 0) { i=0;}
669
670   string varstr_P = varstr(P);
671
672   int p_opt;
673   string s_opt = option();
674   // set p_opt, if option(prot) is set
675   if (find(s_opt, "prot"))
676   {
677     p_opt = 1;
678   }
679
680   if(size(ideal(basering)) > 0)
681   {
682     // the quick hack for qrings - seems to fit most needs
683     // (lres is not implemented for qrings, sres is not so efficient)
684     if (p_opt) { "using nres";}
685     return(nres(m,i));
686   }
687
688   if(homog(m)==1)
689   {
690      resolution re;
691      if (((i==0) or (i>=nvars(basering))) && typeof(m) != "module")
692      {
693        //LaScala for the homogeneous case and i == 0
694        if (p_opt) { "using lres";}
695        re=lres(m,i);
696        if(size(#)>2)
697        {
698           re=minres(re);
699        }
700      }
701      else
702      {
703        if(size(#)>2)
704        {
705          if (p_opt) { "using mres";}
706          re=mres(m,i);
707        }
708        else
709        {
710          if (p_opt) { "using sres";}
711          re=sres(std(m),i);
712        }
713      }
714      return(re);
715   }
716
717   //mres for the global non homogeneous case
718   if(find(ordstr(P),"s")==0)
719   {
720      string ri= "ring Phelp ="
721                  +string(char(P))+",("+varstr_P+"),(dp,C);";
722      execute(ri);
723      def m=imap(P,m);
724      if (p_opt) { "using mres in another ring";}
725      list re=mres(m,i);
726      setring P;
727      resolution result=imap(Phelp,re);
728      if (size(#) > 2) {result = minres(result);}
729      return(result);
730   }
731
732   //sres for the local case and not minimal resolution
733   if(size(#)<=2)
734   {
735      string ri= "ring Phelp ="
736                  +string(char(P))+",("+varstr_P+"),(ls,c);";
737      execute(ri);
738      def m=imap(P,m);
739      m=std(m);
740      if (p_opt) { "using sres in another ring";}
741      list re=sres(m,i);
742      setring P;
743      resolution result=imap(Phelp,re);
744      return(result);
745   }
746
747   //mres for the local case and minimal resolution
748   string ri= "ring Phelp ="
749                  +string(char(P))+",("+varstr_P+"),(ls,C);";
750   execute(ri);
751   def m=imap(P,m);
752    if (p_opt) { "using mres in another ring";}
753   list re=mres(m,i);
754   setring P;
755   resolution result=imap(Phelp,re);
756   result = minres(result);
757   return(result);
758}
759example
760{"EXAMPLE:"; echo = 2;
761  ring r=0,(x,y,z),dp;
762  ideal i=xz,yz,x3-y3;
763  def l=res(i,0); // homogeneous ideal: uses lres
764  l;
765  print(betti(l), "betti"); // input to betti may be of type resolution
766  l[2];         // element access may take some time
767  i=i,x+1;
768  l=res(i,0);   // inhomogeneous ideal: uses mres
769  l;
770  ring rs=0,(x,y,z),ds;
771  ideal i=imap(r,i);
772  def l=res(i,0); // local ring not minimized: uses sres
773  l;
774  res(i,0,0);     // local ring and minimized: uses mres
775}
776/////////////////////////////////////////////////////////////////////////
777
778proc quot (m1,m2,list #)
779"SYNTAX: @code{quot (} module_expression@code{,} module_expression @code{)}
780         @*@code{quot (} module_expression@code{,} module_expression@code{,}
781            int_expression @code{)}
782         @*@code{quot (} ideal_expression@code{,} ideal_expression @code{)}
783         @*@code{quot (} ideal_expression@code{,} ideal_expression@code{,}
784            int_expression @code{)}
785TYPE:    ideal
786SYNTAX:  @code{quot (} module_expression@code{,} ideal_expression @code{)}
787TYPE:    module
788PURPOSE: computes the quotient of the 1st and the 2nd argument.
789         If a 3rd argument @code{n} is given the @code{n}-th method is used
790         (@code{n}=1...5).
791SEE ALSO: quotient
792EXAMPLE: example quot; shows an example"
793{
794  if (((typeof(m1)!="ideal") and (typeof(m1)!="module"))
795     or ((typeof(m2)!="ideal") and (typeof(m2)!="module")))
796  {
797    "USAGE:   quot(m1, m2[, n]); m1, m2 two submodules of k^s,";
798    "         n (optional) integer (1<= n <=5)";
799    "RETURN:  the quotient of m1 and m2";
800    "EXAMPLE: example quot; shows an example";
801    return();
802  }
803  if (typeof(m1)!=typeof(m2))
804  {
805    return(quotient(m1,m2));
806  }
807  if (size(#)>0)
808  {
809    if (typeof(#[1])=="int" )
810    {
811      return(quot1(m1,m2,#[1]));
812    }
813  }
814  else
815  {
816    return(quot1(m1,m2,2));
817  }
818}
819example
820{ "EXAMPLE:"; echo = 2;
821  ring r=181,(x,y,z),(c,ls);
822  ideal id1=maxideal(4);
823  ideal id2=x2+xyz,y2-z3y,z3+y5xz;
824  option(prot);
825  ideal id3=quotient(id1,id2);
826  id3;
827  ideal id4=quot(id1,id2,1);
828  id4;
829  ideal id5=quot(id1,id2,2);
830  id5;
831}
832
833static proc quot1 (module m1, module m2,int n)
834"USAGE:   quot1(m1, m2, n); m1, m2 two submodules of k^s,
835         n integer (1<= n <=5)
836RETURN:  the quotient of m1 and m2
837EXAMPLE: example quot1; shows an example"
838{
839  if (n==1)
840  {
841    return(quotient1(m1,m2));
842  }
843  else
844  {
845    if (n==2)
846    {
847      return(quotient2(m1,m2));
848    }
849    else
850    {
851      if (n==3)
852      {
853        return(quotient3(m1,m2));
854      }
855      else
856      {
857        if (n==4)
858        {
859          return(quotient4(m1,m2));
860        }
861        else
862        {
863          if (n==5)
864          {
865            return(quotient5(m1,m2));
866          }
867          else
868          {
869            return(quotient(m1,m2));
870          }
871        }
872      }
873    }
874  }
875}
876example
877{ "EXAMPLE:"; echo = 2;
878  ring r=181,(x,y,z),(c,ls);
879  ideal id1=maxideal(4);
880  ideal id2=x2+xyz,y2-z3y,z3+y5xz;
881  option(prot);
882  ideal id6=quotient(id1,id2);
883  id6;
884  ideal id7=quot1(id1,id2,1);
885  id7;
886  ideal id8=quot1(id1,id2,2);
887  id8;
888}
889
890static proc quotient0(module a,module b)
891{
892  module mm=b+a;
893  resolution rs=lres(mm,0);
894  list I=list(rs);
895  matrix M=I[2];
896  matrix A[1][nrows(M)]=M[1..nrows(M),1];
897  ideal i=A;
898  return (i);
899}
900proc quotient1(module a,module b)  //17sec
901"USAGE:   quotient1(m1, m2); m1, m2 two submodules of k^s,
902RETURN:  the quotient of m1 and m2"
903{
904  int i;
905  a=std(a);
906  module dummy;
907  module B=NF(b,a)+dummy;
908  ideal re=quotient(a,module(B[1]));
909  for(i=2;i<=ncols(B);i++)
910  {
911     re=intersect1(re,quotient(a,module(B[i])));
912  }
913  return(re);
914}
915proc quotient2(module a,module b)    //13sec
916"USAGE:   quotient2(m1, m2); m1, m2 two submodules of k^s,
917RETURN:  the quotient of m1 and m2"
918{
919  a=std(a);
920  module dummy;
921  module bb=NF(b,a)+dummy;
922  int i=ncols(bb);
923  ideal re=quotient(a,module(bb[i]));
924  bb[i]=0;
925  module temp;
926  module temp1;
927  module bbb;
928  int mx;
929  i=i-1;
930  while (1)
931  {
932    if (i==0) break;
933    temp = a+bb*re;
934    temp1 = lead(interred(temp));
935    mx=ncols(a);
936    if (ncols(temp1)>ncols(a))
937    {
938      mx=ncols(temp1);
939    }
940    temp1 = matrix(temp1,1,mx)-matrix(lead(a),1,mx);
941    temp1 = dummy+temp1;
942    if (deg(temp1[1])<0) break;
943    re=intersect1(re,quotient(a,module(bb[i])));
944    bb[i]=0;
945    i = i-1;
946  }
947  return(re);
948}
949proc quotient3(module a,module b)   //89sec
950"USAGE:   quotient3(m1, m2); m1, m2 two submodules of k^s,
951         only for global rings
952RETURN:  the quotient of m1 and m2"
953{
954  string s="ring @newr=("+charstr(basering)+
955           "),("+varstr(basering)+",@t,@w),dp;";
956  def @newP=basering;
957  execute(s);
958  module b=imap(@newP,b);
959  module a=imap(@newP,a);
960  int i;
961  int j=ncols(b);
962  vector @b;
963  for(i=1;i<=j;i++)
964  {
965     @b=@b+@t^(i-1)*@w^(j-i+1)*b[i];
966  }
967  ideal re=quotient(a,module(@b));
968  setring @newP;
969  ideal re=imap(@newr,re);
970  return(re);
971}
972proc quotient5(module a,module b)   //89sec
973"USAGE:   quotient5(m1, m2); m1, m2 two submodules of k^s,
974         only for global rings
975RETURN:  the quotient of m1 and m2"
976{
977  string s="ring @newr=("+charstr(basering)+
978           "),("+varstr(basering)+",@t),dp;";
979  def @newP=basering;
980  execute(s);
981  module b=imap(@newP,b);
982  module a=imap(@newP,a);
983  int i;
984  int j=ncols(b);
985  vector @b;
986  for(i=1;i<=j;i++)
987  {
988     @b=@b+@t^(i-1)*b[i];
989  }
990  @b=homog(@b,@w);
991  ideal re=quotient(a,module(@b));
992  setring @newP;
993  ideal re=imap(@newr,re);
994  return(re);
995}
996proc quotient4(module a,module b)   //95sec
997"USAGE:   quotient4(m1, m2); m1, m2 two submodules of k^s,
998         only for global rings
999RETURN:  the quotient of m1 and m2"
1000{
1001  string s="ring @newr=("+charstr(basering)+
1002           "),("+varstr(basering)+",@t),dp;";
1003  def @newP=basering;
1004  execute(s);
1005  module b=imap(@newP,b);
1006  module a=imap(@newP,a);
1007  int i;
1008  vector @b=b[1];
1009  for(i=2;i<=ncols(b);i++)
1010  {
1011     @b=@b+@t^(i-1)*b[i];
1012  }
1013  matrix sy=modulo(@b,a);
1014  ideal re=sy;
1015  setring @newP;
1016  ideal re=imap(@newr,re);
1017  return(re);
1018}
1019static proc intersect1(ideal i,ideal j)
1020{
1021  def R=basering;
1022  execute("ring gnir = ("+charstr(basering)+"),
1023                       ("+varstr(basering)+",@t),(C,dp);");
1024  ideal i=var(nvars(basering))*imap(R,i)+(var(nvars(basering))-1)*imap(R,j);
1025  ideal j=eliminate(i,var(nvars(basering)));
1026  setring R;
1027  map phi=gnir,maxideal(1);
1028  return(phi(j));
1029}
1030
1031//////////////////////////////////////////////////////////////////
1032///
1033/// sprintf, fprintf printf
1034///
1035proc sprintf(string fmt, list #)
1036"SYNTAX:  @code{sprintf (} string_expression @code{[,} any_expressions
1037               @code{] )}
1038RETURN:   string
1039PURPOSE:  @code{sprintf(fmt,...);} performs output formatting. The first
1040          argument is a format control string. Additional arguments may be
1041          required, depending on the content of the control string. A series
1042          of output characters is generated as directed by the control string;
1043          these characters are returned as a string. @*
1044          The control string @code{fmt} is simply text to be copied,
1045          except that the string may contain conversion specifications.@*
1046          Do @code{help print;} for a listing of valid conversion
1047          specifications. As an addition to the conversions of @code{print},
1048          the @code{%n} and @code{%2} conversion specification does not
1049          consume an additional argument, but simply generates a newline
1050          character.
1051NOTE:     If one of the additional arguments is a list, then it should be
1052          enclosed once more into a @code{list()} command, since passing a list
1053          as an argument flattens the list by one level.
1054SEE ALSO: fprintf, printf, print, string
1055EXAMPLE : example sprintf; shows an example
1056"
1057{
1058  int sfmt = size(fmt);
1059  if (sfmt  <= 1)
1060  {
1061    return (fmt);
1062  }
1063  int next, l, nnext;
1064  string ret;
1065  list formats = "%l", "%s", "%2l", "%2s", "%t", "%;", "%p", "%b", "%n", "%2";
1066  while (1)
1067  {
1068    if (size(#) <= 0)
1069    {
1070      return (ret + fmt);
1071    }
1072    nnext = 0;
1073    while (nnext < sfmt)
1074    {
1075      nnext = find(fmt, "%", nnext + 1);
1076      if (nnext == 0)
1077      {
1078        next = 0;
1079        break;
1080      }
1081      l = 1;
1082      while (l <= size(formats))
1083      {
1084        next = find(fmt, formats[l], nnext);
1085        if (next == nnext) break;
1086        l++;
1087      }
1088      if (next == nnext) break;
1089    }
1090    if (next == 0)
1091    {
1092      return (ret + fmt);
1093    }
1094    if (formats[l] != "%2" && formats[l] != "%n")
1095    {
1096      ret = ret + fmt[1, next - 1] + print(#[1], formats[l]);
1097      # = delete(#, 1);
1098    }
1099    else
1100    {
1101      ret = ret + fmt[1, next - 1] + print("", "%2s");
1102    }
1103    if (size(fmt) <= (next + size(formats[l]) - 1))
1104    {
1105      return (ret);
1106    }
1107    fmt = fmt[next + size(formats[l]), size(fmt)-next-size(formats[l]) + 1];
1108  }
1109}
1110example
1111{ "EXAMPLE:"; echo=2;
1112  ring r=0,(x,y,z),dp;
1113  module m=[1,y],[0,x+z];
1114  intmat M=betti(mres(m,0));
1115  list l = r, m, M;
1116  string s = sprintf("s:%s,%n l:%l", 1, 2); s;
1117  s = sprintf("s:%n%s", l); s;
1118  s = sprintf("s:%2%s", list(l)); s;
1119  s = sprintf("2l:%n%2l", list(l)); s;
1120  s = sprintf("%p", list(l)); s;
1121  s = sprintf("%;", list(l)); s;
1122  s = sprintf("%b", M); s;
1123}
1124
1125proc printf(string fmt, list #)
1126"SYNTAX:  @code{printf (} string_expression @code{[,} any_expressions@code{] )}
1127RETURN:   none
1128PURPOSE:  @code{printf(fmt,...);} performs output formatting. The first
1129          argument is a format control string. Additional arguments may be
1130          required, depending on the content of the control string. A series
1131          of output characters is generated as directed by the control string;
1132          these characters are displayed (i.e., printed to standard out). @*
1133          The control string @code{fmt} is simply text to be copied, except
1134          that the string may contain conversion specifications. @*
1135          Do @code{help print;} for a listing of valid conversion
1136          specifications. As an addition to the conversions of @code{print},
1137          the @code{%n} and @code{%2} conversion specification does not
1138          consume an additional argument, but simply generates a newline
1139          character.
1140NOTE:     If one of the additional arguments is a list, then it should be
1141          enclosed once more into a @code{list()} command, since passing a
1142          list as an argument flattens the list by one level.
1143SEE ALSO: sprintf, fprintf, print, string
1144EXAMPLE : example printf; shows an example
1145"
1146{
1147  write("", sprintf(fmt, #));
1148}
1149example
1150{ "EXAMPLE:"; echo=2;
1151  ring r=0,(x,y,z),dp;
1152  module m=[1,y],[0,x+z];
1153  intmat M=betti(mres(m,0));
1154  list l=r,m,matrix(M);
1155  printf("s:%s,l:%l",1,2);
1156  printf("s:%s",l);
1157  printf("s:%s",list(l));
1158  printf("2l:%2l",list(l));
1159  printf("%p",matrix(M));
1160  printf("%;",matrix(M));
1161  printf("%b",M);
1162}
1163
1164
1165proc fprintf(link l, string fmt, list #)
1166"SYNTAX:  @code{fprintf (} link_expression@code{,} string_expression @code{[,}
1167                any_expressions@code{] )}
1168RETURN:   none
1169PURPOSE:  @code{fprintf(l,fmt,...);} performs output formatting.
1170          The second argument is a format control string. Additional
1171          arguments may be required, depending on the content of the
1172          control string. A series of output characters is generated as
1173          directed by the control string; these characters are
1174          written to the link l.
1175          The control string @code{fmt} is simply text to be copied, except
1176          that the string may contain conversion specifications.@*
1177          Do @code{help print;} for a listing of valid conversion
1178          specifications. As an addition to the conversions of @code{print},
1179          the @code{%n} and @code{%2} conversion specification does not
1180          consume an additional argument, but simply generates a newline
1181          character.
1182NOTE:     If one of the additional arguments is a list, then it should be
1183          enclosed once more into a @code{list()} command, since passing
1184          a list as an argument flattens the list by one level.
1185SEE ALSO: sprintf, printf, print, string
1186EXAMPLE : example fprintf; shows an example
1187"
1188{
1189  write(l, sprintf(fmt, #));
1190}
1191example
1192{ "EXAMPLE:"; echo=2;
1193  ring r=0,(x,y,z),dp;
1194  module m=[1,y],[0,x+z];
1195  intmat M=betti(mres(m,0));
1196  list l=r,m,M;
1197  link li="";   // link to stdout
1198  fprintf(li,"s:%s,l:%l",1,2);
1199  fprintf(li,"s:%s",l);
1200  fprintf(li,"s:%s",list(l));
1201  fprintf(li,"2l:%2l",list(l));
1202  fprintf(li,"%p",list(l));
1203  fprintf(li,"%;",list(l));
1204  fprintf(li,"%b",M);
1205}
1206
1207//////////////////////////////////////////////////////////////////////////
1208
1209/*
1210proc minres(list #)
1211{
1212  if (size(#) == 2)
1213  {
1214    if (typeof(#[1]) == "ideal" || typeof(#[1]) == "module")
1215    {
1216      if (typeof(#[2] == "int"))
1217      {
1218        return (res(#[1],#[2],1));
1219      }
1220    }
1221  }
1222
1223  if (typeof(#[1]) == "resolution")
1224  {
1225    return minimizeres(#[1]);
1226  }
1227  else
1228  {
1229    return minimizeres(#);
1230  }
1231
1232}
1233*/
1234///////////////////////////////////////////////////////////////////////////////
1235
1236proc weightKB(def stc, int dd, list wim)
1237"SYNTAX: @code{weightKB (} module_expression@code{,} int_expression @code{,}
1238            list_expression @code{)}@*
1239         @code{weightKB (} ideal_expression@code{,} int_expression@code{,}
1240            list_expression @code{)}
1241RETURN:  the same as the input type of the first argument
1242PURPOSE:  Computes the part of a vector space basis of the respective quotient with
1243          weighted degree of the monomials equal to the second argument. The last
1244          argument contains the information about the weights as a list of intvec:
1245            @code{wim[1]} for all variables (positive),
1246            @code{wim[2]} only for module for the generators.
1247NOTE:     This is a generalisation for the command @code{kbase} with the same first
1248          two arguments.
1249SEE ALSO: kbase
1250EXAMPLE: example weightKB; shows an example
1251"
1252{
1253  if(checkww(wim)){ERROR("wrong weights";);}
1254  kbclass();
1255  wwtop=wim[1];
1256  stc=interred(lead(stc));
1257  if(typeof(stc)=="ideal")
1258  {
1259    stdtop=stc;
1260    ideal out=widkbase(dd);
1261    delkbclass();
1262    return(out);
1263  }
1264  list mbase=kbprepare(stc);
1265  module mout;
1266  int im,ii;
1267  if(size(wim)>1){mmtop=wim[2];}
1268  else{mmtop=0;}
1269  for(im=size(mbase);im>0;im--)
1270  {
1271    stdtop=mbase[im];
1272    if(im>size(mmtop)){ii=dd;}
1273    else{ii=dd-mmtop[im];}
1274    mout=mout+widkbase(ii)*gen(im);
1275  }
1276  delkbclass();
1277  return(mout);
1278}
1279///////////////////////////////////////////////////////////////////////////////
1280// construct global values
1281static proc kbclass()
1282{
1283  intvec wwtop,mmtop;
1284  export (wwtop,mmtop);
1285  ideal stdtop,kbtop;
1286  export (stdtop,kbtop);
1287  return();
1288}
1289// delete global values
1290static proc delkbclass()
1291{
1292  kill wwtop,mmtop;
1293  kill stdtop,kbtop;
1294  return();
1295}
1296//  select parts of the modul
1297static proc kbprepare(module mstc)
1298{
1299  list rr;
1300  ideal kk;
1301  int i1,i2;
1302  mstc=transpose(mstc);
1303  for(i1=ncols(mstc);i1>0;i1--)
1304  {
1305    kk=0;
1306    for(i2=nrows(mstc[i1]);i2>0;i2--)
1307    {
1308      kk=kk+mstc[i1][i2];
1309    }
1310    rr[i1]=kk;
1311  }
1312  return(rr);
1313}
1314//  check for weights
1315static proc checkww(list vv)
1316{
1317  if(typeof(vv[1])!="intvec"){return(1);}
1318  intvec ww=vv[1];
1319  int mv=nvars(basering);
1320  if(size(ww)<mv){return(1);}
1321  while(mv>0)
1322  {
1323    if(ww[mv]<=0){return(1);}
1324    mv--;
1325  }
1326  if(size(vv)>1)
1327  {
1328    if(typeof(vv[2])!="intvec"){return(1);}
1329  }
1330  return(0);
1331}
1332// The "Caller" for ideals
1333//    dd   - the degree of the result
1334static proc widkbase(int dd)
1335{
1336  if((size(stdtop)==1)&&(deg(stdtop[1])==0)){return(0);}
1337  if(dd<=0)
1338  {
1339    if(dd<0){return(0);}
1340    else{return(1);}
1341  }
1342  int m1,m2;
1343  m1=nvars(basering);
1344  while(wwtop[m1]>dd)
1345  {
1346    m1--;
1347    if(m1==0){return(0);}
1348  }
1349  attrib(stdtop,"isSB",1);
1350  poly mo=1;
1351  if(m1==1)
1352  {
1353    m2=dd/wwtop[1];
1354    if((m2*wwtop[1])==dd)
1355    {
1356      mo=var(1)^m2;
1357      if(reduce(mo,stdtop)==mo){return(mo);}
1358      else{return(0);}
1359    }
1360  }
1361  kbtop=0;
1362  m2=dd;
1363  weightmon(m1-1,m2,mo);
1364  while(m2>=wwtop[m1])
1365  {
1366    m2=m2-wwtop[m1];
1367    mo=mo*var(m1);
1368    if(m2==0)
1369    {
1370      if(reduce(mo,stdtop)==mo)
1371      {
1372        kbtop=kbtop+mo;
1373        return(kbtop);
1374      }
1375    }
1376    weightmon(m1-1,m2,mo);
1377  }
1378  return(kbtop);
1379}
1380// the recursive prozedur
1381//    va     - number of the variable
1382//    drest  - rest of the degree
1383//    mm     - the candidate
1384static proc weightmon(int va, int drest, poly mm)
1385{
1386  while(wwtop[va]>drest)
1387  {
1388    va--;
1389    if(va==0){return();}
1390  }
1391  int m2;
1392  if(va==1)
1393  {
1394    m2=drest/wwtop[1];
1395    if((m2*wwtop[1])==drest)
1396    {
1397      mm=mm*var(1)^m2;
1398      if(reduce(mm,stdtop)==mm){kbtop=kbtop+mm;}
1399    }
1400    return();
1401  }
1402  m2=drest;
1403  weightmon(va-1,m2,mm);
1404  while(m2>=wwtop[va])
1405  {
1406    m2=m2-wwtop[va];
1407    mm=mm*var(va);
1408    if(m2==0)
1409    {
1410      if(reduce(mm,stdtop)==mm)
1411      {
1412        kbtop=kbtop+mm;
1413        return();
1414      }
1415    }
1416    weightmon(va-1,m2,mm);
1417  }
1418  return();
1419}
1420example
1421{ "EXAMPLE:"; echo=2;
1422  ring r=0,(x,y,z),dp;
1423  ideal i = x6,y4,xyz;
1424  intvec w = 2,3,6;
1425  weightKB(i, 12, list(w));
1426}
1427///////////////////////////////////////////////////////////////////////////////
1428
Note: See TracBrowser for help on using the repository browser.