source: git/Singular/LIB/matrix.lib @ 65784c6

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