# source:git/Singular/LIB/general.lib@6f2edc

jengelh-datetimespielwiese
Last change on this file since 6f2edc was 6f2edc, checked in by Olaf Bachmann <obachman@…>, 26 years ago
Mon Apr 28 21:00:07 1997 Olaf Bachmann <obachman@ratchwum.mathematik.uni-kl.de (Olaf Bachmann)> * dunno why I am committing these libs -- have not modified any of them git-svn-id: file:///usr/local/Singular/svn/trunk@205 2c84dea3-7e68-4137-9b89-c4e89433aadc
• Property mode set to `100644`
File size: 20.7 KB
Line
1// \$Id: general.lib,v 1.2 1997-04-28 19:27:17 obachman Exp \$
2//system("random",787422842);
4///////////////////////////////////////////////////////////////////////////////
5
6LIBRARY:  general.lib   PROCEDURES OF GENERAL TYPE
7
8 A_Z("a",n);            string a,b,... of n comma seperated letters
9 binomial(n,m[,../..]); n choose m (type int), [type string/type number]
10 factorial(n[,../..]);  n factorial (=n!) (type int), [type string/number]
11 fibonacci(n[,p]);      nth Fibonacci number [char p]
12 kmemory();             int = active memory (kilobyte)
13 killall();             kill all user-defined variables
14 number_e(n);           compute exp(1) up to n decimal digits
15 number_pi(n);          compute pi (area of unit circle) up to n digits
16 primes(n,m);           intvec of primes p, n<=p<=m
17 product(../..[,v]);    multiply components of vector/ideal/...[indices v]
18 ringweights(r);        intvec of weights of ring variables of ring r
19 sort(ideal/module);    sort generators according to monomial ordering
20 sum(vector/id/..[,v]); add components of vector/ideal/...[with indices v]
21           (parameters in square brackets [] are optional)
22 wich(command);         searches for command and returns absolute
23                        path, if found
24LIB "inout.lib";
25///////////////////////////////////////////////////////////////////////////////
26
27proc A_Z (string s,int n)
28USAGE:   A_Z("a",n);  a any letter, n integer (-26<= n <=26, !=0)
29RETURN:  string of n small (if a is small) or capital (if a is capital)
30         letters, comma seperated, beginning with a, in alphabetical
31         order (or revers alphabetical order if n<0)
32EXAMPLE: example A_Z; shows an example
33{
34  if ( n>=-26 and n<=26 and n!=0 )
35  {
36    string alpha =
37    "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,"+
38    "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,"+
39    "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,"+
40    "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";
41    int ii; int aa;
42    for(ii=1; ii<=51; ii=ii+2)
43    {
44       if( alpha[ii]==s ) { aa=ii; }
45    }
46    if ( aa==0)
47    {
48      for(ii=105; ii<=155; ii=ii+2)
49      {
50        if( alpha[ii]==s ) { aa=ii; }
51      }
52    }
53    if( aa!=0 )
54    {
55      string out;
56      if (n > 0) { out = alpha[aa,2*(n)-1];  return (out); }
57      if (n < 0)
58      {
59        string beta =
60        "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,"+
61        "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,"+
62        "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,"+
63        "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";
64        if ( aa < 52 ) { aa=52-aa; }
65        if ( aa > 104 ) { aa=260-aa; }
66        out = beta[aa,2*(-n)-1]; return (out);
67      }
68    }
69  }
70}
71example
72{ "EXAMPLE:"; echo = 2;
73   A_Z("c",5);
74   A_Z("Z",-5);
75   string sR = "ring R = (0,"+A_Z("A",6)+"),("+A_Z("a",10)+"),dp;";
76   sR;
77   execute sR;
78   R;
79}
80///////////////////////////////////////////////////////////////////////////////
81
82proc binomial (int n, int k, list #)
83USAGE:   binomial(n,k[,p/s]); n,k,p integers, s string
84RETURN:  binomial(n,k);    binomial coefficient n choose k of type int
85                           (machine integer, limited size! )
86         binomial(n,k,p);  n choose k in char p of type string
87         binomial(n,k,s);  n choose k of type number (s any string), computed
88                           in char of basering if a basering is defined
89EXAMPLE: example binomial; shows an example
90{
91   if ( size(#)==0 ) { int rr=1; }
92   if ( typeof(#[1])=="int") { ring bin = #[1],x,dp; number rr=1; }
93   if ( typeof(#[1])=="string") { number rr=1; }
94   if ( size(#)==0 or typeof(#[1])=="int" or typeof(#[1])=="string" )
95   {
96      def r = rr;
97      if ( k<=0 or k>n ) { return((k==0)*r); }
98      if ( k>n-k ) { k = n-k; }
99      int l;
100      for (l=1; l<=k; l=l+1 )
101      {
102         r=r*(n+1-l)/l;
103      }
104      if ( typeof(#[1])=="int" ) { return(string(r)); }
105      return(r);
106   }
107}
108example
109{ "EXAMPLE:"; echo = 2;
110   int b1 = binomial(10,7); b1;
111   binomial(37,17,0);
112   ring t = 31,x,dp;
113   number b2 = binomial(37,17,""); b2;
114}
115///////////////////////////////////////////////////////////////////////////////
116
117proc factorial (int n, list #)
118USAGE:   factorial(n[,string]);  n integer
119RETURN:  factorial(n); string of n! in char 0
120         factorial(n,s);  n! of type number (s any string), computed in char of
121         basering if a basering is defined
122EXAMPLE: example factorial; shows an example
123{
124   if ( size(#)==0 ) { ring R = 0,x,dp; poly r=1; }
125   if ( typeof(#[1])=="string" ) { number r=1; }
126   if ( size(#)==0 or typeof(#[1])=="string" )
127   {
128      int l;
129      for (l=2; l<=n; l=l+1)
130      {
131         r=r*l;
132      }
133      if ( size(#)==0 ) { return(string(r)); }
134      return(r);
135   }
136}
137example
138{ "EXAMPLE:"; echo = 2;
139   factorial(37);
140   ring r1 = 32003,(x,y,z),ds;
141   number p = factorial(37,""); p;
142}
143///////////////////////////////////////////////////////////////////////////////
144
145proc fibonacci (int n, list #)
146USAGE:   fibonacci(n[,string]);  (n integer)
147RETURN:  fibonacci(n); string of nth Fibonacci number,
148            f(0)=f(1)=1, f(i+1)=f(i-1)+f(i)
149         fibonacci(n,s);  nth Fibonacci number of type number (s any string),
150         computed in characteristic of basering if a basering is defined
151EXAMPLE: example fibonacci; shows an example
152{
153   if ( size(#)==0 ) { ring fibo = 0,x,dp; number f=1; }
154   if ( typeof(#[1])=="string" ) { number f=1; }
155   if ( size(#)==0 or typeof(#[1])=="string" )
156   {
157      number g,h = 1,1; int ii;
158      for (ii=3; ii<=n; ii=ii+1)
159      {
160         h = f+g; f = g; g = h;
161      }
162      if ( size(#)==0 ) { return(string(h)); }
163      return(h);
164   }
165}
166example
167{ "EXAMPLE:"; echo = 2;
168   fibonacci(37);
169   ring r = 17,x,dp;
170   number b = fibonacci(37,""); b;
171}
172///////////////////////////////////////////////////////////////////////////////
173
174proc kmemory ()
175USAGE:   kmemory();
176RETURN:  memory used by active variables, of type int (in kilobyte)
177EXAMPLE: example kmemory; shows an example
178{
179  if ( voice==2 ) { "// memory used by active variables (kilobyte):"; }
180   return ((memory(0)+1023)/1024);
181}
182example
183{ "EXAMPLE:"; echo = 2;
184   kmemory();
185}
186///////////////////////////////////////////////////////////////////////////////
187
188proc killall
189USAGE:   killall(); (no parameter)
190         killall("type_name");
191         killall("not", "type_name");
192COMPUTE: killall(); kills all user-defined variables but not loaded procedures
193         killall("type_name"); kills all user-defined variables, of type "type_name"
194         killall("not", "type_name"); kills all user-defined
195         variables, except those of type "type_name" and except loaded procedures
196RETURN:  no return value
197NOTE:    killall should never be used inside a procedure
198EXAMPLE: example killall; shows an example AND KILLS ALL YOUR VARIABLES
199{
200   list L=names(); int joni=size(L);
201   if( size(#)==0 )
202   {
203      for ( ; joni>0; joni-- )
204      {
205         if( L[joni]!="LIB" and typeof(`L[joni]`)!="proc" ) { kill `L[joni]`; }
206      }
207   }
208   else
209   {
210     if( size(#)==1 )
211     {
212       if( #[1] == "proc" )
213       {
214          for ( joni=size(L); joni>0; joni-- )
215          {
216             if( L[joni]=="LIB" or typeof(`L[joni]`)=="proc" )
217               { kill `L[joni]`; }
218          }
219       }
220       else
221       {
222          for ( ; joni>2; joni-- )
223          {
224            if(typeof(`L[joni]`)==#[1] and L[joni]!="LIB" and typeof(`L[joni]`)!="proc") { kill `L[joni]`; }
225          }
226        }
227     }
228     else
229     {
230        for ( ; joni>2; joni-- )
231        {
232          if(typeof(`L[joni]`)!=#[2] and L[joni]!="LIB" and typeof(`L[joni]`)!="proc") { kill `L[joni]`; }
233        }
234     }
235  }
236  return();
237}
238example
239{ "EXAMPLE:"; echo = 2;
240   ring rtest; ideal i=x,y,z; number n=37; string str="hi"; int j = 3;
241   export rtest,i,n,str,j;     //this makes the local variables global
242   listvar(all);
243   killall("string"); // kills all string variables
244   listvar(all);
245   killall("not", "int"); // kills all variables except int's (and procs)
246   listvar(all);
247   killall(); // kills all vars except loaded procs
248   listvar(all);
249}
250///////////////////////////////////////////////////////////////////////////////
251
252proc number_e (int n)
253USAGE:   number_e(n);  n integer
254COMPUTE: exp(1) up to n decimal digits (no rounding)
255         by A.H.J. Sale's algorithm
256RETURN:  - string of exp(1) if no basering of char 0 is defined;
257         - exp(1), of type number, if a basering of char 0 is defined and
258         display its decimal format
259EXAMPLE: example number_e; shows an example
260{
261   int i,m,s,t;
262   intvec u,e;
263   u[n+2]=0; e[n+1]=0; e=e+1;
264   if( defined(basering) )
265   {
266      if( char(basering)==0 ) { number r=2; t=1; }
267   }
268   string result = "2.";
269   for( i=1; i<=n+1; i=i+1 )
270   {
271      e = e*10;
272      for( m=n+1; m>=1; m=m-1 )
273      {
274         s    = e[m]+u[m+1];
275         u[m] = s/(m+1);
276         e[m] = s%(m+1);
277      }
278      result = result+string(u[1]);
279      if( t==1 ) { r = r+number(u[1])/number(10)^i; }
280   }
281   if( t==1 ) { "//",result[1,n+1]; return(r); }
282   return(result[1,n+1]);
283}
284example
285{ "EXAMPLE:"; echo = 2;
286   number_e(15);
287   ring R = 0,t,lp;
288   number e = number_e(10);
289   e;
290}
291///////////////////////////////////////////////////////////////////////////////
292
293proc number_pi (int n)
294USAGE:   number_pi(n);  n positive integer
295COMPUTE: pi (area of unit circle) up to n decimal digits (no rounding)
296         by algorithm of S. Rabinowitz
297RETURN:  - string of pi if no basering of char 0 is defined,
298         - pi, of type number, if a basering of char 0 is defined and display
299         its decimal format
300EXAMPLE: example number_pi; shows an example
301{
302   int i,m,t,e,q,N;
303   intvec r,p,B,Prelim;
304   string result,prelim;
305   N = (10*n)/3 + 2;
306   p[N+1]=0; p=p+2; r=p;
307   for( i=1; i<=N+1; i=i+1 ) { B[i]=2*i-1; }
308   if( defined(basering) )
309   {
310      if( char(basering)==0 ) { number pi; number pri; t=1; }
311   }
312   for( i=0; i<=n; i=i+1 )
313   {
314      p = r*10;
315      e = p[N+1];
316      for( m=N+1; m>=2; m=m-1 )
317      {
318         r[m] = e%B[m];
319         q    = e/B[m];
320         e    = q*(m-1)+p[m-1];
321      }
322      r[1] = e%10;
323      q    = e/10;
324      if( q!=10 and q!=9 )
325      {
326         result = result+prelim;
327         Prelim = q;
328         prelim = string(q);
329      }
330      if( q==9 )
331      {
332         Prelim = Prelim,9;
333         prelim = prelim+"9";
334      }
335      if( q==10 )
336      {
337         Prelim = (Prelim+1)-((Prelim+1)/10)*10;
338         for( m=size(Prelim); m>0; m=m-1)
339         {
340            prelim[m] = string(Prelim[m]);
341         }
342         result = result+prelim;
343         if( t==1 ) { pi=pi+pri; }
344         Prelim = 0;
345         prelim = "0";
346      }
347      if( t==1 ) { pi=pi+number(q)/number(10)^i; }
348   }
349   result = result,prelim[1];
350   result = "3."+result[2,n-1];
351   if( t==1 ) { "//",result; return(pi); }
352   return(result);
353}
354example
355{ "EXAMPLE:"; echo = 2;
356   number_pi(5);
357   ring r = 0,t,lp;
358   number pi = number_pi(6);
359   pi;
360}
361///////////////////////////////////////////////////////////////////////////////
362
363proc primes (int n, int m)
364USAGE:   primes(n,m);  n,m integers
365RETURN:  intvec, consisting of all primes p, prime(n)<=p<=m, in increasing
366         order if n<=m, resp. prime(m)<=p<=n, in decreasing order if m<n
367NOTE:    prime(n); returns the biggest prime number <= n (if n>=2, else 2)
368EXAMPLE: example primes; shows an example
369{  int change;
370   if ( n>m ) { change=n; n=m ; m=change; change=1; }
371   int q,p = prime(m),prime(n); intvec v = q; q = q-1;
372   while ( q>=p ) { q = prime(q); v = q,v; q = q-1; }
373   if ( change==1 ) { v = v[size(v)..1]; }
374   return(v);
375}
376example
377{  "EXAMPLE:"; echo = 2;
378   primes(50,100);
379   intvec v = primes(37,1); v;
380}
381///////////////////////////////////////////////////////////////////////////////
382
383proc product (id, list #)
384USAGE:    product(id[,v]); id=ideal/vector/module/matrix
385          resp.id=intvec/intmat, v=intvec (e.g. v=1..n, n=integer)
386RETURN:   poly resp. int which is the product of all entries of id, with index
387          given by v (default: v=1..number of entries of id)
388NOTE:     id is treated as a list of polys resp. integers. A module m is
389          identified with corresponding matrix M (columns of M generate m)
390EXAMPLE:  example product; shows an example
391{
392   int n,j;
393   if( typeof(id)=="poly" or typeof(id)=="ideal" or typeof(id)=="vector"
394       or typeof(id)=="module" or typeof(id)=="matrix" )
395   {
396      ideal i = ideal(matrix(id));
397      if( size(#)!=0 ) { i = i[#[1]]; }
398      n = ncols(i); poly f=1;
399   }
400   if( typeof(id)=="int" or typeof(id)=="intvec" or typeof(id)=="intmat" )
401   {
402      if ( typeof(id) == "int" ) { intmat S =id; }
403      else { intmat S = intmat(id); }
404      intvec i = S[1..nrows(S),1..ncols(S)];
405      if( size(#)!=0 ) { i = i[#[1]]; }
406      n = size(i); int f=1;
407   }
408   for( j=1; j<=n; j=j+1 ) { f=f*i[j]; }
409   return(f);
410}
411example
412{  "EXAMPLE:"; echo = 2;
413   ring r= 0,(x,y,z),dp;
414   ideal m = maxideal(1);
415   product(m);
416   matrix M[2][3] = 1,x,2,y,3,z;
417   product(M);
418   intvec v=2,4,6;
419   product(M,v);
420   intvec iv = 1,2,3,4,5,6,7,8,9;
421   v=1..5,7,9;
422   product(iv,v);
423   intmat A[2][3] = 1,1,1,2,2,2;
424   product(A,3..5);
425}
426///////////////////////////////////////////////////////////////////////////////
427
428proc ringweights (r)
429USAGE:   ringweights(r); r ring
430RETURN:  intvec of weights of ring variables. If, say, x(1),...,x(n) are the
431         variables of the ring r, in this order, the resulting intvec is
432         deg(x(1)),...,deg(x(n)) where deg denotes the weighted degree if
433         the monomial ordering of r has only one block of type ws,Ws,wp or Wp.
434NOTE:    In all other cases, in particular if there is more than one block,
435         the resulting intvec is 1,...,1
436EXAMPLE: example ringweights; shows an example
437{
438   int i; intvec v; setring r;
439   for (i=1; i<=nvars(basering); i=i+1) { v[i] = deg(var(i)); }
440   return(v);
441}
442example
443{ "EXAMPLE:"; echo = 2;
444   ring r1=32003,(x,y,z),wp(1,2,3);
445   ring r2=32003,(x,y,z),Ws(1,2,3);
446   ring r=0,(x,y,u,v),lp;
447   intvec vr=ringweights(r1); vr;
448   ringweights(r2);
449   ringweights(r);
450}
451///////////////////////////////////////////////////////////////////////////////
452
453proc sort (id, list #)
454USAGE:   sort(id[v,o,n]); id=ideal/module/intvec/list (of intvec's or int's)
455         sort may be called with 1, 2 or 3 arguments in the following way:
456         -  sort(id[v,n]); v=intvec, n=integer,
457         -  sort(id[o,n]); o=string (any allowed ordstr of a ring), n=integer
458RETURN:  a list of two elements:
459         [1]: object of same type as input but sorted in the following manner:
460           - if id=ideal/module: generators of id are sorted w.r.t. intvec v
461             (id[v[1]] becomes 1-st, id[v[2]]  2-nd element, etc.). If no v is
462             present, id is sorted w.r.t. ordering o (if o is given) or w.r.t.
463             actual monomial ordering (if no o is given):
464                    generators with smaller leading term come first
465             (e.g. sort(id); sorts w.r.t actual monomial ordering)
466           - if id=list of intvec's or int's: consider a list element, say
467             id[1]=3,2,5, as exponent vector of the monomial x^3*y^2*z^5;
468             the corresponding monomials are ordered w.r.t. intvec v (s.a.).
469             If no v is present, the monomials are sorted w.r.t. ordering o
470             (if o is given) or w.r.t. lexicographical ordering (if no o is
471             given). The corresponding ordered list of exponent vectors is
472             returned.
473             (e.g. sort(id); sorts lexicographically, smaller int's come first)
474             WARNING: Since negative exponents create the 0 plynomial in
475             Singular, id should not contain negative integers: the result might
476             not be as exspected
477           - if id=intvec: id is treated as list of integers
478           - if n!=0 the ordering is inverse, i.e. w.r.t. v(size(v)..1)
479             default: n=0
480         [2]: intvec, describing the permutation of the input (hence [2]=v if
481             v is given)
482NOTE:    If v is given, id may be any simply indexed object (e.g. any list);
483         entries of v must be pairwise distinct to get a permutation if id.
484         Zero generators of ideal/module are deleted
485EXAMPLE: example sort; shows an example
486{
487   int ii,jj,s,n = 0,0,1,0;
488   intvec v;
489   if ( defined(basering) ) { def P = basering; }
490   if ( size(#)==0 and (typeof(id)=="ideal" or typeof(id)=="module") )
491   {
492      id = simplify(id,2);
493      for ( ii=1; ii<size(id); ii++ )
494      {
495         if ( id[ii]!=id[ii+1] ) { break;}
496      }
497      if ( ii != size(id) ) { v = sortvec(id); }
498      else  { v = size(id)..1; }
499      if ( v == 0 ) { v = 1; }
500   }
501   if ( size(#)>=1 and (typeof(id)=="ideal" or typeof(id)=="module") )
502   {
503      if ( typeof(#[1])=="string" )
504      {
505         execute "ring r1 =("+charstr(P)+"),("+varstr(P)+"),("+#[1]+");";
506         def i = imap(P,id);
507         v = sortvec(i);
508         setring P;
509         n=2;
510      }
511   }
512   if ( typeof(id)=="intvec" or typeof(id)=="list" and n==0 )
513   {
514      string o;
515      if ( size(#)==0 ) { o = "lp"; n=1; }
516      if ( size(#)>=1 )
517      {
518         if ( typeof(#[1])=="string" ) { o = #[1]; n=1; }
519      }
520   }
521   if ( typeof(id)=="intvec" or typeof(id)=="list" and n==1 )
522   {
523      if ( typeof(id)=="list" )
524      {
525         for (ii=1; ii<=size(id); ii++)
526         {
527            if (typeof(id[ii]) != "intvec" and typeof(id[ii]) != "int")
528               { "// list elements must be intvec/int"; return(); }
529            else
530               { s=size(id[ii])*(s < size(id[ii])) + s*(s >= size(id[ii])); }
531         }
532      }
533      execute "ring r=0,x(1..s),("+o+");";
534      ideal i;
535      poly f;
536      for (ii=1; ii<=size(id); ii++)
537      {
538         f=1;
539         for (jj=1; jj<=size(id[ii]); jj++)
540         {
541            f=f*x(jj)^(id[ii])[jj];
542         }
543         i[ii]=f;
544      }
545      v = sort(i)[2];
546   }
547   if ( size(#)!=0 and n==0 ) { v = #[1]; }
548   if( size(#)==2 )
549   {
550      if ( #[2] != 0 ) { v = v[size(v)..1]; }
551   }
552   s = size(v);
553   def m = id;
554   for ( jj=1; jj<=s; jj=jj+1) { m[jj] = id[v[jj]]; }
555   list L=m,v;
556   return(L);
557}
558example
559{  "EXAMPLE:"; echo = 2;
560   ring r0 = 0,(x,y,z),lp;
561   ideal i = x3,y3,z3,x2z,x2y,y2z,y2x,z2y,z2x,xyz;
562   show(sort(i));"";
563   show(sort(i,"wp(1,2,3)"));"";
564   intvec v=10..1;
565   show(sort(i,v));"";
566   show(sort(i,v,1));"";   // should be the identity
567   ring r1  = 0,t,ls;
568   ideal j = t14,t6,t28,t20,t12,t34,t26,t18,t40,t32,t24,t38,t30,t36;
569   show(sort(j)[1]);"";
570   show(sort(j,"lp")[1]);"";
571   list L =1,5..8,10,2,8..5,8,3..10;
572   sort(L)[1];"";          // sort L lexicographically
573   sort(L,"Dp",1)[1];      // sort L w.r.t (total sum, reverse lex)
574}
575///////////////////////////////////////////////////////////////////////////////
576
577proc sum (id, list #)
578USAGE:    sum(id[,v]); id=ideal/vector/module/matrix resp. id=intvec/intmat,
579                       v=intvec (e.g. v=1..n, n=integer)
580RETURN:   poly resp. int which is the sum of all entries of id, with index
581          given by v (default: v=1..number of entries of id)
582NOTE:     id is treated as a list of polys resp. integers. A module m is
583          identified with corresponding matrix M (columns of M generate m)
584EXAMPLE:  example sum; shows an example
585{
586   if( typeof(id)=="poly" or typeof(id)=="ideal" or typeof(id)=="vector"
587       or typeof(id)=="module" or typeof(id)=="matrix" )
588   {
589      ideal i = ideal(matrix(id));
590      if( size(#)!=0 ) { i = i[#[1]]; }
591      matrix Z = matrix(i);
592   }
593   if( typeof(id)=="int" or typeof(id)=="intvec" or typeof(id)=="intmat" )
594   {
595      if ( typeof(id) == "int" ) { intmat S =id; }
596      else { intmat S = intmat(id); }
597      intvec i = S[1..nrows(S),1..ncols(S)];
598      if( size(#)!=0 ) { i = i[#[1]]; }
599      intmat Z=transpose(i);
600   }
601   intvec v; v[ncols(Z)]=0; v=v+1;
602   return((Z*v)[1,1]);
603}
604example
605{  "EXAMPLE:"; echo = 2;
606   ring r= 0,(x,y,z),dp;
607   vector pv = [xy,xz,yz,x2,y2,z2];
608   sum(pv);
609   //sum(pv,2..5);
610   //matrix M[2][3] = 1,x,2,y,3,z;
611   //sum(M);
612   //intvec w=2,4,6;
613   //sum(M,w);
614   //intvec iv = 1,2,3,4,5,6,7,8,9;
615   //w=1..5,7,9;
616   //sum(iv,w);
617   //intmat m[2][3] = 1,1,1,2,2,2;
618   //sum(m,3..4);
619}
620///////////////////////////////////////////////////////////////////////////////
621
622proc which (command)
623USAGE:    which(command); command = string expression
624RETURN:   Absolute pathname of command, if found in search path.
625          Empty string, otherwise.
626NOTE:     Based on the Unix command 'which'.
627EXAMPLE:  example which; shows an example
628{
629   int rs;
630   int i;
631   string fn = "/tmp/which_" + string(system("pid"));
632   string pn;
633   if( typeof(command) != "string")
634   {
635        return pn;
636   }
637   i = system("sh", "which " + command + " > " + fn);
639   pn[size(pn)] = "";
640   i = 1;
641   while ((pn[i] != " ") and (pn[i] != ""))
642   {
643     i = i+1;
644   }
645   if (pn[i] == " ") {pn[i] = "";}
646   rs = system("sh", "ls " + pn + " > " + fn + " 2>&1 ");
647   i = system("sh", "rm " + fn);
648   if (rs == 0) {return (pn);}
649   else
650   {