Karim Belabas on Tue, 29 Jul 2008 01:52:42 +0200 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
[arndt@jjj.de: bugfix for charpoly with finite fields] |
----- Forwarded message from Joerg Arndt <arndt@jjj.de> ----- From: Joerg Arndt <arndt@jjj.de> To: Karim Belabas <Karim.Belabas@math.u-bordeaux1.fr> Subject: bugfix for charpoly with finite fields Attached a workaround/bugfix for pari/gp failing to compute the charpoly if the coefficients of the matrix are in a finite field. (Guess you are using the method involving division by i at step i, this is only good with characteristic zero, Cohen should mention this). The routines use the Hessenberg-based method, straight from Cohen's book. Might be a good idea to forward to the list(s). Note the timings! cheers, jj P.S.: URL is http://www.jjj.de/pari/charpoly2.inc.gp \\% Compute characteristic polynomial for matrices over finite fields \\ Author: Joerg Arndt \\ online at http://www.jjj.de/pari/ \\ version: 2008-July-27 (13:11) /* This is a bugfix for pari/gp: charpoly(matid(3)*Mod(1,2)) *** charpoly: impossible inverse modulo: Mod(0, 2). Also quite fast for small characteristic and dense matrices: with a dense 256 x 256 matrix and p==2 we have charpoly(M); \\ workaround 1: computation over integers *** last result computed in 3mn, 24,765 ms. matdet(Mod(1,2)*('x*matid(n)-M)); \\ workaround 2: use determinant *** last result computed in 11mn, 21,971 ms. charpoly_ff(M,2); *** last result computed in 3,236 ms. charpoly_2(M); *** last result computed in 1,937 ms. */ charpoly_ff(H, p=2)= \\ p must be prime, H a square matrix { local(n, P, t); H = mathess( Mod(1,p)*H ); n = matsize(H)[1]; P = vector(n+1); P[1+0] = 1; for (m=1, n, P[1+m] = ('x-H[m,m])*P[1+m-1]; t = 1; for (i=1, m-1, t *= H[m-i+1, m-i]; if ( 0==t, break(); ); \\ good with small characteristic P[1+m] -= ( t * H[m-i,m] * P[1+m-i-1] ); ); ); return( lift( P[n+1] ) ); } /* ----------- */ charpoly_2(H)= \\ H must be a square matrix { local(n, P); H = lift( mathess( Mod(1,2)*H ) ); n = matsize(H)[1]; P = vector(n+1); P[1+0] = 1; for (m=1, n, \\ P[1+m] = ('x-H[m,m])*P[1+m-1]; P[1+m] = P[1+m-1] << 1; if ( H[m,m], P[1+m] = bitxor(P[1+m], P[1+m-1]) ); \\ t = 1; for (i=1, m-1, \\ t = H[m-i+1, m-i]; if ( 0==H[m-i+1, m-i], break(); ); \\ good with small characteristic \\ if ( H[m-i,m], P[1+m] -= P[1+m-i-1] ); if ( H[m-i,m], P[1+m] = bitxor(P[1+m], P[1+m-i-1]) ); ); ); \\ return( lift( P[n+1] ) ); return( Pol( binary( P[n+1] ) ) ); } /* ----------- */ ----- End forwarded message ----- K.B. -- Karim Belabas, IMB (UMR 5251) Tel: (+33) (0)5 40 00 26 17 Universite Bordeaux 1 Fax: (+33) (0)5 40 00 69 50 351, cours de la Liberation http://www.math.u-bordeaux.fr/~belabas/ F-33405 Talence (France) http://pari.math.u-bordeaux.fr/ [PARI/GP] `