bridge/class-master/depend/pari/src/basemath/alglin2.c
/* Using traces: return the characteristic polynomial of x (in variable v).
 * If py != NULL, the adjoint matrix is put there. */
Using traces: return the characteristic polynomial of x (in variable v).
If py != NULL, the adjoint matrix is put there.
Using traces : return the characteristic polynomial of x ( in variable v ) . If py ! = NULL the adjoint matrix is put there .
GEN
caradj(GEN x, long v, GEN *py)
{
  pari_sp av, av0;
  long i, k, n;
  GEN T, y, t;
  if ((T = easychar(x, v)))
  {
    if (py)
    {
      if (typ(x) != t_MAT) pari_err_TYPE("matadjoint",x);
      *py = cgetg(1,t_MAT);
    }
    return T;
  }
  n = lg(x)-1; av0 = avma;
  T = cgetg(n+3,t_POL); T[1] = evalsigne(1) | evalvarn(v);
  gel(T,n+2) = gen_1;
  if (!n) { if (py) *py = cgetg(1,t_MAT); return T; }
  av = avma; t = gerepileupto(av, gneg(mattrace(x)));
  gel(T,n+1) = t;
  if (n == 1) {
    T = fix_pol(av0, T);
    if (py) *py = matid(1); return T;
  }
  if (n == 2) {
    GEN a = gcoeff(x,1,1), b = gcoeff(x,1,2);
    GEN c = gcoeff(x,2,1), d = gcoeff(x,2,2);
    av = avma;
    gel(T,2) = gerepileupto(av, gsub(gmul(a,d), gmul(b,c)));
    T = fix_pol(av0, T);
    if (py) {
      y = cgetg(3, t_MAT);
      gel(y,1) = mkcol2(gcopy(d), gneg(c));
      gel(y,2) = mkcol2(gneg(b), gcopy(a));
      *py = y;
    }
    return T;
  }
  if (bad_char(residual_characteristic(x), n))
  { 
    T = charpoly(x, v);
    if (!py) return gerepileupto(av, T);
    *py = RgM_adj_from_char(x, v, T);
    gerepileall(av, 2, &T,py);
    return T;
  }
  av = avma; y = RgM_shallowcopy(x);
  for (i = 1; i <= n; i++) gcoeff(y,i,i) = gadd(gcoeff(y,i,i), t);
  for (k = 2; k < n; k++)
  {
    GEN y0 = y;
    y = RgM_mul(y, x);
    t = gdivgs(mattrace(y), -k);
    for (i = 1; i <= n; i++) gcoeff(y,i,i) = gadd(gcoeff(y,i,i), t);
    y = gclone(y);
    gel(T,n-k+2) = gerepilecopy(av, t); av = avma;
    if (k > 2) gunclone(y0);
  }
  t = gmul(gcoeff(x,1,1),gcoeff(y,1,1));
  for (i=2; i<=n; i++) t = gadd(t, gmul(gcoeff(x,1,i),gcoeff(y,i,1)));
  gel(T,2) = gerepileupto(av, gneg(t));
  T = fix_pol(av0, T);
  if (py) *py = odd(n)? gcopy(y): RgM_neg(y);
  gunclone(y); return T;
}
GEN caradj ( GEN x , long v , GEN * py ) { pari_sp av , av0 ; long i , k , n ; GEN T , y , t ; if ( ( T = easychar ( x , v ) ) ) { if ( py ) { if ( typ ( x ) != t_MAT ) pari_err_TYPE ( " " , x ) ; * py = cgetg ( 1 , t_MAT ) ; } return T ; } n = lg ( x ) - 1 ; av0 = avma ; T = cgetg ( n + 3 , t_POL ) ; T [ 1 ] = evalsigne ( 1 ) | evalvarn ( v ) ; gel ( T , n + 2 ) = gen_1 ; if ( ! n ) { if ( py ) * py = cgetg ( 1 , t_MAT ) ; return T ; } av = avma ; t = gerepileupto ( av , gneg ( mattrace ( x ) ) ) ; gel ( T , n + 1 ) = t ; if ( n == 1 ) { T = fix_pol ( av0 , T ) ; if ( py ) * py = matid ( 1 ) ; return T ; } if ( n == 2 ) { GEN a = gcoeff ( x , 1 , 1 ) , b = gcoeff ( x , 1 , 2 ) ; GEN c = gcoeff ( x , 2 , 1 ) , d = gcoeff ( x , 2 , 2 ) ; av = avma ; gel ( T , 2 ) = gerepileupto ( av , gsub ( gmul ( a , d ) , gmul ( b , c ) ) ) ; T = fix_pol ( av0 , T ) ; if ( py ) { y = cgetg ( 3 , t_MAT ) ; gel ( y , 1 ) = mkcol2 ( gcopy ( d ) , gneg ( c ) ) ; gel ( y , 2 ) = mkcol2 ( gneg ( b ) , gcopy ( a ) ) ; * py = y ; } return T ; } if ( bad_char ( residual_characteristic ( x ) , n ) ) { T = charpoly ( x , v ) ; if ( ! py ) return gerepileupto ( av , T ) ; * py = RgM_adj_from_char ( x , v , T ) ; gerepileall ( av , 2 , & T , py ) ; return T ; } av = avma ; y = RgM_shallowcopy ( x ) ; for ( i = 1 ; i <= n ; i ++ ) gcoeff ( y , i , i ) = gadd ( gcoeff ( y , i , i ) , t ) ; for ( k = 2 ; k < n ; k ++ ) { GEN y0 = y ; y = RgM_mul ( y , x ) ; t = gdivgs ( mattrace ( y ) , - k ) ; for ( i = 1 ; i <= n ; i ++ ) gcoeff ( y , i , i ) = gadd ( gcoeff ( y , i , i ) , t ) ; y = gclone ( y ) ; gel ( T , n - k + 2 ) = gerepilecopy ( av , t ) ; av = avma ; if ( k > 2 ) gunclone ( y0 ) ; } t = gmul ( gcoeff ( x , 1 , 1 ) , gcoeff ( y , 1 , 1 ) ) ; for ( i = 2 ; i <= n ; i ++ ) t = gadd ( t , gmul ( gcoeff ( x , 1 , i ) , gcoeff ( y , i , 1 ) ) ) ; gel ( T , 2 ) = gerepileupto ( av , gneg ( t ) ) ; T = fix_pol ( av0 , T ) ; if ( py ) * py = odd ( n ) ? gcopy ( y ) : RgM_neg ( y ) ; gunclone ( y ) ; return T ; }
Using traces: return the characteristic polynomial of x (in variable v).
Using traces : return the characteristic polynomial of x ( in variable v ) .
/* l > 3 */ /* n! not invertible in base ring */