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

spielwiese
Last change on this file since 558209 was 558209, checked in by Hans Schönemann <hannes@…>, 17 years ago
*hannes: sort: smal optimm. git-svn-id: file:///usr/local/Singular/svn/trunk@9637 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 48.7 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.54 2007-01-08 09:33:55 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<ncols(id); ii++ )
871      {
872         if ( id[ii]!=id[ii+1] ) { break;}
873      }
874      if ( ii != ncols(id) ) { v = sortvec(id); }
875      else  { v = ncols(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++)
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///////////////////////////////////////////////////////////////////////////////
960
961static proc lsum (int n, list l)
962{ if (n>10)
963  { return( lsum(n/2,list(l[1..(n/2)])) + lsum(n-n/2, list(l[(n/2+1)..n])) );
964  }
965  else
966  { def Summe=l[1];
967    for (int i=2;i<=n;i++)
968    { Summe=Summe+l[i];
969    }
970    return(Summe);
971  }
972}
973
974///////////////////////////////////////////////////////////////////////////////
975
976proc sum (id, list #)
977"USAGE:    sum(id[,v]); id ideal/vector/module/matrix/intvec/intmat/list,
978          v intvec  (default: v=1..number of entries of id)
979ASSUME:   list members can be added.
980RETURN:   The sum of all entries of id [with index given by v] of type
981          depending on the entries of id.
982NOTE:     If id is not a list, id is treated as a list of polys resp. integers.
983          A module m is identified with the corresponding matrix M (columns
984          of M generate m).
985@*        If v is outside the range of id, we have the empty sum and the
986          result will be 0 (of type int).
987EXAMPLE:  example sum; shows an example
988"
989{
990//-------------------- initialization and special feature ---------------------
991   int n,j,tt;
992   string ty;                                  // will become type of id
993   list l;
994
995// We wish to allow something like sum(x(1..10)) if x(1),...,x(10) are
996// variables. x(1..10) is a list of polys and enters the procedure with
997// id=x(1) and # a list with 9 polys, #[1]= x(2),...,#[9]= x(10). Hence, in
998// this case # is never empty. If an additional intvec v is given,
999// it is added to #, so we have to separate it first and make
1000// the rest a list which has to be added.
1001
1002   int s = size(#);
1003   if( s!=0 )
1004   {  if ( typeof(#[s])=="intvec" or typeof(#[s])=="int")
1005      {  intvec v = #[s];
1006         tt=1;
1007         s=s-1;
1008         if ( s>0 ) { # = #[1..s]; }
1009      }
1010   }
1011   if ( s>0 )
1012   {
1013      l = list(id)+#;
1014      kill id;
1015      list id = l;                                    //case: id = list
1016      ty = "list";
1017   }
1018   else
1019   {
1020      ty = typeof(id);
1021   }
1022//------------------------------ reduce to 3 cases ---------------------------
1023   if( ty=="poly" or ty=="ideal" or ty=="vector"
1024       or ty=="module" or ty=="matrix" )
1025   {                                                 //case: id = ideal
1026      ideal i = ideal(matrix(id));
1027      kill id;
1028      ideal id = simplify(i,2);                      //delete 0 entries
1029   }
1030   if( ty=="int" or ty=="intvec" or ty=="intmat" )
1031   {                                                 //case: id = intvec
1032      if ( ty == "int" ) { intmat S =id; }
1033      else { intmat S = intmat(id); }
1034      intvec i = S[1..nrows(S),1..ncols(S)];
1035      kill id;
1036      intvec id = i;
1037   }
1038//------------------- consider intvec v and empty sum  -----------------------
1039   if( tt!=0 )
1040   {
1041      for (j=1; j<=size(v); j++)
1042      {
1043         if ( v[j] <= 0 or v[j] > size(id) )         //v outside range of id
1044         {
1045            return(0);                               //empty sum is 0
1046         }
1047      }
1048      id = id[v];                                    //consider part of id
1049   }                                                 //corresponding to v
1050
1051//-------------------------- finally, add objects  ---------------------------
1052   n = size(id);
1053   if (n>10)
1054   { return( lsum(n/2,list(id[1..(n/2)])) + lsum(n-n/2, list(id[(n/2+1)..n])) );
1055   }
1056   else
1057   { def Summe=id[1];
1058     for (int lauf=2;lauf<=n;lauf++)
1059     { Summe=Summe+id[lauf];
1060     }
1061     return(Summe);
1062   }
1063}
1064example
1065{  "EXAMPLE:"; echo = 2;
1066   ring r1 = 0,(x,y,z),dp;
1067   vector pv = [xy,xz,yz,x2,y2,z2];
1068   sum(pv);
1069   sum(pv,2..5);
1070   matrix M[2][3] = 1,x,2,y,3,z;
1071   intvec w=2,4,6;
1072   sum(M,w);
1073   intvec iv = 1,2,3,4,5,6,7,8,9;
1074   sum(iv,2..4);
1075   iv = intvec(1..100);
1076   sum(iv);
1077   ring r2 = 0,(x(1..10)),dp;
1078   sum(x(3..7),intvec(1,3,5));
1079}
1080///////////////////////////////////////////////////////////////////////////////
1081
1082
1083///////////////////////////////////////////////////////////////////////////////
1084
1085proc which (command)
1086"USAGE:    which(command); command = string expression
1087RETURN:   Absolute pathname of command, if found in search path.
1088          Empty string, otherwise.
1089NOTE:     Based on the Unix command 'which'.
1090EXAMPLE:  example which; shows an example
1091"
1092{
1093   int rs;
1094   int i;
1095   string fn = "which_" + string(system("pid"));
1096   string pn;
1097   string cmd;
1098   if( typeof(command) != "string")
1099   {
1100     return (pn);
1101   }
1102   if (system("uname") != "ix86-Win")
1103   {
1104     cmd = "which ";
1105   }
1106   else
1107   {
1108     // unfortunately, it does not take -path
1109     cmd = "type ";
1110   }
1111   i = system("sh", cmd + command + " > " + fn);
1112   pn = read(fn);
1113   if (system("uname") != "ix86-Win")
1114   {
1115     // TBC: Hmm... should parse output to get rid of 'command is '
1116     pn[size(pn)] = "";
1117     i = 1;
1118     while ((pn[i] != " ") and (pn[i] != ""))
1119     {
1120       i = i+1;
1121     }
1122     if (pn[i] == " ") {pn[i] = "";}
1123     rs = system("sh", "ls " + pn + " > " + fn + " 2>&1 ");
1124   }
1125   else
1126   {
1127     rs = 0;
1128   }
1129   i = system("sh", "rm " + fn);
1130   if (rs == 0) {return (pn);}
1131   else
1132   {
1133     print (command + " not found ");
1134     return ("");
1135   }
1136}
1137example
1138{  "EXAMPLE:"; echo = 2;
1139    which("sh");
1140}
1141///////////////////////////////////////////////////////////////////////////////
1142
1143proc watchdog(int i, string cmd)
1144"USAGE:   watchdog(i,cmd); i integer, cmd string
1145RETURN:  Result of cmd, if the result can be computed in i seconds.
1146         Otherwise the computation is interrupted after i seconds,
1147         the string "Killed" is returned and the global variable
1148         'watchdog_interrupt' is defined.
1149NOTE:    * the MP package must be enabled
1150         * the current basering should not be watchdog_rneu, since
1151           watchdog_rneu will be killed
1152         * if there are variable names of the structure x(i) all
1153           polynomials have to be put into eval(...) in order to be
1154           interpreted correctly
1155         * a second Singular process is started by this procedure
1156EXAMPLE: example watchdog; shows an example
1157"
1158{
1159  string rname=nameof(basering);
1160  def rsave=basering;
1161  if (defined(watchdog_rneu))
1162  {
1163    kill watchdog_rneu;
1164  }
1165// If we do not have MP-links, watchdog cannot be used
1166  if (system("with","MP"))
1167  {
1168    if ( i > 0 )
1169    {
1170      int j=10;
1171      int k=999999;
1172// fork, get the pid of the child and send it the command
1173      link l_fork="MPtcp:fork";
1174      open(l_fork);
1175      write(l_fork,quote(system("pid")));
1176      int pid=read(l_fork);
1177      execute("write(l_fork,quote(" + cmd + "));");
1178
1179
1180// sleep in small, but growing intervals for appr. 1 second
1181      while(j < k)
1182      {
1183        if (status(l_fork, "read", "ready", j)) {break;}
1184        j = j + j;
1185      }
1186
1187// sleep in intervals of one second
1188      j = 1;
1189      if (!status(l_fork,"read","ready"))
1190      {
1191        while (j < i)
1192        {
1193          if (status(l_fork, "read", "ready", k)) {break;}
1194          j = j + 1;
1195        }
1196      }
1197// check, whether we have a result, and return it
1198      if (status(l_fork, "read", "ready"))
1199      {
1200        def result = read(l_fork);
1201        if (nameof(basering)!=rname)
1202        {
1203          def watchdog_rneu=basering;
1204          setring rsave;
1205          if (!defined(result))
1206          {
1207            def result=fetch(watchdog_rneu,result);
1208          }
1209        }
1210        if(defined(watchdog_interrupt))
1211        {
1212          kill watchdog_interrupt;
1213        }
1214        close(l_fork);
1215      }
1216      else
1217      {
1218        string result="Killed";
1219        if(!defined(watchdog_interrupt))
1220        {
1221          int watchdog_interrupt=1;
1222          export watchdog_interrupt;
1223        }
1224        close(l_fork);
1225        j = system("sh","kill " + string(pid));
1226      }
1227      return(result);
1228    }
1229    else
1230    {
1231      ERROR("First argument of watchdog has to be a positive integer.");
1232    }
1233  }
1234  else
1235  {
1236    ERROR("MP-support is not enabled in this version of Singular.");
1237  }
1238}
1239example
1240{ "EXAMPLE:"; echo=2;
1241  ring r=0,(x,y,z),dp;
1242  poly f=x^30+y^30;
1243  watchdog(1,"factorize(eval("+string(f)+"))");
1244  watchdog(100,"factorize(eval("+string(f)+"))");
1245}
1246///////////////////////////////////////////////////////////////////////////////
1247
1248proc deleteSublist(intvec v,list l)
1249"USAGE:   deleteSublist(v,l); intvec v; list l
1250         where the entries of the integer vector v correspond to the
1251         positions of the elements to be deleted
1252RETURN:  list without the deleted elements
1253EXAMPLE: example deleteSublist; shows an example"
1254{
1255  list k;
1256  int i,j,skip;
1257  j=1;
1258  skip=0;
1259  intvec vs=sort(v)[1];
1260  for ( i=1 ; i <=size(vs) ; i++)
1261  {
1262    while ((j+skip) < vs[i])
1263    {
1264      k[j] = l[j+skip];
1265      j++;
1266    }
1267    skip++;
1268  }
1269  if(vs[size(vs)]<size(l))
1270  {
1271    k=k+list(l[(vs[size(vs)]+1)..size(l)]);
1272  }
1273  return(k);
1274}
1275example
1276{ "EXAMPLE:"; echo=2;
1277   list l=1,2,3,4,5;
1278   intvec v=1,3,4;
1279   l=deleteSublist(v,l);
1280   l;
1281}
1282///////////////////////////////////////////////////////////////////////////////
1283proc primefactors (n, list #)
1284"USAGE:   primefactors(n [,p]); n = int or number, p = integer
1285COMPUTE: primefactors <= min(p,32003) of n (default p = 32003)
1286RETURN:  a list, say l,
1287         l[1] : primefactors <= min(p,32003) of n
1288         l[2] : l[2][i] = multiplicity of l[1][i]
1289         l[3] : remaining factor ( n=product{ (l[1][i]^l[2][i])*l[3]} )
1290                type(l[3])=typeof(n)
1291NOTE:    If n is a long integer (of type number) then the procedure
1292         finds primefactors <= min(p,32003) but n may as larger as
1293         2147483647 (max. integer representation)
1294WARNING: the procedure works for small integers only, just by testing all
1295         primes (not to be considerd as serious prime factorization!)
1296EXAMPLE: example primefactors; shows an example
1297"
1298{
1299   int ii,jj,z,p,num,w3,q;
1300   intvec w1,w2,v;
1301   list l;
1302   if (size(#) == 0)
1303   {
1304      p=32003;
1305   }
1306   else
1307   {
1308     if( typeof(#[1]) != "int")
1309     {
1310       ERROR("2nd parameter must be of type int"+newline);
1311     }
1312     p=#[1];
1313   }
1314   if( n<0) { n=-n;};
1315
1316// ----------------- case: 1st parameter is a number --------------------
1317   if (typeof(n) =="number")
1318   {
1319     kill w3;
1320     number w3;
1321     if( n > 2147483647 )           //2147483647 max. integer representation
1322     {
1323        v = primes(2,p);
1324        number m;
1325        for( ii=1; ii<=size(v); ii++)
1326        {
1327          jj=0;
1328          while(1)
1329          {
1330            q  = v[ii];
1331            jj = jj+1;
1332            m  = n/q;                  //divide n as often as possible
1333            if (denominator(m)!=1) { break;  }
1334            n=m;
1335          }
1336          if( jj>1 )
1337          {
1338             w1 = w1,v[ii];          //primes
1339             w2 = w2,jj-1;           //powers
1340          }
1341          if( n <= 2147483647 ) { break;  }
1342        }
1343     }
1344
1345     if( n >  2147483647 )            //n is still too big
1346     {
1347       if( size(w1) >1 )               //at least 1 primefactor was found
1348       {
1349         w1 = w1[2..size(w1)];
1350         w2 = w2[2..size(w2)];
1351       }
1352       else                           //no primefactor was found
1353       {
1354         w1 = 1; w2 = 1;
1355       }
1356       l  = w1,w2,n;
1357       return(l);
1358     }
1359
1360     if( n <= 2147483647 )          //n is in inter range
1361     {
1362       num = int(n);
1363       kill n;
1364       int n = num;
1365     }
1366   }
1367
1368// --------------------------- trivial cases --------------------
1369   if( n==0 )
1370   {
1371     w1=1; w2=1; w3=0; l=w1,w2,w3;
1372     return(l);
1373   }
1374
1375   if( n==1 )
1376   {
1377       w3=1;
1378       if( size(w1) >1 )               //at least 1 primefactor was found
1379       {
1380         w1 = w1[2..size(w1)];
1381         w2 = w2[2..size(w2)];
1382       }
1383       else                           //no primefactor was found
1384       {
1385         w1 = 1; w2 = 1;
1386       }
1387      l=w1,w2,w3;
1388      return(l);
1389   }
1390   if ( prime(n)==n )         //note: prime(n) <= 32003 in Singular
1391   {                          //case n is a prime
1392      if (p > n)
1393      {
1394        w1=w1,n; w2=w2,1; w3=1;
1395        w1 = w1[2..size(w1)];
1396        w2 = w2[2..size(w2)];
1397        l=w1,w2,w3;
1398        return(l);
1399      }
1400      else
1401      {
1402        w3=n;
1403        if( size(w1) >1 )               //at least 1 primefactor was found
1404        {
1405           w1 = w1[2..size(w1)];
1406           w2 = w2[2..size(w2)];
1407         }
1408         else                           //no primefactor was found
1409         {
1410           w1 = 1; w2 = 1;
1411         }
1412         l=w1,w2,w3;
1413        return(l);
1414      }
1415   }
1416   else
1417   {
1418      if ( p >= n)
1419      {
1420         v = primes(q,n div 2 + 1);
1421      }
1422      else
1423      {
1424         v = primes(q,p);
1425      }
1426//------------- search for primfactors <= last entry of v ------------
1427      for(ii=1; ii<=size(v); ii++)
1428      {
1429         z=0;
1430         while( (n mod v[ii]) == 0 )
1431         {
1432            z=z+1;
1433            n = n div v[ii];
1434         }
1435         if (z!=0)
1436         {
1437            w1 = w1,v[ii];        //primes
1438            w2 = w2,z;            //multiplicities
1439         }
1440      }
1441   }
1442//--------------- case:at least 1 primefactor was found ---------------
1443   if( size(w1) >1 )               //at least 1 primefactor was found
1444   {
1445      w1 = w1[2..size(w1)];
1446      w2 = w2[2..size(w2)];
1447   }
1448   else                           //no primefactor was found
1449   {
1450     w1 = 1; w2 = 1;
1451   }
1452   w3 = n;
1453   l  = w1,w2,w3;
1454   return(l);
1455}
1456example
1457{ "EXAMPLE:"; echo = 2;
1458   primefactors(7*8*121);
1459   ring r = 0,x,dp;
1460   primefactors(123456789100);
1461}
1462
1463///////////////////////////////////////////////////////////////////////////////
1464proc primecoeffs(J, list #)
1465"USAGE:   primecoeffs(J[,p]); J any type which can be converted to a matrix
1466         e.g. ideal, matrix, vector, module, int, intvec
1467         p = integer
1468COMPUTE: primefactors <= min(p,32003) of coeffs of J (default p = 32003)
1469RETURN:  a list, say l, of two intvectors:@*
1470         l[1] : the different primefactors of all coefficients of J@*
1471         l[2] : the different remaining factors
1472NOTE:    the procedure works for small integers only, just by testing all
1473         primes (not to be considered as serious prime factorization!)
1474EXAMPLE: example primecoeffs; shows an example
1475"
1476{
1477   int q,ii,n,mark;;
1478   if (size(#) == 0)
1479   {
1480      q=32003;
1481   }
1482   else
1483   {
1484     if( typeof(#[1]) != "int")
1485     {
1486       ERROR("2nd parameter must be of type int"+newline);
1487     }
1488     q=#[1];
1489   }
1490
1491   if (defined(basering) == 0)
1492   {
1493     mark=1;
1494     ring r = 0,x,dp;
1495   }
1496   def I = ideal(matrix(J));
1497   poly p = product(maxideal(1));
1498   matrix Coef=coef(I[1],p);
1499   ideal id, jd, rest;
1500   intvec v,re;
1501   list result,l;
1502   for(ii=2; ii<=ncols(I); ii++)
1503   {
1504     Coef=concat(Coef,coef(I[ii],p));
1505   }
1506   id = Coef[2,1..ncols(Coef)];
1507   id = simplify(id,6);
1508   for (ii=1; ii<=size(id); ii++)
1509   {
1510     l = primefactors(number(id[ii]),q);
1511     jd = jd,l[1];
1512     rest = rest,l[3];
1513   }
1514   jd = simplify(jd,6);
1515   for (ii=1; ii<=size(jd); ii++)
1516   {
1517     v[ii]=int(jd[ii]);
1518   }
1519   v = sort(v)[1];
1520   rest = simplify(rest,6);
1521   id = sort(id)[1];
1522   if (mark)
1523   {
1524     for (ii=1; ii<=size(rest); ii++)
1525     {
1526       re[ii] = int(rest[ii]);
1527     }
1528     result = v,re;
1529   }
1530   else
1531   {
1532      result = v,rest;
1533   }
1534   return(result);
1535}
1536example
1537{ "EXAMPLE:"; echo = 2;
1538   primecoeffs(intvec(7*8*121,7*8));"";
1539   ring r = 0,(b,c,t),dp;
1540   ideal I = -13b6c3t+4b5c4t,-10b4c2t-5b4ct2;
1541   primecoeffs(I);
1542}
1543///////////////////////////////////////////////////////////////////////////////
1544proc timeFactorize(poly i,list #)
1545"USAGE:  timeFactorize(p,d); poly p , integer d
1546RETURN:  factorize(p) if the factorization finished after d-1
1547         seconds otherwhise f is considered to be irreducible
1548EXAMPLE: example timeFactorize; shows an example
1549"
1550{
1551  def P=basering;
1552  if (size(#) > 0)
1553  {
1554    if (system("with", "MP"))
1555    {
1556      if ((typeof(#[1]) == "int")&&(#[1]))
1557      {
1558        int wait = #[1];
1559        int j = 10;
1560
1561        string bs = nameof(basering);
1562        link l_fork = "MPtcp:fork";
1563        open(l_fork);
1564        write(l_fork, quote(system("pid")));
1565        int pid = read(l_fork);
1566        write(l_fork, quote(timeFactorize(eval(i))));
1567
1568        // sleep in small intervalls for appr. one second
1569        if (wait > 0)
1570        {
1571          while(j < 1000000)
1572          {
1573            if (status(l_fork, "read", "ready", j)) {break;}
1574            j = j + j;
1575          }
1576        }
1577
1578        // sleep in intervalls of one second from now on
1579        j = 1;
1580        while (j < wait)
1581        {
1582          if (status(l_fork, "read", "ready", 1000000)) {break;}
1583          j = j + 1;
1584        }
1585
1586        if (status(l_fork, "read", "ready"))
1587        {
1588          def result = read(l_fork);
1589          if (bs != nameof(basering))
1590          {
1591            def PP = basering;
1592            setring P;
1593            def result = imap(PP, result);
1594            kill PP;
1595          }
1596          kill l_fork;
1597        }
1598        else
1599        {
1600          list result;
1601          intvec v=1,1;
1602          result[1]=list(1,i);
1603          result[2]=v;
1604          j = system("sh", "kill " + string(pid));
1605        }
1606        return (result);
1607      }
1608    }
1609  }
1610  return(factorH(i));
1611}
1612example
1613{ "EXAMPLE:"; echo = 2;
1614   ring r=0,(x,y),dp;
1615   poly p=((x2+y3)^2+xy6)*((x3+y2)^2+x10y);
1616   p=p^2;
1617   //timeFactorize(p,2);
1618   //timeFactorize(p,20);
1619}
1620
1621proc timeStd(ideal i,list #)
1622"USAGE:  timeStd(i,d), i ideal, d integer
1623RETURN:  std(i) if the standard basis computation finished after
1624         d-1 seconds and i otherwhise
1625EXAMPLE: example timeStd; shows an example
1626"
1627{
1628  def P=basering;
1629  if (size(#) > 0)
1630  {
1631    if (system("with", "MP"))
1632    {
1633      if ((typeof(#[1]) == "int")&&(#[1]))
1634      {
1635        int wait = #[1];
1636        int j = 10;
1637
1638        string bs = nameof(basering);
1639        link l_fork = "MPtcp:fork";
1640        open(l_fork);
1641        write(l_fork, quote(system("pid")));
1642        int pid = read(l_fork);
1643        write(l_fork, quote(timeStd(eval(i))));
1644
1645        // sleep in small intervalls for appr. one second
1646        if (wait > 0)
1647        {
1648          while(j < 1000000)
1649          {
1650            if (status(l_fork, "read", "ready", j)) {break;}
1651            j = j + j;
1652          }
1653        }
1654        j = 1;
1655        while (j < wait)
1656        {
1657          if (status(l_fork, "read", "ready", 1000000)) {break;}
1658          j = j + 1;
1659        }
1660        if (status(l_fork, "read", "ready"))
1661        {
1662          def result = read(l_fork);
1663          if (bs != nameof(basering))
1664          {
1665            def PP = basering;
1666            setring P;
1667            def result = imap(PP, result);
1668            kill PP;
1669          }
1670          kill l_fork;
1671        }
1672        else
1673        {
1674          ideal result=i;
1675          j = system("sh", "kill " + string(pid));
1676        }
1677        return (result);
1678      }
1679    }
1680  }
1681  return(std(i));
1682}
1683example
1684{ "EXAMPLE:"; echo = 2;
1685   ring r=32003,(a,b,c,d,e),dp;
1686   int n=6;
1687   ideal i=
1688   a^n-b^n,
1689   b^n-c^n,
1690   c^n-d^n,
1691   d^n-e^n,
1692   a^(n-1)*b+b^(n-1)*c+c^(n-1)*d+d^(n-1)*e+e^(n-1)*a;
1693   timeStd(i,2);
1694   timeStd(i,20);
1695}
1696
1697proc factorH(poly p)
1698"USAGE:  factorH(p)  p poly
1699RETURN:  factorize(p)
1700NOTE:    changes variables to make the last variable the principal
1701         one in the multivariate factorization and factorizes then
1702         the polynomial
1703EXAMPLE: example factorH; shows an example
1704"
1705{
1706   def R=basering;
1707   int i,j;
1708   int n=1;
1709   int d=nrows(coeffs(p,var(1)));
1710   for(i=1;i<=nvars(R);i++)
1711   {
1712      j=nrows(coeffs(p,var(i)));
1713      if(d>j)
1714      {
1715         n=i;
1716         d=j;
1717      }
1718   }
1719   ideal ma=maxideal(1);    //die letzte Variable ist die Hauptvariable
1720   ma[nvars(R)]=var(n);
1721   ma[n]=var(nvars(R));
1722   map phi=R,ma;
1723   list fac=factorize(phi(p));
1724   list re=phi(fac);
1725   return(re);
1726}
1727example
1728{ "EXAMPLE:"; echo = 2;
1729  system("random",992851144);
1730  ring r=32003,(x,y,z,w,t),lp;
1731  poly p=y2w9+yz7t-yz5w4-z2w4t4-w8t3;
1732  factorize(p);  //fast
1733  system("random",992851262);
1734  //factorize(p);  //slow
1735  system("random",992851262);
1736  factorH(p);
1737}
Note: See TracBrowser for help on using the repository browser.