source: git/Singular/LIB/general.lib @ 90d772

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