diff --git a/lib/zlattice.gi b/lib/zlattice.gi index 9a1632e0e7..a7b5c4c63d 100644 --- a/lib/zlattice.gi +++ b/lib/zlattice.gi @@ -37,8 +37,7 @@ end ); ## #M InverseMatMod( , ) ## -#T Is this method really good? -#T (There is a generic method in `matrix.gi' that looks nicer.) +## This method is much faster than the generic method in `matrix.gi' ## InstallMethod( InverseMatMod, "method for a matrix, and an integer", @@ -49,36 +48,12 @@ InstallMethod( InverseMatMod, n, # dimension intmatq, intmatqinv, # matrix & inverse modulo p x, # solution of one iteration - zline, # help-line for exchange - mult, # multiplication table of the field - inverse; # list of inverses of field elements + zline; # help-line for exchange n:= Length( intmat ); - # inverses modulo `p'; we have `inverse[x] * x = 1' - inverse:= [ 1 ]; - for i in [ 2 .. p-1 ] do - inverse[i]:= Inverse( i ) mod p; -#T better? - od; - - # multiplication table; we have `mult[i][j]' congruent `i*j' mod `p' - mult:= []; - for i in [ 1 .. p-1 ] do - mult[i]:= []; - for j in [ 1 .. p-1 ] do - mult[i][j]:= ( i*j ) mod p; - od; - od; - # `intmatq': `intmat' reduced mod `p' - intmatq := []; - for i in [ 1 .. n ] do - intmatq[i] := []; - for j in [ 1 .. n ] do - intmatq[i][j]:= intmat[i][j] mod p; - od; - od; + intmatq := intmat mod p; intmatqinv := IdentityMat( n ); for i in [ 1 .. n ] do @@ -105,17 +80,17 @@ InstallMethod( InverseMatMod, # normalize line `i' zline:= intmatq[i]; if zline[i] <> 1 then - x:= mult[ inverse[ zline[i] ] ]; + x:= (1/zline[i]) mod p; zline[i]:= 1; for k in [ i+1 .. n ] do if zline[k] <> 0 then - zline[k]:= x[ zline[k] ]; + zline[k]:= (x * zline[k]) mod p; fi; od; zline:= intmatqinv[i]; for k in [1 .. n] do if zline[k] <> 0 then - zline[k]:= x[ zline[k] ]; + zline[k]:= (x * zline[k]) mod p; fi; od; fi; @@ -123,15 +98,15 @@ InstallMethod( InverseMatMod, # elimination in column `i' for j in [ 1 .. n ] do if j <> i and intmatq[j][i] <> 0 then - x:= mult[ intmatq[j][i] ]; + x:= intmatq[j][i]; for k in [ 1 .. n ] do if intmatqinv[i][k] <> 0 then intmatqinv[j][k]:= - (intmatqinv[j][k] - x[ intmatqinv[i][k] ] ) mod p; + (intmatqinv[j][k] - x * intmatqinv[i][k] ) mod p; fi; if intmatq[i][k] <> 0 then intmatq[j][k]:= - (intmatq[j][k] - x[ intmatq[i][k] ] ) mod p; + (intmatq[j][k] - x * intmatq[i][k] ) mod p; fi; od; fi; diff --git a/tst/testinstall/opers/InverseMatMod.tst b/tst/testinstall/opers/InverseMatMod.tst new file mode 100644 index 0000000000..1931904405 --- /dev/null +++ b/tst/testinstall/opers/InverseMatMod.tst @@ -0,0 +1,14 @@ +gap> START_TEST("InverseMatMod.tst"); + +# +gap> for d in [1..10] do +> id:=IdentityMat(d); +> m:=RandomUnimodularMat(d); +> for p in [2, 251, 65537] do +> x:=InverseMatMod(m, p); +> Assert(0, (x*m mod p) = id); +> od; +> od; + +# +gap> STOP_TEST("InverseMatMod.tst", 1);