`mod/rtable/Gausselim` := proc(A::Matrix,rank::{integer,name},
det::{integer,name})
local B, d, nrows, ncols, right_margin, i,j,
col, row, s, t, p, Q;
Q := type( A, 'Matrix( rational )' );
if not Q and not type( A, 'Matrix( ratpoly( algnum ) )' ) then
error "first argument must be a matrix over a finite field"
end if;
( nrows, ncols ) := LinearAlgebra:-Dimensions( A );
p := args[-1];
right_margin := ncols;
if type( args[-2], 'integer' ) then
right_margin := args[-2]
end if;
if nargs > 3 and type( det, 'name' )
and nrows <> right_margin then
error "cannot compute determinant of a non-square matrix"
end if;
if Q then
B := map( s -> s mod p, A );
else
B := map( s -> 'Normal'( s ) mod p, A );
end if;
row := 1; # initialise the row
d := 1; # initialise the determinant
for col to right_margin while row <= nrows do
# Find the first nonzero entry in this column
for i from row to nrows while B[ i, col ] = 0 do
# empty
end do;
if i > nrows then
# found a zero column so determinant is zero
d := 0;
next
end if;
if i <> row then
# interchange row i with row row
B[ i, 1..-1 ], B[ row, 1..-1 ] :=
B[ row, 1..-1 ], B[ i, 1 .. -1 ];
d := -d mod p; # keep track of determinant
end if;
if nargs = 4 then
d := 'Normal'( d * B[ row, col ] ) mod p
end if;
# Make all the nonzero entries below this one
# are equal to 1
if Q then
s := 1/B[ row, col ] mod p;
for i from row + 1 to nrows do
# do i-th row
if B[ i, col ] = 0 then
next
end if;
t := s * B[ i, col ] mod p;
for j from col + 1 to ncols do
B[ i, j ] := B[ i, j ] -
t * B[ row, j ] mod p
end do;
B[ i, col ] := 0
end do
else
s := 'Normal'( 1 / B[ row, col ] ) mod p;
for i from row + 1 to nrows do
if B[ i, col ] = 0 then
next
end if;
t := 'Normal'( s * B[ i, col ] ) mod p;
for j from col + 1 to ncols do
B[i,j] := 'Normal'( B[ i, j ] -
t * B[ row, j ] ) mod p
end do;
B[ i, col ] := 0
end do
end if;
row := 1 + row # go to next row
end do; # go to next column
if nargs > 2 and type( rank, 'name' ) then
rank := row-1
end if;
if nargs > 3 and type( det, 'name' ) then
det := d
end if;
B
end proc: