source: git/Singular/LIB/standard.lib @ 0266ac

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