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

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