source: git/Singular/LIB/linalg.lib @ 6fe9a5

fieker-DuValspielwiese
Last change on this file since 6fe9a5 was 62dc18e, checked in by Hans Schoenemann <hannes@…>, 13 years ago
some format fixes git-svn-id: file:///usr/local/Singular/svn/trunk@13733 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 45.6 KB
RevLine 
[30f140]1//////////////////////////////////////////////////////////////////////////////
[341696]2version="$Id$";
[49998f]3category="Linear Algebra";
[30f140]4info="
[275721f]5LIBRARY:  linalg.lib  Algorithmic Linear Algebra
[6188357]6AUTHORS:  Ivor Saynisch (ivs@math.tu-cottbus.de)
7@*        Mathias Schulze (mschulze@mathematik.uni-kl.de)
[30f140]8
9PROCEDURES:
[a0c62d]10 inverse(A);          matrix, the inverse of A
11 inverse_B(A);        list(matrix Inv,poly p),Inv*A=p*En ( using busadj(A) )
12 inverse_L(A);        list(matrix Inv,poly p),Inv*A=p*En ( using lift )
13 sym_gauss(A);        symmetric gaussian algorithm
14 orthogonalize(A);    Gram-Schmidt orthogonalization
15 diag_test(A);        test whether A can be diagnolized
16 busadj(A);           coefficients of Adj(E*t-A) and coefficients of det(E*t-A)
17 charpoly(A,v);       characteristic polynomial of A ( using busadj(A) )
18 adjoint(A);          adjoint of A ( using busadj(A) )
19 det_B(A);            determinant of A ( using busadj(A) )
20 gaussred(A);         gaussian reduction: P*A=U*S, S a row reduced form of A
21 gaussred_pivot(A);   gaussian reduction: P*A=U*S, uses row pivoting
22 gauss_nf(A);         gaussian normal form of A
23 mat_rk(A);           rank of constant matrix A
24 U_D_O(A);            P*A=U*D*O, P,D,U,O=permutaion,diag,lower-,upper-triang
25 pos_def(A,i);        test symmetric matrix for positive definiteness
[e9124e]26 hessenberg(M);       Hessenberg form of M
[7248478]27 eigenvals(M);        eigenvalues with multiplicities of M
[2699a6]28 minipoly(M);         minimal polynomial of M
[cb40b5]29 spnf(sp);            normal form of spectrum sp
30 spprint(sp);         print spectrum sp
[275721f]31 jordan(M);           Jordan data of M
32 jordanbasis(M);      Jordan basis and weight filtration of M
[cb40b5]33 jordanmatrix(jd);    Jordan matrix with Jordan data jd
[275721f]34 jordannf(M);         Jordan normal form of M
[30f140]35";
36
37LIB "matrix.lib";
38LIB "ring.lib";
[6188357]39LIB "elim.lib";
[6d37e8]40LIB "general.lib";
[30f140]41//////////////////////////////////////////////////////////////////////////////
42// help functions
43//////////////////////////////////////////////////////////////////////////////
[6188357]44static proc const_mat(matrix A)
[30f140]45"RETURN:   1 (0) if A is (is not) a constant matrix"
46{
47  int i;
48  int n=ncols(A);
49  def BR=basering;
[daa83b]50  def @R=changeord("dp,c",BR);
51  setring @R;
[30f140]52  matrix A=fetch(BR,A);
53  for(i=1;i<=n;i=i+1){
54    if(deg(lead(A)[i])>=1){
55      //"input is not a constant matrix";
56      kill @R;
57      setring BR;
58      return(0);
59    }
60  }
61  kill @R;
62  setring BR;
[337919]63  return(1);
[30f140]64}
[8942a5]65//////////////////////////////////////////////////////////////////////////////
66static proc red(matrix A,int i,int j)
[30f140]67"USAGE:    red(A,i,j);  A = constant matrix
68          reduces column j with respect to A[i,i] and column i
69          reduces row j with respect to A[i,i] and row i
70RETURN:   matrix
71"
[337919]72{
[30f140]73  module m=module(A);
[337919]74
[30f140]75  if(A[i,i]==0){
76    m[i]=m[i]+m[j];
77    m=module(transpose(matrix(m)));
78    m[i]=m[i]+m[j];
79    m=module(transpose(matrix(m)));
80  }
[337919]81
[30f140]82  A=matrix(m);
83  m[j]=m[j]-(A[i,j]/A[i,i])*m[i];
84  m=module(transpose(matrix(m)));
85  m[j]=m[j]-(A[i,j]/A[i,i])*m[i];
86  m=module(transpose(matrix(m)));
[337919]87
[30f140]88  return(matrix(m));
89}
90
[8942a5]91//////////////////////////////////////////////////////////////////////////////
[2636865]92proc inner_product(vector v1,vector v2)
[30f140]93"RETURN:   inner product <v1,v2> "
94{
95  int k;
[337919]96  if (nrows(v2)>nrows(v1)) { k=nrows(v2); } else { k=nrows(v1); }
[30f140]97  return ((transpose(matrix(v1,k,1))*matrix(v2,k,1))[1,1]);
98}
99
100/////////////////////////////////////////////////////////////////////////////
101// user functions
102/////////////////////////////////////////////////////////////////////////////
103
[6188357]104proc inverse(matrix A, list #)
[963885]105"USAGE:    inverse(A [,opt]);  A a square matrix, opt integer
[337919]106RETURN:
107@format
[963885]108          a matrix:
109          - the inverse matrix of A, if A is invertible;
110          - the 1x1 0-matrix if A is not invertible (in the polynomial ring!).
111          There are the following options:
[337919]112          - opt=0 or not given: heuristically best option from below
[963885]113          - opt=1 : apply std to (transpose(E,A)), ordering (C,dp).
114          - opt=2 : apply interred (transpose(E,A)), ordering (C,dp).
[337919]115          - opt=3 : apply lift(A,E), ordering (C,dp).
[963885]116@end format
117NOTE:     parameters and minpoly are allowed; opt=2 is only correct for
118          matrices with entries in a field
119SEE ALSO: inverse_B, inverse_L
120EXAMPLE:  example inverse; shows an example
121"
[30f140]122{
[963885]123//--------------------------- initialization and check ------------------------
[f0fb366]124   int ii,u,notInvertible,opt;
[337919]125   matrix invA;
[963885]126   int db = printlevel-voice+3;      //used for comments
127   def R=basering;
128   string mp = string(minpoly);
129   int n = nrows(A);
130   module M = A;
131   intvec v = option(get);           //get options to reset it later
132   if ( ncols(A)!=n )
133   {
134     ERROR("// ** no square matrix");
135   }
136//----------------------- choose heurisitically best option ------------------
137// This may change later, depending on improvements of the implemantation
138// at the monent we use if opt=0 or opt not given:
139// opt = 1 (std) for everything
140// opt = 2 (interred) for nothing, NOTE: interred is ok for constant matricea
141// opt = 3 (lift) for nothing
142// NOTE: interred is ok for constant matrices only (Beispiele am Ende der lib)
143   if(size(#) != 0) {opt = #[1];}
144   if(opt == 0)
145   {
146      if(npars(R) == 0)                       //no parameters
147      {
148         if( size(ideal(A-jet(A,0))) == 0 )   //constant matrix
149         {opt = 1;}
150         else
[337919]151         {opt = 1;}
[963885]152      }
153      else {opt = 1;}
154   }
155//------------------------- change ring if necessary -------------------------
156   if( ordstr(R) != "C,dp(nvars(R))" )
157   {
158     u=1;
[daa83b]159     def @R=changeord("C,dp",R);
160     setring @R;
[963885]161     module M = fetch(R,M);
162     execute("minpoly="+mp+";");
163   }
164//----------------------------- opt=3: use lift ------------------------------
165   if( opt==3 )
166   {
167      module D2;
168      D2 = lift(M,freemodule(n));
169      if (size(ideal(D2))==0)
170      {                                               //catch error in lift
171         dbprint(db,"// ** matrix is not invertible");
172         setring R;
173         if (u==1) { kill @R;}
174         return(invA);
175      }
176   }
177//-------------- opt = 1 resp. opt = 2: use std resp. interred --------------
178   if( opt==1 or opt==2 )
179   {
[337919]180      option(redSB);
[963885]181      module B = freemodule(n),M;
182      if(opt == 2)
183      {
184         module D = interred(transpose(B));
185         D = transpose(simplify(D,1));
186      }
187      if(opt == 1)
188      {
[337919]189         module D = std(transpose(B));
[963885]190         D = transpose(simplify(D,1));
191      }
192      module D2 = D[1..n];
193      module D1 = D[n+1..2*n];
194//----------------------- check if matrix is invertible ----------------------
[337919]195      for (ii=1; ii<=n; ii++)
196      {
[963885]197         if ( D1[ii] != gen(ii) )
198         {
[f0fb366]199            notInvertible = 1;
[963885]200            break;
201         }
202      }
203   }
204   option(set,v);
205//------------------ return to basering and return result ---------------------
206   if ( u==1 )
207   {
208      setring R;
209      module D2 = fetch(@R,D2);
210      if( opt==1 or opt==2 )
211      { module D1 = fetch(@R,D1);}
212      kill @R;
213   }
[f0fb366]214   if( notInvertible == 1 )
215   {
216     // The matrix A seems to be non-invertible.
217     // Note that there are examples, where this is not true but only due to
218     // inexact computations in the field of reals or complex numbers:
219     // ring r = complex, x, dp;
220     // The following matrix has non-zero determinante but seems non-invertible:
221     // matrix A[3][3] = 1,i,i,0,1,2,1,0,1+i;
222     // For this example, inverse_B yields the correct answer.
223     // So, let's use this as a workaround whenever we have this situation:
224     list myList = inverse_B(A);
225     matrix Try = inverse_B(A)[1];
226     if (myList[2] == poly(1)) { return (Try); }
227     else
228     {
229       dbprint(db,"// ** matrix is not invertible");
230       return(invA);
231     }
232   }
[963885]233   else { return(matrix(D2)); }     //matrix invertible with inverse D2
[30f140]234
235}
[2636865]236example
237{ "EXAMPLE:"; echo = 2;
[963885]238  ring r=0,(x,y,z),lp;
239  matrix A[3][3]=
240   1,4,3,
241   1,5,7,
242   0,4,17;
243  print(inverse(A));"";
244  matrix B[3][3]=
[337919]245   y+1,  x+y,    y,
246   z,    z+1,    z,
[963885]247   y+z+2,x+y+z+2,y+z+1;
248  print(inverse(B));
249  print(B*inverse(B));
[30f140]250}
251
252//////////////////////////////////////////////////////////////////////////////
253proc sym_gauss(matrix A)
254"USAGE:    sym_gauss(A);  A = symmetric matrix
[979c4c]255RETURN:   matrix, diagonalisation of A with symmetric gauss algorithm
[30f140]256EXAMPLE:  example sym_gauss; shows an example"
257{
[2636865]258  int i,j;
[30f140]259  int n=nrows(A);
260
261  if (ncols(A)!=n){
[6188357]262    "// ** input is not a square matrix";;
[30f140]263    return(A);
[337919]264  }
265
[30f140]266  if(!const_mat(A)){
[6188357]267    "// ** input is not a constant matrix";
[30f140]268    return(A);
269  }
[337919]270
271  if(deg(std(A-transpose(A))[1])!=-1){
[6188357]272    "// ** input is not a symmetric matrix";
[30f140]273    return(A);
274  }
275
[2636865]276  for(i=1; i<n; i++){
277    for(j=i+1; j<=n; j++){
[30f140]278      if(A[i,j]!=0){ A=red(A,i,j); }
279    }
280  }
[337919]281
[30f140]282  return(A);
283}
[2636865]284example
285{"EXAMPLE:"; echo = 2;
286  ring r=0,(x),lp;
287  matrix A[2][2]=1,4,4,15;
288  print(A);
289  print(sym_gauss(A));
[30f140]290}
291
292//////////////////////////////////////////////////////////////////////////////
[337919]293proc orthogonalize(matrix A)
[979c4c]294"USAGE:    orthogonalize(A); A = matrix of constants
[30f140]295RETURN:    matrix, orthogonal basis of the colum space of A
296EXAMPLE:   example orthogonalize; shows an example "
[2636865]297{
298  int i,j;
[30f140]299  int n=ncols(A);
300  poly k;
301
302  if(!const_mat(A)){
[6188357]303    "// ** input is not a constant matrix";
[30f140]304    matrix B;
305    return(B);
[337919]306  }
[30f140]307
308  module B=module(interred(A));
[337919]309
[30f140]310  for(i=1;i<=n;i=i+1) {
311    for(j=1;j<i;j=j+1) {
[2636865]312      k=inner_product(B[j],B[j]);
[6188357]313      if (k==0) { "Error: vector of length zero"; return(matrix(B)); }
[2636865]314      B[i]=B[i]-(inner_product(B[i],B[j])/k)*B[j];
[30f140]315    }
316  }
[337919]317
[30f140]318  return(matrix(B));
319}
[2636865]320example
321{ "EXAMPLE:"; echo = 2;
322  ring r=0,(x),lp;
323  matrix A[4][4]=5,6,12,4,7,3,2,6,12,1,1,2,6,4,2,10;
324  print(A);
325  print(orthogonalize(A));
[30f140]326}
327
328////////////////////////////////////////////////////////////////////////////
329proc diag_test(matrix A)
[337919]330"USAGE:          diag_test(A); A = const square matrix
[979c4c]331RETURN:   int,  1 if A is diagonalizable,@*
332                0 if not@*
333               -1 if no statement is possible, since A does not split.
[6188357]334NOTE:     The test works only for split matrices, i.e if eigenvalues of A
335          are in the ground field.
336          Does not work with parameters (uses factorize,gcd).
[30f140]337EXAMPLE:  example diag_test; shows an example"
338{
[2636865]339  int i,j;
[337919]340  int n     = nrows(A);
[2636865]341  string mp = string(minpoly);
342  string cs = charstr(basering);
[30f140]343  int np=0;
344
[337919]345  if(ncols(A) != n) {
[2636865]346    "// input is not a square matrix";
[30f140]347    return(-1);
[337919]348  }
[30f140]349
350   if(!const_mat(A)){
[2636865]351    "// input is not a constant matrix";
[30f140]352    return(-1);
[337919]353  }
[30f140]354
355  //Parameterring wegen factorize nicht erlaubt
356  for(i=1;i<size(cs);i=i+1){
357    if(cs[i]==","){np=np+1;} //Anzahl der Parameter
358  }
359  if(np>0){
[337919]360        "// rings with parameters not allowed";
361        return(-1);
[30f140]362  }
363
[337919]364  //speichern des aktuellen Rings
[30f140]365  def BR=basering;
366  //setze R[t]
367  execute("ring rt=("+charstr(basering)+"),(@t,"+varstr(basering)+"),lp;");
368  execute("minpoly="+mp+";");
[337919]369  matrix A=imap(BR,A);
[30f140]370
371  intvec z;
372  intvec s;
[337919]373  poly X;         //characteristisches Polynom
[30f140]374  poly dXdt;      //Ableitung von X nach t
[337919]375  ideal g;              //ggT(X,dXdt)
376  poly b;              //Komponente der Busadjunkten-Matrix
[30f140]377  matrix E[n][n]; //Einheitsmatrix
[337919]378
[30f140]379  E=E+1;
380  A=E*@t-A;
381  X=det(A);
382
[337919]383  matrix Xfactors=matrix(factorize(X,1));        //zerfaellt die Matrtix ?
[30f140]384  int nf=ncols(Xfactors);
385
386  for(i=1;i<=nf;i++){
387    if(lead(Xfactors[1,i])>=@t^2){
[6188357]388      //" matrix does not split";
[30f140]389      setring BR;
390      return(-1);
391    }
[337919]392  }
[30f140]393
394  dXdt=diff(X,@t);
395  g=std(ideal(gcd(X,dXdt)));
396
397  //Busadjunkte
[337919]398  z=2..n;
[30f140]399  for(i=1;i<=n;i++){
[337919]400    s=2..n;
[30f140]401    for(j=1;j<=n;j++){
402      b=det(submat(A,z,s));
[337919]403
[30f140]404      if(0!=reduce(b,g)){
[337919]405        //" matrix not diagonalizable";
406        setring BR;
407        return(0);
[30f140]408      }
[337919]409
[30f140]410      s[j]=j;
411    }
412    z[i]=i;
413  }
[337919]414
415  //"Die Matrix ist diagonalisierbar";
[30f140]416  setring BR;
417  return(1);
418}
[2636865]419example
420{ "EXAMPLE:"; echo = 2;
421  ring r=0,(x),dp;
422  matrix A[4][4]=6,0,0,0,0,0,6,0,0,6,0,0,0,0,0,6;
423  print(A);
424  diag_test(A);
[30f140]425}
426
427//////////////////////////////////////////////////////////////////////////////
428proc busadj(matrix A)
[6188357]429"USAGE:   busadj(A);  A = square matrix (of size nxn)
430RETURN:  list L:
[337919]431@format
432         L[1] contains the (n+1) coefficients of the characteristic
[6188357]433              polynomial X of A, i.e.
[2636865]434              X = L[1][1]+..+L[1][k]*t^(k-1)+..+(L[1][n+1])*t^n
435         L[2] contains the n (nxn)-matrices Hk which are the coefficients of
[6188357]436              the busadjoint bA = adjoint(E*t-A) of A, i.e.
[337919]437              bA = (Hn-1)*t^(n-1)+...+Hk*t^k+...+H0,  ( Hk=L[2][k+1] )
[6188357]438@end format
[30f140]439EXAMPLE: example busadj; shows an example"
440{
441  int k;
[2636865]442  int n    = nrows(A);
443  matrix E = unitmat(n);
[30f140]444  matrix H[n][n];
445  matrix B[n][n];
[2636865]446  list bA, X, L;
[30f140]447  poly a;
448
[337919]449  if(ncols(A) != n) {
[30f140]450    "input is not a square matrix";
451    return(L);
[337919]452  }
[30f140]453
[2636865]454  bA   = E;
455  X[1] = 1;
456  for(k=1; k<n; k++){
457    B  = A*bA[1];              //bA[1] is the last H
458    a  = -trace(B)/k;
459    H  = B+a*E;
460    bA = insert(bA,H);
461    X  = insert(X,a);
[30f140]462  }
[2636865]463  B = A*bA[1];
464  a = -trace(B)/n;
465  X = insert(X,a);
[30f140]466
[2636865]467  L = insert(L,bA);
468  L = insert(L,X);
[30f140]469  return(L);
470}
[2636865]471example
472{ "EXAMPLE"; echo = 2;
473  ring r = 0,(t,x),lp;
474  matrix A[2][2] = 1,x2,x,x2+3x;
475  print(A);
476  list L = busadj(A);
477  poly X = L[1][1]+L[1][2]*t+L[1][3]*t2; X;
[337919]478  matrix bA[2][2] = L[2][1]+L[2][2]*t;
[2636865]479  print(bA);               //the busadjoint of A;
[337919]480  print(bA*(t*unitmat(2)-A));
[30f140]481}
482
483//////////////////////////////////////////////////////////////////////////////
[2636865]484proc charpoly(matrix A, list #)
[6188357]485"USAGE:   charpoly(A[,v]); A square matrix, v string, name of a variable
[337919]486RETURN:  poly, the characteristic polynomial det(E*v-A)
[6188357]487         (default: v=name of last variable)
488NOTE:    A must be independent of the variable v. The computation uses det.
489         If printlevel>0, det(E*v-A) is diplayed recursively.
[30f140]490EXAMPLE: example charpoly; shows an example"
[6188357]491{
492  int n = nrows(A);
493  int z = nvars(basering);
494  int i,j;
495  string v;
496  poly X;
497  if(ncols(A) != n)
[337919]498  {
[6188357]499    "// input is not a square matrix";
500    return(X);
[337919]501  }
[6188357]502  //---------------------- test for correct variable -------------------------
[337919]503  if( size(#)==0 ){
504    #[1] = varstr(z);
[6188357]505  }
506  if( typeof(#[1]) == "string") { v = #[1]; }
507  else
508  {
509    "// 2nd argument must be a name of a variable not contained in the matrix";
510    return(X);
[337919]511  }
[6188357]512  j=-1;
513  for(i=1; i<=z; i++)
514  {
515    if(varstr(i)==v){j=i;}
516  }
517  if(j==-1)
518  {
519    "// "+v+" is not a variable in the basering";
520    return(X);
521  }
522  if ( size(select1(module(A),j)) != 0 )
523  {
524    "// matrix must not contain the variable "+v;
525    "// change to a ring with an extra variable, if necessary."
526    return(X);
527  }
528  //-------------------------- compute charpoly ------------------------------
529  X = det(var(j)*unitmat(n)-A);
530  if( printlevel-voice+2 >0) { showrecursive(X,var(j));}
531  return(X);
532}
533example
534{ "EXAMPLE"; echo=2;
535  ring r=0,(x,t),dp;
536  matrix A[3][3]=1,x2,x,x2,6,4,x,4,1;
537  print(A);
538  charpoly(A,"t");
539}
540
541//////////////////////////////////////////////////////////////////////////////
542proc charpoly_B(matrix A, list #)
543"USAGE:   charpoly_B(A[,v]); A square matrix, v string, name of a variable
544RETURN:  poly, the characteristic polynomial det(E*v-A)
545         (default: v=name of last variable)
546NOTE:    A must be constant in the variable v. The computation uses busadj(A).
547EXAMPLE: example charpoly_B; shows an example"
[30f140]548{
[2636865]549  int i,j;
550  string s,v;
[30f140]551  list L;
[2636865]552  int n     = nrows(A);
553  poly X    = 0;
554  def BR    = basering;
555  string mp = string(minpoly);
[30f140]556
[337919]557  if(ncols(A) != n){
[2636865]558    "// input is not a square matrix";
[30f140]559    return(X);
[337919]560  }
[30f140]561
[2636865]562  //test for correct variable
[337919]563  if( size(#)==0 ){
564    #[1] = varstr(nvars(BR));
[2636865]565  }
566  if( typeof(#[1]) == "string"){
567     v = #[1];
568  }
569  else{
570    "// 2nd argument must be a name of a variable not contained in the matrix";
571    return(X);
[337919]572  }
573
[30f140]574  j=-1;
[2636865]575  for(i=1; i<=nvars(BR); i++){
[30f140]576    if(varstr(i)==v){j=i;}
577  }
578  if(j==-1){
[2636865]579    "// "+v+" is not a variable in the basering";
[30f140]580    return(X);
581  }
[337919]582
[3754ca]583  //var cannot be in A
[30f140]584  s="Wp(";
[2636865]585  for( i=1; i<=nvars(BR); i++ ){
[30f140]586    if(i!=j){ s=s+"0";}
587    else{ s=s+"1";}
[2636865]588    if( i<nvars(BR)) {s=s+",";}
[30f140]589  }
590  s=s+")";
591
[daa83b]592  def @R=changeord(s);
593  setring @R;
[30f140]594  execute("minpoly="+mp+";");
[2636865]595  matrix A = imap(BR,A);
596  for(i=1; i<=n; i++){
[30f140]597    if(deg(lead(A)[i])>=1){
[6188357]598      "// matrix must not contain the variable "+v;
[30f140]599      kill @R;
600      setring BR;
601      return(X);
602    }
603  }
604
605  //get coefficients and build the char. poly
606  kill @R;
607  setring BR;
[2636865]608  L = busadj(A);
609  for(i=1; i<=n+1; i++){
[30f140]610    execute("X=X+L[1][i]*"+v+"^"+string(i-1)+";");
611  }
[337919]612
613  return(X);
[30f140]614}
[2636865]615example
616{ "EXAMPLE"; echo=2;
617  ring r=0,(x,t),dp;
618  matrix A[3][3]=1,x2,x,x2,6,4,x,4,1;
619  print(A);
[6188357]620  charpoly_B(A,"t");
[30f140]621}
622
623//////////////////////////////////////////////////////////////////////////////
[2636865]624proc adjoint(matrix A)
625"USAGE:    adjoint(A);  A = square matrix
[6188357]626RETURN:   adjoint matrix of A, i.e. Adj*A=det(A)*E
[30f140]627NOTE:     computation uses busadj(A)
[2636865]628EXAMPLE:  example adjoint; shows an example"
[30f140]629{
630  int n=nrows(A);
631  matrix Adj[n][n];
632  list L;
633
[337919]634  if(ncols(A) != n) {
[2636865]635    "// input is not a square matrix";
[30f140]636    return(Adj);
[337919]637  }
638
[2636865]639  L  = busadj(A);
640  Adj= (-1)^(n-1)*L[2][1];
[30f140]641  return(Adj);
[337919]642
[30f140]643}
[2636865]644example
645{ "EXAMPLE"; echo=2;
646  ring r=0,(t,x),lp;
647  matrix A[2][2]=1,x2,x,x2+3x;
648  print(A);
649  matrix Adj[2][2]=adjoint(A);
650  print(Adj);                    //Adj*A=det(A)*E
651  print(Adj*A);
[30f140]652}
653
654//////////////////////////////////////////////////////////////////////////////
655proc inverse_B(matrix A)
[6188357]656"USAGE:    inverse_B(A);  A = square matrix
657RETURN:   list Inv with
[337919]658          - Inv[1] = matrix I and
659          - Inv[2] = poly p
660          such that I*A = unitmat(n)*p;
[6188357]661NOTE:     p=1 if 1/det(A) is computable and  p=det(A) if not;
662          the computation uses busadj.
[963885]663SEE ALSO: inverse, inverse_L
[6188357]664EXAMPLE:  example inverse_B; shows an example"
[30f140]665{
666  int i;
667  int n=nrows(A);
668  matrix I[n][n];
669  poly factor;
670  list L;
671  list Inv;
[337919]672
673  if(ncols(A) != n) {
[30f140]674    "input is not a square matrix";
675    return(I);
[337919]676  }
677
[30f140]678  L=busadj(A);
[337919]679  I=module(-L[2][1]);        //+-Adj(A)
[30f140]680
[337919]681  if(reduce(1,std(L[1][1]))==0){
682    I=I*lift(L[1][1],1)[1][1];
[30f140]683    factor=1;
684  }
685  else{ factor=L[1][1];}     //=+-det(A) or 1
686  Inv=insert(Inv,factor);
687  Inv=insert(Inv,matrix(I));
688
689  return(Inv);
690}
[2636865]691example
692{ "EXAMPLE"; echo=2;
693  ring r=0,(x,y),lp;
[6188357]694  matrix A[3][3]=x,y,1,1,x2,y,x,6,0;
[2636865]695  print(A);
696  list Inv=inverse_B(A);
697  print(Inv[1]);
698  print(Inv[2]);
699  print(Inv[1]*A);
[30f140]700}
701
702//////////////////////////////////////////////////////////////////////////////
703proc det_B(matrix A)
[337919]704"USAGE:     det_B(A);  A any matrix
[30f140]705RETURN:    returns the determinant of A
706NOTE:      the computation uses the busadj algorithm
707EXAMPLE:   example det_B; shows an example"
708{
[337919]709  int n=nrows(A);
[30f140]710  list L;
711
712  if(ncols(A) != n){ return(0);}
713
714  L=busadj(A);
715  return((-1)^n*L[1][1]);
716}
[2636865]717example
[337919]718{ "EXAMPLE"; echo=2;
[2636865]719  ring r=0,(x),dp;
720  matrix A[10][10]=random(2,10,10)+unitmat(10)*x;
721  print(A);
[337919]722  det_B(A);
[30f140]723}
724
725//////////////////////////////////////////////////////////////////////////////
726proc inverse_L(matrix A)
727"USAGE:     inverse_L(A);  A = square matrix
[2636865]728RETURN:    list Inv representing a left inverse of A, i.e
[337919]729           - Inv[1] = matrix I and
[6188357]730           - Inv[2] = poly p
[337919]731           such that I*A = unitmat(n)*p;
[6188357]732NOTE:      p=1 if 1/det(A) is computable and p=det(A) if not;
[963885]733           the computation computes first det(A) and then uses lift
[337919]734SEE ALSO:  inverse, inverse_B
[30f140]735EXAMPLE:   example inverse_L; shows an example"
736{
737  int n=nrows(A);
738  matrix I;
739  matrix E[n][n]=unitmat(n);
740  poly factor;
741  poly d=1;
742  list Inv;
743
744  if (ncols(A)!=n){
[2636865]745    "// input is not a square matrix";
[30f140]746    return(I);
747  }
748
749  d=det(A);
750  if(d==0){
[2636865]751    "// matrix is not invertible";
[30f140]752    return(Inv);
753  }
754
755  // test if 1/det(A) exists
756  if(reduce(1,std(d))!=0){ E=E*d;}
[337919]757
[30f140]758  I=lift(A,E);
[337919]759  if(I==unitmat(n)-unitmat(n)){ //catch error in lift
[2636865]760    "// matrix is not invertible";
[30f140]761    return(Inv);
762  }
763
764  factor=d;      //=det(A) or 1
765  Inv=insert(Inv,factor);
766  Inv=insert(Inv,I);
[337919]767
[30f140]768  return(Inv);
769}
[2636865]770example
771{ "EXAMPLE"; echo=2;
772  ring r=0,(x,y),lp;
[6188357]773  matrix A[3][3]=x,y,1,1,x2,y,x,6,0;
[2636865]774  print(A);
775  list Inv=inverse_L(A);
776  print(Inv[1]);
777  print(Inv[2]);
778  print(Inv[1]*A);
[30f140]779}
780
781//////////////////////////////////////////////////////////////////////////////
782proc gaussred(matrix A)
[337919]783"USAGE:   gaussred(A);   A any constant matrix
[6188357]784RETURN:  list Z:  Z[1]=P , Z[2]=U , Z[3]=S , Z[4]=rank(A)
785         gives a row reduced matrix S, a permutation matrix P and a
[337919]786         normalized lower triangular matrix U, with P*A=U*S
[6188357]787NOTE:    This procedure is designed for teaching purposes mainly.
[337919]788         The straight forward implementation in the interpreted library
789         is not very efficient (no standard basis computation).
[6188357]790EXAMPLE: example gaussred; shows an example"
[30f140]791{
[2636865]792  int i,j,l,k,jp,rang;
793  poly c,pivo;
[30f140]794  list Z;
[2636865]795  int n = nrows(A);
796  int m = ncols(A);
797  int mr= n; //max. rang
798  matrix P[n][n] = unitmat(n);
799  matrix U[n][n] = P;
[30f140]800
801  if(!const_mat(A)){
[2636865]802    "// input is not a constant matrix";
[30f140]803    return(Z);
804  }
805
806  if(n>m){mr=m;} //max. rang
807
808  for(i=1;i<=mr;i=i+1){
[62dc18e]809    if((i+k)>m){break;}
[337919]810
[30f140]811    //Test: Diagonalelement=0
812    if(A[i,i+k]==0){
813      jp=i;pivo=0;
814      for(j=i+1;j<=n;j=j+1){
[6d37e8]815        c=absValue(A[j,i+k]);
[337919]816        if(pivo<c){ pivo=c;jp=j;}
[30f140]817      }
[2636865]818      if(jp != i){       //Zeilentausch
[337919]819        for(j=1;j<=m;j=j+1){ //Zeilentausch in A (und U) (i-te mit jp-ter)
820          c=A[i,j];
821          A[i,j]=A[jp,j];
822          A[jp,j]=c;
823        }
824        for(j=1;j<=n;j=j+1){ //Zeilentausch in P
825          c=P[i,j];
826          P[i,j]=P[jp,j];
827          P[jp,j]=c;
828        }
[30f140]829      }
830      if(pivo==0){k++;continue;} //eine von selbst auftauchende Stufe !
831    }                          //i sollte im naechsten Lauf nicht erhoeht sein
[337919]832
833    //Eliminationsschritt
834    for(j=i+1;j<=n;j=j+1){
[30f140]835      c=A[j,i+k]/A[i,i+k];
836      for(l=i+k+1;l<=m;l=l+1){
[337919]837        A[j,l]=A[j,l]-A[i,l]*c;
[30f140]838      }
839      A[j,i+k]=0;  // nur wichtig falls k>0 ist
840      A[j,i]=c;    // bildet U
841    }
[337919]842  rang=i;
[30f140]843  }
[337919]844
[30f140]845  for(i=1;i<=mr;i=i+1){
846    for(j=i+1;j<=n;j=j+1){
847      U[j,i]=A[j,i];
848      A[j,i]=0;
849    }
850  }
[337919]851
[30f140]852  Z=insert(Z,rang);
853  Z=insert(Z,A);
854  Z=insert(Z,U);
855  Z=insert(Z,P);
[337919]856
[30f140]857  return(Z);
858}
[2636865]859example
860{ "EXAMPLE";echo=2;
861  ring r=0,(x),dp;
862  matrix A[5][4]=1,3,-1,4,2,5,-1,3,1,3,-1,4,0,4,-3,1,-3,1,-5,-2;
863  print(A);
864  list Z=gaussred(A);   //construct P,U,S s.t. P*A=U*S
865  print(Z[1]);          //P
866  print(Z[2]);          //U
867  print(Z[3]);          //S
868  print(Z[4]);          //rank
869  print(Z[1]*A);        //P*A
870  print(Z[2]*Z[3]);     //U*S
[30f140]871}
872
873//////////////////////////////////////////////////////////////////////////////
874proc gaussred_pivot(matrix A)
[2636865]875"USAGE:     gaussred_pivot(A);   A any constant matrix
[5c187b]876RETURN:    list Z:  Z[1]=P , Z[2]=U , Z[3]=S , Z[4]=rank(A)
[979c4c]877           gives a row reduced matrix S, a permutation matrix P and a
[2636865]878           normalized lower triangular matrix U, with P*A=U*S
[337919]879NOTE:      with row pivoting
[2636865]880EXAMPLE:   example gaussred_pivot; shows an example"
[30f140]881{
[2636865]882  int i,j,l,k,jp,rang;
883  poly c,pivo;
884  list Z;
[30f140]885  int n=nrows(A);
886  int m=ncols(A);
887  int mr=n; //max. rang
888  matrix P[n][n]=unitmat(n);
889  matrix U[n][n]=P;
890
891  if(!const_mat(A)){
[2636865]892    "// input is not a constant matrix";
[30f140]893    return(Z);
894  }
895
896  if(n>m){mr=m;} //max. rang
897
898  for(i=1;i<=mr;i=i+1){
[62dc18e]899    if((i+k)>m){break;}
[337919]900
[30f140]901    //Pivotisierung
[6d37e8]902    pivo=absValue(A[i,i+k]);jp=i;
[30f140]903    for(j=i+1;j<=n;j=j+1){
[6d37e8]904      c=absValue(A[j,i+k]);
[30f140]905      if(pivo<c){ pivo=c;jp=j;}
906    }
907    if(jp != i){ //Zeilentausch
908      for(j=1;j<=m;j=j+1){ //Zeilentausch in A (und U) (i-te mit jp-ter)
[337919]909        c=A[i,j];
910        A[i,j]=A[jp,j];
911        A[jp,j]=c;
[30f140]912      }
913      for(j=1;j<=n;j=j+1){ //Zeilentausch in P
[337919]914        c=P[i,j];
915        P[i,j]=P[jp,j];
916        P[jp,j]=c;
[30f140]917      }
918    }
919    if(pivo==0){k++;continue;} //eine von selbst auftauchende Stufe !
920                               //i sollte im naechsten Lauf nicht erhoeht sein
[337919]921    //Eliminationsschritt
922    for(j=i+1;j<=n;j=j+1){
[30f140]923      c=A[j,i+k]/A[i,i+k];
924      for(l=i+k+1;l<=m;l=l+1){
[337919]925        A[j,l]=A[j,l]-A[i,l]*c;
[30f140]926      }
927      A[j,i+k]=0;  // nur wichtig falls k>0 ist
928      A[j,i]=c;    // bildet U
929    }
[337919]930  rang=i;
[30f140]931  }
[337919]932
[30f140]933  for(i=1;i<=mr;i=i+1){
934    for(j=i+1;j<=n;j=j+1){
935      U[j,i]=A[j,i];
936      A[j,i]=0;
937    }
938  }
[337919]939
[30f140]940  Z=insert(Z,rang);
941  Z=insert(Z,A);
942  Z=insert(Z,U);
943  Z=insert(Z,P);
[337919]944
[30f140]945  return(Z);
946}
[2636865]947example
948{ "EXAMPLE";echo=2;
949  ring r=0,(x),dp;
950  matrix A[5][4] = 1, 3,-1,4,
951                   2, 5,-1,3,
952                   1, 3,-1,4,
953                   0, 4,-3,1,
954                  -3,1,-5,-2;
955  list Z=gaussred_pivot(A);  //construct P,U,S s.t. P*A=U*S
956  print(Z[1]);               //P
957  print(Z[2]);               //U
958  print(Z[3]);               //S
959  print(Z[4]);               //rank
960  print(Z[1]*A);             //P*A
961  print(Z[2]*Z[3]);          //U*S
[30f140]962}
963
964//////////////////////////////////////////////////////////////////////////////
[0b59f5]965proc gauss_nf(matrix A)
[2636865]966"USAGE:    gauss_nf(A); A any constant matrix
[6188357]967RETURN:   matrix; gauss normal form of A (uses gaussred)
[0b59f5]968EXAMPLE:  example gauss_nf; shows an example"
[30f140]969{
970  list Z;
971  if(!const_mat(A)){
[2636865]972    "// input is not a constant matrix";
[30f140]973    return(A);
974  }
[2636865]975  Z = gaussred(A);
[30f140]976  return(Z[3]);
977}
[2636865]978example
979{ "EXAMPLE";echo=2;
980  ring r = 0,(x),dp;
981  matrix A[4][4] = 1,4,4,7,2,5,5,4,4,1,1,3,0,2,2,7;
982  print(gauss_nf(A));
[30f140]983}
984
985//////////////////////////////////////////////////////////////////////////////
[0b59f5]986proc mat_rk(matrix A)
[2636865]987"USAGE:    mat_rk(A); A any constant matrix
[337919]988RETURN:   int, rank of A
[0b59f5]989EXAMPLE:  example mat_rk; shows an example"
[30f140]990{
991  list Z;
992  if(!const_mat(A)){
[6188357]993    "// input is not a constant matrix";
[30f140]994    return(-1);
995  }
[2636865]996  Z = gaussred(A);
[30f140]997  return(Z[4]);
998}
[2636865]999example
1000{ "EXAMPLE";echo=2;
1001  ring r = 0,(x),dp;
1002  matrix A[4][4] = 1,4,4,7,2,5,5,4,4,1,1,3,0,2,2,7;
1003  mat_rk(A);
[30f140]1004}
1005
1006//////////////////////////////////////////////////////////////////////////////
[0b59f5]1007proc U_D_O(matrix A)
[2636865]1008"USAGE:     U_D_O(A);   constant invertible matrix A
[30f140]1009RETURN:    list Z:  Z[1]=P , Z[2]=U , Z[3]=D , Z[4]=O
[337919]1010           gives a permutation matrix P,
[2636865]1011           a normalized lower triangular matrix U ,
[337919]1012           a diagonal matrix D, and
[6188357]1013           a normalized upper triangular matrix O
[2636865]1014           with P*A=U*D*O
[6188357]1015NOTE:      Z[1]=-1 means that A is not regular (proc uses gaussred)
[2636865]1016EXAMPLE:   example U_D_O; shows an example"
[30f140]1017{
[2636865]1018  int i,j;
1019  list Z,L;
[30f140]1020  int n=nrows(A);
1021  matrix O[n][n]=unitmat(n);
1022  matrix D[n][n];
1023
1024  if (ncols(A)!=n){
[2636865]1025    "// input is not a square matrix";
[30f140]1026    return(Z);
1027  }
1028  if(!const_mat(A)){
[2636865]1029    "// input is not a constant matrix";
[30f140]1030    return(Z);
1031  }
[337919]1032
[30f140]1033  L=gaussred(A);
1034
1035  if(L[4]!=n){
[2636865]1036    "// input is not an invertible matrix";
[337919]1037    Z=insert(Z,-1);  //hint for calling procedures
[30f140]1038    return(Z);
1039  }
1040
1041  D=L[3];
1042
[2636865]1043  for(i=1; i<=n; i++){
1044    for(j=i+1; j<=n; j++){
1045      O[i,j] = D[i,j]/D[i,i];
1046      D[i,j] = 0;
[30f140]1047    }
1048  }
1049
1050  Z=insert(Z,O);
1051  Z=insert(Z,D);
1052  Z=insert(Z,L[2]);
1053  Z=insert(Z,L[1]);
1054  return(Z);
1055}
[2636865]1056example
1057{ "EXAMPLE";echo=2;
1058  ring r = 0,(x),dp;
[337919]1059  matrix A[5][5] = 10, 4,  0, -9,  8,
1060                   -3, 6, -6, -4,  9,
[2636865]1061                    0, 3, -1, -9, -8,
1062                   -4,-2, -6, -10,10,
1063                   -9, 5, -1, -6,  5;
[337919]1064  list Z = U_D_O(A);              //construct P,U,D,O s.t. P*A=U*D*O
[2636865]1065  print(Z[1]);                    //P
1066  print(Z[2]);                    //U
1067  print(Z[3]);                    //D
1068  print(Z[4]);                    //O
1069  print(Z[1]*A);                  //P*A
1070  print(Z[2]*Z[3]*Z[4]);          //U*D*O
[30f140]1071}
1072
1073//////////////////////////////////////////////////////////////////////////////
1074proc pos_def(matrix A)
[337919]1075"USAGE:     pos_def(A); A = constant, symmetric square matrix
1076RETURN:    int:
1077           1  if A is positive definit ,
1078           0  if not,
1079           -1 if unknown
[30f140]1080EXAMPLE:   example pos_def; shows an example"
1081{
1082  int j;
1083  list Z;
[2636865]1084  int n = nrows(A);
[30f140]1085  matrix H[n][n];
1086
1087  if (ncols(A)!=n){
[2636865]1088    "// input is not a square matrix";
[30f140]1089    return(0);
1090  }
1091  if(!const_mat(A)){
[2636865]1092    "// input is not a constant matrix";
[30f140]1093    return(-1);
[337919]1094  }
1095  if(deg(std(A-transpose(A))[1])!=-1){
[2636865]1096    "// input is not a hermitian (symmetric) matrix";
[30f140]1097    return(-1);
1098  }
[337919]1099
[0b59f5]1100  Z=U_D_O(A);
[30f140]1101
[2636865]1102  if(Z[1]==-1){
1103    return(0);
1104  }  //A not regular, therefore not pos. definit
[30f140]1105
1106  H=Z[1];
[337919]1107  //es fand Zeilentausch statt: also nicht positiv definit
[2636865]1108  if(deg(std(H-unitmat(n))[1])!=-1){
1109    return(0);
1110  }
[337919]1111
[30f140]1112  H=Z[3];
[337919]1113
[30f140]1114  for(j=1;j<=n;j=j+1){
[337919]1115    if(H[j,j]<=0){
[2636865]1116      return(0);
1117    } //eigenvalue<=0, not pos.definit
[30f140]1118  }
1119
1120  return(1); //positiv definit;
1121}
[2636865]1122example
1123{ "EXAMPLE"; echo=2;
1124  ring r = 0,(x),dp;
1125  matrix A[5][5] = 20,  4,  0, -9,   8,
1126                    4, 12, -6, -4,   9,
[337919]1127                    0, -6, -2, -9,  -8,
1128                   -9, -4, -9, -20, 10,
[2636865]1129                    8,  9, -8,  10, 10;
1130  pos_def(A);
1131  matrix B[3][3] =  3,  2,  0,
1132                    2, 12,  4,
1133                    0,  4,  2;
1134  pos_def(B);
[30f140]1135}
1136
1137//////////////////////////////////////////////////////////////////////////////
[2636865]1138proc linsolve(matrix A, matrix b)
1139"USAGE:     linsolve(A,b); A a constant nxm-matrix, b a constant nx1-matrix
[337919]1140RETURN:    a 1xm matrix X, solution of inhomogeneous linear system A*X = b
[6188357]1141           return the 0-matrix if system is not solvable
1142NOTE:      uses gaussred
[2636865]1143EXAMPLE:   example linsolve; shows an example"
[30f140]1144{
[2636865]1145  int i,j,k,rc,r;
[30f140]1146  poly c;
1147  list Z;
[2636865]1148  int n  = nrows(A);
1149  int m  = ncols(A);
1150  int n_b= nrows(b);
1151  matrix Ab[n][m+1];
1152  matrix X[m][1];
[337919]1153
[30f140]1154  if(ncols(b)!=1){
[2636865]1155    "// right hand side b is not a nx1 matrix";
[30f140]1156    return(X);
1157  }
1158
1159  if(!const_mat(A)){
[2636865]1160    "// input hand is not a constant matrix";
[30f140]1161    return(X);
[337919]1162  }
1163
[30f140]1164  if(n_b>n){
[2636865]1165    for(i=n; i<=n_b; i++){
[30f140]1166      if(b[i,1]!=0){
[337919]1167        "// right hand side b not in Image(A)";
1168        return X;
[30f140]1169      }
[337919]1170    }
[30f140]1171  }
[337919]1172
1173  if(n_b<n){
[30f140]1174    matrix copy[n_b][1]=b;
1175    matrix b[n][1]=0;
1176    for(i=1;i<=n_b;i=i+1){
1177      b[i,1]=copy[i,1];
1178    }
1179  }
[337919]1180
[0b59f5]1181  r=mat_rk(A);
[337919]1182
[30f140]1183  //1. b constant vector
[337919]1184  if(const_mat(b)){
[30f140]1185    //extend A with b
[2636865]1186    for(i=1; i<=n; i++){
1187      for(j=1; j<=m; j++){
1188        Ab[i,j]=A[i,j];
[30f140]1189      }
1190      Ab[i,m+1]=b[i,1];
1191    }
[337919]1192
[2636865]1193    //Gauss reduction
1194    Z  = gaussred(Ab);
1195    Ab = Z[3];  //normal form
[337919]1196    rc = Z[4];  //rank(Ab)
[2636865]1197    //print(Ab);
[30f140]1198
1199    if(r<rc){
[337919]1200        "// no solution";
1201        return(X);
[30f140]1202    }
[337919]1203    k=m;
[30f140]1204    for(i=r;i>=1;i=i-1){
[337919]1205
1206      j=1;
1207      while(Ab[i,j]==0){j=j+1;}// suche Ecke
1208
[30f140]1209      for(;k>j;k=k-1){ X[k]=0;}//springe zur Ecke
[337919]1210
[30f140]1211
1212      c=Ab[i,m+1]; //i-te Komponene von b
1213      for(j=m;j>k;j=j-1){
[337919]1214        c=c-X[j,1]*Ab[i,j];
[30f140]1215      }
1216      if(Ab[i,k]==0){
[337919]1217        X[k,1]=1; //willkuerlich
[30f140]1218      }
[337919]1219      else{
1220          X[k,1]=c/Ab[i,k];
[30f140]1221      }
1222      k=k-1;
1223      if(k==0){break;}
1224    }
[337919]1225
1226
[30f140]1227  }//endif (const b)
1228  else{  //b not constant
[2636865]1229    "// !not implemented!";
[337919]1230
[30f140]1231  }
1232
1233  return(X);
1234}
[2636865]1235example
1236{ "EXAMPLE";echo=2;
1237  ring r=0,(x),dp;
1238  matrix A[3][2] = -4,-6,
[337919]1239                    2, 3,
[2636865]1240                   -5, 7;
1241  matrix b[3][1] = 10,
1242                   -5,
1243                    2;
1244  matrix X = linsolve(A,b);
1245  print(X);
1246  print(A*X);
[30f140]1247}
[2636865]1248//////////////////////////////////////////////////////////////////////////////
[30f140]1249
[6188357]1250///////////////////////////////////////////////////////////////////////////////
[ecf3424]1251//    PROCEDURES for Jordan normal form
[6188357]1252//    AUTHOR:  Mathias Schulze, email: mschulze@mathematik.uni-kl.de
1253///////////////////////////////////////////////////////////////////////////////
1254
[e9124e]1255static proc rowcolswap(matrix M,int i,int j)
1256{
1257  if(i==j)
1258  {
1259    return(M);
1260  }
1261  poly p;
1262  for(int k=1;k<=nrows(M);k++)
1263  {
1264    p=M[i,k];
1265    M[i,k]=M[j,k];
1266    M[j,k]=p;
1267  }
1268  for(k=1;k<=ncols(M);k++)
1269  {
1270    p=M[k,i];
1271    M[k,i]=M[k,j];
1272    M[k,j]=p;
1273  }
1274  return(M);
1275}
1276//////////////////////////////////////////////////////////////////////////////
1277
1278static proc rowelim(matrix M,int i,int j,int k)
1279{
1280  if(jet(M[i,k],0)==0||jet(M[j,k],0)==0)
1281  {
1282    return(M);
1283  }
1284  number n=number(jet(M[i,k],0))/number(jet(M[j,k],0));
1285  for(int l=1;l<=ncols(M);l++)
1286  {
1287    M[i,l]=M[i,l]-n*M[j,l];
1288  }
1289  for(l=1;l<=nrows(M);l++)
1290  {
1291    M[l,j]=M[l,j]+n*M[l,i];
1292  }
1293  return(M);
1294}
1295///////////////////////////////////////////////////////////////////////////////
1296
1297static proc colelim(matrix M,int i,int j,int k)
1298{
1299  if(jet(M[k,i],0)==0||jet(M[k,j],0)==0)
1300  {
1301    return(M);
1302  }
1303  number n=number(jet(M[k,i],0))/number(jet(M[k,j],0));
1304  for(int l=1;l<=nrows(M);l++)
1305  {
1306    M[l,i]=M[l,i]-n*M[l,j];
1307  }
1308  for(l=1;l<=ncols(M);l++)
1309  {
1310    M[j,l]=M[j,l]+n*M[i,l];
1311  }
1312  return(M);
1313}
1314///////////////////////////////////////////////////////////////////////////////
1315
1316proc hessenberg(matrix M)
1317"USAGE:   hessenberg(M); matrix M
1318ASSUME:  M constant square matrix
1319RETURN:  matrix H;  Hessenberg form of M
1320EXAMPLE: example hessenberg; shows examples
1321"
1322{
1323  if(system("with","eigenval"))
1324  {
[cb40b5]1325    return(system("hessenberg",M));
[e9124e]1326  }
1327
1328  int n=ncols(M);
1329  int i,j;
1330  for(int k=1;k<n-1;k++)
1331  {
1332    j=k+1;
1333    while(j<n&&jet(M[j,k],0)==0)
1334    {
1335      j++;
1336    }
1337    if(jet(M[j,k],0)!=0)
1338    {
1339      M=rowcolswap(M,j,k+1);
1340      for(i=j+1;i<=n;i++)
1341      {
1342        M=rowelim(M,i,k+1,k);
1343      }
1344    }
1345  }
1346  return(M);
1347}
1348example
1349{ "EXAMPLE:"; echo=2;
1350  ring R=0,x,dp;
1351  matrix M[3][3]=3,2,1,0,2,1,0,0,3;
1352  print(M);
1353  print(hessenberg(M));
1354}
1355///////////////////////////////////////////////////////////////////////////////
1356
[275721f]1357proc eigenvals(matrix M)
1358"USAGE:   eigenvals(M); matrix M
1359ASSUME:  eigenvalues of M in basefield
[ecf3424]1360RETURN:
1361@format
[3c4dcc]1362list l;
[f91f7a6]1363  ideal l[1];
1364    number l[1][i];  i-th eigenvalue of M
[3c4dcc]1365  intvec l[2];
[f91f7a6]1366    int l[2][i];  multiplicity of i-th eigenvalue of M
[ecf3424]1367@end format
[275721f]1368EXAMPLE: example eigenvals; shows examples
[ecf3424]1369"
1370{
[e9124e]1371  if(system("with","eigenval"))
1372  {
[cb40b5]1373    return(system("eigenvals",jet(M,0)));
[e9124e]1374  }
1375
1376  M=jet(hessenberg(M),0);
1377  int n=ncols(M);
1378  int k;
1379  ideal e;
1380  intvec m;
1381  number e0;
1382  intvec v;
1383  list l;
1384  int i,j;
1385  j=1;
1386  while(j<=n)
1387  {
1388    v=j;
1389    j++;
1390    if(j<=n)
1391    {
1392      while(j<n&&M[j,j-1]!=0)
1393      {
1394        v=v,j;
1395        j++;
1396      }
1397      if(M[j,j-1]!=0)
1398      {
1399        v=v,j;
1400        j++;
1401      }
1402    }
1403    if(size(v)==1)
1404    {
1405      k++;
1406      e[k]=M[v,v];
1407      m[k]=1;
1408    }
1409    else
1410    {
1411      l=factorize(det(submat(M,v,v)-var(1)));
1412      for(i=size(l[1]);i>=1;i--)
1413      {
1414        e0=number(jet(l[1][i]/var(1),0));
1415        if(e0!=0)
[3c4dcc]1416        {
[e9124e]1417          k++;
1418          e[k]=(e0*var(1)-l[1][i])/e0;
1419          m[k]=l[2][i];
[3c4dcc]1420        }
[e9124e]1421      }
1422    }
1423  }
[cb40b5]1424  return(spnf(list(e,m)));
[ecf3424]1425}
1426example
1427{ "EXAMPLE:"; echo=2;
1428  ring R=0,x,dp;
1429  matrix M[3][3]=3,2,1,0,2,1,0,0,3;
1430  print(M);
[275721f]1431  eigenvals(M);
[ecf3424]1432}
1433///////////////////////////////////////////////////////////////////////////////
1434
[2699a6]1435proc minipoly(matrix M,list #)
[979c4c]1436"USAGE:   minipoly(M); matrix M
[2699a6]1437ASSUME:  eigenvalues of M in basefield
1438RETURN:
1439@format
1440list l;  minimal polynomial of M
[3c4dcc]1441  ideal l[1];
[2699a6]1442    number l[1][i];  i-th root of minimal polynomial of M
[3c4dcc]1443  intvec l[2];
[2699a6]1444    int l[2][i];  multiplicity of i-th root of minimal polynomial of M
1445@end format
1446EXAMPLE: example minipoly; shows examples
1447"
1448{
1449  if(nrows(M)==0)
1450  {
1451    ERROR("non empty expected");
1452  }
1453  if(ncols(M)!=nrows(M))
1454  {
1455    ERROR("square matrix expected");
1456  }
1457
1458  M=jet(M,0);
1459
1460  if(size(#)==0)
1461  {
1462    #=eigenvals(M);
1463  }
1464  def e0,m0=#[1..2];
1465
1466  intvec m1;
1467  matrix N0,N1;
1468  for(int i=1;i<=ncols(e0);i++)
1469  {
1470    m1[i]=1;
1471    N0=M-e0[i];
1472    N1=N0;
1473    while(size(syz(N1))<m0[i])
1474    {
1475      m1[i]=m1[i]+1;
1476      N1=N1*N0;
1477    }
1478  }
1479
1480  return(list(e0,m1));
1481}
1482example
1483{ "EXAMPLE:"; echo=2;
1484  ring R=0,x,dp;
1485  matrix M[3][3]=3,2,1,0,2,1,0,0,3;
1486  print(M);
1487  minipoly(M);
1488}
1489///////////////////////////////////////////////////////////////////////////////
1490
[348bbc]1491proc spnf(list #)
[cb40b5]1492"USAGE:   spnf(list(a[,m])); ideal a, intvec m
1493ASSUME:  ncols(a)==size(m)
[906458]1494RETURN:  list l:
1495            l[1] an ideal, the generators of a; sorted and with multiple entries displayed only once@*
1496            l[2] and intvec, l[2][i] provides the multiplicity of l[1][i]
[cb40b5]1497EXAMPLE: example spnf; shows examples
1498"
1499{
[348bbc]1500  list sp=#;
[cb40b5]1501  ideal a=sp[1];
1502  int n=ncols(a);
1503  intvec m;
1504  list V;
1505  module v;
1506  int i,j;
1507  for(i=2;i<=size(sp);i++)
1508  {
1509    if(typeof(sp[i])=="intvec")
1510    {
1511      m=sp[i];
1512    }
1513    if(typeof(sp[i])=="module")
1514    {
1515      v=sp[i];
1516      for(j=n;j>=1;j--)
1517      {
1518        V[j]=module(v[j]);
1519      }
1520    }
1521    if(typeof(sp[i])=="list")
1522    {
1523      V=sp[i];
1524    }
1525  }
1526  if(m==0)
1527  {
1528    for(i=n;i>=1;i--)
1529    {
1530      m[i]=1;
1531    }
1532  }
1533
1534  int k;
1535  ideal a0;
1536  intvec m0;
1537  list V0;
1538  number a1;
1539  int m1;
1540  for(i=n;i>=1;i--)
1541  {
1542    if(m[i]!=0)
1543    {
1544      for(j=i-1;j>=1;j--)
1545      {
1546        if(m[j]!=0)
[3c4dcc]1547        {
[cb40b5]1548          if(number(a[i])>number(a[j]))
1549          {
1550            a1=number(a[i]);
1551            a[i]=a[j];
1552            a[j]=a1;
1553            m1=m[i];
1554            m[i]=m[j];
1555            m[j]=m1;
1556            if(size(V)>0)
1557            {
1558              v=V[i];
1559              V[i]=V[j];
1560              V[j]=v;
1561            }
1562          }
1563          if(number(a[i])==number(a[j]))
1564          {
1565            m[i]=m[i]+m[j];
1566            m[j]=0;
1567            if(size(V)>0)
1568            {
1569              V[i]=V[i]+V[j];
1570            }
1571          }
1572        }
1573      }
1574      k++;
1575      a0[k]=a[i];
1576      m0[k]=m[i];
1577      if(size(V)>0)
1578      {
1579        V0[k]=V[i];
1580      }
1581    }
1582  }
1583
1584  if(size(V0)>0)
1585  {
1586    n=size(V0);
1587    module U=std(V0[n]);
1588    for(i=n-1;i>=1;i--)
1589    {
1590      V0[i]=simplify(reduce(V0[i],U),1);
1591      if(i>=2)
1592      {
1593        U=std(U+V0[i]);
1594      }
1595    }
1596  }
1597
1598  if(k>0)
1599  {
1600    sp=a0,m0;
1601    if(size(V0)>0)
1602    {
1603      sp[3]=V0;
1604    }
1605  }
1606  return(sp);
1607}
1608example
1609{ "EXAMPLE:"; echo=2;
1610  ring R=0,(x,y),ds;
1611  list sp=list(ideal(-1/2,-3/10,-3/10,-1/10,-1/10,0,1/10,1/10,3/10,3/10,1/2));
1612  spprint(spnf(sp));
1613}
1614///////////////////////////////////////////////////////////////////////////////
1615
1616proc spprint(list sp)
[906458]1617"USAGE:   spprint(sp); list sp (helper routine for spnf)
[cb40b5]1618RETURN:  string s;  spectrum sp
1619EXAMPLE: example spprint; shows examples
[979c4c]1620SEE ALSO: gmssing_lib, spnf
[cb40b5]1621"
1622{
1623  string s;
1624  for(int i=1;i<size(sp[2]);i++)
1625  {
1626    s=s+"("+string(sp[1][i])+","+string(sp[2][i])+"),";
1627  }
1628  s=s+"("+string(sp[1][i])+","+string(sp[2][i])+")";
1629  return(s);
1630}
1631example
1632{ "EXAMPLE:"; echo=2;
1633  ring R=0,(x,y),ds;
1634  list sp=list(ideal(-1/2,-3/10,-1/10,0,1/10,3/10,1/2),intvec(1,2,2,1,2,2,1));
1635  spprint(sp);
1636}
1637///////////////////////////////////////////////////////////////////////////////
1638
[a0c62d]1639proc jordan(matrix M,list #)
[65b27c]1640"USAGE:   jordan(M); matrix M
[275721f]1641ASSUME:  eigenvalues of M in basefield
[65b27c]1642RETURN:
[337919]1643@format
[275721f]1644list l;  Jordan data of M
[3c4dcc]1645  ideal l[1];
[275721f]1646    number l[1][i];  eigenvalue of i-th Jordan block of M
[3c4dcc]1647  intvec l[2];
[275721f]1648    int l[2][i];  size of i-th Jordan block of M
[3c4dcc]1649  intvec l[3];
[275721f]1650    int l[3][i];  multiplicity of i-th Jordan block of M
[6188357]1651@end format
[ecf3424]1652EXAMPLE: example jordan; shows examples
[6188357]1653"
1654{
[65b27c]1655  if(nrows(M)==0)
[6188357]1656  {
[65b27c]1657    ERROR("non empty expected");
[6188357]1658  }
[65b27c]1659  if(ncols(M)!=nrows(M))
[6188357]1660  {
[65b27c]1661    ERROR("square matrix expected");
[6188357]1662  }
1663
1664  M=jet(M,0);
1665
[a0c62d]1666  if(size(#)==0)
1667  {
[275721f]1668    #=eigenvals(M);
[a0c62d]1669  }
1670  def e0,m0=#[1..2];
[6188357]1671
[65b27c]1672  int i;
[4b6c75]1673  for(i=1;i<=ncols(e0);i++)
[6188357]1674  {
[275721f]1675    if(deg(e0[i])>0)
[65b27c]1676    {
[275721f]1677
[65b27c]1678      ERROR("eigenvalues in coefficient field expected");
1679      return(list());
1680    }
[6188357]1681  }
1682
[65b27c]1683  int j,k;
[4b6c75]1684  matrix N0,N1;
[65b27c]1685  module K0;
1686  list K;
[4b6c75]1687  ideal e;
1688  intvec s,m;
[6188357]1689
[4b6c75]1690  for(i=1;i<=ncols(e0);i++)
[6188357]1691  {
[0ebbcf4]1692    N0=M-e0[i]*matrix(freemodule(ncols(M)));
[6188357]1693
[4b6c75]1694    N1=N0;
[65b27c]1695    K0=0;
1696    K=module();
[4b6c75]1697    while(size(K0)<m0[i])
[6188357]1698    {
[4b6c75]1699      K0=syz(N1);
[65b27c]1700      K=K+list(K0);
[4b6c75]1701      N1=N1*N0;
[6188357]1702    }
1703
[4b6c75]1704    for(j=2;j<size(K);j++)
[6188357]1705    {
[4b6c75]1706      if(2*size(K[j])-size(K[j-1])-size(K[j+1])>0)
[6188357]1707      {
[4b6c75]1708        k++;
1709        e[k]=e0[i];
1710        s[k]=j-1;
1711        m[k]=2*size(K[j])-size(K[j-1])-size(K[j+1]);
[6188357]1712      }
1713    }
[4b6c75]1714    if(size(K[j])-size(K[j-1])>0)
1715    {
1716      k++;
1717      e[k]=e0[i];
1718      s[k]=j-1;
1719      m[k]=size(K[j])-size(K[j-1]);
1720    }
[6188357]1721  }
1722
[4b6c75]1723  return(list(e,s,m));
[65b27c]1724}
1725example
1726{ "EXAMPLE:"; echo=2;
1727  ring R=0,x,dp;
1728  matrix M[3][3]=3,2,1,0,2,1,0,0,3;
1729  print(M);
1730  jordan(M);
1731}
1732///////////////////////////////////////////////////////////////////////////////
1733
[a0c62d]1734proc jordanbasis(matrix M,list #)
[fa01b7]1735"USAGE:   jordanbasis(M); matrix M
[275721f]1736ASSUME:  eigenvalues of M in basefield
[4b6c75]1737RETURN:
1738@format
1739list l:
[91fc5e]1740  module l[1];  inverse(l[1])*M*l[1] in Jordan normal form
[3c4dcc]1741  intvec l[2];
[275721f]1742    int l[2][i];  weight filtration index of l[1][i]
[4b6c75]1743@end format
[ecf3424]1744EXAMPLE: example jordanbasis; shows examples
[65b27c]1745"
1746{
1747  if(nrows(M)==0)
[6188357]1748  {
[65b27c]1749    ERROR("non empty matrix expected");
[6188357]1750  }
[65b27c]1751  if(ncols(M)!=nrows(M))
[6188357]1752  {
[65b27c]1753    ERROR("square matrix expected");
[6188357]1754  }
1755
[65b27c]1756  M=jet(M,0);
1757
[a0c62d]1758  if(size(#)==0)
1759  {
[275721f]1760    #=eigenvals(M);
[a0c62d]1761  }
1762  def e,m=#[1..2];
[6188357]1763
[61549b]1764  for(int i=1;i<=ncols(e);i++)
[6188357]1765  {
[0ebbcf4]1766    if(deg(e[i])>0)
[6188357]1767    {
[65b27c]1768      ERROR("eigenvalues in coefficient field expected");
1769      return(freemodule(ncols(M)));
[6188357]1770    }
1771  }
[65b27c]1772
[61549b]1773  int j,k,l,n;
[fa01b7]1774  matrix N0,N1;
[65b27c]1775  module K0,K1;
[6188357]1776  list K;
[65b27c]1777  matrix u[ncols(M)][1];
1778  module U;
[4b6c75]1779  intvec w;
[6188357]1780
[61549b]1781  for(i=1;i<=ncols(e);i++)
[6188357]1782  {
[0ebbcf4]1783    N0=M-e[i]*matrix(freemodule(ncols(M)));
[6188357]1784
[fa01b7]1785    N1=N0;
[4b6c75]1786    K0=0;
1787    K=list();
[65b27c]1788    while(size(K0)<m[i])
[6188357]1789    {
[fa01b7]1790      K0=syz(N1);
[65b27c]1791      K=K+list(K0);
[fa01b7]1792      N1=N1*N0;
[6188357]1793    }
1794
[65b27c]1795    K1=0;
[4b6c75]1796    for(j=1;j<size(K);j++)
[6188357]1797    {
[65b27c]1798      K0=K[j];
[fa01b7]1799      K[j]=interred(reduce(K[j],std(K1+module(N0*K[j+1]))));
[65b27c]1800      K1=K0;
[6188357]1801    }
[65b27c]1802    K[j]=interred(reduce(K[j],std(K1)));
[6188357]1803
[4b6c75]1804    for(l=size(K);l>=1;l--)
[6188357]1805    {
[4b6c75]1806      for(k=size(K[l]);k>0;k--)
[6188357]1807      {
[4b6c75]1808        u=K[l][k];
1809        for(j=l;j>=1;j--)
[6188357]1810        {
[61549b]1811          U=U+module(u);
1812          n++;
1813          w[n]=2*j-l-1;
[fa01b7]1814          u=N0*u;
[6188357]1815        }
1816      }
1817    }
1818  }
[61549b]1819
[4b6c75]1820  return(list(U,w));
[6188357]1821}
1822example
1823{ "EXAMPLE:"; echo=2;
1824  ring R=0,x,dp;
1825  matrix M[3][3]=3,2,1,0,2,1,0,0,3;
1826  print(M);
[4b6c75]1827  list l=jordanbasis(M);
1828  print(l[1]);
1829  print(l[2]);
1830  print(inverse(l[1])*M*l[1]);
[6188357]1831}
1832///////////////////////////////////////////////////////////////////////////////
1833
[cb40b5]1834proc jordanmatrix(list jd)
1835"USAGE:   jordanmatrix(list(e,s,m)); ideal e, intvec s, intvec m
[f91f7a6]1836ASSUME:  ncols(e)==size(s)==size(m)
[4b6c75]1837RETURN:
1838@format
[26a4bb]1839matrix J;  Jordan matrix with list(e,s,m)==jordan(J)
[4b6c75]1840@end format
[ecf3424]1841EXAMPLE: example jordanmatrix; shows examples
[6188357]1842"
1843{
[cb40b5]1844  ideal e=jd[1];
1845  intvec s=jd[2];
1846  intvec m=jd[3];
[4f1139]1847  if(ncols(e)!=size(s)||ncols(e)!=size(m))
[6188357]1848  {
[65b27c]1849    ERROR("arguments of equal size expected");
[6188357]1850  }
1851
[4b6c75]1852  int i,j,k,l;
1853  int n=int((transpose(matrix(s))*matrix(m))[1,1]);
[6188357]1854  matrix J[n][n];
[4b6c75]1855  for(k=1;k<=ncols(e);k++)
[6188357]1856  {
[4b6c75]1857    for(l=1;l<=m[k];l++)
[6188357]1858    {
[4b6c75]1859      j++;
1860      J[j,j]=e[k];
1861      for(i=s[k];i>=2;i--)
[6188357]1862      {
[61549b]1863        J[j+1,j]=1;
[4b6c75]1864        j++;
1865        J[j,j]=e[k];
[6188357]1866      }
1867    }
1868  }
1869
1870  return(J);
1871}
1872example
1873{ "EXAMPLE:"; echo=2;
1874  ring R=0,x,dp;
[65b27c]1875  ideal e=ideal(2,3);
[4b6c75]1876  intvec s=1,2;
1877  intvec m=1,1;
[cb40b5]1878  print(jordanmatrix(list(e,s,m)));
[6188357]1879}
1880///////////////////////////////////////////////////////////////////////////////
1881
[275721f]1882proc jordannf(matrix M,list #)
1883"USAGE:   jordannf(M); matrix M
1884ASSUME:  eigenvalues of M in basefield
1885RETURN:  matrix J; Jordan normal form of M
1886EXAMPLE: example jordannf; shows examples
[6188357]1887"
1888{
[cb40b5]1889  return(jordanmatrix(jordan(M,#)));
[6188357]1890}
1891example
1892{ "EXAMPLE:"; echo=2;
1893  ring R=0,x,dp;
1894  matrix M[3][3]=3,2,1,0,2,1,0,0,3;
1895  print(M);
[275721f]1896  print(jordannf(M));
[6188357]1897}
[e9124e]1898
[963885]1899///////////////////////////////////////////////////////////////////////////////
1900
1901/*
1902///////////////////////////////////////////////////////////////////////////////
1903//          Auskommentierte zusaetzliche Beispiele
1904//
[6188357]1905///////////////////////////////////////////////////////////////////////////////
[963885]1906// Singular for ix86-Linux version 1-3-10  (2000121517)  Dec 15 2000 17:55:12
1907// Rechnungen auf AMD700 mit 632 MB
1908
1909 LIB "linalg.lib";
1910
19111. Sparse integer Matrizen
1912--------------------------
1913ring r1=0,(x),dp;
1914system("--random", 12345678);
1915int n = 70;
[337919]1916matrix m = sparsemat(n,n,50,100);
[963885]1917option(prot,mem);
1918
1919int t=timer;
[337919]1920matrix im = inverse(m,1)[1];
[963885]1921timer-t;
1922print(im*m);
[337919]1923//list l0 = watchdog(100,"inverse("+"m"+",3)");
[963885]1924//bricht bei 100 sec ab und gibt l0[1]: string Killed zurueck
1925
[337919]1926//inverse(m,1): std       5sec 5,5 MB
[963885]1927//inverse(m,2): interred  12sec
1928//inverse(m,2): lift      nach 180 sec 13MB abgebrochen
1929//n=60: linalgorig: 3  linalg: 5
[337919]1930//n=70: linalgorig: 6,7 linalg: 11,12
1931// aber linalgorig rechnet falsch!
[963885]1932
19332. Sparse poly Matrizen
1934-----------------------
1935ring r=(0),(a,b,c),dp;
1936system("--random", 12345678);
1937int n=6;
1938matrix m = sparsematrix(n,n,2,0,50,50,9); //matrix of polys of deg <=2
1939option(prot,mem);
1940
1941int t=timer;
[337919]1942matrix im = inverse(m);
[963885]1943timer-t;
1944print(im*m);
1945//inverse(m,1): std       0sec 1MB
1946//inverse(m,2): interred  0sec 1MB
1947//inverse(m,2): lift      nach 2000 sec 33MB abgebrochen
1948
19493. Sparse Matrizen mit Parametern
1950---------------------------------
1951//liborig rechnet hier falsch!
1952ring r=(0),(a,b),dp;
1953system("--random", 12345678);
1954int n=7;
1955matrix m = sparsematrix(n,n,1,0,40,50,9);
1956ring r1 = (0,a,b),(x),dp;
1957matrix m = imap(r,m);
1958option(prot,mem);
1959
1960int t=timer;
[337919]1961matrix im = inverse(m);
[963885]1962timer-t;
1963print(im*m);
1964//inverse(m)=inverse(m,3):15 sec inverse(m,1)=1sec inverse(m,2):>120sec
1965//Bei Parametern vergeht die Zeit beim Normieren!
1966
19673. Sparse Matrizen mit Variablen und Parametern
1968-----------------------------------------------
1969ring r=(0),(a,b),dp;
1970system("--random", 12345678);
1971int n=6;
1972matrix m = sparsematrix(n,n,1,0,35,50,9);
1973ring r1 = (0,a),(b),dp;
1974matrix m = imap(r,m);
1975option(prot,mem);
1976
1977int t=timer;
[337919]1978matrix im = inverse(m,3);
[963885]1979timer-t;
1980print(im*m);
1981//n=7: inverse(m,3):lange sec inverse(m,1)=1sec inverse(m,2):1sec
1982
19834. Ueber Polynomring invertierbare Matrizen
1984-------------------------------------------
1985LIB"random.lib"; LIB"linalg.lib";
1986system("--random", 12345678);
1987int n =3;
1988ring r= 0,(x,y,z),(C,dp);
[337919]1989matrix A=triagmatrix(n,n,1,0,0,50,2);
1990intmat B=sparsetriag(n,n,20,1);
[963885]1991matrix M = A*transpose(B);
1992M=M*transpose(M);
1993M[1,1..ncols(M)]=M[1,1..n]+xyz*M[n,1..ncols(M)];
1994print(M);
1995//M hat det=1 nach Konstruktion
1996
1997int t=timer;
1998matrix iM=inverse(M);
1999timer-t;
2000print(iM*M);                      //test
2001
2002//ACHTUNG: Interred liefert i.A. keine Inverse, Gegenbeispiel z.B.
2003//mit n=3
2004//eifacheres Gegenbeispiel:
2005matrix M =
[337919]20069yz+3y+3z+2,             9y2+6y+1,
[963885]20079xyz+3xy+3xz-9z2+2x-6z-1,9xy2+6xy-9yz+x-3y-3z
2008//det M=1, inverse(M,2); ->// ** matrix is not invertible
2009//lead(M); 9xyz*gen(2) 9xy2*gen(2) nicht teilbar!
2010
20115. charpoly:
2012-----------
[337919]2013//ring rp=(0,A,B,C),(x),dp;
2014ring r=0,(A,B,C,x),dp;
[963885]2015matrix m[12][12]=
[337919]2016AC,BC,-3BC,0,-A2+B2,-3AC+1,B2,   B2,  1,   0, -C2+1,0,
20171, 1, 2C,  0,0,     B,     -A,   -4C, 2A+1,0, 0,    0,
20180, 0, 0,   1,0,     2C+1,  -4C+1,-A,  B+1, 0, B+1,  3B,
[963885]2019AB,B2,0,   1,0,     1,     0,    1,   A,   0, 1,    B+1,
[337919]20201, 0, 1,   0,0,     1,     0,    -C2, 0,   1, 0,    1,
20210, 0, 2,   1,2A,    1,     0,    0,   0,   0, 1,    1,
20220, 1, 0,   1,1,     2,     A,    3B+1,1,   B2,1,    1,
20230, 1, 0,   1,1,     1,     1,    1,   2,   0, 0,    0,
20241, 0, 1,   0,0,     0,     1,    0,   1,   1, 0,    3,
20251, 3B,B2+1,0,0,     1,     0,    1,   0,   0, 1,    0,
20260, 0, 1,   0,0,     0,     0,    1,   0,   0, 0,    0,
20270, 1, 0,   1,1,     3,     3B+1, 0,   1,   1, 1,    0;
[963885]2028option(prot,mem);
2029
2030int t=timer;
2031poly q=charpoly(m,"x");         //1sec, charpoly_B 1sec, 16MB
2032timer-t;
2033//1sec, charpoly_B 1sec, 16MB  (gleich in r und rp)
2034
[337919]2035*/
Note: See TracBrowser for help on using the repository browser.