source: git/Singular/LIB/general.lib @ 84375a

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