| 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]
`