#################################### # # compatibility code for the new # IsMatrixObj interface # ####################################
InstallMethod( Length,
[ IsHomalgMatrix ], 0,
NumberColumns );
#################################### # # methods for operations: # ####################################
##----------------------------------------------------------------------------- # # put all methods to trace errors in LIMAT.gi with the very high priority 10001 # ##-----------------------------------------------------------------------------
MM := HomalgMatrixWithAttributes( [ Eval, RP!.ShallowCopy( M ),
NumberRows, NumberRows( M ),
NumberColumns, NumberColumns( M ),
], R );
MatchPropertiesAndAttributes( M, MM,
LIMAT.intrinsic_properties,
LIMAT.intrinsic_attributes,
LIMAT.intrinsic_components,
LIMAT.intrinsic_attributes_do_not_check_their_equality
);
MM := HomalgMatrixWithAttributes( [ Eval, RP!.ShallowCopy( M ),
NumberRows, NumberRows( M ),
NumberColumns, NumberColumns( M ),
], R );
if not IsIdenticalObj( Eval( M ), Eval( MM ) ) then
MatchPropertiesAndAttributes( M, MM,
LIMAT.intrinsic_properties,
LIMAT.intrinsic_attributes,
LIMAT.intrinsic_components,
LIMAT.intrinsic_attributes_do_not_check_their_equality
);
return MM;
fi; fi;
if not IsInternalMatrixHull( Eval( M ) ) then
TryNextMethod( ); fi;
return HomalgMatrix( One( R ) * Eval( M )!.matrix, NumberRows( M ), NumberColumns( M ), R );
## do not use HomalgZeroMatrix since ## we might want to alter the result
return HomalgInitialMatrix( NumberRows( M ), NumberColumns( M ), HomalgRing( M ) );
if not CompareVersionNumbers( GAPInfo.Version, "4.10" ) then
## copied from gap-4.10.2/lib/matobj.gi
# Install fallback methods for m[i,j] which delegate MatElm resp. SetMatElm, # for old MatrixObj implementation which don't provide them. We lower the rank # so that these are only used as a last resort.
InstallMethod( \[\], "for a matrix object and two positions",
[ IsMatrixObj, IsPosInt, IsPosInt ],
-RankFilter(IsMatrixObj), function( m, row, col )
return MatElm( m, row, col ); end );
InstallMethod( \[\]\:\=, "for a matrix object, two positions, and an object",
[ IsMatrixObj and IsMutable, IsPosInt, IsPosInt, IsObject ],
-RankFilter(IsMatrixObj), function( m, row, col, obj )
SetMatElm( m, row, col, obj ); end );
##
InstallMethod( GetListListOfStringsOfMatrix, "for matrices and a homalg internal ring",
[ IsList, IsHomalgInternalRingRep ],
function( M, R )
local c, d, z;
if not ForAll( M, IsList ) then
TryNextMethod( ); fi;
if not HasCharacteristic( R ) then
Error( "characteristic not set\n" ); fi;
c := Characteristic( R );
if c = 0then
return List( M, a -> List( a, String ) ); elif IsPrime( c ) then if HasDegreeOverPrimeField( R ) and DegreeOverPrimeField( R ) > 1then
d := DegreeOverPrimeField( R );
z := R!.NameOfPrimitiveElement;
return List( M, a -> List( a, b -> FFEToString( b, c, d, z ) ) ); fi;
return List( M, a -> List( a, b -> String( IntFFE( b ) ) ) ); fi;
return List( M, a -> List( a, b -> String( b![1] ) ) );
if not IsInternalMatrixHull( Eval( M ) ) then
TryNextMethod( ); fi;
s := Eval( M )!.matrix;
if HasCharacteristic( R ) then
m := Characteristic( R ); if m > 0 and not HasCoefficientsRing( R ) then## FIXME: we can only deal with Z/mZ and GF(p): m = Size( R ) !!! if IsPrime( m ) then
s := List( s, a -> List( a, IntFFE ) ); else
s := List( s, a -> List( a, b -> b![1] ) ); fi; fi; fi;
for i in [ 1 .. NumberRows( M ) ] do for j in [ 1 .. c ] do
e := M[ i, j ]; if not IsZero( e ) then
Add( s, [ String( i ), String( j ), String( e ) ] ); fi;
od;
od;
s := JoinStringsWithSeparator( List( s, JoinStringsWithSeparator ), "],[" );
if not IsInternalMatrixHull( Eval( M ) ) then
TryNextMethod( ); fi;
s := Eval( M )!.matrix;
if HasCharacteristic( R ) then
m := Characteristic( R ); if m > 0 and not HasCoefficientsRing( R ) then## FIXME: we can only deal with Z/mZ and GF(p): m = Size( R ) !!! if IsPrime( m ) then
s := List( s, a -> List( a, IntFFE ) ); else
s := List( s, a -> List( a, b -> b![1] ) ); fi; fi; fi;
r := NumberRows( M );
c := NumberColumns( M );
z := Zero( R );
s := List( [ 1 .. r ], a -> Filtered( List( [ 1 .. c ], function( b ) if s[a][b] <> z then return [ a, b, s[a][b] ]; else return 0; fi; end ), x -> x <> 0 ) );
## do not touch mutable matrices if not ( IsMutable( M1 ) or IsMutable( M2 ) ) then
MatchPropertiesAndAttributes( M1, M2,
LIMAT.intrinsic_properties,
LIMAT.intrinsic_attributes,
LIMAT.intrinsic_components,
LIMAT.intrinsic_attributes_do_not_check_their_equality
); fi;
return true;
fi;
elifEval( M1 ) = Eval( M2 ) then
## do not touch mutable matrices if not ( IsMutable( M1 ) or IsMutable( M2 ) ) then
MatchPropertiesAndAttributes( M1, M2,
LIMAT.intrinsic_properties,
LIMAT.intrinsic_attributes,
LIMAT.intrinsic_components,
LIMAT.intrinsic_attributes_do_not_check_their_equality
); fi;
return HomalgZeroMatrix( NumberRows( M ), NumberColumns( M ), HomalgRing( M ) );
end );
## <#GAPDoc Label="Involution"> ## <ManSection> ## <Meth Arg="M" Name="Involution" Label="for matrices"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## The twisted transpose of the &homalg; matrix <A>M</A>. If the underlying ring is commutative, the twist is the identity.<P/> ## (for the installed standard method see <Ref Meth="Eval" Label="for matrices created with Involution"/>) ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallMethod( Involution, "for homalg matrices",
[ IsHomalgMatrix ],
function( M )
local C;
C := HomalgMatrixWithAttributes( [
EvalInvolution, M,
NumberRows, NumberColumns( M ),
NumberColumns, NumberRows( M ),
], HomalgRing( M ) );
SetItsInvolution( M, C );
SetItsInvolution( C, M );
## <#GAPDoc Label="CertainRows"> ## <ManSection> ## <Meth Arg="M, plist" Name="CertainRows" Label="for matrices"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## The matrix of which the <M>i</M>-th row is the <M>k</M>-th row of the &homalg; matrix <A>M</A>, ## where <M>k=</M><A>plist</A><M>[i]</M>.<P/> ## (for the installed standard method see <Ref Meth="Eval" Label="for matrices created with CertainRows"/>) ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallMethod( CertainRows, "for homalg matrices",
[ IsHomalgMatrix, IsList ],
return HomalgMatrixWithAttributes( [
EvalCertainRows, [ M, plist ],
NumberRows, Length( plist ),
NumberColumns, NumberColumns( M )
], HomalgRing( M ) );
end );
##
InstallOtherMethod( \[\], "for a homalg matrix and a positive integer",
[ IsHomalgMatrix, IsInt ],
function( M, r )
return CertainRows( M, [ r ] );
end );
##
InstallOtherMethod( \{\}, "for a homalg matrix and a positive integer",
[ IsHomalgMatrix, IsList ],
CertainRows );
## <#GAPDoc Label="CertainColumns"> ## <ManSection> ## <Meth Arg="M, plist" Name="CertainColumns" Label="for matrices"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## The matrix of which the <M>j</M>-th column is the <M>l</M>-th column of the &homalg; matrix <A>M</A>, ## where <M>l=</M><A>plist</A><M>[j]</M>.<P/> ## (for the installed standard method see <Ref Meth="Eval" Label="for matrices created with CertainColumns"/>) ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallMethod( CertainColumns, "for homalg matrices",
[ IsHomalgMatrix, IsList ],
return HomalgMatrixWithAttributes( [
EvalCertainColumns, [ M, plist ],
NumberColumns, Length( plist ),
NumberRows, NumberRows( M )
], HomalgRing( M ) );
end );
## <#GAPDoc Label="UnionOfRows"> ## <ManSection> ## <Func Arg="[R, nr_cols, ]L" Name="UnionOfRows" Label="for a homalg ring, an integer and a list of homalg matrices"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## Stack the &homalg; matrices in the list <A>L</A>. The entries of <A>L</A> must be matrices over the &homalg; ring <A>R</A> with <A>nr_cols</A> columns. ## If <A>L</A> is non-empty, <A>R</A> and <A>nr_cols</A> can be omitted.<P/> ## ## (for the installed standard method see <Ref Meth="Eval" Label="for matrices created with UnionOfRows"/>) ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallGlobalFunction( UnionOfRows, function( arg )
local R, nr_cols, list;
if IsEmpty( arg ) then
Error( "<arg> must be nonempty" ); elif IsHomalgMatrix( arg[1] ) then # UnionOfRows( mat1, mat2, ... )
list := arg;
R := HomalgRing( list[1] );
nr_cols := NumberColumns( list[1] ); elif Length( arg ) = 1 and IsList( arg[1] ) then # UnionOfRows( [ mat1, mat2, ... ] ) if IsEmpty( arg[1] ) then
Error( "<arg>[1] must be nonempty" ); fi;
list := arg[1];
R := HomalgRing( list[1] );
nr_cols := NumberColumns( list[1] ); elif Length( arg ) = 3 and IsHomalgRing( arg[1] ) and IsInt( arg[2] ) and IsList( arg[3] ) then # UnionOfRows( ring, nr_cols, [ mat1, mat2, ... ] )
R := arg[1];
nr_cols := arg[2];
list := arg[3]; else
Error("usage: UnionOfRows( mat1, mat2, ... ) or UnionOfRows( [ mat1, mat2, ... ] ) or UnionOfRows( ring, nr_cols, [ mat1, mat2, ... ] )"); fi;
return UnionOfRowsOp( R, nr_cols, list );
end );
##
InstallMethod( UnionOfRowsOp, "of a homalg ring, an integer and a list of homalg matrices",
[ IsHomalgRing, IsInt, IsList ],
function( R, nr_cols, L )
local result;
result := HomalgMatrixWithAttributes( [
EvalUnionOfRows, L,
NumberRows, Sum( List( L, NumberRows ) ),
NumberColumns, nr_cols
], R );
if IsBound( HOMALG_MATRICES.UnionOfRowsEager ) and HOMALG_MATRICES.UnionOfRowsEager = true then Eval( result ); fi;
return result;
end );
##
InstallGlobalFunction( UnionOfRowsEager, function( arg )
local nargs;
nargs := Length( arg );
if nargs = 0then
Error( "<arg> must be nonempty" ); elif Length( arg ) = 1 and IsList( arg[1] ) then if IsEmpty( arg[1] ) then
Error( "<arg>[1] must be nonempty" ); fi;
arg := arg[1]; fi;
return UnionOfRowsEagerOp( arg, arg[1] );
end );
##
InstallMethod( UnionOfRowsEagerOp, "of a list of homalg matrices and a homalg matrix",
[ IsList, IsHomalgMatrix ],
## <#GAPDoc Label="UnionOfColumns"> ## <ManSection> ## <Func Arg="[R, nr_rows, ]L" Name="UnionOfColumns" Label="for a homalg ring, an integer and a list of homalg matrices"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## Augment the &homalg; matrices in the list <A>L</A>. The entries of <A>L</A> must be matrices over the &homalg; ring <A>R</A> with <A>nr_rows</A> rows. ## If <A>L</A> is non-empty, <A>R</A> and <A>nr_rows</A> can be omitted.<P/> ## ## (for the installed standard method see <Ref Meth="Eval" Label="for matrices created with UnionOfColumns"/>) ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallGlobalFunction( UnionOfColumns, function( arg )
local R, nr_rows, list;
if IsEmpty( arg ) then
Error( "<arg> must be nonempty" ); elif IsHomalgMatrix( arg[1] ) then # UnionOfColumns( mat1, mat2, ... )
list := arg;
R := HomalgRing( list[1] );
nr_rows := NumberRows( list[1] ); elif Length( arg ) = 1 and IsList( arg[1] ) then # UnionOfColumns( [ mat1, mat2, ... ] ) if IsEmpty( arg[1] ) then
Error( "<arg>[1] must be nonempty" ); fi;
list := arg[1];
R := HomalgRing( list[1] );
nr_rows := NumberRows( list[1] ); elif Length( arg ) = 3 and IsHomalgRing( arg[1] ) and IsInt( arg[2] ) and IsList( arg[3] ) then # UnionOfColumns( ring, nr_rows, [ mat1, mat2, ... ] )
R := arg[1];
nr_rows := arg[2];
list := arg[3]; else
Error("usage: UnionOfColumns( mat1, mat2, ... ) or UnionOfColumns( [ mat1, mat2, ... ] ) or UnionOfColumns( ring, nr_rows, [ mat1, mat2, ... ] )"); fi;
return UnionOfColumnsOp( R, nr_rows, list );
end );
##
InstallMethod( UnionOfColumnsOp, "of a list of homalg matrices and a homalg matrix",
[ IsHomalgRing, IsInt, IsList ],
function( R, nr_rows, L )
local result;
result := HomalgMatrixWithAttributes( [
EvalUnionOfColumns, L,
NumberRows, nr_rows,
NumberColumns, Sum( List( L, NumberColumns ) )
], R );
if IsBound( HOMALG_MATRICES.UnionOfColumnsEager ) and HOMALG_MATRICES.UnionOfColumnsEager = true then Eval( result ); fi;
return result;
end );
##
InstallGlobalFunction( UnionOfColumnsEager, function( arg )
local nargs;
nargs := Length( arg );
if nargs = 0then
Error( "<arg> must be nonempty" ); elif Length( arg ) = 1 and IsList( arg[1] ) then if IsEmpty( arg[1] ) then
Error( "<arg>[1] must be nonempty" ); fi;
arg := arg[1]; fi;
return UnionOfColumnsEagerOp( arg, arg[1] );
end );
##
InstallMethod( UnionOfColumnsEagerOp, "of a list of homalg matrices and a homalg matrix",
[ IsList, IsHomalgMatrix ],
if c = 0 or ( HasIsZero( M ) and IsZero( M ) ) then
return HomalgZeroMatrix( r * c, 1, R ); fi;
C := HomalgMatrixWithAttributes( [
EvalConvertMatrixToColumn, M,
NumberRows, r * c,
NumberColumns, 1,
], R );
return C;
end );
## <#GAPDoc Label="DiagMat"> ## <ManSection> ## <Meth Arg="[R, ]list" Name="DiagMat" Label="for a homalg ring and a list of homalg matrices"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## Build the block diagonal matrix out of the &homalg; matrices listed in <A>list</A>. ## If <A>list</A> is non-empty, <A>R</A> can be omitted.<P/> ## ## (for the installed standard method see <Ref Meth="Eval" Label="for matrices created with DiagMat"/>) ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallMethod( DiagMat, "of a homalg ring and a list of homalg matrices",
[ IsHomalgRing, IsHomogeneousList ],
## # convenience
InstallOtherMethod( DiagMat, "of a list of homalg matrices",
[ IsHomogeneousList ],
function( list )
if IsEmpty( list ) then
Error( "the given list of diagonal blocks is empty\n" ); fi;
return DiagMat( HomalgRing( list[1] ), list );
end );
## <#GAPDoc Label="KroneckerMat"> ## <ManSection> ## <Meth Arg="A, B" Name="KroneckerMat" Label="for matrices"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## The Kronecker (or tensor) product of the two &homalg; matrices <A>A</A> and <A>B</A>.<P/> ## (for the installed standard method see <Ref Meth="Eval" Label="for matrices created with KroneckerMat"/>) ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallMethod( KroneckerMat, "of two homalg matrices",
[ IsHomalgMatrix, IsHomalgMatrix ],
function( A, B )
return HomalgMatrixWithAttributes( [
EvalKroneckerMat, [ A, B ],
NumberRows, NumberRows( A ) * NumberRows( B ),
NumberColumns, NumberColumns( A ) * NumberColumns ( B )
], HomalgRing( A ) );
end );
## <#GAPDoc Label="DualKroneckerMat"> ## <ManSection> ## <Meth Arg="A, B" Name="DualKroneckerMat" Label="for matrices"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## The dual Kronecker product of the two &homalg; matrices <A>A</A> and <A>B</A>.<P/> ## (for the installed standard method see <Ref Meth="Eval" Label="for matrices created with DualKroneckerMat"/>) ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallMethod( DualKroneckerMat, "of two homalg matrices",
[ IsHomalgMatrix, IsHomalgMatrix ],
function( A, B )
return HomalgMatrixWithAttributes( [
EvalDualKroneckerMat, [ A, B ],
NumberRows, NumberRows( A ) * NumberRows( B ),
NumberColumns, NumberColumns( A ) * NumberColumns ( B )
], HomalgRing( A ) );
end );
##
InstallMethod( \*, "for internal matrix hulls",
[ IsRingElement, IsInternalMatrixHull ], 1001, ## it could otherwise run into the method ``PROD: negative integer * additive element with inverse'', value: 24
function( a, A )
return homalgInternalMatrixHull( a * A!.matrix );
end );
## <#GAPDoc Label="MulMat"> ## <ManSection> ## <Meth Arg="a, A" Name="\*" Label="for ring elements and matrices"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## The product of the ring element <A>a</A> with the &homalg; matrix <A>A</A> (enter: <A>a</A> <C>*</C> <A>A</A>;).<P/> ## (for the installed standard method see <Ref Meth="Eval" Label="for matrices created with MulMat"/>) ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallMethod( \*, "for a homalg matrix and a homalg ring element",
[ IsHomalgMatrix, IsRingElement ], 1001, ## it could otherwise run into the method ``PROD: negative integer * additive element with inverse'', value: 24 (if this value is increased, the corresonding values for \* in LIMAT, COLEM, and below must be increased as well!!!)
function( A, a )
return HomalgMatrixWithAttributes( [
EvalMulMatRight, [ A, a ],
NumberRows, NumberRows( A ),
NumberColumns, NumberColumns( A )
], HomalgRing( A ) );
end );
##
InstallMethod( \*, "for a homalg ring element and a homalg matrix",
[ IsRingElement, IsHomalgMatrix ], 1001, ## it could otherwise run into the method ``PROD: negative integer * additive element with inverse'', value: 24 (if this value is increased, the corresonding values for \* in LIMAT, COLEM, and below must be increased as well!!!)
function( a, A )
return HomalgMatrixWithAttributes( [
EvalMulMat, [ a, A ],
NumberRows, NumberRows( A ),
NumberColumns, NumberColumns( A )
], HomalgRing( A ) );
## <#GAPDoc Label="Compose:matrix"> ## <ManSection> ## <Meth Arg="A, B" Name="\*" Label="for composable matrices"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## The matrix product of the two &homalg; matrices <A>A</A> and <A>B</A> (enter: <A>A</A> <C>*</C> <A>B</A>;).<P/> ## (for the installed standard method see <Ref Meth="Eval" Label="for matrices created with Compose"/>) ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallMethod( \*, "for pairs of homalg matrices",
[ IsHomalgMatrix, IsHomalgMatrix ], 14001, ## it could otherwise run into the method ``PROD: IsRingElement * IsHomalgMatrix'', value: 1001 (if this value is increased, the corresonding values in LIMAT must be increased as well!!!)
function( A, B )
return HomalgMatrixWithAttributes( [
EvalCompose, [ A, B ],
NumberRows, NumberRows( A ),
NumberColumns, NumberColumns( B )
], HomalgRing( A ) );
if not HasIsCommutative( R ) then
Error( "the ring is not known to be commutative\n" ); elif not IsCommutative( R ) then
Error( "the ring is not commutative\n" ); fi;
m := NumberRows( C );
if not m = NumberColumns( C ) then
Error( "the input ", m, "x", NumberColumns( C ), "-matrix is not quadratic\n" ); fi;
m := [ 1 .. m ];
A := List( m, c -> List( m, r -> (-1)^(r+c) * Determinant( CertainRows( CertainColumns( C, Difference( m, [ c ] ) ), Difference( m, [ r ] ) ) ) ) );
return HomalgMatrix( A, R );
end );
## <#GAPDoc Label="LeftInverseLazy"> ## <ManSection> ## <Oper Arg="M" Name="LeftInverseLazy" Label="for matrices"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## A lazy evaluated left inverse <M>C</M> of the matrix <A>M</A>. If no left inverse exists then ## <C>Eval</C>( <A>C</A> ) will issue an error.<P/> ## (for the installed standard method see <Ref Meth="Eval" Label="for matrices created with LeftInverseLazy"/>) ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallMethod( LeftInverseLazy, "for homalg matrices",
[ IsHomalgMatrix ],
function( M )
local C;
## we assume the LeftInverse exists
C := HomalgMatrixWithAttributes( [
EvalLeftInverse, M,
NumberRows, NumberColumns( M ),
NumberColumns, NumberRows( M )
], HomalgRing( M ) );
## check assertion
Assert( 6, not IsBool( Eval( C ) ) );
## SetLeftInverse( M, C ) will cause a infinite loop
return C;
end );
## <#GAPDoc Label="RightInverseLazy"> ## <ManSection> ## <Oper Arg="M" Name="RightInverseLazy" Label="for matrices"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## A lazy evaluated right inverse <M>C</M> of the matrix <A>M</A>. If no right inverse exists then ## <C>Eval</C>( <A>C</A> ) will issue an error.<P/> ## (for the installed standard method see <Ref Meth="Eval" Label="for matrices created with RightInverseLazy"/>) ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallMethod( RightInverseLazy, "for homalg matrices",
[ IsHomalgMatrix ],
function( M )
local C;
## we assume the RightInverse exists
C := HomalgMatrixWithAttributes( [
EvalRightInverse, M,
NumberColumns, NumberRows( M ),
NumberRows, NumberColumns( M )
], HomalgRing( M ) );
## check assertion
Assert( 6, not IsBool( Eval( C ) ) );
## SetRightInverse( M, C ) will cause a infinite loop
if not HasIsCommutative( R ) then
Error( "the ring is not known to be commutative\n" ); elif not IsCommutative( R ) then
Error( "the ring is not commutative\n" ); fi;
if d <= 0then
return [ One( R ) ]; fi;
r := NumberRows( M );
c := NumberColumns( M );
if d > Minimum( r, c ) then
return [ Zero( R ) ]; fi;
l := Cartesian( Combinations( [ 1 .. r ], d ), Combinations( [ 1 .. c ], d ) );
l := List( l, rc -> Determinant( CertainColumns( CertainRows( M, rc[1] ), rc[2] ) ) );
function( M )
local R, c, d, rank, iter, save, F, r;
R := HomalgRing( M );
if not IsFieldForHomalg( R ) or
( not HasCharacteristic( R ) or Characteristic( R ) = 0 ) or
( not HasDegreeOverPrimeField( R ) or not IsInt( DegreeOverPrimeField( R ) ) ) then
TryNextMethod( ); fi;
c := Characteristic( R );
d := DegreeOverPrimeField( R );
M := BasisOfRows( M );
if not IsLeftRegular( M ) then
TryNextMethod( ); fi;
rank := RowRankOfMatrix( M );
iter := Iterator( GF(c^d)^rank );
if IsHomalgInternalRingRep( R ) then
F := R; else
F := HomalgRingOfIntegers( c, d ); fi;
r := rec(
ring := R,
iter := iter,
matrix := M,
rank := rank,
GF := F,
NextIterator := function( i )
local mat;
mat := HomalgMatrix( NextIterator( i!.iter ), 1, i!.rank, i!.GF );
SetNumberRows( mat, 1 ); ## should be obsolete
SetNumberColumns( mat, i!.rank ); ## should be obsolete
return ( i!.ring * mat ) * i!.matrix; end,
IsDoneIterator := function( i )
return IsDoneIterator( i!.iter ); end,
ShallowCopy := function( i );
return
rec(
ring := i!.ring,
iter := ShallowCopy( i!.iter ),
matrix := i!.matrix,
rank := i!.rank,
GF := i!.GF,
NextIterator := i!.NextIterator,
IsDoneIterator := i!.IsDoneIterator,
ShallowCopy := i!.ShallowCopy
); end
);
return IteratorByFunctions( r );
end );
##
InstallMethod( Select, "for a matrix and a list",
[ IsHomalgMatrix, IsList ],
function( M, L )
local R, indets, zero, map, N;
R := HomalgRing( M );
if HasRelativeIndeterminatesOfPolynomialRing( R ) then
indets := RelativeIndeterminatesOfPolynomialRing( R ); elif HasIndeterminatesOfPolynomialRing( R ) then
indets := IndeterminatesOfPolynomialRing( R ); else
TryNextMethod( ); fi;
if not IsSubset( indets, L ) then
Error( "the second argument is not a subset of the list of indeterminates\n" ); fi;
zero := Zero( R );
map := List( indets, function( a ) if a in L then return a; else return zero; fi; end );
map := RingMap( map, R, R );
N := Pullback( map, M );
return CertainRows( M, ZeroRows( M - N ) );
end );
#################################### # # constructor functions and methods: # ####################################
##
InstallGlobalFunction( homalgInternalMatrixHull, function( M )
return Objectify( TheTypeInternalMatrixHull, rec( matrix := M ) );
if IsMatrix( s ) then
return HomalgMatrix( s, r, c, R ); elif IsList( s ) then
return HomalgMatrix( ListToListList( s, r, c ), r, c, R ); else
Error( "the evaluated string is not in {IsMatrix, IsList}\n" ); fi;
if IsList( L[1] ) then
M := List( L, r -> List( r, String ) );
M := Concatenation( "[[", JoinStringsWithSeparator( List( M, r -> JoinStringsWithSeparator( r ) ), "],[" ), "]]" ); else ## this resembles NormalizeInput in Maple's homalg ( a legacy ;) )
M := Concatenation( "[[", JoinStringsWithSeparator( List( L, String ), "],[" ), "]]" ); ## What is the use case for this? Wouldn't it be better to replace this by an error message? # Error( "the number of rows and columns must be specified to construct a matrix from a list" ); fi;
elif not IsHomalgInternalRingRep( R ) and ## the ring R is not internal,
( IsList( M ) or ## while M is either a list of ring elements,
IsMatrix( M ) ) then## or a matrix of (hopefully) ring elements
if not IsHomalgRing( R ) then
Error( "the last argument must be an IsHomalgRing\n" ); fi;
## here we take care of the degenerate input M = [ ] for all rings if M = [ ] then## CreateHomalgMatrixFromString also covers M = "", "[]", etc. if nargs = 2then
return HomalgZeroMatrix( 0, 0, R ); else
return CallFuncList( HomalgZeroMatrix, arg{[ 2 .. nargs ]} ); fi; fi;
if HasTypeOfHomalgMatrix( R ) then
type := TypeOfHomalgMatrix( R ); elif IsHomalgInternalRingRep( R ) then
type := TheTypeHomalgInternalMatrix; else
Error( "the homalg ring must contain the type of the matrices as the attribute TypeOfHomalgMatrix\n" ); fi;
matrix := rec( ring := R );
## here we take care of the case when only the ring is given if nargs = 1then
## Objectify:
Objectify( type, matrix );
## an empty matrix
return matrix;
fi;
RP := homalgTable( R );
if IsList( M ) and Length( M ) > 0 and not IsList( M[1] ) and
ForAll( M, IsRingElement ) then if IsBound( R!.pre_matrix_constructor ) then
M := R!.pre_matrix_constructor( M ); ## [ 0, x ] fi; if Length( arg ) > 2 and arg[2] in NonnegativeIntegers then
M := ListToListList( M, arg[2], Length( M ) / arg[2] ); else
M := List( M, a -> [ a ] ); ## this resembles NormalizeInput in Maple's homalg ( a legacy ;) ) fi;
if IsBound(RP!.ImportMatrix) then
M := RP!.ImportMatrix( M, R ); fi; elif IsInternalMatrixHull( M ) then## why are we doing this? for ShallowCopy? if IsMatrix( M!.matrix ) then
M := M!.matrix; else
M := homalgInternalMatrixHull( M!.matrix ); fi; elif IsMatrix( M ) and IsBound(RP!.ImportMatrix) then
M := RP!.ImportMatrix( M, R ); elif IsList( M ) and Length( M ) > 0 and IsBound( R!.pre_matrix_constructor ) then
M := R!.pre_matrix_constructor( M ); ## [ 0, x ] else
M := ShallowCopy( M ); ## by this we are sure that possible changes to a mutable GAP matrix arg[1] does not destroy the logic of homalg fi;
if IsHomalgInternalRingRep( R ) and
not IsInternalMatrixHull( M ) then## TheTypeHomalgInternalMatrix
if IsMatrix( M ) then ## Objectify:
ObjectifyWithAttributes(
matrix, type,
NumberRows, Length( M ),
NumberColumns, Length( M[1] ), Eval, homalgInternalMatrixHull( M ) ); elif IsList( M ) then ## Objectify:
ObjectifyWithAttributes(
matrix, type, Eval, homalgInternalMatrixHull( M ) ); if M = [ ] then
SetNumberRows( matrix, 0 );
SetNumberColumns( matrix, 0 ); elif M[1] = [] then
SetNumberRows( matrix, Length( M ) );
SetNumberColumns( matrix, 0 ); fi; else if Length( arg ) > 2 and arg[2] in NonnegativeIntegers then
nr_rows := true; else
nr_rows := false; fi;
if Length( arg ) > 3 and arg[3] in NonnegativeIntegers then
nr_columns := true; else
nr_columns := false; fi;
if nr_rows and nr_columns then ## Objectify:
ObjectifyWithAttributes(
matrix, type,
NumberRows, arg[2],
NumberColumns, arg[3], Eval, M ); else ## Objectify:
ObjectifyWithAttributes(
matrix, type, Eval, M );
if nr_rows then
SetNumberRows( matrix, arg[2] ); fi;
if nr_columns then
SetNumberColumns( matrix, arg[3] ); fi; fi; fi;
else
if Length( arg ) > 2 and arg[2] in NonnegativeIntegers then
nr_rows := true; else
nr_rows := false; fi;
if Length( arg ) > 3 and arg[3] in NonnegativeIntegers then
nr_columns := true; else
nr_columns := false; fi;
if nr_rows and nr_columns then ## Objectify:
ObjectifyWithAttributes(
matrix, type,
NumberRows, arg[2],
NumberColumns, arg[3], Eval, M ); else ## Objectify:
ObjectifyWithAttributes(
matrix, type, Eval, M );
if nr_rows then
SetNumberRows( matrix, arg[2] ); fi;
if nr_columns then
SetNumberColumns( matrix, arg[3] ); fi; fi;
fi;
return matrix;
end );
## <#GAPDoc Label="HomalgMatrixListList"> ## <ManSection> ## <Func Arg="llist, m, n, R" Name="HomalgMatrixListList" Label="constructor for matrices using a listlist with given dimensions"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## Special case of <Ref Meth="HomalgMatrix" Label="constructor for matrices using a listlist with given dimensions"/>. ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallGlobalFunction( HomalgMatrixListList, function( llist, m, n, R )
if m > 0 and n > 0then
Assert( 1, IsList( llist ) and Length( llist ) = m );
Assert( 1, ForAll( llist, list -> IsList( list ) and Length( list ) = n ) );
fi;
return HomalgMatrix( llist, m, n, R );
end );
## <#GAPDoc Label="HomalgRowVector"> ## <ManSection> ## <Func Arg="entries, nr_cols, R" Name="HomalgRowVector" Label="constructor for matrices with a single row"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## Special case of <Ref Meth="HomalgMatrix" Label="constructor for matrices using a list"/> for matrices with a single row. ## <A>entries</A> must be a list of ring elements. ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallGlobalFunction( HomalgRowVector, function( entries, c, R )
return HomalgMatrixListList( [ entries ], 1, c, R );
end );
## <#GAPDoc Label="HomalgColumnVector"> ## <ManSection> ## <Func Arg="entries, nr_rows, R" Name="HomalgColumnVector" Label="constructor for matrices with a single column"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## Special case of <Ref Meth="HomalgMatrix" Label="constructor for matrices using a list"/> for matrices with a single column. ## <A>entries</A> must be a list of ring elements. ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallGlobalFunction( HomalgColumnVector, function( entries, r, R )
return HomalgMatrixListList( List( entries, x -> [ x ] ), r, 1, R );
end );
##
InstallGlobalFunction( HomalgMatrixWithAttributes, function( attributes, R )
local matrix;
## for performance reasons this internal function ## should not perform syntax checks
if HOMALG_MATRICES.Eager = true and not IsEmptyMatrix( matrix ) then Eval( matrix ); fi;
return matrix;
end );
## <#GAPDoc Label="HomalgZeroMatrix"> ## <ManSection> ## <Func Arg="m, n, R" Name="HomalgZeroMatrix" Label="constructor for zero matrices"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## An immutable unevaluated <M><A>m</A> \times <A>n</A></M> &homalg; zero matrix over the &homalg; ring <A>R</A>. ## <Example><![CDATA[ ## gap> zz := HomalgRingOfIntegers( ); ## Z ## gap> z := HomalgZeroMatrix( 2, 3, zz ); ## <An unevaluated 2 x 3 zero matrix over an internal ring> ## gap> Display( z ); ## [ [ 0, 0, 0 ], ## [ 0, 0, 0 ] ] ## gap> z; ## <A 2 x 3 zero matrix over an internal ring> ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallGlobalFunction( HomalgZeroMatrix, function( arg ) ## the zero matrix
local R, type, matrix, nr_rows, nr_columns;
R := arg[Length( arg )];
if not IsHomalgRing( R ) then
Error( "the last argument must be an IsHomalgRing\n" ); fi;
if HasTypeOfHomalgMatrix( R ) then
type := TypeOfHomalgMatrix( R ); elif IsHomalgInternalRingRep( R ) then
type := TheTypeHomalgInternalMatrix; else
Error( "the homalg ring must contain the type of the matrices as the attribute TypeOfHomalgMatrix\n" ); fi;
matrix := rec( ring := R );
if Length( arg ) > 1 and arg[1] in NonnegativeIntegers then
nr_rows := true; else
nr_rows := false; fi;
if Length( arg ) > 2 and arg[2] in NonnegativeIntegers then
nr_columns := true; else
nr_columns := false; fi;
if nr_rows and nr_columns then
## cache the 1 x 1 zero matrix if nr_rows = 1 and nr_columns = 1then if IsBound( R!.OneByOneZeroMatrix ) then
return R!.OneByOneZeroMatrix; else
R!.OneByOneZeroMatrix := matrix; fi; fi;
if nr_rows then
SetNumberRows( matrix, arg[1] ); fi;
if nr_columns then
SetNumberColumns( matrix, arg[2] ); fi; fi;
return matrix;
end );
## <#GAPDoc Label="HomalgIdentityMatrix"> ## <ManSection> ## <Func Arg="m, R" Name="HomalgIdentityMatrix" Label="constructor for identity matrices"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## An immutable unevaluated <M><A>m</A> \times <A>m</A></M> &homalg; identity matrix over the &homalg; ring <A>R</A>. ## <Example><![CDATA[ ## gap> zz := HomalgRingOfIntegers( ); ## Z ## gap> id := HomalgIdentityMatrix( 3, zz ); ## <An unevaluated 3 x 3 identity matrix over an internal ring> ## gap> Display( id ); ## [ [ 1, 0, 0 ], ## [ 0, 1, 0 ], ## [ 0, 0, 1 ] ] ## gap> id; ## <A 3 x 3 identity matrix over an internal ring> ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallGlobalFunction( HomalgIdentityMatrix, function( arg ) ## the identity matrix
local R, type, matrix;
R := arg[Length( arg )];
if not IsHomalgRing( R ) then
Error( "the last argument must be an IsHomalgRing\n" ); fi;
if HasTypeOfHomalgMatrix( R ) then
type := TypeOfHomalgMatrix( R ); elif IsHomalgInternalRingRep( R ) then
type := TheTypeHomalgInternalMatrix; else
Error( "the homalg ring must contain the type of the matrices as the attribute TypeOfHomalgMatrix\n" ); fi;
matrix := rec( ring := R );
if Length( arg ) > 1 and arg[1] in NonnegativeIntegers then ## Objectify:
ObjectifyWithAttributes(
matrix, type,
NumberRows, arg[1],
NumberColumns, arg[1],
IsOne, true ); else ## Objectify:
ObjectifyWithAttributes(
matrix, type,
IsOne, true ); fi;
return matrix;
end );
## <#GAPDoc Label="HomalgInitialMatrix"> ## <ManSection> ## <Func Arg="m, n, R" Name="HomalgInitialMatrix" Label="constructor for initial matrices filled with zeros"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## A mutable unevaluated initial <M><A>m</A> \times <A>n</A></M> &homalg; matrix filled with zeros ## over the &homalg; ring <A>R</A>. This construction is useful in case one wants to define a matrix ## by assigning its nonzero entries. ## The property <Ref Prop="IsInitialMatrix"/> is reset as soon as the matrix is evaluated. ## New computed properties or attributes of the matrix won't be cached, ## until the matrix is explicitly made immutable using (&see; <Ref Func="MakeImmutable" ## BookName="Reference" Style="Number"/>). ## <Example><![CDATA[ ## gap> zz := HomalgRingOfIntegers( ); ## Z ## gap> z := HomalgInitialMatrix( 2, 3, zz ); ## <An initial 2 x 3 matrix over an internal ring> ## gap> HasIsZero( z ); ## false ## gap> IsZero( z ); ## true ## gap> z; ## <A 2 x 3 mutable matrix over an internal ring> ## gap> HasIsZero( z ); ## false ## ]]></Example> ## <Example><![CDATA[ ## gap> n := HomalgInitialMatrix( 2, 3, zz ); ## <An initial 2 x 3 matrix over an internal ring> ## gap> n[ 1, 1 ] := "1";; ## gap> n[ 2, 3 ] := "1";; ## gap> MakeImmutable( n ); ## <A 2 x 3 matrix over an internal ring> ## gap> Display( n ); ## [ [ 1, 0, 0 ], ## [ 0, 0, 1 ] ] ## gap> IsZero( n ); ## false ## gap> n; ## <A non-zero 2 x 3 matrix over an internal ring> ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallGlobalFunction( HomalgInitialMatrix, function( arg ) ## an initial matrix having the flag IsInitialMatrix
local R, type, matrix, nr_rows, nr_columns; ## and filled with zeros BUT NOT marked as an IsZero
R := arg[Length( arg )];
if not IsHomalgRing( R ) then
Error( "the last argument must be an IsHomalgRing\n" ); fi;
if HasTypeOfHomalgMatrix( R ) then
type := TypeOfHomalgMatrix( R ); elif IsHomalgInternalRingRep( R ) then
type := TheTypeHomalgInternalMatrix; else
Error( "the homalg ring must contain the type of the matrices as the attribute TypeOfHomalgMatrix\n" ); fi;
matrix := rec( ring := R );
if Length( arg ) > 1 and arg[1] in NonnegativeIntegers then
nr_rows := true; else
nr_rows := false; fi;
if Length( arg ) > 2 and arg[2] in NonnegativeIntegers then
nr_columns := true; else
nr_columns := false; fi;
if nr_rows and nr_columns then ## Objectify:
ObjectifyWithAttributes(
matrix, type,
NumberRows, arg[1],
NumberColumns, arg[2],
IsInitialMatrix, true ); else ## Objectify:
ObjectifyWithAttributes(
matrix, type,
IsInitialMatrix, true );
if nr_rows then
SetNumberRows( matrix, arg[1] ); fi;
if nr_columns then
SetNumberColumns( matrix, arg[2] ); fi; fi;
SetIsMutableMatrix( matrix, true );
return matrix;
end );
## <#GAPDoc Label="HomalgInitialIdentityMatrix"> ## <ManSection> ## <Func Arg="m, R" Name="HomalgInitialIdentityMatrix" Label="constructor for initial quadratic matrices with ones on the diagonal"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## A mutable unevaluated initial <M><A>m</A> \times <A>m</A></M> &homalg; quadratic matrix with ones ## on the diagonal over the &homalg; ring <A>R</A>. This construction is useful in case one wants to define ## an elementary matrix by assigning its off-diagonal nonzero entries. ## The property <Ref Prop="IsInitialIdentityMatrix"/> is reset as soon as the matrix is evaluated. ## New computed properties or attributes of the matrix won't be cached, ## until the matrix is explicitly made immutable using (&see; <Ref Func="MakeImmutable" ## BookName="Reference" Style="Number"/>). ## <Example><![CDATA[ ## gap> zz := HomalgRingOfIntegers( ); ## Z ## gap> id := HomalgInitialIdentityMatrix( 3, zz ); ## <An initial identity 3 x 3 matrix over an internal ring> ## gap> HasIsOne( id ); ## false ## gap> IsOne( id ); ## true ## gap> id; ## <A 3 x 3 mutable matrix over an internal ring> ## gap> HasIsOne( id ); ## false ## ]]></Example> ## <Example><![CDATA[ ## gap> e := HomalgInitialIdentityMatrix( 3, zz ); ## <An initial identity 3 x 3 matrix over an internal ring> ## gap> e[ 1, 2 ] := "1";; ## gap> e[ 2, 1 ] := "-1";; ## gap> MakeImmutable( e ); ## <A 3 x 3 matrix over an internal ring> ## gap> Display( e ); ## [ [ 1, 1, 0 ], ## [ -1, 1, 0 ], ## [ 0, 0, 1 ] ] ## gap> IsOne( e ); ## false ## gap> e; ## <A 3 x 3 matrix over an internal ring> ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallGlobalFunction( HomalgInitialIdentityMatrix, function( arg ) ## a square initial matrix having the flag IsInitialIdentityMatrix
local R, type, matrix; ## and filled with an identity matrix BUT NOT marked as an IsOne
R := arg[Length( arg )];
if not IsHomalgRing( R ) then
Error( "the last argument must be an IsHomalgRing\n" ); fi;
if HasTypeOfHomalgMatrix( R ) then
type := TypeOfHomalgMatrix( R ); elif IsHomalgInternalRingRep( R ) then
type := TheTypeHomalgInternalMatrix; else
Error( "the homalg ring must contain the type of the matrices as the attribute TypeOfHomalgMatrix\n" ); fi;
matrix := rec( ring := R );
if Length( arg ) > 1 and arg[1] in NonnegativeIntegers then ## Objectify:
ObjectifyWithAttributes(
matrix, type,
NumberRows, arg[1],
NumberColumns, arg[1],
IsInitialIdentityMatrix, true ); else ## Objectify:
ObjectifyWithAttributes(
matrix, type,
IsInitialIdentityMatrix, true ); fi;
SetIsMutableMatrix( matrix, true );
return matrix;
end );
## <#GAPDoc Label="HomalgVoidMatrix"> ## <ManSection> ## <Func Arg="[ m,][ n,] R" Name="HomalgVoidMatrix" Label="constructor for void matrices"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## A void <M><A>m</A> \times <A>n</A></M> &homalg; matrix. ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallGlobalFunction( HomalgVoidMatrix, function( arg ) ## a void matrix filled with nothing having the flag IsVoidMatrix
local R, type, matrix, nr_rows, nr_columns;
R := arg[Length( arg )];
if not IsHomalgRing( R ) then
Error( "the last argument must be an IsHomalgRing\n" ); fi;
if HasTypeOfHomalgMatrix( R ) then
type := TypeOfHomalgMatrix( R ); elif IsHomalgInternalRingRep( R ) then
type := TheTypeHomalgInternalMatrix; else
Error( "the homalg ring must contain the type of the matrices as the attribute TypeOfHomalgMatrix\n" ); fi;
matrix := rec( ring := R );
if Length( arg ) > 1 and arg[1] in NonnegativeIntegers then
nr_rows := true; else
nr_rows := false; fi;
if Length( arg ) > 2 and arg[2] in NonnegativeIntegers then
nr_columns := true; else
nr_columns := false; fi;
if nr_rows and nr_columns then ## Objectify:
ObjectifyWithAttributes(
matrix, type,
NumberRows, arg[1],
NumberColumns, arg[2],
IsVoidMatrix, true ); else ## Objectify:
ObjectifyWithAttributes(
matrix, type,
IsVoidMatrix, true );
if nr_rows then
SetNumberRows( matrix, arg[1] ); fi;
if nr_columns then
SetNumberColumns( matrix, arg[2] ); fi; fi;
return matrix;
end );
## <#GAPDoc Label="HomalgDiagonalMatrix"> ## <ManSection> ## <Func Arg="diag, R" Name="HomalgDiagonalMatrix" Label="constructor for diagonal matrices"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## An immutable unevaluated diagonal &homalg; matrix over the &homalg; ring <A>R</A>. The diagonal ## consists of the entries of the list <A>diag</A>. ## <Example><![CDATA[ ## gap> zz := HomalgRingOfIntegers( ); ## Z ## gap> d := HomalgDiagonalMatrix( [ 1, 2, 3 ], zz ); ## <An unevaluated diagonal 3 x 3 matrix over an internal ring> ## gap> Display( d ); ## [ [ 1, 0, 0 ], ## [ 0, 2, 0 ], ## [ 0, 0, 3 ] ] ## gap> d; ## <A diagonal 3 x 3 matrix over an internal ring> ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallGlobalFunction( HomalgDiagonalMatrix, function( arg ) ## the diagonal matrix
local nargs, R, diag, d, M;
nargs := Length( arg );
if nargs = 0then
Error( "no arguments provided\n" ); fi;
if IsHomalgRing( arg[nargs] ) then
R := arg[nargs]; fi;
if IsRingElement( arg[1] ) then
diag := [ arg[1] ]; elif ForAll( arg[1], IsRingElement ) then
diag := arg[1]; fi;
if not IsBound( R ) and IsBound( diag ) and diag <> [ ] and IsHomalgRingElement( diag[1] ) then
R := HomalgRing( diag[1] ); fi;
if not IsBound( diag ) then
return CallFuncList( DiagMat, arg ); elif not IsBound( R ) then
Error( "no homalg ring provided\n" ); fi;
if diag = [ ] then
return HomalgZeroMatrix( 0, 0, R ); fi;
diag := List( diag, a -> HomalgMatrix( [ a ], 1, 1, R ) ); ## a listlist would screw Singular
M := DiagMat( diag );
d := Length( diag );
if nargs > 1 and IsInt( arg[2] ) then if arg[2] > d then
M := UnionOfRows( M, HomalgZeroMatrix( arg[2] - d, d, R ) ); elif arg[2] < d then
M := CertainRows( M, [ 1 .. arg[2] ] ); fi; fi;
if nargs > 2 and IsInt( arg[3] ) then if arg[3] > d then
M := UnionOfColumns( M, HomalgZeroMatrix( NumberRows( M ), arg[3] - d, R ) ); elif arg[3] < d then
M := CertainColumns( M, [ 1 .. arg[3] ] ); fi; fi;
return M;
end );
## <#GAPDoc Label="HomalgScalarMatrix"> ## <ManSection> ## <Func Arg="r, n, R" Name="HomalgScalarMatrix" Label="constructor for scalar matrices"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## An immutable unevaluated <M><A>n</A> \times <A>n</A></M> scalar &homalg; matrix over the &homalg; ring <A>R</A> with ## the ring element <A>r</A> as diagonal scalar. ## <Example><![CDATA[ ## gap> zz := HomalgRingOfIntegers( ); ## Z ## gap> d := HomalgScalarMatrix( 2, 3, zz ); ## <An unevaluated scalar 3 x 3 matrix over an internal ring> ## gap> Display( d ); ## [ [ 2, 0, 0 ], ## [ 0, 2, 0 ], ## [ 0, 0, 2 ] ] ## gap> d; ## <A scalar 3 x 3 matrix over an internal ring> ## ]]></Example> ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallGlobalFunction( HomalgScalarMatrix, function( arg ) ## the scalar matrix
local nargs, r, n, R, diag, d, M;
nargs := Length( arg );
if nargs = 0then
Error( "no arguments provided\n" ); fi;
if IsRingElement( arg[1] ) then
r := arg[1]; else
Error( "the first argument must be a ring element\n" ); fi;
if IsInt( arg[2] ) and arg[2] >= 0then
n := arg[2]; else
Error( "the second argument must be a non-negative integer\n" ); fi;
if IsHomalgRing( arg[nargs] ) then
R := arg[nargs]; fi;
if not IsBound( R ) then if IsHomalgRingElement( r ) then
R := HomalgRing( r ); else
Error( "no homalg ring provided\n" ); fi; fi;
if n = 0then
return HomalgZeroMatrix( 0, 0, R ); fi;
diag := ListWithIdenticalEntries( n, HomalgMatrix( [ r ], 1, 1, R ) ); ## a listlist would screw Singular
M := DiagMat( diag );
SetIsScalarMatrix( M, true );
return M;
end );
##
InstallGlobalFunction( StringToHomalgColumnMatrix, function( str, R )
if str in [ "", " ", "[]", "[ ]" ] then
return HomalgZeroMatrix( 0, 1, R ); fi;
## # convenience
InstallMethod( CoercedMatrix, "for a homalg ring and a homalg matrix",
[ IsHomalgRing, IsHomalgMatrix ],
function( new_ring, M )
return CoercedMatrix( HomalgRing( M ), new_ring, M );
end );
## <#GAPDoc Label="CoercedMatrix"> ## <ManSection> ## <Oper Arg="ring_from, ring_to, mat" Name="CoercedMatrix" Label="copy a matrix over a different ring"/> ## <Oper Arg="ring_to, mat" Name="CoercedMatrix" Label="copy a matrix over a different ring (convenience)"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## A copy of the &homalg; matrix <A>mat</A> with &homalg; ring <A>ring_from</A> in the &homalg; ring <A>ring_to</A>.<P/> ## (for the installed standard method see <Ref Meth="Eval" Label="for matrices created with CoercedMatrix"/>) ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallMethod( CoercedMatrix, "for two homalg rings and a homalg matrix",
[ IsHomalgRing, IsHomalgRing, IsHomalgMatrix ],
function( old_ring, new_ring, M )
local C;
if not IsIdenticalObj( old_ring, HomalgRing( M ) ) then
Error( "the matrix <M> must be a matrix over the ring <old_ring>" );
fi;
C := HomalgMatrixWithAttributes( [
EvalCoercedMatrix, M
], new_ring );
BlindlyCopyMatrixProperties( M, C );
return C;
end );
##
InstallGlobalFunction( ListToListList, function( L, r, c )
return List( [ 1 .. r ], i -> L{[ (i-1)*c+1 .. i*c ]} );
end );
## <#GAPDoc Label="CoefficientsWithGivenMonomials"> ## <ManSection> ## <Meth Arg="M, monomials" Name="CoefficientsWithGivenMonomials" Label="for two homalg matrices"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## Let <C>R := HomalgRing(</C><A>M</A><C>)</C>. <C>monomials</C> must be a &homalg; matrix with the same number ## of columns as <C>M</C> consisting of monomials of <C>R</C>. ## This method computes a &homalg; matrix <C>coeffs</C> (with entries in the coefficients ring of <C>R</C>, ## yet still considered as elements of <C>R</C>) such that <C>M = coeffs * monomials</C>. ## If no such matrix exists, the behavior is undefined. ## If the first argument is a &homalg; ring element, it is viewed as a &homalg; matrix with a single entry. ## If the second argument is a list of monomials, it is viewed as a column matrix with the list elements as entries. ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallMethod( CoefficientsWithGivenMonomials, "for two homalg matrices",
[ IsHomalgMatrix, IsHomalgMatrix ],
function( M, monomials )
local R;
if NumberColumns( monomials ) <> NumberColumns( M ) then
Error( "the given matrices must have the same number of columns" );
fi;
R := HomalgRing( M );
return HomalgMatrixWithAttributes( [
EvalCoefficientsWithGivenMonomials, [ M, monomials ],
NumberRows, NumberRows( M ),
NumberColumns, NumberRows( monomials )
], R );
end );
##
InstallMethod( CoefficientsWithGivenMonomials, "for a homalg column matrix and a list of monomials",
[ IsHomalgMatrix, IsList ],
function( M, monomials )
return CoefficientsWithGivenMonomials( M, HomalgMatrix( monomials, Length( monomials ), 1, HomalgRing( M ) ) );
end );
##
InstallMethod( CoefficientsWithGivenMonomials, "for a homalg ring element and a homalg column matrix",
[ IsHomalgRingElement, IsHomalgMatrix ],
function( o )
local R, first_attribute, str, not_row_or_column_matrix;
R := HomalgRing( o );
first_attribute := true;
str :="";
if IsVoidMatrix( o ) then
Append( str, "<A void" ); elif IsInitialMatrix( o ) then
Append( str, "<An initial" ); elif IsInitialIdentityMatrix( o ) then
Append( str, "<An initial identity" ); elif not HasEval( o ) then
Append( str, "<An unevaluated" ); else
Append( str, "<A" );
first_attribute := false; fi;
if not ( HasIsSubidentityMatrix( o ) and IsSubidentityMatrix( o ) )
and HasIsZero( o ) then## if this method applies and HasIsZero is set we already know that o is a non-zero homalg matrix
Append( str, " non-zero" );
first_attribute := true; fi;
not_row_or_column_matrix := not ( ( HasNumberRows( o ) and NumberRows( o ) = 1 ) or ( HasNumberColumns( o ) and NumberColumns( o ) = 1 ) );
if not ( HasNumberRows( o ) and NumberRows( o ) = 1 and HasNumberColumns( o ) and NumberColumns( o ) = 1 ) then if HasIsDiagonalMatrix( o ) and IsDiagonalMatrix( o ) then
Append( str, " diagonal" ); elif HasIsUpperStairCaseMatrix( o ) and IsUpperStairCaseMatrix( o ) and not_row_or_column_matrix then if not first_attribute then
Append( str, "n upper staircase" ); else
Append( str, " upper staircase" ); fi; elif HasIsStrictUpperTriangularMatrix( o ) and IsStrictUpperTriangularMatrix( o ) then
Append( str, " strict upper triangular" ); elif HasIsLowerStairCaseMatrix( o ) and IsLowerStairCaseMatrix( o ) and not_row_or_column_matrix then
Append( str, " lower staircase" ); elif HasIsStrictLowerTriangularMatrix( o ) and IsStrictLowerTriangularMatrix( o ) then
Append( str, " strict lower triangular" ); elif HasIsUpperTriangularMatrix( o ) and IsUpperTriangularMatrix( o ) and not ( HasNumberRows( o ) and NumberRows( o ) = 1 ) then if not first_attribute then
Append( str, "n upper triangular" ); else
Append( str, " upper triangular" ); fi; elif HasIsLowerTriangularMatrix( o ) and IsLowerTriangularMatrix( o ) and not ( HasNumberColumns( o ) and NumberColumns( o ) = 1 ) then
Append( str, " lower triangular" ); elif HasIsTriangularMatrix( o ) and IsTriangularMatrix( o ) and not_row_or_column_matrix then
Append( str, " triangular" ); elif not first_attribute then
first_attribute := fail; fi;
if first_attribute <> fail then
first_attribute := true; else
first_attribute := false; fi;
if HasIsInvertibleMatrix( o ) and IsInvertibleMatrix( o ) then if not first_attribute then
Append( str, "n invertible" ); else
Append( str, " invertible" ); fi; else if HasIsRightInvertibleMatrix( o ) and IsRightInvertibleMatrix( o ) then
Append( str, " right invertible" ); elif HasIsLeftRegular( o ) and IsLeftRegular( o ) then
Append( str, " left regular" ); fi;
if HasIsLeftInvertibleMatrix( o ) and IsLeftInvertibleMatrix( o ) then
Append( str, " left invertible" ); elif HasIsRightRegular( o ) and IsRightRegular( o ) then
Append( str, " right regular" ); fi; fi; fi;
if HasIsSubidentityMatrix( o ) and IsSubidentityMatrix( o ) then
Append( str, " sub-identity" ); fi;
if HasNumberRows( o ) then
Append( str, Concatenation( " ", String( NumberRows( o ) ), " " ) ); if not HasNumberColumns( o ) then
Append( str, "x ?" ); fi; fi;
if HasNumberColumns( o ) then if not HasNumberRows( o ) then
Append( str, " ? " ); fi;
Append( str, Concatenation( "x ", String( NumberColumns( o ) ) ) ); fi;
if IsMutable( o ) and HasEval( o ) then
Append( str, " mutable" ); fi;
Append( str, " matrix over a" );
if IsBound( R!.description ) then
Append( str, R!.description ); elif IsHomalgInternalMatrixRep( o ) then
Append( str, "n internal" ); fi;
if HasEval( o ) then
Append( str, "<A " ); else
Append( str, "<An unevaluated " ); fi;
if HasNumberRows( o ) then
Append( str, Concatenation( String( NumberRows( o ) ), " " ) ); if not HasNumberColumns( o ) then
Append( str, "x ?" ); fi; fi;
if HasNumberColumns( o ) then if not HasNumberRows( o ) then
Append( str, "? " ); fi;
Append( str, Concatenation( "x ", String( NumberColumns( o ) ) ) ); fi;
Append( str, " permutation matrix over a" );
R := HomalgRing( o );
if IsBound( R!.description ) then
Append( str, R!.description ); elif IsHomalgInternalMatrixRep( o ) then
Append( str, "n internal" ); fi;
if HasEval( o ) then
Append( str, "<A " ); else
Append( str, "<An unevaluated " ); fi;
if HasNumberRows( o ) then
Append( str, Concatenation( String( NumberRows( o ) ), " " ) ); if not HasNumberColumns( o ) then
Append( str, "x ?" ); fi; fi;
if HasNumberColumns( o ) then if not HasNumberRows( o ) then
Append( str, "? " ); fi;
Append( str, Concatenation( "x ", String( NumberColumns( o ) ) ) ); fi;
Append( str, " identity matrix over a" );
R := HomalgRing( o );
if IsBound( R!.description ) then
Append( str, R!.description ); elif IsHomalgInternalMatrixRep( o ) then
Append( str, "n internal" ); fi;
if HasEval( o ) then
Append( str, "<A " ); else
Append( str, "<An unevaluated " ); fi;
if HasNumberRows( o ) then
Append( str, Concatenation( String( NumberRows( o ) ), " " ) ); if not HasNumberColumns( o ) then
Append( str, "x ?" ); fi; fi;
if HasNumberColumns( o ) then if not HasNumberRows( o ) then
Append( str, "? " ); fi;
Append( str, Concatenation( "x ", String( NumberColumns( o ) ) ) ); fi;
Append( str, " zero matrix over a" );
R := HomalgRing( o );
if IsBound( R!.description ) then
Append( str, R!.description ); elif IsHomalgInternalMatrixRep( o ) then
Append( str, "n internal" ); fi;
for i in [ 1 .. r ] do for j in [ 1 .. c ] do
Append( l, " " );
e := m[i][j]; if IsZero( e ) then
Append( l, "\\cdot" ); else
Append( l, LaTeXOutput( m[i][j] ) ); fi; if j < c then
Append( l, " &" ); fi;
od; if i < r then
Append( l, " \\\\" ); fi;
Append( l, " \n" );
od;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.