source: git/Singular/LIB/matrix.lib @ a57b65

spielwiese
Last change on this file since a57b65 was 3686937, checked in by Oleksandr Motsak <motsak@…>, 11 years ago
Added '$Id$' as a comment to all libs (LIB/*.lib)
  • Property mode set to 100644
File size: 39.4 KB
Line 
1//////////////////////////////////////////////////////////////////////////////
2version="version matrix.lib 4.0.0.0 Jun_2013 "; // $Id$
3category="Linear Algebra";
4info="
5LIBRARY:  matrix.lib    Elementary Matrix Operations
6
7PROCEDURES:
8 compress(A);           matrix, zero columns from A deleted
9 concat(A1,A2,..);      matrix, concatenation of matrices A1,A2,...
10 diag(p,n);             matrix, nxn diagonal matrix with entries poly p
11 dsum(A1,A2,..);        matrix, direct sum of matrices A1,A2,...
12 flatten(A);            ideal, generated by entries of matrix A
13 genericmat(n,m[,id]);  generic nxm matrix [entries from id]
14 is_complex(c);         1 if list c is a complex, 0 if not
15 outer(A,B);            matrix, outer product of matrices A and B
16 power(A,n);            matrix/intmat, n-th power of matrix/intmat A
17 skewmat(n[,id]);       generic skew-symmetric nxn matrix [entries from id]
18 submat(A,r,c);         submatrix of A with rows/cols specified by intvec r/c
19 symmat(n[,id]);        generic symmetric nxn matrix [entries from id]
20 tensor(A,B);           matrix, tensor product of matrices A nd B
21 unitmat(n);            unit square matrix of size n
22 gauss_col(A);          transform a matrix into col-reduced Gauss normal form
23 gauss_row(A);          transform a matrix into row-reduced Gauss normal form
24 addcol(A,c1,p,c2);     add p*(c1-th col) to c2-th column of matrix A, p poly
25 addrow(A,r1,p,r2);     add p*(r1-th row) to r2-th row of matrix A, p poly
26 multcol(A,c,p);        multiply c-th column of A with poly p
27 multrow(A,r,p);        multiply r-th row of A with poly p
28 permcol(A,i,j);        permute i-th and j-th columns
29 permrow(A,i,j);        permute i-th and j-th rows
30 rowred(A[,any]);       reduction of matrix A with elementary row-operations
31 colred(A[,any]);       reduction of matrix A with elementary col-operations
32 linear_relations(E);   find linear relations between homogeneous vectors
33 rm_unitrow(A);         remove unit rows and associated columns of A
34 rm_unitcol(A);         remove unit columns and associated rows of A
35 headStand(A);          A[n-i+1,m-j+1]:=A[i,j]
36 symmetricBasis(n,k[,s]); basis of k-th symmetric power of n-dim v.space
37 exteriorBasis(n,k[,s]); basis of k-th exterior power of n-dim v.space
38 symmetricPower(A,k);   k-th symmetric power of a module/matrix A
39 exteriorPower(A,k);    k-th exterior power of a module/matrix A
40          (parameters in square brackets [] are optional)
41";
42
43LIB "inout.lib";
44LIB "ring.lib";
45LIB "random.lib";
46LIB "general.lib"; // for sort
47LIB "nctools.lib"; // for superCommutative
48
49///////////////////////////////////////////////////////////////////////////////
50
51proc compress (A)
52"USAGE:   compress(A); A matrix/ideal/module/intmat/intvec
53RETURN:  same type, zero columns/generators from A deleted
54         (if A=intvec, zero elements are deleted)
55EXAMPLE: example compress; shows an example
56"
57{
58   if( typeof(A)=="matrix" ) { return(matrix(simplify(A,2))); }
59   if( typeof(A)=="intmat" or typeof(A)=="intvec" )
60   {
61      ring r=0,x,lp;
62      if( typeof(A)=="intvec" ) { intmat C=transpose(A); kill A; intmat A=C; }
63      module m = matrix(A);
64      if ( size(m) == 0)
65      { intmat B; }
66      else
67      { intmat B[nrows(A)][size(m)]; }
68      int i,j;
69      for( i=1; i<=ncols(A); i++ )
70      {
71         if( m[i]!=[0] )
72         {
73            j++;
74            B[1..nrows(A),j]=A[1..nrows(A),i];
75         }
76      }
77      if( defined(C) ) { return(intvec(B)); }
78      return(B);
79    }
80   return(simplify(A,2));
81}
82example
83{ "EXAMPLE:"; echo = 2;
84   ring r=0,(x,y,z),ds;
85   matrix A[3][4]=1,0,3,0,x,0,z,0,x2,0,z2,0;
86   print(A);
87   print(compress(A));
88   module m=module(A); show(m);
89   show(compress(m));
90   intmat B[3][4]=1,0,3,0,4,0,5,0,6,0,7,0;
91   compress(B);
92   intvec C=0,0,1,2,0,3;
93   compress(C);
94}
95///////////////////////////////////////////////////////////////////////////////
96proc concat (list #)
97"USAGE:   concat(A1,A2,..); A1,A2,... matrices
98RETURN:  matrix, concatenation of A1,A2,.... Number of rows of result matrix
99         is max(nrows(A1),nrows(A2),...)
100EXAMPLE: example concat; shows an example
101"
102{
103   int i;
104   for( i=size(#);i>0; i-- ) { #[i]=module(#[i]); }
105   module B=#[1..size(#)];
106   return(matrix(B));
107}
108example
109{ "EXAMPLE:"; echo = 2;
110   ring r=0,(x,y,z),ds;
111   matrix A[3][3]=1,2,3,x,y,z,x2,y2,z2;
112   matrix B[2][2]=1,0,2,0; matrix C[1][4]=4,5,x,y;
113   print(A);
114   print(B);
115   print(C);
116   print(concat(A,B,C));
117}
118///////////////////////////////////////////////////////////////////////////////
119
120proc diag (list #)
121"USAGE:   diag(p,n); p poly, n integer
122         diag(A);   A matrix
123RETURN:  diag(p,n): diagonal matrix, p times unit matrix of size n.
124@*       diag(A)  : n*m x n*m diagonal matrix with entries all the entries of
125                    the nxm matrix A, taken from the 1st row, 2nd row etc of A
126EXAMPLE: example diag; shows an example
127"
128{
129   if( size(#)==2 ) { return(matrix(#[1]*freemodule(#[2]))); }
130   if( size(#)==1 )
131   {
132      int i; ideal id=#[1];
133      int n=ncols(id); matrix A[n][n];
134      for( i=1; i<=n; i++ ) { A[i,i]=id[i]; }
135   }
136   return(A);
137}
138example
139{ "EXAMPLE:"; echo = 2;
140   ring r = 0,(x,y,z),ds;
141   print(diag(xy,4));
142   matrix A[3][2] = 1,2,3,4,5,6;
143   print(A);
144   print(diag(A));
145}
146///////////////////////////////////////////////////////////////////////////////
147
148proc dsum (list #)
149"USAGE:   dsum(A1,A2,..); A1,A2,... matrices
150RETURN:  matrix, direct sum of A1,A2,...
151EXAMPLE: example dsum; shows an example
152"
153{
154   int i,N,a;
155   list L;
156   for( i=1; i<=size(#); i++ ) { N=N+nrows(#[i]); }
157   for( i=1; i<=size(#); i++ )
158   {
159      matrix B[N][ncols(#[i])];
160      B[a+1..a+nrows(#[i]),1..ncols(#[i])]=#[i];
161      a=a+nrows(#[i]);
162      L[i]=B; kill B;
163   }
164   return(concat(L));
165}
166example
167{ "EXAMPLE:"; echo = 2;
168   ring r = 0,(x,y,z),ds;
169   matrix A[3][3] = 1,2,3,4,5,6,7,8,9;
170   matrix B[2][2] = 1,x,y,z;
171   print(A);
172   print(B);
173   print(dsum(A,B));
174}
175///////////////////////////////////////////////////////////////////////////////
176
177proc flatten (matrix A)
178"USAGE:   flatten(A); A matrix
179RETURN:  ideal, generated by all entries from A
180EXAMPLE: example flatten; shows an example
181"
182{
183   return(ideal(A));
184}
185example
186{ "EXAMPLE:"; echo = 2;
187   ring r = 0,(x,y,z),ds;
188   matrix A[2][3] = 1,2,x,y,z,7;
189   print(A);
190   flatten(A);
191}
192///////////////////////////////////////////////////////////////////////////////
193
194proc genericmat (int n,int m,list #)
195"USAGE:   genericmat(n,m[,id]);  n,m=integers, id=ideal
196RETURN:  nxm matrix, with entries from id.
197NOTE:    if id has less than nxm elements, the matrix is filled with 0's,
198         (default: id=maxideal(1)).
199         genericmat(n,m); creates the generic nxm matrix
200EXAMPLE: example genericmat; shows an example
201"
202{
203   if( size(#)==0 ) { ideal id=maxideal(1); }
204   if( size(#)==1 ) { ideal id=#[1]; }
205   if( size(#)>=2 ) { "// give 3 arguments, 3-rd argument must be an ideal"; }
206   matrix B[n][m]=id;
207   return(B);
208}
209example
210{ "EXAMPLE:"; echo = 2;
211   ring R = 0,x(1..16),lp;
212   print(genericmat(3,3));      // the generic 3x3 matrix
213   ring R1 = 0,(a,b,c,d),dp;
214   matrix A = genericmat(3,4,maxideal(1)^3);
215   print(A);
216   int n,m = 3,2;
217   ideal i = ideal(randommat(1,n*m,maxideal(1),9));
218   print(genericmat(n,m,i));    // matrix of generic linear forms
219}
220///////////////////////////////////////////////////////////////////////////////
221
222proc is_complex (list c)
223"USAGE:   is_complex(c); c = list of size-compatible modules or matrices
224RETURN:  1 if c[i]*c[i+1]=0 for all i, 0 if not, hence checking whether the
225         list of matrices forms a complex.
226NOTE:    Ideals are treated internally as 1-line matrices.
227         If printlevel > 0, the position where c is not a complex is shown.
228EXAMPLE: example is_complex; shows an example
229"
230{
231   int i;
232   module @test;
233   for( i=1; i<=size(c)-1; i++ )
234   {
235      c[i]=matrix(c[i]); c[i+1]=matrix(c[i+1]);
236      @test=c[i]*c[i+1];
237      if (size(@test)!=0)
238      {
239        dbprint(printlevel-voice+2,"// not a complex at position " +string(i));
240         return(0);
241      }
242   }
243   return(1);
244}
245example
246{ "EXAMPLE:";   echo = 2;
247   ring r  = 32003,(x,y,z),ds;
248   ideal i = x4+y5+z6,xyz,yx2+xz2+zy7;
249   list L  = nres(i,0);
250   is_complex(L);
251   L[4]    = matrix(i);
252   is_complex(L);
253}
254///////////////////////////////////////////////////////////////////////////////
255
256proc outer (matrix A, matrix B)
257"USAGE:   outer(A,B); A,B matrices
258RETURN:  matrix, outer (tensor) product of A and B
259EXAMPLE: example outer; shows an example
260"
261{
262   int i,j; list L;
263   int triv = nrows(B)*ncols(B);
264   if( triv==1 )
265   {
266     return(B[1,1]*A);
267   }
268   else
269   {
270     int N = nrows(A)*nrows(B);
271     matrix C[N][ncols(B)];
272     for( i=ncols(A);i>0; i-- )
273     {
274       for( j=1; j<=nrows(A); j++ )
275       {
276          C[(j-1)*nrows(B)+1..j*nrows(B),1..ncols(B)]=A[j,i]*B;
277       }
278       L[i]=C;
279     }
280     return(concat(L));
281   }
282}
283example
284{ "EXAMPLE:"; echo = 2;
285   ring r=32003,(x,y,z),ds;
286   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
287   matrix B[2][2]=x,y,0,z;
288   print(A);
289   print(B);
290   print(outer(A,B));
291}
292///////////////////////////////////////////////////////////////////////////////
293
294proc power ( A, int n)
295"USAGE:   power(A,n);  A a square-matrix of type intmat or matrix, n=integer>=0
296RETURN:  intmat resp. matrix, the n-th power of A
297NOTE:    for A=intmat and big n the result may be wrong because of int overflow
298EXAMPLE: example power; shows an example
299"
300{
301//---------------------------- type checking ----------------------------------
302   if( typeof(A)!="matrix" and typeof(A)!="intmat" )
303   {
304      ERROR("no matrix or intmat!");
305   }
306   if( ncols(A) != nrows(A) )
307   {
308      ERROR("not a square matrix!");
309   }
310//---------------------------- trivial cases ----------------------------------
311   int ii;
312   if( n <= 0 )
313   {
314      if( typeof(A)=="matrix" )
315      {
316         return (unitmat(nrows(A)));
317      }
318      if( typeof(A)=="intmat" )
319      {
320         intmat B[nrows(A)][nrows(A)];
321         for( ii=1; ii<=nrows(A); ii++ )
322         {
323            B[ii,ii] = 1;
324         }
325         return (B);
326      }
327   }
328   if( n == 1 ) { return (A); }
329//---------------------------- sub procedure ----------------------------------
330   proc matpow (A, int n)
331   {
332      def B = A*A;
333      int ii= 2;
334      int jj= 4;
335      while( jj <= n )
336      {
337         B=B*B;
338         ii=jj;
339         jj=2*jj;
340      }
341      return(B,n-ii);
342   }
343//----------------------------- main program ----------------------------------
344   list L = matpow(A,n);
345   def B  = L[1];
346   ii     = L[2];
347   while( ii>=2 )
348   {
349      L = matpow(A,ii);
350      B = B*L[1];
351      ii= L[2];
352   }
353   if( ii == 0) { return(B); }
354   if( ii == 1) { return(A*B); }
355}
356example
357{ "EXAMPLE:"; echo = 2;
358   intmat A[3][3]=1,2,3,4,5,6,7,8,9;
359   print(power(A,3));"";
360   ring r=0,(x,y,z),dp;
361   matrix B[3][3]=0,x,y,z,0,0,y,z,0;
362   print(power(B,3));"";
363}
364///////////////////////////////////////////////////////////////////////////////
365
366proc skewmat (int n, list #)
367"USAGE:   skewmat(n[,id]);  n integer, id ideal
368RETURN:  skew-symmetric nxn matrix, with entries from id
369         (default: id=maxideal(1))
370         skewmat(n); creates the generic skew-symmetric matrix
371NOTE:    if id has less than n*(n-1)/2 elements, the matrix is
372         filled with 0's,
373EXAMPLE: example skewmat; shows an example
374"
375{
376   matrix B[n][n];
377   if( size(#)==0 ) { ideal id=maxideal(1); }
378   else { ideal id=#[1]; }
379   id = id,B[1..n,1..n];
380   int i,j;
381   for( i=0; i<=n-2; i++ )
382   {
383      B[i+1,i+2..n]=id[j+1..j+n-i-1];
384      j=j+n-i-1;
385   }
386   matrix A=transpose(B);
387   B=B-A;
388   return(B);
389}
390example
391{ "EXAMPLE:"; echo = 2;
392   ring R=0,x(1..5),lp;
393   print(skewmat(4));    // the generic skew-symmetric matrix
394   ring R1 = 0,(a,b,c),dp;
395   matrix A=skewmat(4,maxideal(1)^2);
396   print(A);
397   int n=3;
398   ideal i = ideal(randommat(1,n*(n-1) div 2,maxideal(1),9));
399   print(skewmat(n,i));  // skew matrix of generic linear forms
400   kill R1;
401}
402///////////////////////////////////////////////////////////////////////////////
403
404proc submat (matrix A, intvec r, intvec c)
405"USAGE:   submat(A,r,c);  A=matrix, r,c=intvec
406RETURN:  matrix, submatrix of A with rows specified by intvec r
407         and columns specified by intvec c.
408EXAMPLE: example submat; shows an example
409"
410{
411   matrix B[size(r)][size(c)]=A[r,c];
412   return(B);
413}
414example
415{ "EXAMPLE:"; echo = 2;
416   ring R=32003,(x,y,z),lp;
417   matrix A[4][4]=x,y,z,0,1,2,3,4,5,6,7,8,9,x2,y2,z2;
418   print(A);
419   intvec v=1,3,4;
420   matrix B=submat(A,v,1..3);
421   print(B);
422}
423///////////////////////////////////////////////////////////////////////////////
424
425proc symmat (int n, list #)
426"USAGE:   symmat(n[,id]);  n integer, id ideal
427RETURN:  symmetric nxn matrix, with entries from id (default: id=maxideal(1))
428NOTE:    if id has less than n*(n+1)/2 elements, the matrix is filled with 0's,
429         symmat(n); creates the generic symmetric matrix
430EXAMPLE: example symmat; shows an example
431"
432{
433   matrix B[n][n];
434   if( size(#)==0 ) { ideal id=maxideal(1); }
435   else { ideal id=#[1]; }
436   id = id,B[1..n,1..n];
437   int i,j;
438   for( i=0; i<=n-1; i++ )
439   {
440      B[i+1,i+1..n]=id[j+1..j+n-i];
441      j=j+n-i;
442   }
443   matrix A=transpose(B);
444   for( i=1; i<=n; i++ ) {  A[i,i]=0; }
445   B=A+B;
446   return(B);
447}
448example
449{ "EXAMPLE:"; echo = 2;
450   ring R=0,x(1..10),lp;
451   print(symmat(4));    // the generic symmetric matrix
452   ring R1 = 0,(a,b,c),dp;
453   matrix A=symmat(4,maxideal(1)^3);
454   print(A);
455   int n=3;
456   ideal i = ideal(randommat(1,n*(n+1) div 2,maxideal(1),9));
457   print(symmat(n,i));  // symmetric matrix of generic linear forms
458   kill R1;
459}
460///////////////////////////////////////////////////////////////////////////////
461
462proc tensor (matrix A, matrix B)
463"USAGE:   tensor(A,B); A,B matrices
464RETURN:  matrix, tensor product of A and B
465EXAMPLE: example tensor; shows an example
466"
467{
468   if (ncols(A)==0)
469   {
470     int q=nrows(A)*nrows(B);
471     matrix D[q][0];
472     return(D);
473   }
474
475   int i,j;
476   matrix C,D;
477   for( i=1; i<=nrows(A); i++ )
478   {
479     C = A[i,1]*B;
480     for( j=2; j<=ncols(A); j++ )
481     {
482       C = concat(C,A[i,j]*B);
483     }
484     D = concat(D,transpose(C));
485   }
486   D = transpose(D);
487   return(submat(D,2..nrows(D),1..ncols(D)));
488}
489example
490{ "EXAMPLE:"; echo = 2;
491   ring r=32003,(x,y,z),(c,ds);
492   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
493   matrix B[2][2]=x,y,0,z;
494   print(A);
495   print(B);
496   print(tensor(A,B));
497}
498///////////////////////////////////////////////////////////////////////////////
499
500proc unitmat (int n)
501"USAGE:   unitmat(n);  n integer >= 0
502RETURN:  nxn unit matrix
503NOTE:    needs a basering, diagonal entries are numbers (=1) in the basering
504EXAMPLE: example unitmat; shows an example
505"
506{
507   return(matrix(freemodule(n)));
508}
509example
510{ "EXAMPLE:"; echo = 2;
511   ring r=32003,(x,y,z),lp;
512   print(xyz*unitmat(4));
513   print(unitmat(5));
514}
515///////////////////////////////////////////////////////////////////////////////
516
517proc gauss_col (matrix A, list #)
518"USAGE:   gauss_col(A[,e]); A a matrix, e any type
519RETURN:  - a matrix B, if called with one argument; B is the complete column-
520           reduced upper-triangular normal form of A if A is constant,
521           (resp. as far as this is possible if A is a polynomial matrix;
522           no division by polynomials).
523@*       - a list L of two matrices, if called with two arguments;
524           L satisfies L[1] = A * L[2] with L[1] the column-reduced form of A
525           and L[2] the transformation matrix.
526NOTE:    * The procedure just applies interred to A with ordering (C,dp).
527           The transformation matrix is obtained by applying 'lift'.
528           This should be faster than the procedure colred.
529@*       * It should only be used with exact coefficient field (there is no
530           pivoting and rounding error treatment).
531@*       * Parameters are allowed. Hence, if the entries of A are parameters,
532           B is the column-reduced form of A over the rational function field.
533SEE ALSO:  colred
534EXAMPLE: example gauss_col; shows an example
535"
536{
537   def R=basering; int u;
538   string mp = string(minpoly);
539   int n = nrows(A);
540   int m = ncols(A);
541   module M = A;
542   intvec v = option(get);
543//------------------------ change ordering if necessary ----------------------
544   if( ordstr(R) != ("C,dp("+string(nvars(R))+")") )
545   {
546     def @R=changeord(list(list("C",0:1),list("dp",1:nvars(R))),R);
547     setring @R; u=1;
548     execute("minpoly="+mp+";");
549     matrix A = imap(R,A);
550     module M = A;
551   }
552//------------------------------ start computation ---------------------------
553   option(redSB);
554   M = simplify(interred(M),1);
555   if(size(#) != 0)
556   {
557      module N = lift(A,M);
558   }
559//--------------- reset ring and options and return --------------------------
560   if ( u==1 )
561   {
562      setring R;
563      M=imap(@R,M);
564      if (size(#) != 0)
565      {
566         module N = imap(@R,N);
567      }
568      kill @R;
569   }
570   option(set,v);
571   // M = sort(M,size(M)..1)[1];
572   A = matrix(M,n,m);
573   if (size(#) != 0)
574   {
575     list L= A,matrix(N,m,m);
576     return(L);
577   }
578   return(matrix(M,n,m));
579}
580example
581{ "EXAMPLE:"; echo = 2;
582   ring r=(0,a,b),(A,B,C),dp;
583   matrix m[8][6]=
584   0,    2*C, 0,    0,  0,   0,
585   0,    -4*C,a*A,  0,  0,   0,
586   b*B,  -A,  0,    0,  0,   0,
587   -A,   B,   0,    0,  0,   0,
588   -4*C, 0,   B,    2,  0,   0,
589   2*A,  B,   0,    0,  0,   0,
590   0,    3*B, 0,    0,  2b,  0,
591   0,    AB,  0,    2*A,A,   2a;"";
592   list L=gauss_col(m,1);
593   print(L[1]);
594   print(L[2]);
595
596   ring S=0,x,(c,dp);
597   matrix A[5][4] =
598    3, 1, 1, 1,
599   13, 8, 6,-7,
600   14,10, 6,-7,
601    7, 4, 3,-3,
602    2, 1, 0, 3;
603   print(gauss_col(A));
604}
605///////////////////////////////////////////////////////////////////////////////
606
607proc gauss_row (matrix A, list #)
608"USAGE:  gauss_row(A [,e]); A matrix, e any type
609RETURN: - a matrix B, if called with one argument; B is the complete row-
610          reduced lower-triangular normal form of A if A is constant,
611          (resp. as far as this is possible if A is a polynomial matrix;
612          no division by polynomials).
613@*      - a list L of two matrices, if called with two arguments;
614          L satisfies transpose(L[2])*A=transpose(L[1])
615          with L[1] the row-reduced form of A
616          and L[2] the transformation matrix.
617NOTE:   * This procedure just applies gauss_col to the transposed matrix.
618          The transformation matrix is obtained by applying lift.
619          This should be faster than the procedure rowred.
620@*      * It should only be used with exact coefficient field (there is no
621          pivoting and rounding error treatment).
622@*      * Parameters are allowed. Hence, if the entries of A are parameters,
623          B is the row-reduced form of A over the rational function field.
624SEE ALSO: rowred
625EXAMPLE: example gauss_row; shows an example
626"
627{
628   if(size(#) > 0)
629   {
630     list L = gauss_col(transpose(A),1);
631     return(L);
632   }
633   A = gauss_col(transpose(A));
634   return(transpose(A));
635}
636example
637{ "EXAMPLE:"; echo = 2;
638   ring r=(0,a,b),(A,B,C),dp;
639   matrix m[6][8]=
640   0, 0,  b*B, -A,-4C,2A,0, 0,
641   2C,-4C,-A,B, 0,  B, 3B,AB,
642   0,a*A,  0, 0, B,  0, 0, 0,
643   0, 0,  0, 0, 2,  0, 0, 2A,
644   0, 0,  0, 0, 0,  0, 2b, A,
645   0, 0,  0, 0, 0,  0, 0, 2a;"";
646   print(gauss_row(m));"";
647   ring S=0,x,dp;
648   matrix A[4][5] =  3, 1,1,-1,2,
649                    13, 8,6,-7,1,
650                    14,10,6,-7,1,
651                     7, 4,3,-3,3;
652   list L=gauss_row(A,1);
653   print(L[1]);
654   print(L[2]);
655}
656///////////////////////////////////////////////////////////////////////////////
657
658proc addcol (matrix A, int c1, poly p, int c2)
659"USAGE:   addcol(A,c1,p,c2);  A matrix, p poly, c1, c2 positive integers
660RETURN:  matrix,  A being modified by adding p times column c1 to column c2
661EXAMPLE: example addcol; shows an example
662"
663{
664   int k=nrows(A);
665   A[1..k,c2]=A[1..k,c2]+p*A[1..k,c1];
666   return(A);
667}
668example
669{ "EXAMPLE:"; echo = 2;
670   ring r=32003,(x,y,z),lp;
671   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
672   print(A);
673   print(addcol(A,1,xy,2));
674}
675///////////////////////////////////////////////////////////////////////////////
676
677proc addrow (matrix A, int r1, poly p, int r2)
678"USAGE:   addrow(A,r1,p,r2);  A matrix, p poly, r1, r2 positive integers
679RETURN:  matrix,  A being modified by adding p times row r1 to row r2
680EXAMPLE: example addrow; shows an example
681"
682{
683   int k=ncols(A);
684   A[r2,1..k]=A[r2,1..k]+p*A[r1,1..k];
685   return(A);
686}
687example
688{ "EXAMPLE:"; echo = 2;
689   ring r=32003,(x,y,z),lp;
690   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
691   print(A);
692   print(addrow(A,1,xy,3));
693}
694///////////////////////////////////////////////////////////////////////////////
695
696proc multcol (matrix A, int c, poly p)
697"USAGE:   multcol(A,c,p);  A matrix, p poly, c positive integer
698RETURN:  matrix,  A being modified by multiplying column c by p
699EXAMPLE: example multcol; shows an example
700"
701{
702   int k=nrows(A);
703   A[1..k,c]=p*A[1..k,c];
704   return(A);
705}
706example
707{ "EXAMPLE:"; echo = 2;
708   ring r=32003,(x,y,z),lp;
709   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
710   print(A);
711   print(multcol(A,2,xy));
712}
713///////////////////////////////////////////////////////////////////////////////
714
715proc multrow (matrix A, int r, poly p)
716"USAGE:   multrow(A,r,p);  A matrix, p poly, r positive integer
717RETURN:  matrix,  A being modified by multiplying row r by p
718EXAMPLE: example multrow; shows an example
719"
720{
721   int k=ncols(A);
722   A[r,1..k]=p*A[r,1..k];
723   return(A);
724}
725example
726{ "EXAMPLE:"; echo = 2;
727   ring r=32003,(x,y,z),lp;
728   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
729   print(A);
730   print(multrow(A,2,xy));
731}
732///////////////////////////////////////////////////////////////////////////////
733
734proc permcol (matrix A, int c1, int c2)
735"USAGE:   permcol(A,c1,c2);  A matrix, c1,c2 positive integers
736RETURN:  matrix,  A being modified by permuting columns c1 and c2
737EXAMPLE: example permcol; shows an example
738"
739{
740   matrix B=A;
741   int k=nrows(B);
742   B[1..k,c1]=A[1..k,c2];
743   B[1..k,c2]=A[1..k,c1];
744   return(B);
745}
746example
747{ "EXAMPLE:"; echo = 2;
748   ring r=32003,(x,y,z),lp;
749   matrix A[3][3]=1,x,3,4,y,6,7,z,9;
750   print(A);
751   print(permcol(A,2,3));
752}
753///////////////////////////////////////////////////////////////////////////////
754
755proc permrow (matrix A, int r1, int r2)
756"USAGE:   permrow(A,r1,r2);  A matrix, r1,r2 positive integers
757RETURN:  matrix,  A being modified by permuting rows r1 and r2
758EXAMPLE: example permrow; shows an example
759"
760{
761   matrix B=A;
762   int k=ncols(B);
763   B[r1,1..k]=A[r2,1..k];
764   B[r2,1..k]=A[r1,1..k];
765   return(B);
766}
767example
768{ "EXAMPLE:"; echo = 2;
769   ring r=32003,(x,y,z),lp;
770   matrix A[3][3]=1,2,3,x,y,z,7,8,9;
771   print(A);
772   print(permrow(A,2,1));
773}
774///////////////////////////////////////////////////////////////////////////////
775
776proc rowred (matrix A,list #)
777"USAGE:   rowred(A[,e]);  A matrix, e any type
778RETURN:  - a matrix B, being the row reduced form of A, if rowred is called
779           with one argument.
780           (as far as this is possible over the polynomial ring; no division
781           by polynomials)
782@*       - a list L of two matrices, such that L[1] = L[2] * A with L[1]
783           the row-reduced form of A and L[2] the transformation matrix
784           (if rowred is called with two arguments).
785ASSUME:  The entries of A are in the base field. It is not verified whether
786         this assumption holds.
787NOTE:    * This procedure is designed for teaching purposes mainly.
788@*       * The straight forward Gaussian algorithm is implemented in the
789           library (no standard basis computation).
790           The transformation matrix is obtained by concatenating a unit
791           matrix to A. proc gauss_row should be faster.
792@*       * It should only be used with exact coefficient field (there is no
793           pivoting) over the polynomial ring (ordering lp or dp).
794@*       * Parameters are allowed. Hence, if the entries of A are parameters
795           the computation takes place over the field of rational functions.
796SEE ALSO:  gauss_row
797EXAMPLE: example rowred; shows an example
798"
799{
800   int m,n=nrows(A),ncols(A);
801   int i,j,k,l,rk;
802   poly p;
803   matrix d[m][n];
804   for (i=1;i<=m;i++)
805   {  for (j=1;j<=n;j++)
806      {  p = A[i,j];
807         if (ord(p)==0)
808         {  if (deg(p)==0) { d[i,j]=p; }
809         }
810      }
811   }
812   matrix b = A;
813   if (size(#) != 0) { b = concat(b,unitmat(m)); }
814      for (l=1;l<=n;l=l+1)
815   {
816      k  = findfirst(ideal(d[l]),rk+1);
817      if (k)
818      {  rk = rk+1;
819         b  = permrow(b,rk,k);
820         p  = b[rk,l];         p = 1/p;
821         b  = multrow(b,rk,p);
822         for (i=1;i<=m;i++)
823         {
824            if (rk-i) { b = addrow(b,rk,-b[i,l],i);}
825         }
826         d = 0;
827         for (i=rk+1;i<=m;i++)
828         {  for (j=l+1;j<=n;j++)
829            {  p = b[i,j];
830               if (ord(p)==0)
831               {  if (deg(p)==0) { d[i,j]=p; }
832               }
833            }
834         }
835
836      }
837   }
838   d = submat(b,1..m,1..n);
839   if (size(#))
840   {
841      list L=d,submat(b,1..m,n+1..n+m);
842      return(L);
843   }
844   return(d);
845}
846example
847{ "EXAMPLE:"; echo = 2;
848   ring r=(0,a,b),(A,B,C),dp;
849   matrix m[6][8]=
850   0, 0,  b*B, -A,-4C,2A,0, 0,
851   2C,-4C,-A,B, 0,  B, 3B,AB,
852   0,a*A,  0, 0, B,  0, 0, 0,
853   0, 0,  0, 0, 2,  0, 0, 2A,
854   0, 0,  0, 0, 0,  0, 2b, A,
855   0, 0,  0, 0, 0,  0, 0, 2a;"";
856   print(rowred(m));"";
857   list L=rowred(m,1);
858   print(L[1]);
859   print(L[2]);
860}
861///////////////////////////////////////////////////////////////////////////////
862
863proc colred (matrix A,list #)
864"USAGE:   colred(A[,e]);  A matrix, e any type
865RETURN:  - a matrix B, being the column reduced form of A, if colred is
866           called with one argument.
867           (as far as this is possible over the polynomial ring;
868           no division by polynomials)
869@*       - a list L of two matrices, such that L[1] = A * L[2] with L[1]
870           the column-reduced form of A and L[2] the transformation matrix
871           (if colred is called with two arguments).
872ASSUME:  The entries of A are in the base field. It is not verified whether
873         this assumption holds.
874NOTE:    * This procedure is designed for teaching purposes mainly.
875@*       * It applies rowred to the transposed matrix.
876           proc gauss_col should be faster.
877@*       * It should only be used with exact coefficient field (there is no
878           pivoting) over the polynomial ring (ordering lp or dp).
879@*       * Parameters are allowed. Hence, if the entries of A are parameters
880           the computation takes place over the field of rational functions.
881SEE ALSO:  gauss_col
882EXAMPLE: example colred; shows an example
883"
884{
885   A = transpose(A);
886   if (size(#))
887   { list L = rowred(A,1); return(transpose(L[1]),transpose(L[2]));}
888   else
889   { return(transpose(rowred(A)));}
890}
891example
892{ "EXAMPLE:"; echo = 2;
893   ring r=(0,a,b),(A,B,C),dp;
894   matrix m[8][6]=
895   0,    2*C, 0,    0,  0,   0,
896   0,    -4*C,a*A,  0,  0,   0,
897   b*B,  -A,  0,    0,  0,   0,
898   -A,   B,   0,    0,  0,   0,
899   -4*C, 0,   B,    2,  0,   0,
900   2*A,  B,   0,    0,  0,   0,
901   0,    3*B, 0,    0,  2b,  0,
902   0,    AB,  0,    2*A,A,   2a;"";
903   print(colred(m));"";
904   list L=colred(m,1);
905   print(L[1]);
906   print(L[2]);
907}
908//////////////////////////////////////////////////////////////////////////////
909
910proc linear_relations(module M)
911"USAGE:   linear_relations(M);
912         M: a module
913ASSUME:  All non-zero entries of M are homogeneous polynomials of the same
914         positive degree. The base field must be an exact field (not real
915         or complex).
916         It is not checked whether these assumptions hold.
917RETURN:  a maximal module R such that M*R is formed by zero vectors.
918EXAMPLE: example linear_relations; shows an example.
919"
920{ int n = ncols(M);
921  def BaseR = basering;
922  def br = changeord(list(list("dp",1:nvars(basering))));
923  setring br;
924  module M = imap(BaseR,M);
925  ideal vars = maxideal(1);
926  ring tmpR = 0, ('y(1..n)), dp;
927  def newR = br + tmpR;
928  setring newR;
929  module M = imap(br,M);
930  ideal vars = imap(br,vars);
931  attrib(vars,"isSB",1);
932  for (int i = 1; i<=n; i++) {
933    M[i] = M[i] + 'y(i)*gen(1);
934  }
935  M = interred(M);
936  module redM = NF(M,vars);
937  module REL;
938  int sizeREL;
939  int j;
940  for (i=1; i<=n; i++) {
941    if (M[i][1]==redM[i][1]) { //-- relation found!
942      sizeREL++;
943      REL[sizeREL]=0;
944      for (j=1; j<=n; j++) {
945        REL[sizeREL] = REL[sizeREL] + (M[i][1]/'y(j))*gen(j);
946      }
947    }
948  }
949  setring BaseR;
950  return(minbase(imap(newR,REL)));
951}
952example
953{ "EXAMPLE:"; echo = 2;
954  ring r = (3,w), (a,b,c,d),dp;
955  minpoly = w2-w-1;
956  module M = [a2,b2],[wab,w2c2+2b2],[(w-2)*a2+wab,wb2+w2c2];
957  module REL = linear_relations(M);
958  pmat(REL);
959  pmat(M*REL);
960}
961
962//////////////////////////////////////////////////////////////////////////////
963
964static proc findfirst (ideal i,int t)
965{
966   int n,k;
967   for (n=t;n<=ncols(i);n=n+1)
968   {
969      if (i[n]!=0) { k=n;break;}
970   }
971   return(k);
972}
973//////////////////////////////////////////////////////////////////////////////
974
975proc rm_unitcol(matrix A)
976"USAGE:   rm_unitcol(A); A matrix (being row-reduced)
977RETURN:  matrix, obtained from A by deleting unit columns (having just one 1
978         and else 0 as entries) and associated rows
979EXAMPLE: example rm_unitcol; shows an example
980"
981{
982 int l,j;
983 intvec v;
984 for (j=1;j<=ncols(A);j++)
985 {
986    if (gen(l+1)==module(A)[j]) {l=l+1;}
987    else { v=v,j;}
988 }
989 if (size(v)>1)
990    {  v = v[2..size(v)];
991       return(submat(A,l+1..nrows(A),v));
992    }
993 else
994    { return(0);}
995}
996example
997{ "EXAMPLE:"; echo = 2;
998   ring r=0,(A,B,C),dp;
999   matrix m[6][8]=
1000   0,  0,    A,   0, 1,0,  0,0,
1001   0,  0,  -C2,   0, 0,0,  1,0,
1002   0,  0,    0,1/2B, 0,0,  0,1,
1003   0,  0,    B,  -A, 0,2A, 0,0,
1004   2C,-4C,  -A,   B, 0,B,  0,0,
1005   0,  A,    0,   0, 0,0,  0,0;
1006   print(rm_unitcol(m));
1007}
1008//////////////////////////////////////////////////////////////////////////////
1009
1010proc rm_unitrow (matrix A)
1011"USAGE:   rm_unitrow(A); A matrix (being col-reduced)
1012RETURN:  matrix, obtained from A by deleting unit rows (having just one 1
1013         and else 0 as entries) and associated columns
1014EXAMPLE: example rm_unitrow; shows an example
1015"
1016{
1017 int l,j;
1018 intvec v;
1019 module M = transpose(A);
1020 for (j=1; j <= nrows(A); j++)
1021 {
1022    if (gen(l+1) == M[j]) { l=l+1; }
1023    else { v=v,j; }
1024 }
1025 if (size(v) > 1)
1026    {  v = v[2..size(v)];
1027       return(submat(A,v,l+1..ncols(A)));
1028    }
1029 else
1030    { return(0);}
1031}
1032example
1033{ "EXAMPLE:"; echo = 2;
1034   ring r=0,(A,B,C),dp;
1035   matrix m[8][6]=
1036   0,0,  0,   0, 2C, 0,
1037   0,0,  0,   0, -4C,A,
1038   A,-C2,0,   B, -A, 0,
1039   0,0,  1/2B,-A,B,  0,
1040   1,0,  0,   0, 0,  0,
1041   0,0,  0,   2A,B,  0,
1042   0,1,  0,   0, 0,  0,
1043   0,0,  1,   0, 0,  0;
1044   print(rm_unitrow(m));
1045}
1046//////////////////////////////////////////////////////////////////////////////
1047proc headStand(matrix M)
1048"USAGE:   headStand(M);  M matrix
1049RETURN:  matrix B such that B[i][j]=M[n-i+1,m-j+1], n=nrows(M), m=ncols(M)
1050EXAMPLE: example headStand; shows an example
1051"
1052{
1053  int i,j;
1054  int n=nrows(M);
1055  int m=ncols(M);
1056  matrix B[n][m];
1057  for(i=1;i<=n;i++)
1058  {
1059     for(j=1;j<=m;j++)
1060     {
1061        B[n-i+1,m-j+1]=M[i,j];
1062     }
1063  }
1064  return(B);
1065}
1066example
1067{ "EXAMPLE:"; echo = 2;
1068   ring r=0,(A,B,C),dp;
1069   matrix M[2][3]=
1070   0,A,  B,
1071   A2, B2, C;
1072   print(M);
1073   print(headStand(M));
1074}
1075//////////////////////////////////////////////////////////////////////////////
1076
1077// Symmetric/Exterior powers thanks to Oleksandr Iena for his persistence ;-)
1078
1079proc symmetricBasis(int n, int k, list #)
1080"USAGE:    symmetricBasis(n, k[,s]); n int, k int, s string
1081RETURN:   ring, poynomial ring containing the ideal \"symBasis\",
1082          being a basis of the k-th symmetric power of an n-dim vector space.
1083NOTE:     The output polynomial ring has characteristics 0 and n variables
1084          named \"S(i)\", where the base variable name S is either given by the
1085          optional string argument(which must not contain brackets) or equal to
1086          "e" by default.
1087SEE ALSO: exteriorBasis
1088KEYWORDS: symmetric basis
1089EXAMPLE:  example symmetricBasis; shows an example"
1090{
1091//------------------------ handle optional base variable name---------------
1092  string S = "e";
1093  if( size(#) > 0 )
1094  {
1095    if( typeof(#[1]) != "string" )
1096    {
1097      ERROR("Wrong optional argument: must be a string");
1098    }
1099    S = #[1];
1100    if( (find(S, "(") + find(S, ")")) > 0 )
1101    {
1102      ERROR("Wrong optional argument: must be a string without brackets");
1103    }
1104  }
1105
1106//------------------------- create ring container for symmetric power basis-
1107  execute("ring @@@SYM_POWER_RING_NAME=(0),("+S+"(1.."+string(n)+")),dp;");
1108
1109//------------------------- choose symmetric basis -------------------------
1110  ideal symBasis = maxideal(k);
1111
1112//------------------------- export and return      -------------------------
1113  export symBasis;
1114  return(basering);
1115}
1116example
1117{ "EXAMPLE:"; echo = 2;
1118
1119// basis of the 3-rd symmetricPower of a 4-dim vector space:
1120def R = symmetricBasis(4, 3, "@e"); setring R;
1121R;  // container ring:
1122symBasis; // symmetric basis:
1123}
1124
1125//////////////////////////////////////////////////////////////////////////////
1126
1127proc exteriorBasis(int n, int k, list #)
1128"USAGE:    exteriorBasis(n, k[,s]); n int, k int, s string
1129RETURN:   qring, an exterior algebra containing the ideal \"extBasis\",
1130          being a basis of the k-th exterior power of an n-dim vector space.
1131NOTE:     The output polynomial ring has characteristics 0 and n variables
1132          named \"S(i)\", where the base variable name S is either given by the
1133          optional string argument(which must not contain brackets) or equal to
1134          "e" by default.
1135SEE ALSO: symmetricBasis
1136KEYWORDS: exterior basis
1137EXAMPLE:  example exteriorBasis; shows an example"
1138{
1139//------------------------ handle optional base variable name---------------
1140  string S = "e";
1141  if( size(#) > 0 )
1142  {
1143    if( typeof(#[1]) != "string" )
1144    {
1145      ERROR("Wrong optional argument: must be a string");
1146    }
1147    S = #[1];
1148    if( (find(S, "(") + find(S, ")")) > 0 )
1149    {
1150      ERROR("Wrong optional argument: must be a string without brackets");
1151    }
1152  }
1153
1154//------------------------- create ring container for symmetric power basis-
1155  execute("ring @@@EXT_POWER_RING_NAME=(0),("+S+"(1.."+string(n)+")),dp;");
1156
1157//------------------------- choose exterior basis -------------------------
1158  def T = superCommutative(); setring T;
1159  ideal extBasis = simplify( NF(maxideal(k), std(0)), 1 + 2 + 8 );
1160
1161//------------------------- export and return      -------------------------
1162  export extBasis;
1163  return(basering);
1164}
1165example
1166{ "EXAMPLE:"; echo = 2;
1167// basis of the 3-rd symmetricPower of a 4-dim vector space:
1168def r = exteriorBasis(4, 3, "@e"); setring r;
1169r; // container ring:
1170extBasis; // exterior basis:
1171}
1172
1173//////////////////////////////////////////////////////////////////////////////
1174
1175static proc chooseSafeVarName(string prefix, string suffix)
1176"USAGE: give appropreate prefix for variable names
1177RETURN: safe variable name (repeated prefix + suffix)
1178"
1179{
1180  string V = varstr(basering);
1181  string S = suffix;
1182  while( find(V, S) > 0 )
1183  {
1184    S = prefix + S;
1185  }
1186  return(S);
1187}
1188
1189//////////////////////////////////////////////////////////////////////////////
1190
1191static proc mapPower(int p, module A, int k, def Tn, def Tm)
1192"USAGE: by both symmetric- and exterior-Power"
1193NOTE: everything over the basering!
1194      module A (matrix of the map), int k (power)
1195      rings Tn is source- and Tm is image-ring with bases
1196          resp. Ink and Imk.
1197      M = max dim of Image, N - dim. of source
1198SEE ALSO: symmetricPower, exteriorPower"
1199{
1200  def save = basering;
1201
1202  int n = nvars(save);
1203  int M = nrows(A);
1204  int N = ncols(A);
1205
1206  int i, j;
1207
1208//------------------------- compute matrix of single images ------------------
1209  def Rm = save + Tm;  setring Rm;
1210  dbprint(p-2, "Temporary Working Ring", Rm);
1211
1212  module A = imap(save, A);
1213
1214  ideal B; poly t;
1215
1216  for( i = N; i > 0; i-- )
1217  {
1218    t = 0;
1219    for( j = M; j > 0; j-- )
1220    {
1221      t = t + A[i][j] * var(n + j);
1222    }
1223
1224    B[i] = t;
1225  }
1226
1227  dbprint(p-1, "Matrix of single images", B);
1228
1229//------------------------- compute image ---------------------
1230  // apply S^k(A): Tn -> Rm  to Source basis vectors Ink:
1231  map TMap = Tn, B;
1232
1233  ideal C = NF(TMap(Ink), std(0));
1234  dbprint(p-1, "Image Matrix: ", C);
1235
1236
1237//------------------------- write it in Image basis ---------------------
1238  ideal Imk = imap(Tm, Imk);
1239
1240  module D; poly lm; vector tt;
1241
1242  for( i = ncols(C); i > 0; i-- )
1243  {
1244    t = C[i];
1245    tt = 0;
1246
1247    while( t != 0 )
1248    {
1249      lm = leadmonom(t);
1250      //    lm;
1251      for( j = ncols(Imk); j > 0; j-- )
1252      {
1253        if( lm / Imk[j] != 0 )
1254        {
1255          tt = tt + (lead(t) / Imk[j]) * gen(j);
1256          break;
1257        }
1258      }
1259      t = t - lead(t);
1260    }
1261
1262    D[i] = tt;
1263  }
1264
1265//------------------------- map it back and return  ---------------------
1266  setring save;
1267  return( imap(Rm, D) );
1268}
1269
1270
1271//////////////////////////////////////////////////////////////////////////////
1272
1273proc symmetricPower(module A, int k)
1274"USAGE:    symmetricPower(A, k); A module, k int
1275RETURN:   module: the k-th symmetric power of A
1276NOTE:     the chosen bases and most of intermediate data will be shown if
1277          printlevel is big enough
1278SEE ALSO: exteriorPower
1279KEYWORDS: symmetric power
1280EXAMPLE:  example symmetricPower; shows an example"
1281{
1282  int p = printlevel - voice + 2;
1283
1284  def save = basering;
1285
1286  int M = nrows(A);
1287  int N = ncols(A);
1288
1289  string S = chooseSafeVarName("@", "@_e");
1290
1291//------------------------- choose source basis -------------------------
1292  def Tn = symmetricBasis(N, k, S); setring Tn;
1293  ideal Ink = symBasis;
1294  export Ink;
1295  dbprint(p-3, "Temporary Source Ring", basering);
1296  dbprint(p, "S^k(Source Basis)", Ink);
1297
1298//------------------------- choose image basis -------------------------
1299  def Tm = symmetricBasis(M, k, S); setring Tm;
1300  ideal Imk = symBasis;
1301  export Imk;
1302  dbprint(p-3, "Temporary Image Ring", basering);
1303  dbprint(p, "S^k(Image Basis)", Imk);
1304
1305//------------------------- compute and return S^k(A) in chosen bases --
1306  setring save;
1307
1308  return(mapPower(p, A, k, Tn, Tm));
1309}
1310example
1311{ "EXAMPLE:"; echo = 2;
1312
1313ring r = (0),(a, b, c, d), dp; r;
1314module B = a*gen(1) + c* gen(2), b * gen(1) + d * gen(2); print(B);
1315
1316// symmetric power over a commutative K-algebra:
1317print(symmetricPower(B, 2));
1318print(symmetricPower(B, 3));
1319
1320// symmetric power over an exterior algebra:
1321def g = superCommutative(); setring g; g;
1322
1323module B = a*gen(1) + c* gen(2), b * gen(1) + d * gen(2); print(B);
1324
1325print(symmetricPower(B, 2)); // much smaller!
1326print(symmetricPower(B, 3)); // zero! (over an exterior algebra!)
1327
1328}
1329
1330//////////////////////////////////////////////////////////////////////////////
1331
1332proc exteriorPower(module A, int k)
1333"USAGE:    exteriorPower(A, k); A module, k int
1334RETURN:   module: the k-th exterior power of A
1335NOTE:     the chosen bases and most of intermediate data will be shown if
1336          printlevel is big enough. Last rows will be invisible if zero.
1337SEE ALSO: symmetricPower
1338KEYWORDS: exterior power
1339EXAMPLE:  example exteriorPower; shows an example"
1340{
1341  int p = printlevel - voice + 2;
1342  def save = basering;
1343
1344  int M = nrows(A);
1345  int N = ncols(A);
1346
1347  string S = chooseSafeVarName("@", "@_e");
1348
1349//------------------------- choose source basis -------------------------
1350  def Tn = exteriorBasis(N, k, S); setring Tn;
1351  ideal Ink = extBasis;
1352  export Ink;
1353  dbprint(p-3, "Temporary Source Ring", basering);
1354  dbprint(p, "E^k(Source Basis)", Ink);
1355
1356//------------------------- choose image basis -------------------------
1357  def Tm = exteriorBasis(M, k, S); setring Tm;
1358  ideal Imk = extBasis;
1359  export Imk;
1360  dbprint(p-3, "Temporary Image Ring", basering);
1361  dbprint(p, "E^k(Image Basis)", Imk);
1362
1363//------------------------- compute and return E^k(A) in chosen bases --
1364  setring save;
1365  return(mapPower(p, A, k, Tn, Tm));
1366}
1367example
1368{ "EXAMPLE:"; echo = 2;
1369  ring r = (0),(a, b, c, d, e, f), dp;
1370  r; "base ring:";
1371
1372  module B = a*gen(1) + c*gen(2) + e*gen(3),
1373             b*gen(1) + d*gen(2) + f*gen(3),
1374                        e*gen(1) + f*gen(3);
1375
1376  print(B);
1377  print(exteriorPower(B, 2));
1378  print(exteriorPower(B, 3));
1379
1380  def g = superCommutative(); setring g; g;
1381
1382  module A = a*gen(1), b * gen(1), c*gen(2), d * gen(2);
1383  print(A);
1384
1385  print(exteriorPower(A, 2));
1386
1387  module B = a*gen(1) + c*gen(2) + e*gen(3),
1388             b*gen(1) + d*gen(2) + f*gen(3),
1389                        e*gen(1) + f*gen(3);
1390  print(B);
1391
1392  print(exteriorPower(B, 2));
1393  print(exteriorPower(B, 3));
1394
1395}
1396
1397//////////////////////////////////////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.