source: git/Singular/LIB/general.lib @ 2f436b

spielwiese
Last change on this file since 2f436b was 2f436b, checked in by Olaf Bachmann <obachman@…>, 23 years ago
* version 1-3-13: sparsemat improivements git-svn-id: file:///usr/local/Singular/svn/trunk@5003 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 38.3 KB
Line 
1//GMG, last modified 18.6.99
2//anne, added deleteSublist and watchdog 12.12.2000
3///////////////////////////////////////////////////////////////////////////////
4version="$Id: general.lib,v 1.34 2000-12-31 15:14:46 obachman Exp $";
5category="General purpose";
6info="
7LIBRARY:  general.lib   Elementary Computations of General Type
8
9PROCEDURES:
10 A_Z(\"a\",n);          string a,b,... of n comma separated letters
11 ASCII([n,m]);          string of printable ASCII characters (number n to m)
12 binomial(n,m[,../..]); n choose m (type int), [type string/type number]
13 deleteSublist(iv,l);   delete entries given by iv from list l
14 factorial(n[,../..]);  n factorial (=n!) (type int), [type string/number]
15 fibonacci(n[,p]);      nth Fibonacci number [char p]
16 kmemory([n[,v]]);      active [allocated] memory in kilobyte
17 killall();             kill all user-defined variables
18 number_e(n);           compute exp(1) up to n decimal digits
19 number_pi(n);          compute pi (area of unit circle) up to n digits
20 primes(n,m);           intvec of primes p, n<=p<=m
21 product(../..[,v]);    multiply components of vector/ideal/...[indices v]
22 ringweights(r);        intvec of weights of ring variables of ring r
23 sort(ideal/module);    sort generators according to monomial ordering
24 sum(vector/id/..[,v]); add components of vector/ideal/...[with indices v]
25 watchdog(i,cmd);       only wait for result of command cmd for i seconds
26 which(command);        search for command and return absolute path, if found
27           (parameters in square brackets [] are optional)
28";
29
30LIB "inout.lib";
31///////////////////////////////////////////////////////////////////////////////
32
33proc A_Z (string s,int n)
34"USAGE:   A_Z(\"a\",n);  a any letter, n integer (-26<= n <=26, !=0)
35RETURN:  string of n small (if a is small) or capital (if a is capital)
36         letters, comma separated, beginning with a, in alphabetical
37         order (or revers alphabetical order if n<0)
38EXAMPLE: example A_Z; shows an example
39"
40{
41  if ( n>=-26 and n<=26 and n!=0 )
42  {
43    string alpha =
44    "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,"+
45    "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,"+
46    "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,"+
47    "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";
48    int ii; int aa;
49    for(ii=1; ii<=51; ii=ii+2)
50    {
51       if( alpha[ii]==s ) { aa=ii; }
52    }
53    if ( aa==0)
54    {
55      for(ii=105; ii<=155; ii=ii+2)
56      {
57        if( alpha[ii]==s ) { aa=ii; }
58      }
59    }
60    if( aa!=0 )
61    {
62      string out;
63      if (n > 0) { out = alpha[aa,2*(n)-1];  return (out); }
64      if (n < 0)
65      {
66        string beta =
67        "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,"+
68        "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,"+
69        "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,"+
70        "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";
71        if ( aa < 52 ) { aa=52-aa; }
72        if ( aa > 104 ) { aa=260-aa; }
73        out = beta[aa,2*(-n)-1]; return (out);
74      }
75    }
76  }
77}
78example
79{ "EXAMPLE:"; echo = 2;
80   A_Z("c",5);
81   A_Z("Z",-5);
82   string sR = "ring R = (0,"+A_Z("A",6)+"),("+A_Z("a",10)+"),dp;";
83   sR;
84   execute(sR);
85   R;
86}
87///////////////////////////////////////////////////////////////////////////////
88proc ASCII (list #)
89"USAGE:   ASCII([n,m]); n,m= integers (32 <= n <= m <= 126)
90RETURN:   string of printable ASCII characters (no native language support)
91          ASCII():    string of  all ASCII characters with its numbers,
92          ASCII(n):   n-th ASCII character
93          ASCII(n,m): n-th up to m-th ASCII character (inclusive)
94EXAMPLE: example ASCII; shows an example
95"
96{
97  string s1 =
98 "     !    \"    #    $    %    &    '    (    )    *    +    ,    -    .
9932   33   34   35   36   37   38   39   40   41   42   43   44   45   46
100/    0    1    2    3    4    5    6    7    8    9    :    ;    <    =
10147   48   49   50   51   52   53   54   55   56   57   58   59   60   61
102>    ?    @    A    B    C    D    E    F    G    H    I    J    K    L
10362   63   64   65   66   67   68   69   70   71   72   73   74   75   76
104M    N    O    P    Q    R    S    T    U    V    W    X    Y    Z    [
10577   78   79   80   81   82   83   84   85   86   87   88   89   90   91
106\\    ]    ^    _    `    a    b    c    d    e    f    g    h    i    j
10792   93   94   95   96   97   98   99  100  101  102  103  104  105  10
108k    l    m    n    o    p    q    r    s    t    u    v    w    x    y
109107  108  109  110  111  112  113  114  115  116  117  118  119  120  121
110z    {    |    }    ~
111122  123  124  125  126 ";
112
113   string s2 =
114 " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
115
116   if ( size(#) == 0 )
117   {
118      return(s1);
119   }
120   if ( size(#) == 1 )
121   {
122      return( s2[#[1]-31] );
123   }
124   if ( size(#) == 2 )
125   {
126      return( s2[#[1]-31,#[2]-#[1]+1] );
127   }
128}
129example
130{ "EXAMPLE:"; echo = 2;
131   ASCII();"";
132   ASCII(42);
133   ASCII(32,126);
134}
135///////////////////////////////////////////////////////////////////////////////
136
137proc binomial (int n, int k, list #)
138"USAGE:   binomial(n,k[,p]); n,k,p integers
139RETURN:  binomial(n,k); binomial coefficient n choose k
140@*       - of type string (computed in characteristic 0)
141@*       binomial(n,k,p); n choose k, computed in characteristic 0 or prime(p)
142@*       - of type number if a basering, say R, is present and p=0=char(R)
143           or if prime(p)=char(R)
144@*       - of type string else
145NOTE:    In any characteristic, binomial(n,k) = coefficient of x^k in (1+x)^n
146SEE ALSO: prime
147EXAMPLE: example binomial; shows an example
148"
149{
150   int str,p;
151//---------------------------- initialization -------------------------------
152   if ( size(#) == 0 )
153   {  str = 1;
154      ring bin = 0,x,dp;
155      number r=1;
156   }
157   if ( size(#) > 0 )
158   {
159      p = (#[1]!=0)*prime(#[1]);
160      if ( defined(basering) )
161      {
162         if ( p == char(basering) )
163         {  number r=1;
164         }
165         else
166         {  str = 1;
167            ring bin = p,x,dp;
168            number r=1;
169         }
170      }
171      else
172      {  str = 1;
173         ring bin = p,x,dp;
174         number r=1;
175      }
176   }
177//-------------------------------- char 0 -----------------------------------
178   if ( p==0 )
179   {
180      r = binom0(n,k);
181   }
182//-------------------------------- char p -----------------------------------
183   else
184   {
185      r = binomp(n,k,p);
186   }
187//-------------------------------- return -----------------------------------
188   if ( str==1 ) { return(string(r)); }
189   else { return(r); }
190 }
191example
192{ "EXAMPLE:"; echo = 2;
193   binomial(200,100);"";                   //type string, computed in char 0
194   binomial(200,100,3);"";                 //type string, computed in char 3
195   int n,k = 200,100;
196   ring r = 0,x,dp;
197   number b1 = binomial(n,k,0);            //type number, computed in ring r
198   poly b2 = coeffs((x+1)^n,x)[k+1,1];     //coefficient of x^k in (x+1)^n
199   b1-b2;                                  //b1 and b2 should coincide
200}
201///////////////////////////////////////////////////////////////////////////////
202
203static proc binom0 (int n, int k)
204 //computes binomial coefficient n choose k in basering, assume 0<k<=n
205 //and char(basering) = 0 or n < char(basering)
206{
207   int l;
208   number r=1;
209   if ( k > n-k )
210   { k = n-k;
211   }
212   if ( k<=0 or k>n )               //trivial cases
213   { r = (k==0)*r;
214   }
215   for (l=1; l<=k; l++ )
216   {
217      r=r*(n+1-l)/l;
218   }
219   return(r);
220}
221///////////////////////////////////////////////////////////////////////////////
222
223static proc binomp (int n, int k, int p)
224 //computes binomial coefficient n choose k in basering of char p > 0
225 //binomial(n,k) = coefficient of x^k in (1+x)^n.
226 //Let n=q*p^j, gcd(q,p)=1, then (1+x)^n = (1 + x^(p^j))^q. We have
227 //binomial(n,k)=0 if k!=l*p^j and binomial(n,l*p^j) = binomial(q,l).
228 //Do this reduction first. Then, in denominator and numerator
229 //of defining formula for binomial coefficient, reduce those factors
230 //mod p which are not divisible by p and cancel common factors p. Hence,
231 //if n = h*p+r, k=l*p+s, r,s<p, binomial(n,k) = binomial(r,s)*binomial(h,l)
232{
233   int l,q,i= 1,n,1;
234   number r=1;
235   if ( k > n-k )
236   { k = n-k;
237   }
238   if ( k<=0 or k>n)               //trivial cases
239   { r = (k==0)*r;
240   }
241   else
242   {
243      while ( q mod p == 0 )
244      {  l = l*p;
245         q = q div p;
246      }                            //we have now n=q*l, l=p^j, gcd(q,p)=1;
247      if (k mod l != 0 )
248      { r = 0;
249      }
250      else
251      {  l = k div l;
252         n = q mod p;
253         k = l mod p;              //now 0<= k,n <p, use binom0 for n,k
254         q = q div p;              //recursion for q,l
255         l = l div p;              //use binomp for q,l
256         r = binom0(n,k)*binomp(q,l,p);
257      }
258   }
259   return(r);
260}
261///////////////////////////////////////////////////////////////////////////////
262
263proc factorial (int n, list #)
264"USAGE:    factorial(n[,p]);  n,p integers
265RETURN:   factorial(n):   n! (computed in characteristic 0), of type string.
266@*        factorial(n,p): n! computed in characteristic 0 or prime(p)
267@*        - of type number if a basering is present and 0=p=char(basering)
268            or if prime(p)=char(basering)
269@*        - of type string else
270SEE ALSO: prime
271EXAMPLE:  example factorial; shows an example
272"
273{   int l,p;
274//---------------------------- initialization -------------------------------
275   if ( size(#) == 0 )
276   { 
277      ring bin = 0,x,dp;
278      number r=1;
279   }
280   if ( size(#) > 0 )
281   {
282      p = (#[1]!=0)*prime(#[1]);
283      if ( defined(basering) )
284      {
285         if ( p == char(basering) )
286         {
287           // do it clever !
288           if (n < 1) {return (0);}
289           if (! defined(sv_factorials))
290           {
291             ideal sv_factorials;
292             sv_factorials[1] = 1;
293             export(sv_factorials);
294           }
295           if (n > size(sv_factorials))
296           {
297             int i = size(sv_factorials);
298             sv_factorials[n] = 0;
299             number fi = number(sv_factorials[i]);
300             for (i++;i<=n;i++)
301             {
302               fi = fi * i;
303               sv_factorials[i] = fi;
304             }
305             return (fi);
306           }
307           else
308           {
309             return (number(sv_factorials[n]));
310           }
311         }
312         else
313         { 
314            ring bin = p,x,dp;
315            number r=1;
316         }
317      }
318      else
319      { 
320         ring bin = p,x,dp;
321         number r=1;
322      }
323   }
324//------------------------------ computation --------------------------------
325   for (l=2; l<=n; l++)
326   {
327      r=r*l;
328   }
329   return(string(r));
330}
331example
332{ "EXAMPLE:"; echo = 2;
333   factorial(37);"";                 //37! of type string (as long integer)
334   ring r1 = 0,x,dp;
335   number p = factorial(37,0);       //37! of type number, computed in r
336   p;
337}
338   
339       
340///////////////////////////////////////////////////////////////////////////////
341
342proc fibonacci (int n, list #)
343"USAGE:    fibonacci(n);  n,p integers
344RETURN:   fibonacci(n): nth Fibonacci number, f(0)=f(1)=1, f(i+1)=f(i-1)+f(i)
345@*        - computed in characteristic 0, of type string
346@*        fibonacci(n,p): f(n) computed in characteristic 0 or prime(p)
347@*        - of type number if a basering is present and p=0=char(basering)
348            or if prime(p)=char(basering)
349@*        - of type string else
350SEE ALSO: prime
351EXAMPLE: example fibonacci; shows an example
352"
353{   int str,ii,p;
354//---------------------------- initialization -------------------------------
355   if ( size(#) == 0 )
356   {  str = 1;
357      ring bin = 0,x,dp;
358      number f,g,h=1,1,1;
359   }
360   if ( size(#) > 0 )
361   {
362      p = (#[1]!=0)*prime(#[1]);
363      if ( defined(basering) )
364      {
365         if ( p == char(basering) )
366         {  number f,g,h=1,1,1;
367         }
368         else
369         {  str = 1;
370            ring bin = p,x,dp;
371            number f,g,h=1,1,1;
372         }
373      }
374      else
375      {  str = 1;
376         ring bin = p,x,dp;
377         number f,g,h=1,1,1;
378      }
379   }
380//------------------------------ computation --------------------------------
381   for (ii=3; ii<=n; ii=ii+1)
382   {
383      h = f+g; f = g; g = h;
384    }
385   if ( str==1 ) { return(string(h)); }
386   else { return(h); }
387}
388example
389{ "EXAMPLE:"; echo = 2;
390   fibonacci(42); "";             //f(42) of type string (as long integer)
391   ring r = 2,x,dp;
392   number b = fibonacci(42,2);    //f(42) of type number, computed in r
393   b;
394}
395///////////////////////////////////////////////////////////////////////////////
396
397proc kmemory (list #)
398"USAGE:   kmemory([n,[v]]); n,v integers
399RETURN:  memory in kilobyte of type int
400@*       n=0: memory used by active variables (same as no parameters)
401@*       n=1: total memory allocated by Singular
402@*       n=2: difference between top and init memory adress (sbrk memory)
403@*       n!=0,1,2: 0
404DISPLAY: detailed information about allocated and used memory if v!=0
405NOTE:    kmemory uses internal function 'memory' to compute kilobyte, and
406         is the same as 'memory' for n!=0,1,2
407EXAMPLE: example kmemory; shows an example
408"
409{
410   int n;
411   int verb;
412   if (size(#) != 0)
413   {
414     n=#[1];
415     if (size(#) >1)
416     { verb=#[2]; }
417   }
418
419  if ( verb != 0)
420  {
421    if ( n==0)
422    { dbprint(printlevel-voice+3,
423      "// memory used, at the moment, by active variables (kilobyte):"); }
424    if ( n==1 )
425    { dbprint(printlevel-voice+3,
426      "// total memory allocated, at the moment, by SINGULAR (kilobyte):"); }
427   }
428   return ((memory(n)+1023)/1024);
429}
430example
431{ "EXAMPLE:"; echo = 2;
432   kmemory();
433   kmemory(1,1);
434}
435///////////////////////////////////////////////////////////////////////////////
436
437proc killall
438"USAGE:   killall(); (no parameter)
439         killall(\"type_name\");
440         killall(\"not\", \"type_name\");
441RETURN:  killall(); kills all user-defined variables except loaded procedures,
442         no return value.
443@*       - killall(\"type_name\"); kills all user-defined variables,
444           of type \"type_name\"
445@*       - killall(\"not\", \"type_name\"); kills all user-defined variables,
446           except those of type \"type_name\" and except loaded procedures
447@*       - killall(\"not\", \"name_1\", \"name_2\", ...);
448           kills all user-defined variables, except those of name \"name_i\"
449           and except loaded procedures
450NOTE:    killall should never be used inside a procedure
451EXAMPLE: example killall; shows an example AND KILLS ALL YOUR VARIABLES
452"
453{
454  list @marie=names();
455  int no_kill, @joni;
456  for ( @joni=1; @joni<=size(#);  @joni++)
457  {
458    if (typeof(#[@joni]) != "string")
459    {
460      ERROR("Need string as " + string(@joni) + "th argument");
461    }
462  }
463 
464  // kills all user-defined variables but not loaded procedures
465  if( size(#)==0 )
466  {
467    for ( @joni=size(@marie); @joni>0; @joni-- )
468    {
469      if( @marie[@joni]!="LIB" and typeof(`@marie[@joni]`)!="proc" )
470      { kill `@marie[@joni]`; }
471    }
472  }
473  else
474  {
475    // kills all user-defined variables
476    if( size(#)==1 )
477    {
478      // of type proc
479      if( #[1] == "proc" )
480      {
481        for ( @joni=size(@marie); @joni>0; @joni-- )
482        {
483          if((@marie[@joni]!="killall") and (@marie[@joni]=="LIB" or
484                                       typeof(`@marie[@joni]`)=="proc"))
485          { kill `@marie[@joni]`; }
486        }
487      }
488      else
489      { 
490        // other types
491        for ( @joni=size(@marie); @joni>2; @joni-- )
492        {
493          if(typeof(`@marie[@joni]`)==#[1] and @marie[@joni]!="LIB"
494             and typeof(`@marie[@joni]`)!="proc")
495          { kill `@marie[@joni]`; }
496        }
497      }
498    }
499    else
500    {
501      // kills all user-defined variables whose name or type is not #i
502      for ( @joni=size(@marie); @joni>2; @joni-- )
503      {
504        if ( @marie[@joni] != "LIB" && typeof(`@marie[@joni]`) != "proc")
505        {
506          no_kill = 0;
507          for (j=2; j<= size(#); j++)
508          {
509            if (typeof(`@marie[@joni]`)==#[j] or @marie[@joni] == #[j])
510            {
511              no_kill = 1;
512              break;
513            }
514          }
515          if (! no_kill)
516          {
517            kill `@marie[@joni]`;
518          }
519        }
520      }
521    }
522  }
523}
524example
525{ "EXAMPLE:"; echo = 2;
526   ring rtest; ideal i=x,y,z; string str="hi"; int j = 3;
527   export rtest,i,str,j;       //this makes the local variables global
528   listvar();
529   killall("ring");            // kills all rings
530   listvar();
531   killall("not", "int");      // kills all variables except int's (and procs)
532   listvar();
533   killall();                  // kills all vars except loaded procs
534   listvar();
535}
536///////////////////////////////////////////////////////////////////////////////
537
538proc number_e (int n)
539"USAGE:   number_e(n);  n integer
540RETURN:  Euler number e=exp(1) up to n decimal digits (no rounding)
541@*       - of type string if no basering of char 0 is defined
542@*       - of type number if a basering of char 0 is defined
543DISPLAY: decimal format of e if printlevel > 0 (default:printlevel=0 )
544NOTE:    procedure uses algorithm of A.H.J. Sale
545EXAMPLE: example number_e; shows an example
546"
547{
548   int i,m,s,t;
549   intvec u,e;
550   u[n+2]=0; e[n+1]=0; e=e+1;
551   if( defined(basering) )
552   {
553      if( char(basering)==0 ) { number r=2; t=1; }
554   }
555   string result = "2.";
556   for( i=1; i<=n+1; i=i+1 )
557   {
558      e = e*10;
559      for( m=n+1; m>=1; m=m-1 )
560      {
561         s    = e[m]+u[m+1];
562         u[m] = s div (m+1);
563         e[m] = s%(m+1);
564      }
565      result = result+string(u[1]);
566      if( t==1 ) { r = r+number(u[1])/number(10)^i; }
567   }
568   if( t==1 )
569   { dbprint(printlevel-voice+2,"// "+result[1,n+1]);
570     return(r);
571   }
572   return(result[1,n+1]);
573}
574example
575{ "EXAMPLE:"; echo = 2;
576   number_e(30);"";
577   ring R = 0,t,lp;
578   number e = number_e(30);
579   e;
580}
581///////////////////////////////////////////////////////////////////////////////
582
583proc number_pi (int n)
584"USAGE:   number_pi(n);  n positive integer
585RETURN:  pi (area of unit circle) up to n decimal digits (no rounding)
586@*       - of type string if no basering of char 0 is defined,
587@*       - of type number, if a basering of char 0 is defined
588DISPLAY: decimal format of pi if printlevel > 0 (default:printlevel=0 )
589NOTE:    procedure uses algorithm of S. Rabinowitz
590EXAMPLE: example number_pi; shows an example
591"
592{
593   int i,m,t,e,q,N;
594   intvec r,p,B,Prelim;
595   string result,prelim;
596   N = (10*n) div 3 + 2;
597   p[N+1]=0; p=p+2; r=p;
598   for( i=1; i<=N+1; i=i+1 ) { B[i]=2*i-1; }
599   if( defined(basering) )
600   {
601      if( char(basering)==0 ) { number pi; number pri; t=1; }
602   }
603   for( i=0; i<=n; i=i+1 )
604   {
605      p = r*10;
606      e = p[N+1];
607      for( m=N+1; m>=2; m=m-1 )
608      {
609         r[m] = e%B[m];
610         q    = e div B[m];
611         e    = q*(m-1)+p[m-1];
612      }
613      r[1] = e%10;
614      q    = e div 10;
615      if( q!=10 and q!=9 )
616      {
617         result = result+prelim;
618         Prelim = q;
619         prelim = string(q);
620      }
621      if( q==9 )
622      {
623         Prelim = Prelim,9;
624         prelim = prelim+"9";
625      }
626      if( q==10 )
627      {
628         Prelim = (Prelim+1)-((Prelim+1) div 10)*10;
629         for( m=size(Prelim); m>0; m=m-1)
630         {
631            prelim[m] = string(Prelim[m]);
632         }
633         result = result+prelim;
634         if( t==1 ) { pi=pi+pri; }
635         Prelim = 0;
636         prelim = "0";
637      }
638      if( t==1 ) { pi=pi+number(q)/number(10)^i; }
639   }
640   result = result,prelim[1];
641   result = "3."+result[2,n-1];
642   if( t==1 )
643   { dbprint(printlevel-voice+2,"// "+result);
644     return(pi);
645   }
646   return(result);
647}
648example
649{ "EXAMPLE:"; echo = 2;
650   number_pi(11);"";
651   ring r = (real,10),t,dp;
652   number pi = number_pi(11); pi;
653}
654///////////////////////////////////////////////////////////////////////////////
655
656proc primes (int n, int m)
657"USAGE:   primes(n,m);  n,m integers
658RETURN:  intvec, consisting of all primes p, prime(n)<=p<=m, in increasing
659         order if n<=m, resp. prime(m)<=p<=n, in decreasing order if m<n.
660NOTE:    prime(n); returns the biggest prime number <= min(n,32003)
661         if n>=2, else 2
662EXAMPLE: example primes; shows an example
663"
664{  int change;
665   if ( n>m ) { change=n; n=m ; m=change; change=1; }
666   int q,p = prime(m),prime(n); intvec v = q; q = q-1;
667   while ( q>=p ) { q = prime(q); v = q,v; q = q-1; }
668   if ( change==1 ) { v = v[size(v)..1]; }
669   return(v);
670}
671example
672{  "EXAMPLE:"; echo = 2;
673    primes(50,100);"";
674    intvec v = primes(37,1); v;
675}
676///////////////////////////////////////////////////////////////////////////////
677
678proc product (id, list #)
679"USAGE:    product(id[,v]); id ideal/vector/module/matrix/intvec/intmat/list,
680          v intvec  (default: v=1..number of entries of id)
681ASSUME:   list members can be multiplied.
682RETURN:   The product of all entries of id [with index given by v] of type
683          depending on the entries of id.
684NOTE:     If id is not a list, id is treated as a list of polys resp. integers.
685          A module m is identified with the corresponding matrix M (columns
686          of M generate m).
687@*        If v is outside the range of id, we have the empty product and the
688          result will be 1 (of type int).
689EXAMPLE:  example product; shows an example
690"
691
692//-------------------- initialization and special feature ---------------------
693   int n,j,tt;
694   string ty;                                         //will become type of id
695   list l;
696
697// We wish to allow something like product(x(1..10)) if x(1),...,x(10) are
698// variables. x(1..10) is a list of polys and enters the procedure with
699// id=x(1) and # a list with 9 polys, #[1]= x(2),...,#[9]= x(10). Hence, in
700// this case # is never empty. If an additional intvec v is given,
701// it is added to #, so we have to separate it first and make
702// the rest a list which has to be multiplied.
703
704   int s = size(#);
705   if( s!=0 )
706   {  if ( typeof(#[s])=="intvec" or typeof(#[s])=="int")   
707      { 
708         intvec v = #[s];
709         tt=1;
710         s=s-1;
711         if ( s>0 ) { # = #[1..s]; }
712      }
713   }
714   if ( s>0 )
715   {
716      l = list(id)+#;
717      kill id;
718      list id = l;                                    //case: id = list
719      ty = "list";
720      n = size(id);
721   }
722   else
723   {
724      ty = typeof(id);
725      if( ty == "list" )
726      { n = size(id); }
727   }
728//------------------------------ reduce to 3 cases ---------------------------
729   if( ty=="poly" or ty=="ideal" or ty=="vector"
730       or ty=="module" or ty=="matrix" )
731   {
732      ideal i = ideal(matrix(id));
733      kill id;
734      ideal id = i;                                   //case: id = ideal
735      n = ncols(id);
736   }
737   if( ty=="int" or ty=="intvec" or ty=="intmat" )
738   {
739      if ( ty == "int" ) { intmat S =id; }
740      else { intmat S = intmat(id); }
741      intvec i = S[1..nrows(S),1..ncols(S)];
742      kill id;
743      intvec id = i;                                  //case: id = intvec
744      n = size(id);
745   }
746//--------------- consider intvec v and empty product  -----------------------
747   if( tt!=0 )
748   {
749      for (j=1; j<=size(v); j++)
750      {
751         if ( v[j] <= 0 or v[j] > n )                 //v outside range of id
752         {
753            return(1);                                //empty product is 1
754         }                               
755      }
756      id = id[v];                                     //consider part of id
757   }                                                  //corresponding to v
758//--------------------- special case: one factor is zero  ---------------------
759   if ( typeof(id) == "ideal")
760   {
761      if( size(id) < ncols(id) )
762      {
763          poly f; return(f);
764      }
765   }
766//-------------------------- finally, multiply objects  -----------------------
767   n = size(id);
768   def f(1) = id[1];
769   for( j=2; j<=n; j=j+1 ) { def f(j)=f(j-1)*id[j]; }
770   return(f(n));
771}
772example
773{  "EXAMPLE:"; echo = 2;
774   ring r= 0,(x,y,z),dp;
775   ideal m = maxideal(1);
776   product(m);
777   product(m[2..3]);
778   matrix M[2][3] = 1,x,2,y,3,z;
779   product(M);
780   intvec v=2,4,6;
781   product(M,v);
782   intvec iv = 1,2,3,4,5,6,7,8,9;
783   v=1..5,7,9;
784   product(iv,v);
785   intmat A[2][3] = 1,1,1,2,2,2;
786   product(A,3..5);
787}
788///////////////////////////////////////////////////////////////////////////////
789proc ringweights (list # )
790"USAGE:   ringweights(P); P=name of an existing ring (true name, not a string)
791RETURN:  intvec consisting of the weights of the variables of P, as they
792         appear when typing P;.
793NOTE:    This is useful when enlarging P but keeping the weights of the old
794         variables.
795EXAMPLE: example ringweights; shows an example
796"
797{
798   int ii,q,fi,fo,fia;
799   intvec rw,nw;
800   string os;
801   def P = #[1];
802   string osP = ordstr(P);
803   fo  = 1;
804//------------------------- find weights in ordstr(P) -------------------------
805   fi  = find(osP,"(",fo);
806   fia = find(osP,"a",fo)+find(osP,"w",fo)+find(osP,"W",fo);
807   while ( fia )
808   {
809      os = osP[fi+1,find(osP,")",fi)-fi-1];
810      if( find(os,",") )
811      {
812         execute("nw = "+os+";");
813         if( size(nw) > ii )
814         {
815             rw = rw,nw[ii+1..size(nw)];
816         }
817         else  {  ii = ii - size(nw); }
818
819         if( find(osP[1,fi],"a",fo) ) { ii = size(nw); }
820      }
821      else
822      {
823         execute("q = "+os+";");
824         if( q > ii )
825         {
826            nw = 0; nw[q-ii] = 0;
827            nw = nw + 1;          //creates an intvec 1,...,1 of length q-ii
828            rw = rw,nw;
829         }
830         else { ii = ii - q; }
831      }
832      fo  = fi+1;
833      fi  = find(osP,"(",fo);
834      fia = find(osP,"a",fo)+find(osP,"w",fo)+find(osP,"W",fo);
835   }
836//-------------- adjust weight vector to length = nvars(P)  -------------------
837   if( fo > 1 )
838   {                                            // case when weights were found
839      rw = rw[2..size(rw)];
840      if( size(rw) > nvars(P) )
841      {
842         rw = rw[1..nvars(P)];
843      }
844      if( size(rw) < nvars(P) )
845      {
846         nw=0; nw[nvars(P)-size(rw)]=0; nw=nw+1; rw=rw,nw;
847      }
848   }
849   else
850   {                                         // case when no weights were found
851      rw[nvars(P)]= 0; rw=rw+1;
852   }
853   return(rw);
854}
855example
856{"EXAMPLE:";  echo = 2;
857  ring r0 = 0,(x,y,z),dp;
858  ringweights(r0);
859  ring r1 = 0,x(1..5),(ds(3),wp(2,3));
860  ringweights(r1);"";
861  // an example for enlarging the ring, keeping the first weights:
862  intvec v = ringweights(r1),6,2,3,4,5;
863  ring R = 0,x(1..10),(a(v),dp);
864  ordstr(R);
865}
866
867///////////////////////////////////////////////////////////////////////////////
868
869proc sort (id, list #)
870"USAGE:   sort(id[v,o,n]); id=ideal/module/intvec/list(of intvec's or int's)
871@*       sort may be called with 1, 2 or 3 arguments in the following way:
872@*       sort(id[v,n]); v=intvec of positive integers, n=integer,
873@*       sort(id[o,n]); o=string (any allowed ordstr of a ring), n=integer
874RETURN:  a list l of two elements:
875@format
876        l[1]: object of same type as input but sorted in the following way:
877           - if id=ideal/module: generators of id are sorted w.r.t. intvec v
878             (id[v[1]] becomes 1-st, id[v[2]]  2-nd element, etc.). If no v is
879             present, id is sorted w.r.t. ordering o (if o is given) or w.r.t.
880             actual monomial ordering (if no o is given):
881             NOTE: generators with SMALLER(!) leading term come FIRST
882             (e.g. sort(id); sorts backwards to actual monomial ordering)
883           - if id=list of intvec's or int's: consider a list element, say
884             id[1]=3,2,5, as exponent vector of the monomial x^3*y^2*z^5;
885             the corresponding monomials are ordered w.r.t. intvec v (s.a.).
886             If no v is present, the monomials are sorted w.r.t. ordering o
887             (if o is given) or w.r.t. lexicographical ordering (if no o is
888             given). The corresponding ordered list of exponent vectors is
889             returned.
890             (e.g. sort(id); sorts lexicographically, smaller int's come first)
891             WARNING: Since negative exponents create the 0 polynomial in
892             Singular, id should not contain negative integers: the result
893             might not be as expected
894           - if id=intvec: id is treated as list of integers
895           - if n!=0 the ordering is inverse, i.e. w.r.t. v(size(v)..1)
896             default: n=0
897         l[2]: intvec, describing the permutation of the input (hence l[2]=v
898             if v is given (with positive integers))
899@end format
900NOTE:    If v is given id may be any simply indexed object (e.g. any list or
901         string); if v[i]<0 and i<=size(id) v[i] is set internally to i;
902         entries of v must be pairwise distinct to get a permutation if id.
903         Zero generators of ideal/module are deleted
904EXAMPLE: example sort; shows an example
905"
906{  int ii,jj,s,n = 0,0,1,0;
907   intvec v;
908   if ( defined(basering) ) { def P = basering; }
909   if ( size(#)==0 and (typeof(id)=="ideal" or typeof(id)=="module") )
910   {
911      id = simplify(id,2);
912      for ( ii=1; ii<size(id); ii++ )
913      {
914         if ( id[ii]!=id[ii+1] ) { break;}
915      }
916      if ( ii != size(id) ) { v = sortvec(id); }
917      else  { v = size(id)..1; }
918   }
919   if ( size(#)>=1 and (typeof(id)=="ideal" or typeof(id)=="module") )
920   {
921      if ( typeof(#[1])=="string" )
922      {
923         execute("ring r1 =("+charstr(P)+"),("+varstr(P)+"),("+#[1]+");");
924         def i = imap(P,id);
925         v = sortvec(i);
926         setring P;
927         n=2;
928      }
929   }
930   if ( typeof(id)=="intvec" or typeof(id)=="list" and n==0 )
931   {
932      string o;
933      if ( size(#)==0 ) { o = "lp"; n=1; }
934      if ( size(#)>=1 )
935      {
936         if ( typeof(#[1])=="string" ) { o = #[1]; n=1; }
937      }
938   }
939   if ( typeof(id)=="intvec" or typeof(id)=="list" and n==1 )
940   {
941      if ( typeof(id)=="list" )
942      {
943         for (ii=1; ii<=size(id); ii++)
944         {
945            if (typeof(id[ii]) != "intvec" and typeof(id[ii]) != "int")
946               { "// list elements must be intvec/int"; return(); }
947            else
948               { s=size(id[ii])*(s < size(id[ii])) + s*(s >= size(id[ii])); }
949         }
950      }
951      execute("ring r=0,x(1..s),("+o+");");
952      ideal i;
953      poly f;
954      for (ii=1; ii<=size(id); ii++)
955      {
956         f=1;
957         for (jj=1; jj<=size(id[ii]); jj++)
958         {
959            f=f*x(jj)^(id[ii])[jj];
960         }
961         i[ii]=f;
962      }
963      v = sort(i)[2];
964   }
965   if ( size(#)!=0 and n==0 ) { v = #[1]; }
966   if( size(#)==2 )
967   {
968      if ( #[2] != 0 ) { v = v[size(v)..1]; }
969   }
970   s = size(v);
971   if( size(id) < s ) { s = size(id); }
972   def m = id;
973   if ( size(m) != 0 )
974   {
975      for ( jj=1; jj<=s; jj=jj+1)
976      {
977         if ( v[jj]<=0 ) { v[jj]=jj; }
978         m[jj] = id[v[jj]];
979      }
980   }
981   if ( v == 0 ) { v = 1; }
982   list L=m,v;
983   return(L);
984}
985example
986{  "EXAMPLE:"; echo = 2;
987   ring r0 = 0,(x,y,z,t),lp;
988   ideal i = x3,z3,xyz;
989   sort(i);            //sorts using lex ordering, smaller polys come first
990 
991   sort(i,3..1);
992
993   sort(i,"ls")[1];     //sort w.r.t. negative lex ordering
994
995   intvec v =1,10..5,2..4;v;
996   sort(v)[1];          // sort v lexicographically
997
998   sort(v,"Dp",1)[1];   // sort v w.r.t (total sum, reverse lex)
999}
1000///////////////////////////////////////////////////////////////////////////////
1001proc sum (id, list #)
1002"USAGE:    sum(id[,v]); id ideal/vector/module/matrix/intvec/intmat/list,
1003          v intvec  (default: v=1..number of entries of id)
1004ASSUME:   list members can be added.
1005RETURN:   The sum of all entries of id [with index given by v] of type
1006          depending on the entries of id.
1007NOTE:     If id is not a list, id is treated as a list of polys resp. integers.
1008          A module m is identified with the corresponding matrix M (columns
1009          of M generate m).
1010@*        If v is outside the range of id, we have the empty sum and the
1011          result will be 0 (of type int).
1012EXAMPLE:  example sum; shows an example
1013"
1014{
1015//-------------------- initialization and special feature ---------------------
1016   int n,j,tt;
1017   string ty;                                  // will become type of id
1018   list l;
1019
1020// We wish to allow something like sum(x(1..10)) if x(1),...,x(10) are
1021// variables. x(1..10) is a list of polys and enters the procedure with
1022// id=x(1) and # a list with 9 polys, #[1]= x(2),...,#[9]= x(10). Hence, in
1023// this case # is never empty. If an additional intvec v is given,
1024// it is added to #, so we have to separate it first and make
1025// the rest a list which has to be added.
1026
1027   int s = size(#);
1028   if( s!=0 )
1029   {  if ( typeof(#[s])=="intvec" or typeof(#[s])=="int")
1030      {  intvec v = #[s];
1031         tt=1;
1032         s=s-1;
1033         if ( s>0 ) { # = #[1..s]; }
1034      }
1035   }
1036   if ( s>0 )
1037   {
1038      l = list(id)+#;
1039      kill id;
1040      list id = l;                                    //case: id = list
1041      ty = "list";
1042   }
1043   else
1044   {
1045      ty = typeof(id);
1046   }
1047//------------------------------ reduce to 3 cases ---------------------------
1048   if( ty=="poly" or ty=="ideal" or ty=="vector"
1049       or ty=="module" or ty=="matrix" )
1050   {                                                 //case: id = ideal
1051      ideal i = ideal(matrix(id));
1052      kill id;
1053      ideal id = simplify(i,2);                      //delete 0 entries
1054   }
1055   if( ty=="int" or ty=="intvec" or ty=="intmat" )
1056   {
1057      if ( ty == "int" ) { intmat S =id; }
1058      else { intmat S = intmat(id); }
1059      intvec i = S[1..nrows(S),1..ncols(S)];
1060      kill id;
1061      intvec id = i;                                 //case: id = intvec
1062   }
1063//------------------- consider intvec v and empty sum  -----------------------
1064   if( tt!=0 )
1065   {
1066      for (j=1; j<=size(v); j++)
1067      {
1068         if ( v[j] <= 0 or v[j] > size(id) )         //v outside range of id
1069         {
1070            return(0);                               //empty sum is 0
1071         }                               
1072      }
1073      id = id[v];                                    //consider part of id
1074   }                                                 //corresponding to v
1075
1076//-------------------------- finally, add objects  ---------------------------
1077   n = size(id);
1078   def f(1) = id[1];
1079   for( j=2; j<=n; j=j+1 ) { def f(j)=f(j-1)+id[j]; }
1080   return(f(n));   int n,j,tt;
1081}
1082example
1083{  "EXAMPLE:"; echo = 2;
1084   ring r= 0,(x,y,z),dp;
1085   vector pv = [xy,xz,yz,x2,y2,z2];
1086   sum(pv);
1087   sum(pv,2..5);
1088   matrix M[2][3] = 1,x,2,y,3,z;
1089   intvec w=2,4,6;
1090   sum(M,w);
1091   intvec iv = 1,2,3,4,5,6,7,8,9;
1092   sum(iv,2..4);
1093}
1094///////////////////////////////////////////////////////////////////////////////
1095
1096proc which (command)
1097"USAGE:    which(command); command = string expression
1098RETURN:   Absolute pathname of command, if found in search path.
1099          Empty string, otherwise.
1100NOTE:     Based on the Unix command 'which'.
1101EXAMPLE:  example which; shows an example
1102"
1103{
1104   int rs;
1105   int i;
1106   string fn = "which_" + string(system("pid"));
1107   string pn;
1108   string cmd;
1109   if( typeof(command) != "string")
1110   {
1111     return (pn);
1112   }
1113   if (system("uname") != "ix86-Win")
1114   {
1115     cmd = "which ";
1116   }
1117   else
1118   {
1119     // unfortunately, it does not take -path
1120     cmd = "type ";
1121   }
1122   i = system("sh", cmd + command + " > " + fn);
1123   pn = read(fn);
1124   if (system("uname") != "ix86-Win")
1125   {
1126     // TBC: Hmm... should parse output to get rid of 'command is '
1127     pn[size(pn)] = "";
1128     i = 1;
1129     while ((pn[i] != " ") and (pn[i] != ""))
1130     {
1131       i = i+1;
1132     }
1133     if (pn[i] == " ") {pn[i] = "";}
1134     rs = system("sh", "ls " + pn + " > " + fn + " 2>&1 ");
1135   }
1136   else
1137   {
1138     rs = 0;
1139   }
1140   i = system("sh", "rm " + fn);
1141   if (rs == 0) {return (pn);}
1142   else
1143   {
1144     print (command + " not found ");
1145     return ("");
1146   }
1147}
1148example
1149{  "EXAMPLE:"; echo = 2;
1150    which("sh");
1151}
1152///////////////////////////////////////////////////////////////////////////////
1153
1154proc watchdog(int i, string cmd)
1155"USAGE:   watchdog(i,cmd); i integer; cmd string
1156RETURN:  Result of cmd, if the result can be computed in i seconds.
1157         Otherwise the computation is interrupted after i seconds,
1158         the string "Killed" is returned and the global variable
1159         'watchdog_interrupt' is defined.
1160NOTE:    * the MP package must be enabled
1161         * the current basering should not be watchdog_rneu, since
1162           watchdog_rneu will be killed
1163         * if there are variable names of the structure x(i) all
1164           polynomials have to be put into eval(...) in order to be
1165           interpreted correctly
1166         * a second Singular process is started by this procedure
1167EXAMPLE: example watchdog; shows an example
1168"
1169{
1170  string rname=nameof(basering);
1171  if (defined(watchdog_rneu))
1172  {
1173    kill watchdog_rneu;
1174  }
1175// If we do not have MP-links, watchdog cannot be used
1176  if (system("with","MP"))
1177  {
1178    if ( i > 0 )
1179    {
1180      int j=10;
1181      int k=999999;
1182// fork, get the pid of the child and send it the command   
1183      link l_fork="MPtcp:fork";
1184      open(l_fork);
1185      write(l_fork,quote(system("pid")));
1186      int pid=read(l_fork);
1187      execute("write(l_fork,quote(" + cmd + "));");
1188
1189
1190// sleep in small, but growing intervals for appr. 1 second
1191      while(j < k)
1192      {
1193        if (status(l_fork, "read", "ready", j)) {break;}
1194        j = j + j;
1195      }
1196
1197// sleep in intervals of one second
1198      j = 1;
1199      if (!status(l_fork,"read","ready"))
1200      {
1201        while (j < i)
1202        {
1203          if (status(l_fork, "read", "ready", k)) {break;}
1204          j = j + 1;
1205        }
1206      }
1207// check, whether we have a result, and return it
1208      if (status(l_fork, "read", "ready"))
1209      {
1210        def result = read(l_fork);
1211        if (nameof(basering)!=rname)
1212        {
1213          def watchdog_rneu=basering;
1214        }
1215        if(defined(watchdog_interrupt))
1216        {
1217          kill (watchdog_interrupt);
1218        }
1219        close(l_fork);
1220      }
1221      else
1222      {
1223        string result="Killed";
1224        if(!defined(watchdog_interrupt))
1225        {
1226          int watchdog_interrupt=1;
1227          export watchdog_interrupt;
1228        }
1229        close(l_fork);
1230        j = system("sh","kill " + string(pid));
1231      }
1232      if (defined(watchdog_rneu))
1233      {
1234        keepring watchdog_rneu;
1235      }
1236      return(result);
1237    }
1238    else
1239    {
1240      ERROR("First argument of watchdog has to be a positive integer.");
1241    }
1242    ERROR("MP-support is not enabled in this version of Singular.");
1243  }
1244}
1245example
1246{ "EXAMPLE:"; echo=2;
1247  ring r=0,(x,y,z),dp;
1248  poly f=x^30+y^30;
1249  watchdog(1,"factorize(eval("+string(f)+"))");
1250  watchdog(100,"factorize(eval("+string(f)+"))");
1251}
1252///////////////////////////////////////////////////////////////////////////////
1253
1254proc deleteSublist(intvec v,list l)
1255"USAGE:   deleteSublist(v,l); intvec v; list l
1256         where the entries of the integer vector v correspond to the
1257         positions of the elements to be deleted
1258RETURN:  list without the deleted elements
1259EXAMPLE: example deleteSublist; shows an example"
1260{
1261  list k;
1262  int i,j,skip;
1263  j=1;
1264  skip=0;
1265  intvec vs=sort(v)[1];
1266  for ( i=1 ; i <=size(vs) ; i++)
1267  {
1268    while ((j+skip) < vs[i])
1269    {
1270      k[j] = l[j+skip];
1271      j++;
1272    }
1273    skip++;
1274  }
1275  if(vs[size(vs)]<size(l))
1276  {
1277    k=k+list(l[(vs[size(vs)]+1)..size(l)]);
1278  }
1279  return(k);
1280}
1281example
1282{ "EXAMPLE:"; echo=2;
1283   list l=1,2,3,4,5;
1284   intvec v=1,3,4;
1285   l=deleteSublist(v,l);
1286   l;
1287}
1288///////////////////////////////////////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.