source: git/Singular/LIB/standard.lib @ 4893c14

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