source: git/Singular/LIB/general.lib @ a7a00b

jengelh-datetimespielwiese
Last change on this file since a7a00b was a7a00b, checked in by Hans Schönemann <hannes@…>, 17 years ago
*hannes: Santiagos changes git-svn-id: file:///usr/local/Singular/svn/trunk@9334 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 48.0 KB
Line 
1//GMG, last modified 18.6.99
2//anne, added deleteSublist and watchdog 12.12.2000
3//eric, added absValue 11.04.2002
4///////////////////////////////////////////////////////////////////////////////
5version="$Id: general.lib,v 1.50 2006-07-20 14:51:56 Singular Exp $";
6category="General purpose";
7info="
8LIBRARY:  general.lib   Elementary Computations of General Type
9
10PROCEDURES:
11 A_Z(\"a\",n);          string a,b,... of n comma separated letters
12 ASCII([n,m]);          string of printable ASCII characters (number n to m)
13 absValue(c);           absolute value of c
14 binomial(n,m[,../..]); n choose m (type int), [type string/type number]
15 deleteSublist(iv,l);   delete entries given by iv from list l
16 factorial(n[,../..]);  n factorial (=n!) (type int), [type string/number]
17 fibonacci(n[,p]);      nth Fibonacci number [char p]
18 kmemory([n[,v]]);      active [allocated] memory in kilobyte
19 killall();             kill all user-defined variables
20 number_e(n);           compute exp(1) up to n decimal digits
21 number_pi(n);          compute pi (area of unit circle) up to n digits
22 primes(n,m);           intvec of primes p, n<=p<=m
23 product(../..[,v]);    multiply components of vector/ideal/...[indices v]
24 sort(ideal/module);    sort generators according to monomial ordering
25 sum(vector/id/..[,v]); add components of vector/ideal/...[with indices v]
26 watchdog(i,cmd);       only wait for result of command cmd for i seconds
27 which(command);        search for command and return absolute path, if found
28 primecoeffs(J[,q]);    primefactors <= min(p,32003) of coeffs of J
29 primefactors(n[,p]);  primefactors <= min(p,32003) of n
30 timeStd(i,d)           std(i) if the standard basis computation finished
31                        after d-1 seconds and i otherwhise
32 timeFactorize(p,d)     factorize(p) if the factorization finished after d-1
33                        seconds otherwhise f is considered to be irreducible
34 factorH(p)             changes variables to become the last variable the
35                        principal one in the multivariate factorization and
36                        factorizes then the polynomial
37
38           (parameters in square brackets [] are optional)
39";
40
41LIB "inout.lib";
42LIB "poly.lib";
43LIB "matrix.lib";
44///////////////////////////////////////////////////////////////////////////////
45
46proc A_Z (string s,int n)
47"USAGE:   A_Z(\"a\",n);  a any letter, n integer (-26<= n <=26, !=0)
48RETURN:  string of n small (if a is small) or capital (if a is capital)
49         letters, comma separated, beginning with a, in alphabetical
50         order (or reverse alphabetical order if n<0)
51EXAMPLE: example A_Z; shows an example
52"
53{
54  if ( n>=-26 and n<=26 and n!=0 )
55  {
56    string alpha =
57    "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,"+
58    "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,"+
59    "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,"+
60    "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
61    int ii; int aa;
62    for(ii=1; ii<=51; ii=ii+2)
63    {
64       if( alpha[ii]==s ) { aa=ii; }
65    }
66    if ( aa==0)
67    {
68      for(ii=105; ii<=155; ii=ii+2)
69      {
70        if( alpha[ii]==s ) { aa=ii; }
71      }
72    }
73    if( aa!=0 )
74    {
75      string out;
76      if (n > 0) { out = alpha[aa,2*(n)-1];  return (out); }
77      if (n < 0)
78      {
79        string beta =
80        "z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a,"+
81        "z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a,"+
82        "Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A,"+
83        "Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A";
84        if ( aa < 52 ) { aa=52-aa; }
85        if ( aa > 104 ) { aa=260-aa; }
86        out = beta[aa,2*(-n)-1]; return (out);
87      }
88    }
89  }
90}
91example
92{ "EXAMPLE:"; echo = 2;
93   A_Z("c",5);
94   A_Z("Z",-5);
95   string sR = "ring R = (0,"+A_Z("A",6)+"),("+A_Z("a",10)+"),dp;";
96   sR;
97   execute(sR);
98   R;
99}
100///////////////////////////////////////////////////////////////////////////////
101proc ASCII (list #)
102"USAGE:   ASCII([n,m]); n,m= integers (32 <= n <= m <= 126)
103RETURN:   string of printable ASCII characters (no native language support)@*
104          ASCII():    string of  all ASCII characters with its numbers,@*
105          ASCII(n):   n-th ASCII character@*
106          ASCII(n,m): n-th up to m-th ASCII character (inclusive)
107EXAMPLE: example ASCII; shows an example
108"
109{
110  string s1 =
111 "     !    \"    #    $    %    &    '    (    )    *    +    ,    -    .
11232   33   34   35   36   37   38   39   40   41   42   43   44   45   46
113/    0    1    2    3    4    5    6    7    8    9    :    ;    <    =
11447   48   49   50   51   52   53   54   55   56   57   58   59   60   61
115>    ?    @    A    B    C    D    E    F    G    H    I    J    K    L
11662   63   64   65   66   67   68   69   70   71   72   73   74   75   76
117M    N    O    P    Q    R    S    T    U    V    W    X    Y    Z    [
11877   78   79   80   81   82   83   84   85   86   87   88   89   90   91
119\\    ]    ^    _    `    a    b    c    d    e    f    g    h    i    j
12092   93   94   95   96   97   98   99  100  101  102  103  104  105  10
121k    l    m    n    o    p    q    r    s    t    u    v    w    x    y
122107  108  109  110  111  112  113  114  115  116  117  118  119  120  121
123z    {    |    }    ~
124122  123  124  125  126 ";
125
126   string s2 =
127 " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
128
129   if ( size(#) == 0 )
130   {
131      return(s1);
132   }
133   if ( size(#) == 1 )
134   {
135      return( s2[#[1]-31] );
136   }
137   if ( size(#) == 2 )
138   {
139      return( s2[#[1]-31,#[2]-#[1]+1] );
140   }
141}
142example
143{ "EXAMPLE:"; echo = 2;
144   ASCII();"";
145   ASCII(42);
146   ASCII(32,126);
147}
148///////////////////////////////////////////////////////////////////////////////
149
150proc absValue(def c)
151"USAGE:  absValue(c); c int, number or poly
152RETURN:  absValue(c); the absolute value of c
153NOTE:    absValue(c)=c if c>=0; absValue=-c if c<=0.
154@*       So the function can be applied to any type, for which comparison
155@*       operators are defined.
156EXAMPLE: example absValue; shows an example
157"
158{
159  if (c>=0) { return(c); }
160  else { return(-c); }
161}
162example
163{ "EXAMPLE:"; echo = 2;
164   ring r1 = 0,x,dp;
165   absValue(-2002);
166
167   poly f=-4;
168   absValue(f);
169}
170///////////////////////////////////////////////////////////////////////////////
171
172proc binomial (int n, int k, list #)
173"USAGE:   binomial(n,k[,p]); n,k,p integers
174RETURN:  binomial(n,k); binomial coefficient n choose k
175@*       - of type string (computed in characteristic 0)
176@*       binomial(n,k,p); n choose k, computed in characteristic 0 or prime(p)
177@*       - of type number if a basering, say R, is present and p=0=char(R)
178           or if prime(p)=char(R)
179@*       - of type string else
180NOTE:    In any characteristic, binomial(n,k) = coefficient of x^k in (1+x)^n
181SEE ALSO: prime
182EXAMPLE: example binomial; shows an example
183"
184{
185   int str,p;
186//---------------------------- initialization -------------------------------
187   if ( size(#) == 0 )
188   {  str = 1;
189      ring bin = 0,x,dp;
190      number r=1;
191   }
192   if ( size(#) > 0 )
193   {
194      p = (#[1]!=0)*prime(#[1]);
195      if ( defined(basering) )
196      {
197         if ( p == char(basering) )
198         {  number r=1;
199         }
200         else
201         {  str = 1;
202            ring bin = p,x,dp;
203            number r=1;
204         }
205      }
206      else
207      {  str = 1;
208         ring bin = p,x,dp;
209         number r=1;
210      }
211   }
212//-------------------------------- char 0 -----------------------------------
213   if ( p==0 )
214   {
215      r = binom0(n,k);
216   }
217//-------------------------------- char p -----------------------------------
218   else
219   {
220      r = binomp(n,k,p);
221   }
222//-------------------------------- return -----------------------------------
223   if ( str==1 ) { return(string(r)); }
224   else { return(r); }
225 }
226example
227{ "EXAMPLE:"; echo = 2;
228   binomial(200,100);"";                   //type string, computed in char 0
229   binomial(200,100,3);"";                 //type string, computed in char 3
230   int n,k = 200,100;
231   ring r = 0,x,dp;
232   number b1 = binomial(n,k,0);            //type number, computed in ring r
233   poly b2 = coeffs((x+1)^n,x)[k+1,1];     //coefficient of x^k in (x+1)^n
234   b1-b2;                                  //b1 and b2 should coincide
235}
236///////////////////////////////////////////////////////////////////////////////
237
238static proc binom0 (int n, int k)
239 //computes binomial coefficient n choose k in basering, assume 0<k<=n
240 //and char(basering) = 0 or n < char(basering)
241{
242   int l;
243   number r=1;
244   if ( k > n-k )
245   { k = n-k;
246   }
247   if ( k<=0 or k>n )               //trivial cases
248   { r = (k==0)*r;
249   }
250   for (l=1; l<=k; l++ )
251   {
252      r=r*(n+1-l)/l;
253   }
254   return(r);
255}
256///////////////////////////////////////////////////////////////////////////////
257
258static proc binomp (int n, int k, int p)
259 //computes binomial coefficient n choose k in basering of char p > 0
260 //binomial(n,k) = coefficient of x^k in (1+x)^n.
261 //Let n=q*p^j, gcd(q,p)=1, then (1+x)^n = (1 + x^(p^j))^q. We have
262 //binomial(n,k)=0 if k!=l*p^j and binomial(n,l*p^j) = binomial(q,l).
263 //Do this reduction first. Then, in denominator and numerator
264 //of defining formula for binomial coefficient, reduce those factors
265 //mod p which are not divisible by p and cancel common factors p. Hence,
266 //if n = h*p+r, k=l*p+s, r,s<p, binomial(n,k) = binomial(r,s)*binomial(h,l)
267{
268   int l,q,i= 1,n,1;
269   number r=1;
270   if ( k > n-k )
271   { k = n-k;
272   }
273   if ( k<=0 or k>n)               //trivial cases
274   { r = (k==0)*r;
275   }
276   else
277   {
278      while ( q mod p == 0 )
279      {  l = l*p;
280         q = q div p;
281      }                            //we have now n=q*l, l=p^j, gcd(q,p)=1;
282      if (k mod l != 0 )
283      { r = 0;
284      }
285      else
286      {  l = k div l;
287         n = q mod p;
288         k = l mod p;              //now 0<= k,n <p, use binom0 for n,k
289         q = q div p;              //recursion for q,l
290         l = l div p;              //use binomp for q,l
291         r = binom0(n,k)*binomp(q,l,p);
292      }
293   }
294   return(r);
295}
296///////////////////////////////////////////////////////////////////////////////
297
298proc factorial (int n, list #)
299"USAGE:    factorial(n[,p]);  n,p integers
300RETURN:   factorial(n):   n! (computed in characteristic 0), of type string.
301@*        factorial(n,p): n! computed in characteristic 0 or prime(p)
302@*        - of type number if a basering is present and 0=p=char(basering)
303            or if prime(p)=char(basering)
304@*        - of type string else
305SEE ALSO: prime
306EXAMPLE:  example factorial; shows an example
307"
308{   int str,l,p;
309//---------------------------- initialization -------------------------------
310   if ( size(#) == 0 )
311   {  str = 1;
312      ring bin = 0,x,dp;
313      number r=1;
314   }
315   if ( size(#) > 0 )
316   {
317      p = (#[1]!=0)*prime(#[1]);
318      if ( defined(basering) )
319      {
320         if ( p == char(basering) )
321         {  number r=1;
322         }
323         else
324         {  str = 1;
325            ring bin = p,x,dp;
326            number r=1;
327         }
328      }
329      else
330      {  str = 1;
331         ring bin = p,x,dp;
332         number r=1;
333      }
334   }
335//------------------------------ computation --------------------------------
336   for (l=2; l<=n; l++)
337   {
338      r=r*l;
339   }
340   if ( str==1 ) { return(string(r)); }
341   else { return(r); }
342}
343example
344{ "EXAMPLE:"; echo = 2;
345   factorial(37);"";                 //37! of type string (as long integer)
346   ring r1 = 0,x,dp;
347   number p = factorial(37,0);       //37! of type number, computed in r1
348   p;
349}
350///////////////////////////////////////////////////////////////////////////////
351
352proc fibonacci (int n, list #)
353"USAGE:    fibonacci(n[,p]);  n,p integers
354RETURN:   fibonacci(n): nth Fibonacci number, f(0)=f(1)=1, f(i+1)=f(i-1)+f(i)
355@*        - computed in characteristic 0, of type string
356@*        fibonacci(n,p): f(n) computed in characteristic 0 or prime(p)
357@*        - of type number if a basering is present and p=0=char(basering)
358            or if prime(p)=char(basering)
359@*        - of type string else
360SEE ALSO: prime
361EXAMPLE: example fibonacci; shows an example
362"
363{   int str,ii,p;
364//---------------------------- initialization -------------------------------
365   if ( size(#) == 0 )
366   {  str = 1;
367      ring bin = 0,x,dp;
368      number f,g,h=1,1,1;
369   }
370   if ( size(#) > 0 )
371   {
372      p = (#[1]!=0)*prime(#[1]);
373      if ( defined(basering) )
374      {
375         if ( p == char(basering) )
376         {  number f,g,h=1,1,1;
377         }
378         else
379         {  str = 1;
380            ring bin = p,x,dp;
381            number f,g,h=1,1,1;
382         }
383      }
384      else
385      {  str = 1;
386         ring bin = p,x,dp;
387         number f,g,h=1,1,1;
388      }
389   }
390//------------------------------ computation --------------------------------
391   for (ii=3; ii<=n; ii=ii+1)
392   {
393      h = f+g; f = g; g = h;
394    }
395   if ( str==1 ) { return(string(h)); }
396   else { return(h); }
397}
398example
399{ "EXAMPLE:"; echo = 2;
400   fibonacci(42); "";             //f(42) of type string (as long integer)
401   ring r = 2,x,dp;
402   number b = fibonacci(42,2);    //f(42) of type number, computed in r
403   b;
404}
405///////////////////////////////////////////////////////////////////////////////
406
407proc kmemory (list #)
408"USAGE:   kmemory([n,[v]]); n,v integers
409RETURN:  memory in kilobyte of type bigint
410@*       n=0: memory used by active variables (same as no parameters)
411@*       n=1: total memory allocated by Singular
412DISPLAY: detailed information about allocated and used memory if v!=0
413NOTE:    kmemory uses internal function 'memory' to compute kilobyte, and
414         is the same as 'memory' for n!=0,1,2
415EXAMPLE: example kmemory; shows an example
416"
417{
418   int n;
419   int verb;
420   if (size(#) != 0)
421   {
422     n=#[1];
423     if (size(#) >1)
424     { verb=#[2]; }
425   }
426
427  if ( verb != 0)
428  {
429    if ( n==0)
430    { dbprint(printlevel-voice+3,
431      "// memory used, at the moment, by active variables (kilobyte):"); }
432    if ( n==1 )
433    { dbprint(printlevel-voice+3,
434      "// total memory allocated, at the moment, by SINGULAR (kilobyte):"); }
435   }
436   return ((memory(n)+1023)/1024);
437}
438example
439{ "EXAMPLE:"; echo = 2;
440   kmemory();
441   kmemory(1,1);
442}
443///////////////////////////////////////////////////////////////////////////////
444
445proc killall
446"USAGE:   killall(); (no parameter)
447         killall(\"type_name\");
448         killall(\"not\", \"type_name\");
449RETURN:  killall(); kills all user-defined variables except loaded procedures,
450         no return value.
451@*       - killall(\"type_name\"); kills all user-defined variables,
452           of type \"type_name\"
453@*       - killall(\"not\", \"type_name\"); kills all user-defined variables,
454           except those of type \"type_name\" and except loaded procedures
455@*       - killall(\"not\", \"name_1\", \"name_2\", ...);
456           kills all user-defined variables, except those of name \"name_i\"
457           and except loaded procedures
458NOTE:    killall should never be used inside a procedure
459EXAMPLE: example killall; shows an example AND KILLS ALL YOUR VARIABLES
460"
461{
462  if (system("with","Namespaces"))
463  {
464    list @marie=names(Top);
465  }
466  else
467  {
468    list @marie=names();
469  }
470  int j, no_kill, @joni;
471  for ( @joni=1; @joni<=size(#);  @joni++)
472  {
473    if (typeof(#[@joni]) != "string")
474    {
475      ERROR("Need string as " + string(@joni) + "th argument");
476    }
477  }
478
479  // kills all user-defined variables but not loaded procedures
480  if( size(#)==0 )
481  {
482    for ( @joni=size(@marie); @joni>0; @joni-- )
483    {
484      if( @marie[@joni]!="LIB" and typeof(`@marie[@joni]`)!="proc"
485      and typeof(`@marie[@joni]`)!="package")
486      { kill `@marie[@joni]`; }
487    }
488  }
489  else
490  {
491    // kills all user-defined variables
492    if( size(#)==1 )
493    {
494      // of type proc
495      if( #[1] == "proc" )
496      {
497        for ( @joni=size(@marie); @joni>0; @joni-- )
498        {
499          if( (@marie[@joni]!="General")
500          and (@marie[@joni]!="Top")
501          and (@marie[@joni]!="killall")
502          and (@marie[@joni]!="LIB") and
503              ((typeof(`@marie[@joni]`)=="package") or
504              (typeof(`@marie[@joni]`)=="proc")))
505          {
506            if (defined(`@marie[@joni]`)) {kill `@marie[@joni]`;}
507          }
508          if (!defined(@joni)) break;
509        }
510        if ((system("with","Namespaces")) && defined(General))
511        {
512          @marie=names(General);
513          for ( @joni=size(@marie); @joni>0; @joni-- )
514          {
515            if(@marie[@joni]!="killall"
516            and typeof(`@marie[@joni]`)=="proc")
517            { kill General::`@marie[@joni]`; }
518          }
519          kill General::killall;
520        }
521      }
522      else
523      {
524        // other types
525        for ( @joni=size(@marie); @joni>2; @joni-- )
526        {
527          if(typeof(`@marie[@joni]`)==#[1] and @marie[@joni]!="LIB"
528             and typeof(`@marie[@joni]`)!="proc")
529          { kill `@marie[@joni]`; }
530        }
531      }
532    }
533    else
534    {
535      // kills all user-defined variables whose name or type is not #i
536      for ( @joni=size(@marie); @joni>2; @joni-- )
537      {
538        if ( @marie[@joni] != "LIB" && @marie[@joni] != "Top"
539             && typeof(`@marie[@joni]`) != "proc")
540        {
541          no_kill = 0;
542          for (j=2; j<= size(#); j++)
543          {
544            if (typeof(`@marie[@joni]`)==#[j] or @marie[@joni] == #[j])
545            {
546              no_kill = 1;
547              break;
548            }
549          }
550          if (! no_kill)
551          {
552            kill `@marie[@joni]`;
553          }
554        }
555        if (!defined(@joni)) break;
556      }
557    }
558  }
559}
560example
561{ "EXAMPLE:"; echo = 2;
562   ring rtest; ideal i=x,y,z; string str="hi"; int j = 3;
563   export rtest,i,str,j;       //this makes the local variables global
564   listvar();
565   killall("ring");            // kills all rings
566   listvar();
567   killall("not", "int");      // kills all variables except int's (and procs)
568   listvar();
569   killall();                  // kills all vars except loaded procs
570   listvar();
571}
572///////////////////////////////////////////////////////////////////////////////
573
574proc number_e (int n)
575"USAGE:   number_e(n);  n integer
576RETURN:  Euler number e=exp(1) up to n decimal digits (no rounding)
577@*       - of type string if no basering of char 0 is defined
578@*       - of type number if a basering of char 0 is defined
579DISPLAY: decimal format of e if printlevel > 0 (default:printlevel=0 )
580NOTE:    procedure uses algorithm of A.H.J. Sale
581EXAMPLE: example number_e; shows an example
582"
583{
584   int i,m,s,t;
585   intvec u,e;
586   u[n+2]=0; e[n+1]=0; e=e+1;
587   if( defined(basering) )
588   {
589      if( char(basering)==0 ) { number r=2; t=1; }
590   }
591   string result = "2.";
592   for( i=1; i<=n+1; i=i+1 )
593   {
594      e = e*10;
595      for( m=n+1; m>=1; m=m-1 )
596      {
597         s    = e[m]+u[m+1];
598         u[m] = s div (m+1);
599         e[m] = s%(m+1);
600      }
601      result = result+string(u[1]);
602      if( t==1 ) { r = r+number(u[1])/number(10)^i; }
603   }
604   if( t==1 )
605   { dbprint(printlevel-voice+2,"// "+result[1,n+1]);
606     return(r);
607   }
608   return(result[1,n+1]);
609}
610example
611{ "EXAMPLE:"; echo = 2;
612   number_e(30);"";
613   ring R = 0,t,lp;
614   number e = number_e(30);
615   e;
616}
617///////////////////////////////////////////////////////////////////////////////
618
619proc number_pi (int n)
620"USAGE:   number_pi(n);  n positive integer
621RETURN:  pi (area of unit circle) up to n decimal digits (no rounding)
622@*       - of type string if no basering of char 0 is defined,
623@*       - of type number, if a basering of char 0 is defined
624DISPLAY: decimal format of pi if printlevel > 0 (default:printlevel=0 )
625NOTE:    procedure uses algorithm of S. Rabinowitz
626EXAMPLE: example number_pi; shows an example
627"
628{
629   int i,m,t,e,q,N;
630   intvec r,p,B,Prelim;
631   string result,prelim;
632   N = (10*n) div 3 + 2;
633   p[N+1]=0; p=p+2; r=p;
634   for( i=1; i<=N+1; i=i+1 ) { B[i]=2*i-1; }
635   if( defined(basering) )
636   {
637      if( char(basering)==0 ) { number pi; number pri; t=1; }
638   }
639   for( i=0; i<=n; i=i+1 )
640   {
641      p = r*10;
642      e = p[N+1];
643      for( m=N+1; m>=2; m=m-1 )
644      {
645         r[m] = e%B[m];
646         q    = e div B[m];
647         e    = q*(m-1)+p[m-1];
648      }
649      r[1] = e%10;
650      q    = e div 10;
651      if( q!=10 and q!=9 )
652      {
653         result = result+prelim;
654         Prelim = q;
655         prelim = string(q);
656      }
657      if( q==9 )
658      {
659         Prelim = Prelim,9;
660         prelim = prelim+"9";
661      }
662      if( q==10 )
663      {
664         Prelim = (Prelim+1)-((Prelim+1) div 10)*10;
665         for( m=size(Prelim); m>0; m=m-1)
666         {
667            prelim[m] = string(Prelim[m]);
668         }
669         result = result+prelim;
670         if( t==1 ) { pi=pi+pri; }
671         Prelim = 0;
672         prelim = "0";
673      }
674      if( t==1 ) { pi=pi+number(q)/number(10)^i; }
675   }
676   result = result,prelim[1];
677   result = "3."+result[2,n-1];
678   if( t==1 )
679   { dbprint(printlevel-voice+2,"// "+result);
680     return(pi);
681   }
682   return(result);
683}
684example
685{ "EXAMPLE:"; echo = 2;
686   number_pi(11);"";
687   ring r = (real,10),t,dp;
688   number pi = number_pi(11); pi;
689}
690///////////////////////////////////////////////////////////////////////////////
691
692proc primes (int n, int m)
693"USAGE:   primes(n,m);  n,m integers
694RETURN:  intvec, consisting of all primes p, prime(n)<=p<=m, in increasing
695         order if n<=m, resp. prime(m)<=p<=n, in decreasing order if m<n.
696NOTE:    prime(n); returns the biggest prime number <= min(n,32003)
697         if n>=2, else 2
698EXAMPLE: example primes; shows an example
699"
700{  int change;
701   if ( n>m ) { change=n; n=m ; m=change; change=1; }
702   int q,p = prime(m),prime(n); intvec v = q; q = q-1;
703   while ( q>=p ) { q = prime(q); v = q,v; q = q-1; }
704   if ( change==1 ) { v = v[size(v)..1]; }
705   return(v);
706}
707example
708{  "EXAMPLE:"; echo = 2;
709    primes(50,100);"";
710    intvec v = primes(37,1); v;
711}
712///////////////////////////////////////////////////////////////////////////////
713
714proc product (id, list #)
715"USAGE:    product(id[,v]); id ideal/vector/module/matrix/intvec/intmat/list,
716          v intvec  (default: v=1..number of entries of id)
717ASSUME:   list members can be multiplied.
718RETURN:   The product of all entries of id [with index given by v] of type
719          depending on the entries of id.
720NOTE:     If id is not a list, id is treated as a list of polys resp. integers.
721          A module m is identified with the corresponding matrix M (columns
722          of M generate m).
723@*        If v is outside the range of id, we have the empty product and the
724          result will be 1 (of type int).
725EXAMPLE:  example product; shows an example
726"
727{
728//-------------------- initialization and special feature ---------------------
729   int n,j,tt;
730   string ty;                                //will become type of id
731   list l;
732
733// We wish to allow something like product(x(1..10)) if x(1),...,x(10) are
734// variables. x(1..10) is a list of polys and enters the procedure with
735// id=x(1) and # a list with 9 polys, #[1]= x(2),...,#[9]= x(10). Hence, in
736// this case # is never empty. If an additional intvec v is given,
737// it is added to #, so we have to separate it first and make
738// the rest a list which has to be multiplied.
739
740   int s = size(#);
741   if( s!=0 )
742   {  if ( typeof(#[s])=="intvec" or typeof(#[s])=="int")
743      {
744         intvec v = #[s];
745         tt=1;
746         s=s-1;
747         if ( s>0 ) { # = #[1..s]; }
748      }
749   }
750   if ( s>0 )
751   {
752      l = list(id)+#;
753      kill id;
754      list id = l;                                    //case: id = list
755      ty = "list";
756      n = size(id);
757   }
758   else
759   {
760      ty = typeof(id);
761      if( ty == "list" )
762      { n = size(id); }
763   }
764//------------------------------ reduce to 3 cases ---------------------------
765   if( ty=="poly" or ty=="ideal" or ty=="vector"
766       or ty=="module" or ty=="matrix" )
767   {
768      ideal i = ideal(matrix(id));
769      kill id;
770      ideal id = i;                                   //case: id = ideal
771      n = ncols(id);
772   }
773   if( ty=="int" or ty=="intvec" or ty=="intmat" )
774   {
775      if ( ty == "int" ) { intmat S =id; }
776      else { intmat S = intmat(id); }
777      intvec i = S[1..nrows(S),1..ncols(S)];
778      kill id;
779      intvec id = i;                                  //case: id = intvec
780      n = size(id);
781   }
782//--------------- consider intvec v and empty product  -----------------------
783   if( tt!=0 )
784   {
785      for (j=1; j<=size(v); j++)
786      {
787         if ( v[j] <= 0 or v[j] > n )                 //v outside range of id
788         {
789            return(1);                                //empty product is 1
790         }
791      }
792      id = id[v];                                     //consider part of id
793   }                                                  //corresponding to v
794//--------------------- special case: one factor is zero  ---------------------
795   if ( typeof(id) == "ideal")
796   {
797      if( size(id) < ncols(id) )
798      {
799          poly f; return(f);
800      }
801   }
802//-------------------------- finally, multiply objects  -----------------------
803   n = size(id);
804   def f(1) = id[1];
805   for( j=2; j<=n; j=j+1 ) { def f(j)=f(j-1)*id[j]; }
806   return(f(n));
807}
808example
809{  "EXAMPLE:"; echo = 2;
810   ring r= 0,(x,y,z),dp;
811   ideal m = maxideal(1);
812   product(m);
813   product(m[2..3]);
814   matrix M[2][3] = 1,x,2,y,3,z;
815   product(M);
816   intvec v=2,4,6;
817   product(M,v);
818   intvec iv = 1,2,3,4,5,6,7,8,9;
819   v=1..5,7,9;
820   product(iv,v);
821   intmat A[2][3] = 1,1,1,2,2,2;
822   product(A,3..5);
823}
824///////////////////////////////////////////////////////////////////////////////
825
826proc sort (id, list #)
827"USAGE:   sort(id[,v,o,n]); id = ideal/module/intvec/list(of intvec's or int's)
828@*       sort may be called with 1, 2 or 3 arguments in the following way:
829@*       sort(id[,v,n]); v=intvec of positive integers, n=integer,
830@*       sort(id[,o,n]); o=string (any allowed ordstr of a ring), n=integer
831RETURN:  a list l of two elements:
832@format
833        l[1]: object of same type as input but sorted in the following way:
834           - if id=ideal/module: generators of id are sorted w.r.t. intvec v
835             (id[v[1]] becomes 1-st, id[v[2]]  2-nd element, etc.). If no v is
836             present, id is sorted w.r.t. ordering o (if o is given) or w.r.t.
837             actual monomial ordering (if no o is given):
838             NOTE: generators with SMALLER(!) leading term come FIRST
839             (e.g. sort(id); sorts backwards to actual monomial ordering)
840           - if id=list of intvec's or int's: consider a list element, say
841             id[1]=3,2,5, as exponent vector of the monomial x^3*y^2*z^5;
842             the corresponding monomials are ordered w.r.t. intvec v (s.a.).
843             If no v is present, the monomials are sorted w.r.t. ordering o
844             (if o is given) or w.r.t. lexicographical ordering (if no o is
845             given). The corresponding ordered list of exponent vectors is
846             returned.
847             (e.g. sort(id); sorts lexicographically, smaller int's come first)
848             WARNING: Since negative exponents create the 0 polynomial in
849             Singular, id should not contain negative integers: the result
850             might not be as expected
851           - if id=intvec: id is treated as list of integers
852           - if n!=0 the ordering is inverse, i.e. w.r.t. v(size(v)..1)
853             default: n=0
854         l[2]: intvec, describing the permutation of the input (hence l[2]=v
855             if v is given (with positive integers))
856@end format
857NOTE:    If v is given id may be any simply indexed object (e.g. any list or
858         string); if v[i]<0 and i<=size(id) v[i] is set internally to i;
859         entries of v must be pairwise distinct to get a permutation if id.
860         Zero generators of ideal/module are deleted
861EXAMPLE: example sort; shows an example
862"
863{  int ii,jj,s,n = 0,0,1,0;
864   intvec v;
865   if ( defined(basering) ) { def P = basering; }
866   if ( size(#)==0 and (typeof(id)=="ideal" or typeof(id)=="module"
867                        or typeof(id)=="matrix"))
868   {
869      id = simplify(id,2);
870      for ( ii=1; ii<size(id); ii++ )
871      {
872         if ( id[ii]!=id[ii+1] ) { break;}
873      }
874      if ( ii != size(id) ) { v = sortvec(id); }
875      else  { v = size(id)..1; }
876   }
877   if ( size(#)>=1 and (typeof(id)=="ideal" or typeof(id)=="module"
878                        or typeof(id)=="matrix") )
879   {
880      if ( typeof(#[1])=="string" )
881      {
882         execute("ring r1 =("+charstr(P)+"),("+varstr(P)+"),("+#[1]+");");
883         def i = imap(P,id);
884         v = sortvec(i);
885         setring P;
886         n=2;
887      }
888   }
889   if ( typeof(id)=="intvec" or typeof(id)=="list" and n==0 )
890   {
891      string o;
892      if ( size(#)==0 ) { o = "lp"; n=1; }
893      if ( size(#)>=1 )
894      {
895         if ( typeof(#[1])=="string" ) { o = #[1]; n=1; }
896      }
897   }
898   if ( typeof(id)=="intvec" or typeof(id)=="list" and n==1 )
899   {
900      if ( typeof(id)=="list" )
901      {
902         for (ii=1; ii<=size(id); ii++)
903         {
904            if (typeof(id[ii]) != "intvec" and typeof(id[ii]) != "int")
905               { ERROR("// list elements must be intvec/int"); }
906            else
907               { s=size(id[ii])*(s < size(id[ii])) + s*(s >= size(id[ii])); }
908         }
909      }
910      execute("ring r=0,x(1..s),("+o+");");
911      ideal i;
912      poly f;
913      for (ii=1; ii<=size(id); ii++)
914      {
915         f=1;
916         for (jj=1; jj<=size(id[ii]); jj++)
917         {
918            f=f*x(jj)^(id[ii])[jj];
919         }
920         i[ii]=f;
921      }
922      v = sort(i)[2];
923   }
924   if ( size(#)!=0 and n==0 ) { v = #[1]; }
925   if( size(#)==2 )
926   {
927      if ( #[2] != 0 ) { v = v[size(v)..1]; }
928   }
929   s = size(v);
930   if( size(id) < s ) { s = size(id); }
931   def m = id;
932   if ( size(m) != 0 )
933   {
934      for ( jj=1; jj<=s; jj=jj+1)
935      {
936         if ( v[jj]<=0 ) { v[jj]=jj; }
937         m[jj] = id[v[jj]];
938      }
939   }
940   if ( v == 0 ) { v = 1; }
941   list L=m,v;
942   return(L);
943}
944example
945{  "EXAMPLE:"; echo = 2;
946   ring r0 = 0,(x,y,z,t),lp;
947   ideal i = x3,z3,xyz;
948   sort(i);            //sorts using lex ordering, smaller polys come first
949
950   sort(i,3..1);
951
952   sort(i,"ls")[1];     //sort w.r.t. negative lex ordering
953
954   intvec v =1,10..5,2..4;v;
955   sort(v)[1];          // sort v lexicographically
956
957   sort(v,"Dp",1)[1];   // sort v w.r.t (total sum, reverse lex)
958}
959///////////////////////////////////////////////////////////////////////////////
960proc sum (id, list #)
961"USAGE:    sum(id[,v]); id ideal/vector/module/matrix/intvec/intmat/list,
962          v intvec  (default: v=1..number of entries of id)
963ASSUME:   list members can be added.
964RETURN:   The sum of all entries of id [with index given by v] of type
965          depending on the entries of id.
966NOTE:     If id is not a list, id is treated as a list of polys resp. integers.
967          A module m is identified with the corresponding matrix M (columns
968          of M generate m).
969@*        If v is outside the range of id, we have the empty sum and the
970          result will be 0 (of type int).
971EXAMPLE:  example sum; shows an example
972"
973{
974//-------------------- initialization and special feature ---------------------
975   int n,j,tt;
976   string ty;                                  // will become type of id
977   list l;
978
979// We wish to allow something like sum(x(1..10)) if x(1),...,x(10) are
980// variables. x(1..10) is a list of polys and enters the procedure with
981// id=x(1) and # a list with 9 polys, #[1]= x(2),...,#[9]= x(10). Hence, in
982// this case # is never empty. If an additional intvec v is given,
983// it is added to #, so we have to separate it first and make
984// the rest a list which has to be added.
985
986   int s = size(#);
987   if( s!=0 )
988   {  if ( typeof(#[s])=="intvec" or typeof(#[s])=="int")
989      {  intvec v = #[s];
990         tt=1;
991         s=s-1;
992         if ( s>0 ) { # = #[1..s]; }
993      }
994   }
995   if ( s>0 )
996   {
997      l = list(id)+#;
998      kill id;
999      list id = l;                                    //case: id = list
1000      ty = "list";
1001   }
1002   else
1003   {
1004      ty = typeof(id);
1005   }
1006//------------------------------ reduce to 3 cases ---------------------------
1007   if( ty=="poly" or ty=="ideal" or ty=="vector"
1008       or ty=="module" or ty=="matrix" )
1009   {                                                 //case: id = ideal
1010      ideal i = ideal(matrix(id));
1011      kill id;
1012      ideal id = simplify(i,2);                      //delete 0 entries
1013   }
1014   if( ty=="int" or ty=="intvec" or ty=="intmat" )
1015   {
1016      if ( ty == "int" ) { intmat S =id; }
1017      else { intmat S = intmat(id); }
1018      intvec i = S[1..nrows(S),1..ncols(S)];
1019      kill id;
1020      intvec id = i;                                 //case: id = intvec
1021   }
1022//------------------- consider intvec v and empty sum  -----------------------
1023   if( tt!=0 )
1024   {
1025      for (j=1; j<=size(v); j++)
1026      {
1027         if ( v[j] <= 0 or v[j] > size(id) )         //v outside range of id
1028         {
1029            return(0);                               //empty sum is 0
1030         }
1031      }
1032      id = id[v];                                    //consider part of id
1033   }                                                 //corresponding to v
1034
1035//-------------------------- finally, add objects  ---------------------------
1036   n = size(id);
1037   def f(1) = id[1];
1038   for( j=2; j<=n; j=j+1 ) { def f(j)=f(j-1)+id[j]; }
1039   return(f(n));   int n,j,tt;
1040}
1041example
1042{  "EXAMPLE:"; echo = 2;
1043   ring r= 0,(x,y,z),dp;
1044   vector pv = [xy,xz,yz,x2,y2,z2];
1045   sum(pv);
1046   sum(pv,2..5);
1047   matrix M[2][3] = 1,x,2,y,3,z;
1048   intvec w=2,4,6;
1049   sum(M,w);
1050   intvec iv = 1,2,3,4,5,6,7,8,9;
1051   sum(iv,2..4);
1052}
1053///////////////////////////////////////////////////////////////////////////////
1054
1055proc which (command)
1056"USAGE:    which(command); command = string expression
1057RETURN:   Absolute pathname of command, if found in search path.
1058          Empty string, otherwise.
1059NOTE:     Based on the Unix command 'which'.
1060EXAMPLE:  example which; shows an example
1061"
1062{
1063   int rs;
1064   int i;
1065   string fn = "which_" + string(system("pid"));
1066   string pn;
1067   string cmd;
1068   if( typeof(command) != "string")
1069   {
1070     return (pn);
1071   }
1072   if (system("uname") != "ix86-Win")
1073   {
1074     cmd = "which ";
1075   }
1076   else
1077   {
1078     // unfortunately, it does not take -path
1079     cmd = "type ";
1080   }
1081   i = system("sh", cmd + command + " > " + fn);
1082   pn = read(fn);
1083   if (system("uname") != "ix86-Win")
1084   {
1085     // TBC: Hmm... should parse output to get rid of 'command is '
1086     pn[size(pn)] = "";
1087     i = 1;
1088     while ((pn[i] != " ") and (pn[i] != ""))
1089     {
1090       i = i+1;
1091     }
1092     if (pn[i] == " ") {pn[i] = "";}
1093     rs = system("sh", "ls " + pn + " > " + fn + " 2>&1 ");
1094   }
1095   else
1096   {
1097     rs = 0;
1098   }
1099   i = system("sh", "rm " + fn);
1100   if (rs == 0) {return (pn);}
1101   else
1102   {
1103     print (command + " not found ");
1104     return ("");
1105   }
1106}
1107example
1108{  "EXAMPLE:"; echo = 2;
1109    which("sh");
1110}
1111///////////////////////////////////////////////////////////////////////////////
1112
1113proc watchdog(int i, string cmd)
1114"USAGE:   watchdog(i,cmd); i integer, cmd string
1115RETURN:  Result of cmd, if the result can be computed in i seconds.
1116         Otherwise the computation is interrupted after i seconds,
1117         the string "Killed" is returned and the global variable
1118         'watchdog_interrupt' is defined.
1119NOTE:    * the MP package must be enabled
1120         * the current basering should not be watchdog_rneu, since
1121           watchdog_rneu will be killed
1122         * if there are variable names of the structure x(i) all
1123           polynomials have to be put into eval(...) in order to be
1124           interpreted correctly
1125         * a second Singular process is started by this procedure
1126EXAMPLE: example watchdog; shows an example
1127"
1128{
1129  string rname=nameof(basering);
1130  if (defined(watchdog_rneu))
1131  {
1132    kill watchdog_rneu;
1133  }
1134// If we do not have MP-links, watchdog cannot be used
1135  if (system("with","MP"))
1136  {
1137    if ( i > 0 )
1138    {
1139      int j=10;
1140      int k=999999;
1141// fork, get the pid of the child and send it the command
1142      link l_fork="MPtcp:fork";
1143      open(l_fork);
1144      write(l_fork,quote(system("pid")));
1145      int pid=read(l_fork);
1146      execute("write(l_fork,quote(" + cmd + "));");
1147
1148
1149// sleep in small, but growing intervals for appr. 1 second
1150      while(j < k)
1151      {
1152        if (status(l_fork, "read", "ready", j)) {break;}
1153        j = j + j;
1154      }
1155
1156// sleep in intervals of one second
1157      j = 1;
1158      if (!status(l_fork,"read","ready"))
1159      {
1160        while (j < i)
1161        {
1162          if (status(l_fork, "read", "ready", k)) {break;}
1163          j = j + 1;
1164        }
1165      }
1166// check, whether we have a result, and return it
1167      if (status(l_fork, "read", "ready"))
1168      {
1169        def result = read(l_fork);
1170        if (nameof(basering)!=rname)
1171        {
1172          def watchdog_rneu=basering;
1173        }
1174        if(defined(watchdog_interrupt))
1175        {
1176          kill watchdog_interrupt;
1177        }
1178        close(l_fork);
1179      }
1180      else
1181      {
1182        string result="Killed";
1183        if(!defined(watchdog_interrupt))
1184        {
1185          int watchdog_interrupt=1;
1186          export watchdog_interrupt;
1187        }
1188        close(l_fork);
1189        j = system("sh","kill " + string(pid));
1190      }
1191      if (defined(watchdog_rneu))
1192      {
1193        keepring watchdog_rneu;
1194      }
1195      return(result);
1196    }
1197    else
1198    {
1199      ERROR("First argument of watchdog has to be a positive integer.");
1200    }
1201  }
1202  else
1203  {
1204    ERROR("MP-support is not enabled in this version of Singular.");
1205  }
1206}
1207example
1208{ "EXAMPLE:"; echo=2;
1209  ring r=0,(x,y,z),dp;
1210  poly f=x^30+y^30;
1211  watchdog(1,"factorize(eval("+string(f)+"))");
1212  watchdog(100,"factorize(eval("+string(f)+"))");
1213}
1214///////////////////////////////////////////////////////////////////////////////
1215
1216proc deleteSublist(intvec v,list l)
1217"USAGE:   deleteSublist(v,l); intvec v; list l
1218         where the entries of the integer vector v correspond to the
1219         positions of the elements to be deleted
1220RETURN:  list without the deleted elements
1221EXAMPLE: example deleteSublist; shows an example"
1222{
1223  list k;
1224  int i,j,skip;
1225  j=1;
1226  skip=0;
1227  intvec vs=sort(v)[1];
1228  for ( i=1 ; i <=size(vs) ; i++)
1229  {
1230    while ((j+skip) < vs[i])
1231    {
1232      k[j] = l[j+skip];
1233      j++;
1234    }
1235    skip++;
1236  }
1237  if(vs[size(vs)]<size(l))
1238  {
1239    k=k+list(l[(vs[size(vs)]+1)..size(l)]);
1240  }
1241  return(k);
1242}
1243example
1244{ "EXAMPLE:"; echo=2;
1245   list l=1,2,3,4,5;
1246   intvec v=1,3,4;
1247   l=deleteSublist(v,l);
1248   l;
1249}
1250///////////////////////////////////////////////////////////////////////////////
1251proc primefactors (n, list #)
1252"USAGE:   primefactors(n [,p]); n = int or number, p = integer
1253COMPUTE: primefactors <= min(p,32003) of n (default p = 32003)
1254RETURN:  a list, say l,
1255         l[1] : primefactors <= min(p,32003) of n
1256         l[2] : l[2][i] = multiplicity of l[1][i]
1257         l[3] : remaining factor ( n=product{ (l[1][i]^l[2][i])*l[3]} )
1258                type(l[3])=typeof(n)
1259NOTE:    If n is a long integer (of type number) then the procedure
1260         finds primefactors <= min(p,32003) but n may as larger as
1261         2147483647 (max. integer representation)
1262WARNING: the procedure works for small integers only, just by testing all
1263         primes (not to be considerd as serious prime factorization!)
1264EXAMPLE: example primefactors; shows an example
1265"
1266{
1267   int ii,jj,z,p,num,w3,q;
1268   intvec w1,w2,v;
1269   list l;
1270   if (size(#) == 0)
1271   {
1272      p=32003;
1273   }
1274   else
1275   {
1276     if( typeof(#[1]) != "int")
1277     {
1278       ERROR("2nd parameter must be of type int"+newline);
1279     }
1280     p=#[1];
1281   }
1282   if( n<0) { n=-n;};
1283
1284// ----------------- case: 1st parameter is a number --------------------
1285   if (typeof(n) =="number")
1286   {
1287     kill w3;
1288     number w3;
1289     if( n > 2147483647 )           //2147483647 max. integer representation
1290     {
1291        v = primes(2,p);
1292        number m;
1293        for( ii=1; ii<=size(v); ii++)
1294        {
1295          jj=0;
1296          while(1)
1297          {
1298            q  = v[ii];
1299            jj = jj+1;
1300            m  = n/q;                  //divide n as often as possible
1301            if (denominator(m)!=1) { break;  }
1302            n=m;
1303          }
1304          if( jj>1 )
1305          {
1306             w1 = w1,v[ii];          //primes
1307             w2 = w2,jj-1;           //powers
1308          }
1309          if( n <= 2147483647 ) { break;  }
1310        }
1311     }
1312
1313     if( n >  2147483647 )            //n is still too big
1314     {
1315       if( size(w1) >1 )               //at least 1 primefactor was found
1316       {
1317         w1 = w1[2..size(w1)];
1318         w2 = w2[2..size(w2)];
1319       }
1320       else                           //no primefactor was found
1321       {
1322         w1 = 1; w2 = 1;
1323       }
1324       l  = w1,w2,n;
1325       return(l);
1326     }
1327
1328     if( n <= 2147483647 )          //n is in inter range
1329     {
1330       num = int(n);
1331       kill n;
1332       int n = num;
1333     }
1334   }
1335
1336// --------------------------- trivial cases --------------------
1337   if( n==0 )
1338   {
1339     w1=1; w2=1; w3=0; l=w1,w2,w3;
1340     return(l);
1341   }
1342
1343   if( n==1 )
1344   {
1345       w3=1;
1346       if( size(w1) >1 )               //at least 1 primefactor was found
1347       {
1348         w1 = w1[2..size(w1)];
1349         w2 = w2[2..size(w2)];
1350       }
1351       else                           //no primefactor was found
1352       {
1353         w1 = 1; w2 = 1;
1354       }
1355      l=w1,w2,w3;
1356      return(l);
1357   }
1358   if ( prime(n)==n )         //note: prime(n) <= 32003 in Singular
1359   {                          //case n is a prime
1360      if (p > n)
1361      {
1362        w1=w1,n; w2=w2,1; w3=1;
1363        w1 = w1[2..size(w1)];
1364        w2 = w2[2..size(w2)];
1365        l=w1,w2,w3;
1366        return(l);
1367      }
1368      else
1369      {
1370        w3=n;
1371        if( size(w1) >1 )               //at least 1 primefactor was found
1372        {
1373           w1 = w1[2..size(w1)];
1374           w2 = w2[2..size(w2)];
1375         }
1376         else                           //no primefactor was found
1377         {
1378           w1 = 1; w2 = 1;
1379         }
1380         l=w1,w2,w3;
1381        return(l);
1382      }
1383   }
1384   else
1385   {
1386      if ( p >= n)
1387      {
1388         v = primes(q,n div 2 + 1);
1389      }
1390      else
1391      {
1392         v = primes(q,p);
1393      }
1394//------------- search for primfactors <= last entry of v ------------
1395      for(ii=1; ii<=size(v); ii++)
1396      {
1397         z=0;
1398         while( (n mod v[ii]) == 0 )
1399         {
1400            z=z+1;
1401            n = n div v[ii];
1402         }
1403         if (z!=0)
1404         {
1405            w1 = w1,v[ii];        //primes
1406            w2 = w2,z;            //multiplicities
1407         }
1408      }
1409   }
1410//--------------- case:at least 1 primefactor was found ---------------
1411   if( size(w1) >1 )               //at least 1 primefactor was found
1412   {
1413      w1 = w1[2..size(w1)];
1414      w2 = w2[2..size(w2)];
1415   }
1416   else                           //no primefactor was found
1417   {
1418     w1 = 1; w2 = 1;
1419   }
1420   w3 = n;
1421   l  = w1,w2,w3;
1422   return(l);
1423}
1424example
1425{ "EXAMPLE:"; echo = 2;
1426   primefactors(7*8*121);
1427   ring r = 0,x,dp;
1428   primefactors(123456789100);
1429}
1430
1431///////////////////////////////////////////////////////////////////////////////
1432proc primecoeffs(J, list #)
1433"USAGE:   primecoeffs(J[,p]); J any type which can be converted to a matrix
1434         e.g. ideal, matrix, vector, module, int, intvec
1435         p = integer
1436COMPUTE: primefactors <= min(p,32003) of coeffs of J (default p = 32003)
1437RETURN:  a list, say l, of two intvectors:@*
1438         l[1] : the different primefactors of all coefficients of J@*
1439         l[2] : the different remaining factors
1440NOTE:    the procedure works for small integers only, just by testing all
1441         primes (not to be considered as serious prime factorization!)
1442EXAMPLE: example primecoeffs; shows an example
1443"
1444{
1445   int q,ii,n,mark;;
1446   if (size(#) == 0)
1447   {
1448      q=32003;
1449   }
1450   else
1451   {
1452     if( typeof(#[1]) != "int")
1453     {
1454       ERROR("2nd parameter must be of type int"+newline);
1455     }
1456     q=#[1];
1457   }
1458
1459   if (defined(basering) == 0)
1460   {
1461     mark=1;
1462     ring r = 0,x,dp;
1463   }
1464   def I = ideal(matrix(J));
1465   poly p = product(maxideal(1));
1466   matrix Coef=coef(I[1],p);
1467   ideal id, jd, rest;
1468   intvec v,re;
1469   list result,l;
1470   for(ii=2; ii<=ncols(I); ii++)
1471   {
1472     Coef=concat(Coef,coef(I[ii],p));
1473   }
1474   id = Coef[2,1..ncols(Coef)];
1475   id = simplify(id,6);
1476   for (ii=1; ii<=size(id); ii++)
1477   {
1478     l = primefactors(number(id[ii]),q);
1479     jd = jd,l[1];
1480     rest = rest,l[3];
1481   }
1482   jd = simplify(jd,6);
1483   for (ii=1; ii<=size(jd); ii++)
1484   {
1485     v[ii]=int(jd[ii]);
1486   }
1487   v = sort(v)[1];
1488   rest = simplify(rest,6);
1489   id = sort(id)[1];
1490   if (mark)
1491   {
1492     for (ii=1; ii<=size(rest); ii++)
1493     {
1494       re[ii] = int(rest[ii]);
1495     }
1496     result = v,re;
1497   }
1498   else
1499   {
1500      result = v,rest;
1501   }
1502   return(result);
1503}
1504example
1505{ "EXAMPLE:"; echo = 2;
1506   primecoeffs(intvec(7*8*121,7*8));"";
1507   ring r = 0,(b,c,t),dp;
1508   ideal I = -13b6c3t+4b5c4t,-10b4c2t-5b4ct2;
1509   primecoeffs(I);
1510}
1511///////////////////////////////////////////////////////////////////////////////
1512proc timeFactorize(poly i,list #)
1513"USAGE:  timeFactorize(p,d); poly p , integer d
1514RETURN:  factorize(p) if the factorization finished after d-1
1515         seconds otherwhise f is considered to be irreducible
1516EXAMPLE: example timeFactorize; shows an example
1517"
1518{
1519  def P=basering;
1520  if (size(#) > 0)
1521  {
1522    if (system("with", "MP"))
1523    {
1524      if ((typeof(#[1]) == "int")&&(#[1]))
1525      {
1526        int wait = #[1];
1527        int j = 10;
1528
1529        string bs = nameof(basering);
1530        link l_fork = "MPtcp:fork";
1531        open(l_fork);
1532        write(l_fork, quote(system("pid")));
1533        int pid = read(l_fork);
1534        write(l_fork, quote(timeFactorize(eval(i))));
1535
1536        // sleep in small intervalls for appr. one second
1537        if (wait > 0)
1538        {
1539          while(j < 1000000)
1540          {
1541            if (status(l_fork, "read", "ready", j)) {break;}
1542            j = j + j;
1543          }
1544        }
1545
1546        // sleep in intervalls of one second from now on
1547        j = 1;
1548        while (j < wait)
1549        {
1550          if (status(l_fork, "read", "ready", 1000000)) {break;}
1551          j = j + 1;
1552        }
1553
1554        if (status(l_fork, "read", "ready"))
1555        {
1556          def result = read(l_fork);
1557          if (bs != nameof(basering))
1558          {
1559            def PP = basering;
1560            setring P;
1561            def result = imap(PP, result);
1562            kill PP;
1563          }
1564          kill l_fork;
1565        }
1566        else
1567        {
1568          list result;
1569          intvec v=1,1;
1570          result[1]=list(1,i);
1571          result[2]=v;
1572          j = system("sh", "kill " + string(pid));
1573        }
1574        return (result);
1575      }
1576    }
1577  }
1578  return(factorH(i));
1579}
1580example
1581{ "EXAMPLE:"; echo = 2;
1582   ring r=0,(x,y),dp;
1583   poly p=((x2+y3)^2+xy6)*((x3+y2)^2+x10y);
1584   p=p^2;
1585   //timeFactorize(p,2);
1586   //timeFactorize(p,20);
1587}
1588
1589proc timeStd(ideal i,list #)
1590"USAGE:  timeStd(i,d), i ideal, d integer
1591RETURN:  std(i) if the standard basis computation finished after
1592         d-1 seconds and i otherwhise
1593EXAMPLE: example timeStd; shows an example
1594"
1595{
1596  def P=basering;
1597  if (size(#) > 0)
1598  {
1599    if (system("with", "MP"))
1600    {
1601      if ((typeof(#[1]) == "int")&&(#[1]))
1602      {
1603        int wait = #[1];
1604        int j = 10;
1605
1606        string bs = nameof(basering);
1607        link l_fork = "MPtcp:fork";
1608        open(l_fork);
1609        write(l_fork, quote(system("pid")));
1610        int pid = read(l_fork);
1611        write(l_fork, quote(timeStd(eval(i))));
1612
1613        // sleep in small intervalls for appr. one second
1614        if (wait > 0)
1615        {
1616          while(j < 1000000)
1617          {
1618            if (status(l_fork, "read", "ready", j)) {break;}
1619            j = j + j;
1620          }
1621        }
1622        j = 1;
1623        while (j < wait)
1624        {
1625          if (status(l_fork, "read", "ready", 1000000)) {break;}
1626          j = j + 1;
1627        }
1628        if (status(l_fork, "read", "ready"))
1629        {
1630          def result = read(l_fork);
1631          if (bs != nameof(basering))
1632          {
1633            def PP = basering;
1634            setring P;
1635            def result = imap(PP, result);
1636            kill PP;
1637          }
1638          kill l_fork;
1639        }
1640        else
1641        {
1642          ideal result=i;
1643          j = system("sh", "kill " + string(pid));
1644        }
1645        return (result);
1646      }
1647    }
1648  }
1649  return(std(i));
1650}
1651example
1652{ "EXAMPLE:"; echo = 2;
1653   ring r=32003,(a,b,c,d,e),dp;
1654   int n=6;
1655   ideal i=
1656   a^n-b^n,
1657   b^n-c^n,
1658   c^n-d^n,
1659   d^n-e^n,
1660   a^(n-1)*b+b^(n-1)*c+c^(n-1)*d+d^(n-1)*e+e^(n-1)*a;
1661   timeStd(i,2);
1662   timeStd(i,20);
1663}
1664
1665proc factorH(poly p)
1666"USAGE:  factorH(p)  p poly
1667RETURN:  factorize(p)
1668NOTE:    changes variables to make the last variable the principal
1669         one in the multivariate factorization and factorizes then
1670         the polynomial
1671EXAMPLE: example factorH; shows an example
1672"
1673{
1674   def R=basering;
1675   int i,j;
1676   int n=1;
1677   int d=nrows(coeffs(p,var(1)));
1678   for(i=1;i<=nvars(R);i++)
1679   {
1680      j=nrows(coeffs(p,var(i)));
1681      if(d>j)
1682      {
1683         n=i;
1684         d=j;
1685      }
1686   }
1687   ideal ma=maxideal(1);    //die letzte Variable ist die Hauptvariable
1688   ma[nvars(R)]=var(n);
1689   ma[n]=var(nvars(R));
1690   map phi=R,ma;
1691   list fac=factorize(phi(p));
1692   list re=phi(fac);
1693   return(re);
1694}
1695example
1696{ "EXAMPLE:"; echo = 2;
1697  system("random",992851144);
1698  ring r=32003,(x,y,z,w,t),lp;
1699  poly p=y2w9+yz7t-yz5w4-z2w4t4-w8t3;
1700  factorize(p);  //fast
1701  system("random",992851262);
1702  //factorize(p);  //slow
1703  system("random",992851262);
1704  factorH(p);
1705}
Note: See TracBrowser for help on using the repository browser.