diff --git a/doc/ref/matobj.xml b/doc/ref/matobj.xml index d0aa9be318..898fa77cd7 100644 --- a/doc/ref/matobj.xml +++ b/doc/ref/matobj.xml @@ -287,5 +287,22 @@ for your new type of vector or matrix objects.) + +
+Basic operations for row/column reductions + +<#Include Label="MultMatrixRow"> +<#Include Label="MultMatrixRowRight"> +<#Include Label="MultMatrixColumn"> +<#Include Label="MultMatrixColumnLeft"> +<#Include Label="AddMatrixRows"> +<#Include Label="AddMatrixRowsRight"> +<#Include Label="AddMatrixColumns"> +<#Include Label="AddMatrixColumnsLeft"> +<#Include Label="SwapMatrixRows"> +<#Include Label="SwapMatrixColumns"> + +
+ diff --git a/lib/matobj.gi b/lib/matobj.gi index e1a681b0d7..e4fa250fe0 100644 --- a/lib/matobj.gi +++ b/lib/matobj.gi @@ -1569,3 +1569,142 @@ InstallMethod( \[\,\]\:\=, "for a matrix object, two positions, and an object", end ); +############################################################################ +# Elementary matrix operations +############################################################################ + +InstallMethod( MultMatrixRowLeft, "for a mutable matrix object, a row number, and a scalar", + [ IsMatrixObj and IsMutable, IsInt, IsObject ], + function( mat, row, scalar ) + local i; + + for i in [1..NrCols(mat)] do + mat[row,i] := scalar * mat[row,i]; + od; + + end ); + +############################################################################ + +InstallMethod( MultMatrixColumnRight, "for a mutable matrix object, a column number, and a scalar", + [ IsMatrixObj and IsMutable, IsInt, IsObject ], + function( mat, column, scalar ) + local i; + + for i in [1..NrRows(mat)] do + mat[i,column] := mat[i,column] * scalar; + od; + + end ); + +############################################################################ + +InstallMethod( MultMatrixRowRight, "for a mutable matrix object, a row number, and a scalar", + [ IsMatrixObj and IsMutable, IsInt, IsObject ], + function( mat, row, scalar ) + local i; + + for i in [1..NrCols(mat)] do + mat[row,i] := mat[row,i] * scalar; + od; + + end ); + +############################################################################ + +InstallMethod( MultMatrixColumnLeft, "for a mutable matrix object, a column number, and a scalar", + [ IsMatrixObj and IsMutable, IsInt, IsObject ], + function( mat, column, scalar ) + local i; + + for i in [1..NrRows(mat)] do + mat[i,column] := scalar * mat[i,column]; + od; + + end ); + +############################################################################ + +InstallMethod( AddMatrixRowsLeft, "for a mutable matrix object, two row numbers, and a scalar", + [ IsMatrixObj and IsMutable, IsInt, IsInt, IsObject ] , + function( mat, row1, row2, scalar ) + local i; + + for i in [1..NrCols(mat)] do + mat[row1,i] := mat[row1,i] + scalar * mat[row2,i]; + od; + + end ); + + ############################################################################ + +InstallMethod( AddMatrixRowsRight, "for a mutable matrix object, two row numbers, and a scalar", + [ IsMatrixObj and IsMutable, IsInt, IsInt, IsObject ] , + function( mat, row1, row2, scalar ) + local i; + + for i in [1..NrCols(mat)] do + mat[row1,i] := mat[row1,i] + mat[row2,i] * scalar; + od; + + end ); + +############################################################################ + +InstallMethod( AddMatrixColumnsRight, "for a mutable matrix object, two column numbers, and a scalar", + [ IsMatrixObj and IsMutable, IsInt, IsInt, IsObject ] , + function( mat, column1, column2, scalar ) + local i; + + for i in [1..NrRows(mat)] do + mat[i,column1] := mat[i,column1] + mat[i,column2] * scalar; + od; + + end ); + +############################################################################ + +InstallMethod( AddMatrixColumnsLeft, "for a mutable matrix object, two column numbers, and a scalar", + [ IsMatrixObj and IsMutable, IsInt, IsInt, IsObject ] , + function( mat, column1, column2, scalar ) + local i; + + for i in [1..NrRows(mat)] do + mat[i,column1] := mat[i,column1] + scalar * mat[i,column2] ; + od; + + end ); + +############################################################################ + +InstallMethod( SwapMatrixRows, "for a mutable matrix object, and two row numbers", + [ IsMatrixObj and IsMutable, IsInt, IsInt ], + function( mat, row1, row2 ) + local temp, i; + + if row1 <> row2 then + for i in [1..NrCols(mat)] do + temp := mat[row1,i]; + mat[row1,i] := mat[row2,i]; + mat[row2,i] := temp; + od; + fi; + + end ); + +############################################################################ + +InstallMethod( SwapMatrixColumns, "for a mutable matrix object, and two column numbers", + [ IsMatrixObj and IsMutable, IsInt, IsInt ], + function( mat, column1, column2 ) + local temp, i; + + if column1 <> column2 then + for i in [1..NrRows(mat)] do + temp := mat[i,column1]; + mat[i,column1] := mat[i,column2]; + mat[i,column2] := temp; + od; + fi; + + end ); diff --git a/lib/matobj2.gd b/lib/matobj2.gd index 579338af05..d7928eef2e 100644 --- a/lib/matobj2.gd +++ b/lib/matobj2.gd @@ -614,7 +614,10 @@ DeclareOperation( "AddVector", ##

## Note that ## is just a synonym for -## . +## . This was chosen because vectors in +## GAP are by default row vectors and scalar multiplication is usually written as +## a \cdot v = a \cdot [v_1,...,v_n] = [a\cdot v_1,...,a\cdot v_n] with scalars being +## applied from the left. ##

## If the optional parameters from and to are given then ## only the index range [from..to] is guaranteed to be @@ -1813,3 +1816,210 @@ DeclareOperation( "Randomize", [ IsMatrixOrMatrixObj and IsMutable, IsRandomSour ## DeclareOperation( "[]", [ IsMatrixOrMatrixObj, IsPosInt, IsPosInt ] ); DeclareOperation( "[]:=", [ IsMatrixOrMatrixObj, IsPosInt, IsPosInt, IsObject ] ); + + +############################################################################ +# Elementary matrix operations +############################################################################ +# +############################################################################ +## +## <#GAPDoc Label="MultMatrixRow"> +## +## +## +## +## nothing +## +## +##

+## Multiplies the i-th row of the mutable matrix mat with the scalar +## elm from the left in-place. +##

+## is a synonym of . This was chosen +## because linear combinations of rows of matrices are usually written as +## v \cdot A = [v_1, ... ,v_n] \cdot A which multiplies scalars from the left. +## +## +## <#/GAPDoc> +## +DeclareOperation( "MultMatrixRowLeft", [ IsMatrixObj and IsMutable, IsInt, IsObject ] ); +DeclareSynonym( "MultMatrixRow", MultMatrixRowLeft); + +############################################################################ +## +## <#GAPDoc Label="MultMatrixRowRight"> +## +## +## +## nothing +## +## +##

+## Multiplies the i-th row of the mutable matrix mat with the scalar +## elm from the right in-place. +## +## +## <#/GAPDoc> +## +DeclareOperation( "MultMatrixRowRight", [ IsMatrixObj and IsMutable, IsInt, IsObject ]); + +############################################################################ +## +## <#GAPDoc Label="MultMatrixColumn"> +## +## +## +## +## nothing +## +## +##

+## Multiplies the i-th column of the mutable matrix mat with the scalar +## elm from the right in-place. +##

+## is a synonym of . This was +## chosen because linear combinations of columns of matrices are usually written as +## A \cdot v^T = A \cdot [v_1, ... ,v_n]^T which multiplies scalars from the right. +## +## +## <#/GAPDoc> +## +DeclareOperation( "MultMatrixColumnRight", [ IsMatrixObj and IsMutable, IsInt, IsObject ] ); +DeclareSynonym( "MultMatrixColumn", MultMatrixColumnRight); + +############################################################################ +## +## <#GAPDoc Label="MultMatrixColumnLeft"> +## +## +## +## nothing +## +## +##

+## Multiplies the i-th column of the mutable matrix mat with the scalar +## elm from the left in-place. +## +## +## <#/GAPDoc> +## +DeclareOperation( "MultMatrixColumnLeft", [ IsMatrixObj and IsMutable, IsInt, IsObject ] ); + +############################################################################ +## +## <#GAPDoc Label="AddMatrixRows"> +## +## +## +## +## nothing +## +## +##

+## Adds the product of elm with the j-th row of the mutable matrix mat to its i-th +## row in-place. The j-th row is multiplied with elm from the left. +##

+## is a synonym of . This was chosen +## because linear combinations of rows of matrices are usually written as +## v \cdot A = [v_1, ... ,v_n] \cdot A which multiplies scalars from the left. +## +## +## <#/GAPDoc> +## +DeclareOperation( "AddMatrixRowsLeft", [ IsMatrixObj and IsMutable, IsInt, IsInt, IsObject ] ); +DeclareSynonym( "AddMatrixRows", AddMatrixRowsLeft); + +############################################################################ +## +## <#GAPDoc Label="AddMatrixRowsRight"> +## +## +## +## nothing +## +## +##

+## Adds the product of elm with the j-th row of the mutable matrix mat to its i-th +## row in-place. The j-th row is multiplied with elm from the right. +## +## +## <#/GAPDoc> +## +DeclareOperation( "AddMatrixRowsRight", [ IsMatrixObj and IsMutable, IsInt, IsInt, IsObject ] ); + +############################################################################ +## +## <#GAPDoc Label="AddMatrixColumns"> +## +## +## +## +## nothing +## +## +##

+## Adds the product of elm with the j-th column of the mutable matrix mat to its i-th +## column in-place. The j-th column is multiplied with elm from the right. +##

+## is a synonym of . This was +## chosen because linear combinations of columns of matrices are usually written as +## A \cdot v^T = A \cdot [v_1, ... ,v_n]^T which multiplies scalars from the right. +## +## +## <#/GAPDoc> +## +DeclareOperation( "AddMatrixColumnsRight", [ IsMatrixObj and IsMutable, IsInt, IsInt, IsObject ] ); +DeclareSynonym( "AddMatrixColumns", AddMatrixColumnsRight); + +############################################################################ +## +## <#GAPDoc Label="AddMatrixColumnsLeft"> +## +## +## +## nothing +## +## +##

+## Adds the product of elm with the j-th column of the mutable matrix mat to its i-th +## column in-place. The j-th column is multiplied with elm from the left. +## +## +## <#/GAPDoc> +## +DeclareOperation( "AddMatrixColumnsLeft", [ IsMatrixObj and IsMutable, IsInt, IsInt, IsObject ] ); + +############################################################################ +## +## <#GAPDoc Label="SwapMatrixRows"> +## +## +## +## nothing +## +## +##

+## Swaps the i-th row and j-th row of a mutable matrix mat. +## +## +## <#/GAPDoc> +## +DeclareOperation( "SwapMatrixRows", [ IsMatrixObj and IsMutable, IsInt, IsInt ] ); + +############################################################################ +## +## <#GAPDoc Label="SwapMatrixColumns"> +## +## +## +## nothing +## +## +##

+## Swaps the i-th column and j-th column of a mutable matrix mat. +## +## +## <#/GAPDoc> +## +DeclareOperation( "SwapMatrixColumns", [ IsMatrixObj and IsMutable, IsInt, IsInt ] ); diff --git a/lib/matrobjrowlist.gi b/lib/matrobjrowlist.gi new file mode 100644 index 0000000000..f1d6c69e2d --- /dev/null +++ b/lib/matrobjrowlist.gi @@ -0,0 +1,83 @@ +############################################################################# +## +## This file is part of GAP, a system for computational discrete algebra. +## +## SPDX-License-Identifier: GPL-2.0-or-later +## +## Copyright of GAP belongs to its developers, whose names are too numerous +## to list here. Please refer to the COPYRIGHT file for details. +## + + + +############################################################################ +# Elementary matrix operations +############################################################################ + +############################################################################ +## +#M MultMatrixRow( , , ) +## +InstallMethod( MultMatrixRowLeft, "for a mutable IsRowListMatrix, a row number, and a scalar", + [ IsRowListMatrix and IsMutable, IsInt, IsObject ], + function( mat, row, scalar ) + + mat[row] := scalar * mat[row]; + + end ); + + +############################################################################ +## +#M MultMatrixRowRight( , , ) +## +InstallMethod( MultMatrixRowRight, "for a mutable IsRowListMatrix, a row number, and a scalar", + [ IsRowListMatrix and IsMutable, IsInt, IsObject ], + function( mat, row, scalar ) + + mat[row] := mat[row] * scalar; + + end ); + + +############################################################################ +## +#M AddMatrixRows( , , , ) +## +InstallMethod( AddMatrixRowsLeft, "for a mutable IsRowListMatrix, two row numbers, and a scalar", + [ IsRowListMatrix and IsMutable, IsInt, IsInt, IsObject ] , + function( mat, row1, row2, scalar ) + + mat[row1] := mat[row1] + scalar * mat[row2]; + + end ); + + +############################################################################ +## +#M AddMatrixRowsRight( , , , ) +## +InstallMethod( AddMatrixRowsRight, "for a mutable IsRowListMatrix, two row numbers, and a scalar", + [ IsRowListMatrix and IsMutable, IsInt, IsInt, IsObject ] , + function( mat, row1, row2, scalar ) + + mat[row1] := mat[row1] + mat[row2] * scalar; + + end ); + +############################################################################ +## +#M SwapMatrixRows( , , ) +## +InstallMethod( SwapMatrixRows, "for a mutable IsRowListMatrix, and two row numbers", + [ IsRowListMatrix and IsMutable, IsInt, IsInt ], + function( mat, row1, row2 ) + local temp; + + temp := mat[row1]; + mat[row1] := mat[row2]; + mat[row2] := temp; + #mat{[row1,row2]} := mat{[row2,row1]}; + + end ); + diff --git a/lib/read5.g b/lib/read5.g index f9a69c9fb8..d29f20b8b3 100644 --- a/lib/read5.g +++ b/lib/read5.g @@ -108,6 +108,7 @@ ReadLib( "fldabnum.gi" ); ReadLib( "padics.gi" ); ReadLib( "matobj.gi" ); +ReadLib( "matrobjrowlist.gi" ); ReadLib( "vecmat.gi" ); ReadLib( "vec8bit.gi" ); ReadLib( "mat8bit.gi" ); diff --git a/tst/testinstall/MatrixObj/ElementaryMatrices.tst b/tst/testinstall/MatrixObj/ElementaryMatrices.tst new file mode 100644 index 0000000000..8debdebe82 --- /dev/null +++ b/tst/testinstall/MatrixObj/ElementaryMatrices.tst @@ -0,0 +1,86 @@ +gap> START_TEST("ElementaryMatrices.tst"); + +# +gap> mat := Matrix( [[2,4,5],[7,11,-4],[-3,20,0]]);; +gap> SwapMatrixRows(mat,1,3); +gap> mat= Matrix( [ [ -3, 20, 0 ], [ 7, 11, -4 ], [ 2, 4, 5 ] ]); +true + +# +gap> mat := Matrix( [[2,4,5],[7,11,-4],[-3,20,0]]);; +gap> SwapMatrixColumns(mat,1,3); +gap> mat= Matrix( [ [ 5, 4, 2 ], [ -4, 11, 7 ], [ 0, 20, -3 ] ]); +true + +# +gap> mat := Matrix( [[2,4,5],[7,11,-4],[-3,20,0]]);; +gap> MultMatrixRow(mat,2,-4); +gap> mat= Matrix( [ [2,4,5], [ -28, -44, 16 ], [-3,20,0]]); +true + +# +gap> mat := Matrix( [[2,4,5],[7,11,-4],[-3,20,0]]);; +gap> MultMatrixRowLeft(mat,2,5); +gap> mat= Matrix( [ [2,4,5], [ 35, 55, -20 ], [-3,20,0]]); +true + +# +gap> mat := Matrix( [[2,4,5],[7,11,-4],[-3,20,0]]);; +gap> MultMatrixRowRight(mat,3,-1); +gap> mat= Matrix( [ [2,4,5], [7,11,-4], [3,-20,0]]); +true + +# +gap> mat := Matrix( [[2,4,5],[7,11,-4],[-3,20,0]]);; +gap> MultMatrixColumn(mat,3,2); +gap> mat= Matrix( [ [2,4,10], [7,11,-8], [-3,20,0]]); +true + +# +gap> mat := Matrix( [[2,4,5],[7,11,-4],[-3,20,0]]);; +gap> MultMatrixColumnRight(mat,1,-3); +gap> mat= Matrix( [ [-6,4,5], [-21,11,-4], [9,20,0]]); +true + +# +gap> mat := Matrix( [[2,4,5],[7,11,-4],[-3,20,0]]);; +gap> MultMatrixColumnLeft(mat,2,4); +gap> mat= Matrix( [ [2,16,5], [7,44,-4], [-3,80,0]]); +true + +# +gap> mat := Matrix( [[2,4,5],[7,11,-4],[-3,20,0]]);; +gap> AddMatrixRows(mat,2,1,-3); +gap> mat= Matrix( [ [2,4,5], [1,-1,-19], [-3,20,0]]); +true + +# +gap> mat := Matrix( [[2,4,5],[7,11,-4],[-3,20,0]]);; +gap> AddMatrixRowsLeft(mat,3,2,2); +gap> mat= Matrix( [ [2,4,5], [7,11,-4], [11,42,-8]]); +true + +# +gap> mat := Matrix( [[2,4,5],[7,11,-4],[-3,20,0]]);; +gap> AddMatrixRowsRight(mat,1,3,-3); +gap> mat= Matrix( [ [11,-56,5], [7,11,-4], [-3,20,0]]); +true + +# +gap> mat := Matrix( [[2,4,5],[7,11,-4],[-3,20,0]]);; +gap> AddMatrixColumns(mat,2,1,-3); +gap> mat= Matrix( [ [2,-2,5], [7,-10,-4], [-3,29,0]]); +true + +# +gap> mat := Matrix( [[2,4,5],[7,11,-4],[-3,20,0]]);; +gap> AddMatrixColumnsRight(mat,3,2,2); +gap> mat= Matrix( [ [2,4,13], [7,11,18], [-3,20,40]]); +true + +# +gap> mat := Matrix( [[2,4,5],[7,11,-4],[-3,20,0]]);; +gap> AddMatrixColumnsLeft(mat,1,3,-3); +gap> mat= Matrix( [ [-13,4,5], [19,11,-4], [-3,20,0]]); +true +gap> STOP_TEST("ElementaryMatrices.tst",1);