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

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