Skip to content

Commit

Permalink
Fast SwapMatrixRows/columns for GF matrices (#5837)
Browse files Browse the repository at this point in the history
Before

    gap> mat:=IdentityMat(10,GF(2));; ConvertToMatrixRep(mat);; mat;
    <a 10x10 matrix over GF2>
    gap> for i in [1..1000000] do SwapMatrixColumns(mat,1,2); od; time;
    1020
    gap> for i in [1..1000000] do SwapMatrixRows(mat,1,2); od; time;
    167
    gap> for i in [1..1000000] do tmp:=mat[1];mat[1]:=mat[2];mat[2]:=tmp; od; time;
    85

After:

    gap> mat:=IdentityMat(10,GF(2));; ConvertToMatrixRep(mat);; mat;
    <a 10x10 matrix over GF2>
    gap> for i in [1..1000000] do SwapMatrixColumns(mat,1,2); od; time;
    135
    gap> for i in [1..1000000] do SwapMatrixRows(mat,1,2); od; time;
    77
    gap> for i in [1..1000000] do tmp:=mat[1];mat[1]:=mat[2];mat[2]:=tmp; od; time;
    87
  • Loading branch information
fingolfin authored Nov 11, 2024
1 parent e234def commit 62bd8f0
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
18 changes: 18 additions & 0 deletions lib/vecmat.gi
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,24 @@ InstallOtherMethod( UNB_LIST,
end);


#############################################################################
##
#M SwapMatrixRows( <gf2mat>, <row1>, <row2> ) . . . swap rows of GF2 matrix
##
InstallMethod( SwapMatrixRows, "for a mutable GF2 matrix, and two row numbers",
[ IsList and IsGF2MatrixRep and IsMutable, IsPosInt, IsPosInt ],
SWAP_ROWS_GF2MAT );


#############################################################################
##
#M SwapMatrixColumns( <gf2mat>, <col1>, <col2> ) . . swap cols of GF2 matrix
##
InstallMethod( SwapMatrixColumns, "for a mutable GF2 matrix, and two column numbers",
[ IsList and IsGF2MatrixRep and IsMutable, IsPosInt, IsPosInt ],
SWAP_COLS_GF2MAT );


#############################################################################
##
#M PrintObj( <gf2mat> ) . . . . . . . . . . . . . . . . print a GF2 matrix
Expand Down
75 changes: 75 additions & 0 deletions src/vecgf2.c
Original file line number Diff line number Diff line change
Expand Up @@ -1948,6 +1948,79 @@ static Obj FuncELM_GF2MAT(Obj self, Obj mat, Obj row)
}


/****************************************************************************
**
*F FuncSWAP_ROWS_GF2MAT( <self>, <mat>, <r1>, <r2> )
**
*/
static Obj FuncSWAP_ROWS_GF2MAT(Obj self, Obj mat, Obj row1, Obj row2)
{
RequireMutable(SELF_NAME, mat, "mat");

UInt r1 = GetSmallInt(SELF_NAME, row1);
UInt r2 = GetSmallInt(SELF_NAME, row2);
UInt m = LEN_GF2MAT(mat);
if (m < r1) {
ErrorMayQuit("row index %d exceeds %d, the number of rows", r1, m);
}
if (m < r2) {
ErrorMayQuit("row index %d exceeds %d, the number of rows", r2, m);
}

Obj a = ELM_GF2MAT(mat, r1);
Obj b = ELM_GF2MAT(mat, r2);

SET_ELM_GF2MAT(mat, r1, b);
SET_ELM_GF2MAT(mat, r2, a);

return 0;
}


/****************************************************************************
**
*F FuncSWAP_COLS_GF2MAT( <self>, <mat>, <c1>, <c2> )
**
*/
static Obj FuncSWAP_COLS_GF2MAT(Obj self, Obj mat, Obj col1, Obj col2)
{
UInt c1 = GetSmallInt(SELF_NAME, col1);
UInt c2 = GetSmallInt(SELF_NAME, col2);
UInt m = LEN_GF2MAT(mat);
if (m == 0)
return 0;

UInt n = LEN_GF2VEC(ELM_GF2MAT(mat, 1));
if (n < c1) {
ErrorMayQuit("column index %d exceeds %d, the number of columns", c1, n);
}
if (n < c2) {
ErrorMayQuit("column index %d exceeds %d, the number of columns", c2, n);
}

for (UInt i = 1; i <= m; ++i) {
Obj vec = ELM_GF2MAT(mat, i);
if (!IS_MUTABLE_OBJ(vec)) {
ErrorMayQuit("row %d is immutable", i, 0);
}
if (LEN_GF2VEC(vec) != n) {
ErrorMayQuit("row length mismatch, %d versus %d", n, LEN_GF2VEC(vec));
}

Obj a = ELM_GF2VEC(vec, c1);
Obj b = ELM_GF2VEC(vec, c2);
if (a != b) {
// one entry is 1, the other is 0; so to switch them,
// we can simply flip each individually
BLOCK_ELM_GF2VEC(vec, c1) ^= MASK_POS_GF2VEC(c1);
BLOCK_ELM_GF2VEC(vec, c2) ^= MASK_POS_GF2VEC(c2);
}
}

return 0;
}


/****************************************************************************
**
*F FuncUNB_GF2VEC( <self>, <list>, <pos> ) . unbind position of a GF2 vector
Expand Down Expand Up @@ -4048,6 +4121,8 @@ static StructGVarFunc GVarFuncs[] = {
GVAR_FUNC_3ARGS(ASS_GF2VEC, gf2vec, pos, elm),
GVAR_FUNC_2ARGS(ELM_GF2MAT, gf2mat, pos),
GVAR_FUNC_3ARGS(ASS_GF2MAT, gf2mat, pos, elm),
GVAR_FUNC_3ARGS(SWAP_ROWS_GF2MAT, gf2mat, row1, row2),
GVAR_FUNC_3ARGS(SWAP_COLS_GF2MAT, gf2mat, col1, col2),
GVAR_FUNC_2ARGS(UNB_GF2VEC, gf2vec, pos),
GVAR_FUNC_2ARGS(UNB_GF2MAT, gf2mat, pos),
GVAR_FUNC_1ARGS(ZERO_GF2VEC, gf2vec),
Expand Down

0 comments on commit 62bd8f0

Please sign in to comment.