source: git/Singular/LIB/matrix.lib @ 6d37e8

spielwiese
Last change on this file since 6d37e8 was 717885, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes: syntax fixed git-svn-id: file:///usr/local/Singular/svn/trunk@5093 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 27.6 KB
Line 
1// GMG/BM, last modified: 8.10.98
2///////////////////////////////////////////////////////////////////////////////
3version="$Id: matrix.lib,v 1.26 2001-01-18 09:32:27 Singular Exp $";
4category="Linear Algebra";
5info="
6LIBRARY:  matrix.lib    Elementary Matrix Operations
7
8PROCEDURES:
9 compress(A);           matrix, zero columns from A deleted
10 concat(A1,A2,..);      matrix, concatenation of matrices A1,A2,...
11 diag(p,n);             matrix, nxn diagonal matrix with entries poly p
12 dsum(A1,A2,..);        matrix, direct sum of matrices A1,A2,...
13 flatten(A);            ideal, generated by entries of matrix A
14 genericmat(n,m[,id]);  generic nxm matrix [entries from id]
15 is_complex(c);         1 if list c is a complex, 0 if not
16 outer(A,B);            matrix, outer product of matrices A and B
17 power(A,n);            matrix/intmat, n-th power of matrix/intmat A
18 skewmat(n[,id]);       generic skew-symmetric nxn matrix [entries from id]
19 submat(A,r,c);         submatrix of A with rows/cols specified by intvec r/c
20 symmat(n[,id]);        generic symmetric nxn matrix [entries from id]
21 tensor(A,B);           matrix, tensor product of matrices A nd B
22 unitmat(n);            unit square matrix of size n
23 gauss_col(A);          transform a matrix into col-reduced Gauss normal form
24 gauss_row(A);          transform a matrix into row-reduced Gauss normal form
25 addcol(A,c1,p,c2);     add p*(c1-th col) to c2-th column of matrix A, p poly
26 addrow(A,r1,p,r2);     add p*(r1-th row) to r2-th row of matrix A, p poly
27 multcol(A,c,p);        multiply c-th column of A with poly p
28 multrow(A,r,p);        multiply r-th row of A with poly p
29 permcol(A,i,j);        permute i-th and j-th columns
30 permrow(A,i,j);        permute i-th and j-th rows
31 rowred(A[,any]);       reduction of matrix A with elementary row-operations
32 colred(A[,any]);       reduction of matrix A with elementary col-operations
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          (parameters in square brackets [] are optional)
36";
37
38LIB "inout.lib";
39LIB "ring.lib";
40LIB "random.lib";
41///////////////////////////////////////////////////////////////////////////////
42
43proc compress (A)
44"USAGE:   compress(A); A matrix/ideal/module/intmat/intvec
45RETURN:  same type, zero columns/generators from A deleted
46         (if A=intvec, zero elements are deleted)
47EXAMPLE: example compress; shows an example
48"
49{
50   if( typeof(A)=="matrix" ) { return(matrix(simplify(A,2))); }
51   if( typeof(A)=="intmat" or typeof(A)=="intvec" )
52   {
53      ring r=0,x,lp;
54      if( typeof(A)=="intvec" ) { intmat C=transpose(A); kill A; intmat A=C; }
55      module m = matrix(A);
56      if ( size(m) == 0)
57      { intmat B; }
58      else
59      { intmat B[nrows(A)][size(m)]; }
60      int i,j;
61      for( i=1; i<=ncols(A); i=i+1 )
62      {
63         if( m[i]!=[0] )
64         {
65            j=j+1;
66            B[1..nrows(A),j]=A[1..nrows(A),i];
67         }
68      }
69      if( defined(C) ) { return(intvec(B)); }
70      return(B);
71    }
72   return(simplify(A,2));
73}
74example
75{ "EXAMPLE:"; echo = 2;
76   ring r=0,(x,y,z),ds;
77   matrix A[3][4]=1,0,3,0,x,0,z,0,x2,0,z2,0;
78   print(A);
79   print(compress(A));
80   module m=module(A); show(m);
81   show(compress(m));
82   intmat B[3][4]=1,0,3,0,4,0,5,0,6,0,7,0;
83   compress(B);
84   intvec C=0,0,1,2,0,3;
85   compress(C);
86}
87///////////////////////////////////////////////////////////////////////////////
88proc concat (list #)
89"USAGE:   concat(A1,A2,..); A1,A2,... matrices
90RETURN:  matrix, concatenation of A1,A2,.... Number of rows of result matrix
91         is max(nrows(A1),nrows(A2),...)
92EXAMPLE: example concat; shows an example
93"
94{
95   int i;
96   module B=module(#[1]);
97   for( i=2; i<=size(#); i=i+1 ) { B=B,module(#[i]); }
98   return(matrix(B));
99}
100example
101{ "EXAMPLE:"; echo = 2;
102   ring r=0,(x,y,z),ds;
103   matrix A[3][3]=1,2,3,x,y,z,x2,y2,z2;
104   matrix B[2][2]=1,0,2,0; matrix C[1][4]=4,5,x,y;
105   print(A);
106   print(B);
107   print(C);
108   print(concat(A,B,C));
109}
110///////////////////////////////////////////////////////////////////////////////
111
112proc diag (list #)
113"USAGE:   diag(p,n); p poly, n integer
114         diag(A);   A matrix
115RETURN:  diag(p,n): diagonal matrix, p times unitmatrix of size n.
116@*       diag(A)  : n*m x n*m diagonal matrix with entries all the entries of
117                    the nxm matrix A, taken from the 1st row, 2nd row etc of A
118EXAMPLE: example diag; shows an example
119"
120{
121   if( size(#)==2 ) { return(matrix(#[1]*freemodule(#[2]))); }
122   if( size(#)==1 )
123   {
124      int i; ideal id=#[1];
125      int n=ncols(id); matrix A[n][n];
126      for( i=1; i<=n; i=i+1 ) { A[i,i]=id[i]; }
127   }
128   return(A);
129}
130example
131{ "EXAMPLE:"; echo = 2;
132   ring r = 0,(x,y,z),ds;
133   print(diag(xy,4));
134   matrix A[3][2] = 1,2,3,4,5,6;
135   print(A);
136   print(diag(A));
137}
138///////////////////////////////////////////////////////////////////////////////
139
140proc dsum (list #)
141"USAGE:   dsum(A1,A2,..); A1,A2,... matrices
142RETURN:  matrix, direct sum of A1,A2,...
143EXAMPLE: example dsum; shows an example
144"
145{
146   int i,N,a;
147   list L;
148   for( i=1; i<=size(#); i=i+1 ) { N=N+nrows(#[i]); }
149   for( i=1; i<=size(#); i=i+1 )
150   {
151      matrix B[N][ncols(#[i])];
152      B[a+1..a+nrows(#[i]),1..ncols(#[i])]=#[i];
153      a=a+nrows(#[i]);
154      L[i]=B; kill B;
155   }
156   return(concat(L));
157}
158example
159{ "EXAMPLE:"; echo = 2;
160   ring r = 0,(x,y,z),ds;
161   matrix A[3][3] = 1,2,3,4,5,6,7,8,9;
162   matrix B[2][2] = 1,x,y,z;
163   print(A);
164   print(B);
165   print(dsum(A,B));
166}
167///////////////////////////////////////////////////////////////////////////////
168
169proc flatten (matrix A)
170"USAGE:   flatten(A); A matrix
171RETURN:  ideal, generated by all entries from A
172EXAMPLE: example flatten; shows an example
173"
174{
175   return(ideal(A));
176}
177example
178{ "EXAMPLE:"; echo = 2;
179   ring r = 0,(x,y,z),ds;
180   matrix A[2][3] = 1,2,x,y,z,7;
181   print(A);
182   flatten(A);
183}
184///////////////////////////////////////////////////////////////////////////////
185
186proc genericmat (int n,int m,list #)
187"USAGE:   genericmat(n,m[,id]);  n,m=integers, id=ideal
188RETURN:  nxm matrix, with entries from id.
189NOTE:    if id has less than nxm elements, the matrix is filled with 0's,
190         (default: id=maxideal(1)).
191         genericmat(n,m); creates the generic nxm matrix
192EXAMPLE: example genericmat; shows an example
193"
194{
195   if( size(#)==0 ) { ideal id=maxideal(1); }
196   if( size(#)==1 ) { ideal id=#[1]; }
197   if( size(#)>=2 ) { "// give 3 arguments, 3-rd argument must be an ideal"; }
198   matrix B[n][m]=id;
199   return(B);
200}
201example
202{ "EXAMPLE:"; echo = 2;
203   ring R = 0,x(1..16),lp;
204   print(genericmat(3,3));      // the generic 3x3 matrix
205   ring R1 = 0,(a,b,c,d),dp;
206   matrix A = genericmat(3,4,maxideal(1)^3);
207   print(A);
208   int n,m = 3,2;
209   ideal i = ideal(randommat(1,n*m,maxideal(1),9));
210   print(genericmat(n,m,i));    // matrix of generic linear forms
211}
212///////////////////////////////////////////////////////////////////////////////
213
214proc is_complex (list c)
215"USAGE:   is_complex(c); c = list of size-compatible modules or matrices
216RETURN:  1 if c[i]*c[i+1]=0 for all i, 0 if not, hence checking whether the
217         list of matrices forms a complex.
218NOTE:    Ideals are treated internally as 1-line matrices.
219         If printlevel > 0, the position where c is not a complex is shown.
220EXAMPLE: example is_complex; shows an example
221"
222{
223   int i;
224   module @test;
225   for( i=1; i<=size(c)-1; i=i+1 )
226   {
227      c[i]=matrix(c[i]); c[i+1]=matrix(c[i+1]);
228      @test=c[i]*c[i+1];
229      if (size(@test)!=0)
230      {
231        dbprint(printlevel-voice+2,"// not a complex at position " +string(i));
232         return(0);
233      }
234   }
235   return(1);
236}
237example
238{ "EXAMPLE:";   echo = 2;
239   ring r  = 32003,(x,y,z),ds;
240   ideal i = x4+y5+z6,xyz,yx2+xz2+zy7;
241   list L  = nres(i,0);
242   is_complex(L);
243   L[4]    = matrix(i);
244   is_complex(L);
245}
246///////////////////////////////////////////////////////////////////////////////
247
248proc outer (matrix A, matrix B)
249"USAGE:   outer(A,B); A,B matrices
250RETURN:  matrix, outer (tensor) product of A and B
251EXAMPLE: example outer; shows an example
252"
253{
254   int i,j; list L;
255   int triv = nrows(B)*ncols(B);
256   if( triv==1 )
257   {
258     return(B[1,1]*A);
259   }
260   else
261   {
262     int N = nrows(A)*nrows(B);
263     matrix C[N][ncols(B)];
264     for( i=1; i<=ncols(A); i=i+1 )
265     {
266       for( j=1; j<=nrows(A); j=j+1 )
267       {
268          C[(j-1)*nrows(B)+1..j*nrows(B),1..ncols(B)]=A[j,i]*B;
269       }
270       L[i]=C;
271     }
272     return(concat(L));
273   }
274}
275example
276{ "EXAMPLE:"; echo = 2;
277   ring r=32003,(x,y,z),ds;
278   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
279   matrix B[2][2]=x,y,0,z;
280   print(A);
281   print(B);
282   print(outer(A,B));
283}
284///////////////////////////////////////////////////////////////////////////////
285
286proc power ( A, int n)
287"USAGE:   power(A,n);  A a square-matrix of type intmat or matrix, n=integer
288RETURN:  intmat resp. matrix, the n-th power of A
289NOTE:    for A=intmat and big n the result may be wrong because of int overflow
290EXAMPLE: example power; shows an example
291"
292{
293//---------------------------- type checking ----------------------------------
294   if( typeof(A)!="matrix" and typeof(A)!="intmat" )
295   {
296      "// no matrix or intmat!";
297      return (A);
298   }
299   if( ncols(A) != nrows(A) )
300   {
301      "// not a suare matrix!";
302      return();
303   }
304//---------------------------- trivial cases ----------------------------------
305   int ii;
306   if( n <= 0 )
307   {
308      if( typeof(A)=="matrix" )
309      {
310         return (unitmat(nrows(A)));
311      }
312      if( typeof(A)=="intmat" )
313      {
314         intmat B[nrows(A)][nrows(A)];
315         for( ii=1; ii<=nrows(A); ii++ )
316         {
317            B[ii,ii] = 1;
318         }
319         return (B);
320      }
321   }
322   if( n == 1 ) { return (A); }
323//---------------------------- sub procedure ----------------------------------
324   proc matpow (A, int n)
325   {
326      def B = A*A;
327      int ii= 2;
328      int jj= 4;
329      while( jj <= n )
330      {
331         B=B*B;
332         ii=jj;
333         jj=2*jj;
334      }
335      return(B,n-ii);
336   }
337//----------------------------- main program ----------------------------------
338   list L = matpow(A,n);
339   def B  = L[1];
340   ii     = L[2];
341   while( ii>=2 )
342   {
343      L = matpow(A,ii);
344      B = B*L[1];
345      ii= L[2];
346   }
347   if( ii == 0) { return(B); }
348   if( ii == 1) { return(A*B); }
349}
350example
351{ "EXAMPLE:"; echo = 2;
352   intmat A[3][3]=1,2,3,4,5,6,7,8,9;
353   print(power(A,3));"";
354   ring r=0,(x,y,z),dp;
355   matrix B[3][3]=0,x,y,z,0,0,y,z,0;
356   print(power(B,3));"";
357}
358///////////////////////////////////////////////////////////////////////////////
359
360proc skewmat (int n, list #)
361"USAGE:   skewmat(n[,id]);  n integer, id ideal
362RETURN:  skew-symmetric nxn matrix, with entries from id
363         (default: id=maxideal(1))
364         kewmat(n); creates the generic skew-symmetric matrix
365NOTE:    if id has less than n*(n-1)/2 elements, the matrix is
366         filled with 0's,
367EXAMPLE: example skewmat; shows an example
368"
369{
370   matrix B[n][n];
371   if( size(#)==0 ) { ideal id=maxideal(1); }
372   else { ideal id=#[1]; }
373   id = id,B[1..n,1..n];
374   int i,j;
375   for( i=0; i<=n-2; i=i+1 )
376   {
377      B[i+1,i+2..n]=id[j+1..j+n-i-1];
378      j=j+n-i-1;
379   }
380   matrix A=transpose(B);
381   B=B-A;
382   return(B);
383}
384example
385{ "EXAMPLE:"; echo = 2;
386   ring R=0,x(1..5),lp;
387   print(skewmat(4));    // the generic skew-symmetric matrix
388   ring R1 = 0,(a,b,c),dp;
389   matrix A=skewmat(4,maxideal(1)^2);
390   print(A);
391   int n=3;
392   ideal i = ideal(randommat(1,n*(n-1) div 2,maxideal(1),9));
393   print(skewmat(n,i));  // skew matrix of generic linear forms
394   kill R1;
395}
396///////////////////////////////////////////////////////////////////////////////
397
398proc submat (matrix A, intvec r, intvec c)
399"USAGE:   submat(A,r,c);  A=matrix, r,c=intvec
400RETURN:  matrix, submatrix of A with rows specified by intvec r
401         and columns specified by intvec c.
402EXAMPLE: example submat; shows an example
403"
404{
405   matrix B[size(r)][size(c)]=A[r,c];
406   return(B);
407}
408example
409{ "EXAMPLE:"; echo = 2;
410   ring R=32003,(x,y,z),lp;
411   matrix A[4][4]=x,y,z,0,1,2,3,4,5,6,7,8,9,x2,y2,z2;
412   print(A);
413   intvec v=1,3,4;
414   matrix B=submat(A,v,1..3);
415   print(B);
416}
417///////////////////////////////////////////////////////////////////////////////
418
419proc symmat (int n, list #)
420"USAGE:   symmat(n[,id]);  n integer, id ideal
421RETURN:  symmetric nxn matrix, with entries from id (default: id=maxideal(1))
422NOTE:    if id has less than n*(n+1)/2 elements, the matrix is filled with 0's,
423         symmat(n); creates the generic symmetric matrix
424EXAMPLE: example symmat; shows an example
425"
426{
427   matrix B[n][n];
428   if( size(#)==0 ) { ideal id=maxideal(1); }
429   else { ideal id=#[1]; }
430   id = id,B[1..n,1..n];
431   int i,j;
432   for( i=0; i<=n-1; i=i+1 )
433   {
434      B[i+1,i+1..n]=id[j+1..j+n-i];
435      j=j+n-i;
436   }
437   matrix A=transpose(B);
438   for( i=1; i<=n; i=i+1 ) {  A[i,i]=0; }
439   B=A+B;
440   return(B);
441}
442example
443{ "EXAMPLE:"; echo = 2;
444   ring R=0,x(1..10),lp;
445   print(symmat(4));    // the generic symmetric matrix
446   ring R1 = 0,(a,b,c),dp;
447   matrix A=symmat(4,maxideal(1)^3);
448   print(A);
449   int n=3;
450   ideal i = ideal(randommat(1,n*(n+1) div 2,maxideal(1),9));
451   print(symmat(n,i));  // symmetric matrix of generic linear forms
452   kill R1;
453}
454///////////////////////////////////////////////////////////////////////////////
455
456proc tensor (matrix A, matrix B)
457"USAGE:   tensor(A,B); A,B matrices
458RETURN:  matrix, tensor product of A and B
459EXAMPLE: example tensor; shows an example
460"
461{
462   int i,j;
463   matrix C,D;
464   for( i=1; i<=nrows(A); i++ )
465   {
466     C = A[i,1]*B;
467     for( j=2; j<=ncols(A); j++ )
468     {
469       C = concat(C,A[i,j]*B);
470     }
471     D = concat(D,transpose(C));
472   }
473   D = transpose(D);
474   return(submat(D,2..nrows(D),1..ncols(D)));
475}
476example
477{ "EXAMPLE:"; echo = 2;
478   ring r=32003,(x,y,z),(c,ds);
479   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
480   matrix B[2][2]=x,y,0,z;
481   print(A);
482   print(B);
483   print(tensor(A,B));
484}
485///////////////////////////////////////////////////////////////////////////////
486
487proc unitmat (int n)
488"USAGE:   unitmat(n);  n integer >= 0
489RETURN:  nxn unit matrix
490NOTE:    needs a basering, diagonal entries are numbers (=1) in the basering
491EXAMPLE: example unitmat; shows an example
492"
493{
494   return(matrix(freemodule(n)));
495}
496example
497{ "EXAMPLE:"; echo = 2;
498   ring r=32003,(x,y,z),lp;
499   print(xyz*unitmat(4));
500   print(unitmat(5));
501}
502///////////////////////////////////////////////////////////////////////////////
503
504proc gauss_col (matrix A, list #)
505"USAGE:   gauss_col(A[,e]); A a matrix, e any type
506RETURN:  - a matrix B, if called with one argument; B is the complete column-
507           reduced upper-triangular normal form of A if A is constant,
508           (resp. as far as this is possible if A is a polynomial matrix;
509           no division by polynomials).
510@*       - a list L of two matrices, if called with two arguments;
511           L satisfies L[1] = A * L[2] with L[1] the column-reduced form of A
512           and L[2] the transformation matrix.
513NOTE:    * The procedure just applies interred to A with ordering (C,dp).
514           The transformation matrix is obtained by applying 'lift'.
515           This should be faster than the procedure colred.
516@*       * It should only be used with exact coefficient field (there is no
517           pivoting and rounding error treatment).
518@*       * Parameters are allowed. Hence, if the entries of A are parameters,
519           B is the column-reduced form of A over the rational function field.
520SEE ALSO:  colred
521EXAMPLE: example gauss_col; shows an example
522"
523{
524   def R=basering; int u;
525   string mp = string(minpoly);
526   int n = nrows(A);
527   int m = ncols(A);
528   module M = A;
529   intvec v = option(get);
530//------------------------ change ordering if necessary ----------------------
531   if( ordstr(R) != ("C,dp("+string(nvars(R))+")") )
532   {
533     changeord("@R","C,dp",R); u=1;
534     execute("minpoly="+mp+";");
535     matrix A = imap(R,A);
536     module M = A;
537   }
538//------------------------------ start computation ---------------------------
539   option(redSB);
540   M = simplify(interred(M),1);
541   if(size(#) != 0)
542   {
543      module N = lift(A,M);
544   }
545//--------------- reset ring and options and return --------------------------
546   if ( u==1 )
547   {
548      setring R;
549      M=imap(@R,M);
550      if (size(#) != 0)
551      {
552         module N = imap(@R,N);
553      }
554      kill @R;
555   }
556   option(set,v);
557   // M = sort(M,size(M)..1)[1];
558   A = matrix(M,n,m);
559   if (size(#) != 0)
560   {
561     list L= A,matrix(N,m,m);
562     return(L);
563   }
564   return(matrix(M,n,m));
565}
566example
567{ "EXAMPLE:"; echo = 2;
568   ring r=(0,a,b),(A,B,C),dp;
569   matrix m[8][6]=
570   0,    2*C, 0,    0,  0,   0,
571   0,    -4*C,a*A,  0,  0,   0,
572   b*B,  -A,  0,    0,  0,   0,
573   -A,   B,   0,    0,  0,   0,
574   -4*C, 0,   B,    2,  0,   0,
575   2*A,  B,   0,    0,  0,   0,
576   0,    3*B, 0,    0,  2b,  0,
577   0,    AB,  0,    2*A,A,   2a;"";
578   list L=gauss_col(m,1);
579   print(L[1]);
580   print(L[2]);
581
582   ring S=0,x,(c,dp);
583   matrix A[5][4] =
584    3, 1, 1, 1,
585   13, 8, 6,-7,
586   14,10, 6,-7,
587    7, 4, 3,-3,
588    2, 1, 0, 3;
589   print(gauss_col(A));
590}
591///////////////////////////////////////////////////////////////////////////////
592
593proc gauss_row (matrix A, list #)
594"USAGE:  gauss_row(A [,e]); A matrix, e any type
595RETURN: - a matrix B, if called with one argument; B is the complete row-
596          reduced lower-triangular normal form of A if A is constant,
597          (resp. as far as this is possible if A is a polynomial matrix;
598          no division by polynomials).
599@*      - a list L of two matrices, if called with two arguments;
600          L satidfies L[1] = L[2] * A with L[1] the row-reduced form of A
601          and L[2] the transformation matrix.
602NOTE:   * This procedure just applies gauss_col to the transposed matrix.
603          The transformation matrix is obtained by applying lift.
604          This should be faster than the procedure rowred.
605@*      * It should only be used with exact coefficient field (there is no
606          pivoting and rounding error treatment).
607@*      * Parameters are allowed. Hence, if the entries of A are parameters,
608          B is the row-reduced form of A over the rational function field.
609SEE ALSO: rowred
610EXAMPLE: example gauss_row; shows an example
611"
612{
613   if(size(#) > 0)
614   {
615     list L = gauss_col(transpose(A),1);
616     return(L);
617   }
618   A = gauss_col(transpose(A));
619   return(transpose(A));
620}
621example
622{ "EXAMPLE:"; echo = 2;
623   ring r=(0,a,b),(A,B,C),dp;
624   matrix m[6][8]=
625   0, 0,  b*B, -A,-4C,2A,0, 0,
626   2C,-4C,-A,B, 0,  B, 3B,AB,
627   0,a*A,  0, 0, B,  0, 0, 0,
628   0, 0,  0, 0, 2,  0, 0, 2A,
629   0, 0,  0, 0, 0,  0, 2b, A,
630   0, 0,  0, 0, 0,  0, 0, 2a;"";
631   print(gauss_row(m));"";
632   ring S=0,x,dp;
633   matrix A[4][5] =  3, 1,1,-1,2,
634                    13, 8,6,-7,1,
635                    14,10,6,-7,1,
636                     7, 4,3,-3,3;
637   list L=gauss_row(A,1);
638   print(L[1]);
639   print(L[2]);
640}
641///////////////////////////////////////////////////////////////////////////////
642
643proc addcol (matrix A, int c1, poly p, int c2)
644"USAGE:   addcol(A,c1,p,c2);  A matrix, p poly, c1, c2 positive integers
645RETURN:  matrix,  A being modified by adding p times column c1 to column c2
646EXAMPLE: example addcol; shows an example
647"
648{
649   A[1..nrows(A),c2]=A[1..nrows(A),c2]+p*A[1..nrows(A),c1];
650   return(A);
651}
652example
653{ "EXAMPLE:"; echo = 2;
654   ring r=32003,(x,y,z),lp;
655   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
656   print(A);
657   print(addcol(A,1,xy,2));
658}
659///////////////////////////////////////////////////////////////////////////////
660
661proc addrow (matrix A, int r1, poly p, int r2)
662"USAGE:   addcol(A,r1,p,r2);  A matrix, p poly, r1, r2 positive integers
663RETURN:  matrix,  A being modified by adding p times row r1 to row r2
664EXAMPLE: example addrow; shows an example
665"
666{
667   A[r2,1..ncols(A)]=A[r2,1..ncols(A)]+p*A[r1,1..ncols(A)];
668   return(A);
669}
670example
671{ "EXAMPLE:"; echo = 2;
672   ring r=32003,(x,y,z),lp;
673   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
674   print(A);
675   print(addrow(A,1,xy,3));
676}
677///////////////////////////////////////////////////////////////////////////////
678
679proc multcol (matrix A, int c, poly p)
680"USAGE:   addcol(A,c,p);  A matrix, p poly, c positive integer
681RETURN:  matrix,  A being modified by multiplying column c with p
682EXAMPLE: example multcol; shows an example
683"
684{
685   A[1..nrows(A),c]=p*A[1..nrows(A),c];
686   return(A);
687}
688example
689{ "EXAMPLE:"; echo = 2;
690   ring r=32003,(x,y,z),lp;
691   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
692   print(A);
693   print(multcol(A,2,xy));
694}
695///////////////////////////////////////////////////////////////////////////////
696
697proc multrow (matrix A, int r, poly p)
698"USAGE:   multrow(A,r,p);  A matrix, p poly, r positive integer
699RETURN:  matrix,  A being modified by multiplying row r with p
700EXAMPLE: example multrow; shows an example
701"
702{
703   A[r,1..ncols(A)]=p*A[r,1..ncols(A)];
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(multrow(A,2,xy));
712}
713///////////////////////////////////////////////////////////////////////////////
714
715proc permcol (matrix A, int c1, int c2)
716"USAGE:   permcol(A,c1,c2);  A matrix, c1,c2 positive integers
717RETURN:  matrix,  A being modified by permuting column c1 and c2
718EXAMPLE: example permcol; shows an example
719"
720{
721   matrix B=A;
722   B[1..nrows(B),c1]=A[1..nrows(A),c2];
723   B[1..nrows(B),c2]=A[1..nrows(A),c1];
724   return(B);
725}
726example
727{ "EXAMPLE:"; echo = 2;
728   ring r=32003,(x,y,z),lp;
729   matrix A[3][3]=1,x,3,4,y,6,7,z,9;
730   print(A);
731   print(permcol(A,2,3));
732}
733///////////////////////////////////////////////////////////////////////////////
734
735proc permrow (matrix A, int r1, int r2)
736"USAGE:   permrow(A,r1,r2);  A matrix, r1,r2 positive integers
737RETURN:  matrix,  A being modified by permuting row r1 and r2
738EXAMPLE: example permrow; shows an example
739"
740{
741   matrix B=A;
742   B[r1,1..ncols(B)]=A[r2,1..ncols(A)];
743   B[r2,1..ncols(B)]=A[r1,1..ncols(A)];
744   return(B);
745}
746example
747{ "EXAMPLE:"; echo = 2;
748   ring r=32003,(x,y,z),lp;
749   matrix A[3][3]=1,2,3,x,y,z,7,8,9;
750   print(A);
751   print(permrow(A,2,1));
752}
753///////////////////////////////////////////////////////////////////////////////
754
755proc rowred (matrix A,list #)
756"USAGE:   rowred(A[,e]);  A matrix, e any type
757RETURN:  - a matrix B, being the row reduced form of A, if rowred is called
758           with one argument.
759           (as far as this is possible over the polynomial ring; no division
760           by polynomials)
761@*       - a list L of two matrices, such that L[1] = L[2] * A with L[1]
762           the row-reduced form of A and L[2] the transformation matrix
763           (if rowred is called with two arguments).
764NOTE:    * This procedure is designed for teaching purposes mainly.
765@*       * The straight forward Gaussian algorithm is implemented in the
766           library (no standard basis computation).
767           The transformation matrix is obtained by concatenating a unit
768           matrix to A. proc gauss_row should be faster.
769@*       * It should only be used with exact coefficient field (there is no
770           pivoting) over the polynomial ring (ordering lp or dp).
771@*       * Parameters are allowed. Hence, if the entries of A are parameters
772           the computation takes place over the field of rational functions.
773SEE ALSO:  gauss_row
774EXAMPLE: example rowred; shows an example
775"
776{
777   int m,n=nrows(A),ncols(A);
778   int i,j,k,l,rk;
779   poly p;
780   matrix d[m][n];
781   for (i=1;i<=m;i=i+1)
782   {  for (j=1;j<=n;j=j+1)
783      {  p = A[i,j];
784         if (ord(p)==0)
785         {  if (deg(p)==0) { d[i,j]=p; }
786         }
787      }
788   }
789   matrix b = A;
790   if (size(#) != 0) { b = concat(b,unitmat(m)); }
791      for (l=1;l<=n;l=l+1)
792   {
793      k  = findfirst(ideal(d[l]),rk+1);
794      if (k)
795      {  rk = rk+1;
796         b  = permrow(b,rk,k);
797         p  = b[rk,l];         p = 1/p;
798         b  = multrow(b,rk,p);
799         for (i=1;i<=m;i=i+1)
800         {
801            if (rk-i) { b = addrow(b,rk,-b[i,l],i);}
802         }
803         d = 0;
804         for (i=rk+1;i<=m;i=i+1)
805         {  for (j=l+1;j<=n;j=j+1)
806            {  p = b[i,j];
807               if (ord(p)==0)
808               {  if (deg(p)==0) { d[i,j]=p; }
809               }
810            }
811         }
812
813      }
814   }
815   d = submat(b,1..m,1..n);
816   if (size(#))
817   {
818      list L=d,submat(b,1..m,n+1..n+m);
819      return(L);
820   }
821   return(d);
822}
823example
824{ "EXAMPLE:"; echo = 2;
825   ring r=(0,a,b),(A,B,C),dp;
826   matrix m[6][8]=
827   0, 0,  b*B, -A,-4C,2A,0, 0,
828   2C,-4C,-A,B, 0,  B, 3B,AB,
829   0,a*A,  0, 0, B,  0, 0, 0,
830   0, 0,  0, 0, 2,  0, 0, 2A,
831   0, 0,  0, 0, 0,  0, 2b, A,
832   0, 0,  0, 0, 0,  0, 0, 2a;"";
833   print(rowred(m));"";
834   list L=rowred(m,1);
835   print(L[1]);
836   print(L[2]);
837}
838///////////////////////////////////////////////////////////////////////////////
839
840proc colred (matrix A,list #)
841"USAGE:   colred(A[,e]);  A matrix, e any type
842RETURN:  - a matrix B, being the column reduced form of A, if colred is
843           called with one argument.
844           (as far as this is possible over the polynomial ring;
845           no division by polynomials)
846@*       - a list L of two matrices, such that L[1] = A * L[2] with L[1]
847           the column-reduced form of A and L[2] the transformation matrix
848           (if colred is called with two arguments).
849NOTE:    * This procedure is designed for teaching purposes mainly.
850@*       * It applies rowred to the transposed matrix.
851           proc gauss_col should be faster.
852@*       * It should only be used with exact coefficient field (there is no
853           pivoting) over the polynomial ring (ordering lp or dp).
854@*       * Parameters are allowed. Hence, if the entries of A are parameters
855           the computation takes place over the field of rational functions.
856SEE ALSO:  gauss_col
857EXAMPLE: example colred; shows an example
858"
859{
860   A = transpose(A);
861   if (size(#))
862   { list L = rowred(A,1); return(transpose(L[1]),transpose(L[2]));}
863   else
864   { return(transpose(rowred(A)));}
865}
866example
867{ "EXAMPLE:"; echo = 2;
868   ring r=(0,a,b),(A,B,C),dp;
869   matrix m[8][6]=
870   0,    2*C, 0,    0,  0,   0,
871   0,    -4*C,a*A,  0,  0,   0,
872   b*B,  -A,  0,    0,  0,   0,
873   -A,   B,   0,    0,  0,   0,
874   -4*C, 0,   B,    2,  0,   0,
875   2*A,  B,   0,    0,  0,   0,
876   0,    3*B, 0,    0,  2b,  0,
877   0,    AB,  0,    2*A,A,   2a;"";
878   print(colred(m));"";
879   list L=colred(m,1);
880   print(L[1]);
881   print(L[2]);
882}
883//////////////////////////////////////////////////////////////////////////////
884
885static proc findfirst (ideal i,int t)
886{
887   int n,k;
888   for (n=t;n<=ncols(i);n=n+1)
889   {
890      if (i[n]!=0) { k=n;break;}
891   }
892   return(k);
893}
894//////////////////////////////////////////////////////////////////////////////
895
896proc rm_unitcol(matrix A)
897"USAGE:   rm_unitcol(A); A matrix (being row-reduced)
898RETURN:  matrix, obtained from A by deleting unit columns (having just one 1
899         and else 0 as entries) and associated rows
900EXAMPLE: example rm_unitcol; shows an example
901"
902{
903 int l,j;
904 intvec v;
905 for (j=1;j<=ncols(A);j=j+1)
906 {
907    if (gen(l+1)==module(A)[j]) {l=l+1;}
908    else { v=v,j;}
909 }
910 if (size(v)>1)
911    {  v = v[2..size(v)];
912       return(submat(A,l+1..nrows(A),v));
913    }
914 else
915    { return(0);}
916}
917example
918{ "EXAMPLE:"; echo = 2;
919   ring r=0,(A,B,C),dp;
920   matrix m[6][8]=
921   0,  0,    A,   0, 1,0,  0,0,
922   0,  0,  -C2,   0, 0,0,  1,0,
923   0,  0,    0,1/2B, 0,0,  0,1,
924   0,  0,    B,  -A, 0,2A, 0,0,
925   2C,-4C,  -A,   B, 0,B,  0,0,
926   0,  A,    0,   0, 0,0,  0,0;
927   print(rm_unitcol(m));
928}
929//////////////////////////////////////////////////////////////////////////////
930
931proc rm_unitrow (matrix A)
932"USAGE:   rm_unitrow(A); A matrix (being col-reduced)
933RETURN:  matrix, obtained from A by deleting unit rows (having just one 1
934         and else 0 as entries) and associated columns
935EXAMPLE: example rm_unitrow; shows an example
936"
937{
938 int l,j;
939 intvec v;
940 module M = transpose(A);
941 for (j=1; j <= nrows(A); j=j+1)
942 {
943    if (gen(l+1) == M[j]) { l=l+1; }
944    else { v=v,j; }
945 }
946 if (size(v) > 1)
947    {  v = v[2..size(v)];
948       return(submat(A,v,l+1..ncols(A)));
949    }
950 else
951    { return(0);}
952}
953example
954{ "EXAMPLE:"; echo = 2;
955   ring r=0,(A,B,C),dp;
956   matrix m[8][6]=
957   0,0,  0,   0, 2C, 0,
958   0,0,  0,   0, -4C,A,
959   A,-C2,0,   B, -A, 0,
960   0,0,  1/2B,-A,B,  0,
961   1,0,  0,   0, 0,  0,
962   0,0,  0,   2A,B,  0,
963   0,1,  0,   0, 0,  0,
964   0,0,  1,   0, 0,  0;
965   print(rm_unitrow(m));
966}
967//////////////////////////////////////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.