GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#############################################################################
##
## Tools.gi GradedRingForHomalg package
##
## Copyright 2009-2011, Mohamed Barakat, University of Kaiserslautern
## Markus Lange-Hegermann, RWTH-Aachen University
##
## Implementations for tools for matrices over graded rings.
##
#############################################################################
####################################
#
# methods for operations:
#
####################################
##
InstallMethod( DegreeOfRingElementFunction,
"for homalg rings",
[ IsHomalgRing, IsList ],
function( R, weights )
local RP, set_weights, weight;
RP := homalgTable( R );
set_weights := Set( weights );
if set_weights = [ 1 ] then
if IsBound(RP!.DegreeOfRingElement) then
return r -> RP!.DegreeOfRingElement( r, R );
fi;
elif Length( set_weights ) = 1 and set_weights[1] in Rationals then
weight := set_weights[1];
if weight <> 0 and IsBound(RP!.DegreeOfRingElement) then
return r -> weight * RP!.DegreeOfRingElement( r, R );
fi;
elif Length( set_weights ) = 2 and 0 in set_weights and
ForAll( set_weights, a -> a in Rationals ) then
weight := Filtered( set_weights, a -> a <> 0 )[1];
weights := List( weights, a -> AbsInt( SignInt( a ) ) );
if IsBound(RP!.WeightedDegreeOfRingElement) then
return r -> weight * RP!.WeightedDegreeOfRingElement( r, weights, R );
fi;
elif weights = [ ] then
if IsBound(RP!.DegreeOfRingElement) and not IsHomalgExternalRingInMAGMARep( R ) then
return r -> RP!.DegreeOfRingElement( r, R );
fi;
return function( r ) if IsZero( r ) then return -1; else return 0; fi; end;
else
if IsBound(RP!.WeightedDegreeOfRingElement) then
return r -> RP!.MultiWeightedDegreeOfRingElement( r, weights, R );
fi;
fi;
## there is no fallback method
TryNextMethod( );
end );
##
InstallMethod( DegreeOfRingElementFunction,
"for a homalg ring and a homalg matrix (of weights)",
[ IsHomalgRing, IsHomalgMatrix ],
function( R, weights )
local RP;
RP := homalgTable( R );
if not IsIdenticalObj( HomalgRing( weights ), HomalgRing( R ) ) then
Error( "the matrix of weights is defined over a different ring\n" );
fi;
return r -> RP!.MultiWeightedDegreeOfRingElement( r, weights, R );
end );
##
InstallMethod( DegreeOfRingElementFunction,
"for homalg residue class rings",
[ IsHomalgResidueClassRingRep, IsList ],
function( R, weights )
local A, deg_func;
A := AmbientRing( R );
deg_func := DegreeOfRingElementFunction( A, weights );
return
function( r )
if r = 0 then
return deg_func( Zero( A ) );
fi;
return deg_func( EvalRingElement( r ) );
end;
end );
##
InstallMethod( DegreesOfEntriesFunction,
"for homalg rings",
[ IsHomalgRing, IsList ],
function( R, weights )
local RP, set_weights, weight, deg_func;
RP := homalgTable( R );
set_weights := Set( weights );
if set_weights = [ 1 ] then
if IsBound(RP!.DegreesOfEntries) then
return C -> RP!.DegreesOfEntries( C );
fi;
elif Length( set_weights ) = 1 and set_weights[1] in Rationals then
weight := set_weights[1];
if IsBound(RP!.DegreesOfEntries) then
return C -> weight * RP!.DegreesOfEntries( C );
fi;
elif Length( set_weights ) = 2 and 0 in set_weights and
ForAll( set_weights, a -> a in Rationals ) then
weight := Filtered( set_weights, a -> a <> 0 )[1];
weights := List( weights, a -> AbsInt( SignInt( a ) ) );
if IsBound(RP!.WeightedDegreesOfEntries) then
return C -> weight * RP!.WeightedDegreesOfEntries( C, weights );
fi;
else
if weights = [ ] then
if IsBound(RP!.MultiWeightedDegreesOfEntries) then
return C -> RP!.MultiWeightedDegreesOfEntries( C, [ 1 ] );
fi;
elif IsList( weights[1] ) then
if IsBound(RP!.MultiWeightedDegreesOfEntries) then
return C -> RP!.MultiWeightedDegreesOfEntries( C, weights );
fi;
elif IsBound(RP!.WeightedDegreesOfEntries) then
return C -> RP!.WeightedDegreesOfEntries( C, weights );
fi;
fi;
#=====# the fallback method #=====#
deg_func := DegreeOfRingElementFunction( R, weights );
return
function( C )
local e;
e := EntriesOfHomalgMatrix( C );
e := List( e, deg_func );
return ListToListList( e, NrRows( C ), NrColumns( C ) );
end;
end );
##
InstallMethod( DegreesOfEntriesFunction,
"for homalg rings",
[ IsHomalgRing, IsHomalgMatrix ],
function( R, weights )
local RP, degree_func;
RP := homalgTable( R );
if IsBound( RP!.MultiWeightedDegreesOfEntries ) then
return r -> RP!.MultiWeightedDegreesOfEntries( r, weights, R );
elif IsBound( RP!.MultiWeightedDegreeOfRingElement ) then
degree_func := RP!.MultiWeightedDegreeOfRingElement;
return function( M )
local weight_list;
weight_list := EntriesOfHomalgMatrixAsListList( M );
Apply( weight_list, i -> List( i, j -> degree_func( j, weights, R ) ) );
return weight_list;
end;
else
Error( "not implemented" );
fi;
end );
##
InstallMethod( NonTrivialDegreePerRowWithColPositionFunction,
"for homalg rings",
[ IsHomalgRing, IsList, IsObject, IsObject ],
function( R, weights, deg0, deg1 )
local RP, set_weights, weight, deg_func;
RP := homalgTable( R );
set_weights := Set( weights );
if Length( set_weights ) = 1 and set_weights[1] in Rationals then
weight := set_weights[1];
if IsBound( RP!.NonTrivialDegreePerRowWithColPosition ) then
return
function( C )
local e;
e := RP!.NonTrivialDegreePerRowWithColPosition( C );
SetPositionOfFirstNonZeroEntryPerRow( C, e[2] );
return weight * e[1]; ## e might be immutable
end;
fi;
elif Length( set_weights ) = 2 and 0 in set_weights and
ForAll( set_weights, a -> a in Rationals ) then
weight := Filtered( set_weights, a -> a <> 0 )[1];
weights := List( weights, a -> AbsInt( SignInt( a ) ) );
if IsBound( RP!.NonTrivialWeightedDegreePerRowWithColPosition ) then
return
function( C )
local e;
e := RP!.NonTrivialWeightedDegreePerRowWithColPosition( C, weights );
SetPositionOfFirstNonZeroEntryPerRow( C, e[2] );
return weight * e[1]; ## e might be immutable
end;
fi;
elif weights = [ ] then
return
function( C )
local e;
e := PositionOfFirstNonZeroEntryPerRow( C );
return List( e, function( c ) if c = 0 then return deg0; fi; return deg1; end );
end;
elif IsList( weights[1] ) then
if IsBound(RP!.NonTrivialMultiWeightedDegreePerRowWithColPosition) then
return
function( C )
local e;
e := RP!.NonTrivialMultiWeightedDegreePerRowWithColPosition( C, weights );
SetPositionOfFirstNonZeroEntryPerRow( C, e[2] );
return e[1];
end;
fi;
elif IsBound(RP!.NonTrivialWeightedDegreePerRowWithColPosition) then
return
function( C )
local e;
e := RP!.NonTrivialWeightedDegreePerRowWithColPosition( C, weights );
SetPositionOfFirstNonZeroEntryPerRow( C, e[2] );
return e[1];
end;
fi;
#=====# the fallback method #=====#
deg_func := DegreeOfRingElementFunction( R, weights );
return
function( C )
local e;
e := PositionOfFirstNonZeroEntryPerRow( C );
return
List( [ 1 .. NrRows( C ) ],
function( r )
if e[r] = 0 then
return deg0;
fi;
return deg_func(
MatElm( C, r, e[r] )
);
end );
end;
end );
##
InstallMethod( NonTrivialDegreePerColumnWithRowPositionFunction,
"for homalg rings",
[ IsHomalgRing, IsList, IsObject, IsObject ],
function( R, weights, deg0, deg1 )
local RP, set_weights, weight, deg_func;
RP := homalgTable( R );
set_weights := Set( weights );
if Length( set_weights ) = 1 and set_weights[1] in Rationals then
weight := set_weights[1];
if IsBound( RP!.NonTrivialDegreePerColumnWithRowPosition ) then
return
function( C )
local e;
e := RP!.NonTrivialDegreePerColumnWithRowPosition( C );
SetPositionOfFirstNonZeroEntryPerColumn( C, e[2] );
return weight * e[1]; ## e might be immutable
end;
fi;
elif Length( set_weights ) = 2 and 0 in set_weights and
ForAll( set_weights, a -> a in Rationals ) then
weight := Filtered( set_weights, a -> a <> 0 )[1];
weights := List( weights, a -> AbsInt( SignInt( a ) ) );
if IsBound( RP!.NonTrivialWeightedDegreePerColumnWithRowPosition ) then
return
function( C )
local e;
e := RP!.NonTrivialWeightedDegreePerColumnWithRowPosition( C, weights );
SetPositionOfFirstNonZeroEntryPerColumn( C, e[2] );
return weight * e[1]; ## e might be immutable
end;
fi;
elif weights = [ ] then
return
function( C )
local e;
e := PositionOfFirstNonZeroEntryPerColumn( C );
return List( e, function( r ) if r = 0 then return deg0; fi; return deg1; end );
end;
elif IsList( weights[1] ) then
if IsBound(RP!.NonTrivialMultiWeightedDegreePerColumnWithRowPosition) then
return
function( C )
local e;
e := RP!.NonTrivialMultiWeightedDegreePerColumnWithRowPosition( C, weights );
SetPositionOfFirstNonZeroEntryPerColumn( C, e[2] );
return e[1];
end;
fi;
elif IsBound(RP!.NonTrivialWeightedDegreePerColumnWithRowPosition) then
return
function( C )
local e;
e := RP!.NonTrivialWeightedDegreePerColumnWithRowPosition( C, weights );
SetPositionOfFirstNonZeroEntryPerColumn( C, e[2] );
return e[1];
end;
fi;
#=====# the fallback method #=====#
deg_func := DegreeOfRingElementFunction( R, weights );
return
function( C )
local e;
e := PositionOfFirstNonZeroEntryPerColumn( C );
return
List( [ 1 .. NrColumns( C ) ],
function( c )
if e[c] = 0 then
return deg0;
fi;
return deg_func(
MatElm( C, e[c], c )
);
end );
end;
end );
##
InstallMethod( LinearSyzygiesGeneratorsOfRows,
"for matrices over graded rings",
[ IsMatrixOverGradedRing ],
function( M )
local R, RP, t, C, degs, deg;
if IsBound(M!.LinearSyzygiesGeneratorsOfRows) then
return M!.LinearSyzygiesGeneratorsOfRows;
fi;
R := HomalgRing( M );
RP := homalgTable( R );
t := homalgTotalRuntimes( );
ColoredInfoForService( "busy", "LinearSyzygiesGeneratorsOfRows", NrRows( M ), " x ", NrColumns( M ) );
if IsBound(RP!.LinearSyzygiesGeneratorsOfRows) then
C := RP!.LinearSyzygiesGeneratorsOfRows( M );
if IsZero( C ) then
C := HomalgZeroMatrix( 0, NrRows( M ), R ); ## most of the computer algebra systems cannot handle degenerated matrices
else
SetNrColumns( C, NrRows( M ) );
fi;
M!.LinearSyzygiesGeneratorsOfRows := C;
ColoredInfoForService( t, "LinearSyzygiesGeneratorsOfRows", NrRows( C ) );
IncreaseRingStatistics( R, "LinearSyzygiesGeneratorsOfRows" );
return C;
elif IsBound(RP!.LinearSyzygiesGeneratorsOfColumns) then
C := Involution( RP!.LinearSyzygiesGeneratorsOfColumns( Involution( M ) ) );
if IsZero( C ) then
C := HomalgZeroMatrix( 0, NrRows( M ), R ); ## most of the computer algebra systems cannot handle degenerated matrices
else
SetNrColumns( C, NrRows( M ) );
fi;
M!.LinearSyzygiesGeneratorsOfRows := C;
ColoredInfoForService( t, "LinearSyzygiesGeneratorsOfRows", NrRows( C ) );
DecreaseRingStatistics( R, "LinearSyzygiesGeneratorsOfRows" );
IncreaseRingStatistics( R, "LinearSyzygiesGeneratorsOfColumns" );
return C;
fi;
#=====# begin of the core procedure #=====#
C := SyzygiesGeneratorsOfRows( M );
degs := NonTrivialDegreePerRow( C );
deg := CommonNonTrivialWeightOfIndeterminates( R );
C := CertainRows( C, Filtered( [ 1 .. Length( degs ) ], r -> degs[r] = deg ) );
if IsZero( C ) then
C := HomalgZeroMatrix( 0, NrRows( M ), R );
fi;
M!.LinearSyzygiesGeneratorsOfRows := C;
ColoredInfoForService( t, "LinearSyzygiesGeneratorsOfRows", NrRows( C ) );
IncreaseRingStatistics( R, "LinearSyzygiesGeneratorsOfRows" );
return C;
end );
##
InstallMethod( LinearSyzygiesGeneratorsOfColumns,
"for matrices over graded rings",
[ IsMatrixOverGradedRing ],
function( M )
local R, RP, t, C, degs, deg;
if IsBound(M!.LinearSyzygiesGeneratorsOfColumns) then
return M!.LinearSyzygiesGeneratorsOfColumns;
fi;
R := HomalgRing( M );
RP := homalgTable( R );
t := homalgTotalRuntimes( );
ColoredInfoForService( "busy", "LinearSyzygiesGeneratorsOfColumns", NrRows( M ), " x ", NrColumns( M ) );
if IsBound(RP!.LinearSyzygiesGeneratorsOfColumns) then
C := RP!.LinearSyzygiesGeneratorsOfColumns( M );
if IsZero( C ) then
C := HomalgZeroMatrix( NrColumns( M ), 0, R );
else
SetNrRows( C, NrColumns( M ) );
fi;
M!.LinearSyzygiesGeneratorsOfColumns := C;
ColoredInfoForService( t, "LinearSyzygiesGeneratorsOfColumns", NrColumns( C ) );
IncreaseRingStatistics( R, "LinearSyzygiesGeneratorsOfColumns" );
return C;
elif IsBound(RP!.LinearSyzygiesGeneratorsOfRows) then
C := Involution( RP!.LinearSyzygiesGeneratorsOfRows( Involution( M ) ) );
if IsZero( C ) then
C := HomalgZeroMatrix( NrColumns( M ), 0, R );
else
SetNrRows( C, NrColumns( M ) );
fi;
M!.LinearSyzygiesGeneratorsOfColumns := C;
ColoredInfoForService( t, "LinearSyzygiesGeneratorsOfColumns", NrColumns( C ) );
DecreaseRingStatistics( R, "LinearSyzygiesGeneratorsOfColumns" );
IncreaseRingStatistics( R, "LinearSyzygiesGeneratorsOfRows" );
return C;
fi;
#=====# begin of the core procedure #=====#
C := SyzygiesGeneratorsOfColumns( M );
degs := NonTrivialDegreePerColumn( C );
deg := CommonNonTrivialWeightOfIndeterminates( R );
C := CertainColumns( C, Filtered( [ 1 .. Length( degs ) ], c -> degs[c] = deg ) );
if IsZero( C ) then
C := HomalgZeroMatrix( NrColumns( M ), 0, R );
fi;
M!.LinearSyzygiesGeneratorsOfColumns := C;
ColoredInfoForService( t, "LinearSyzygiesGeneratorsOfColumns", NrColumns( C ) );
IncreaseRingStatistics( R, "LinearSyzygiesGeneratorsOfColumns" );
return C;
end );
## <#GAPDoc Label="Diff">
## <ManSection>
## <Oper Arg="D, N" Name="Diff"/>
## <Returns>a &homalg; matrix</Returns>
## <Description>
## If <A>D</A> is a <M>f \times p</M>-matrix and <A>N</A> is a <M>g \times q</M>-matrix then
## <M>H=Diff(</M><A>D</A>,<A>N</A><M>)</M> is an <M>fg \times pq</M>-matrix whose entry
## <M>H[g*(i-1)+j,q*(k-1)+l]</M> is the result of differentiating <A>N</A><M>[j,l]</M>
## by the differential operator corresponding to <A>D</A><M>[i,k]</M>. (Here we follow
## the Macaulay2 convention.)
## <Example><![CDATA[
## gap> S := HomalgFieldOfRationalsInDefaultCAS( ) * "a,b,c" * "x,y,z";;
## gap> D := HomalgMatrix( "[ \
## > x,2*y, \
## > y,a-b^2, \
## > z,y-b \
## > ]", 3, 2, S );
## <A 3 x 2 matrix over an external ring>
## gap> N := HomalgMatrix( "[ \
## > x^2-a*y^3,x^3-z^2*y,x*y-b,x*z-c, \
## > x, x*y, a-b, x*a*b \
## > ]", 2, 4, S );
## <A 2 x 4 matrix over an external ring>
## gap> H := Diff( D, N );
## <A 6 x 8 matrix over an external ring>
## gap> Display( H );
## 2*x, 3*x^2, y,z, -6*a*y^2,-2*z^2,2*x,0,
## 1, y, 0,a*b,0, 2*x, 0, 0,
## -3*a*y^2,-z^2, x,0, -y^3, 0, 0, 0,
## 0, x, 0,0, 0, 0, 1, b*x,
## 0, -2*y*z,0,x, -3*a*y^2,-z^2, x+1,0,
## 0, 0, 0,0, 0, x, 1, -a*x
## ]]></Example>
## </Description>
## </ManSection>
## <#/GAPDoc>
##
InstallMethod( Diff,
"for homalg matrices",
[ IsHomalgMatrix, IsHomalgMatrix ],
function( D, N )
local R, RP, diff;
R := HomalgRing( D );
if not IsIdenticalObj( R, HomalgRing( N ) ) then
Error( "the two matrices must be defined over identically the same ring\n" );
fi;
RP := homalgTable( R );
if IsBound(RP!.Diff) then
diff := RP!.Diff( D, N );
if IshomalgExternalObjectRep( diff ) then
diff := HomalgMatrix( diff, NrRows( D ) * NrRows( N ), NrColumns( D ) * NrColumns( N ), R );
fi;
return diff;
fi;
if not IsHomalgInternalRingRep( R ) then
Error( "could not find a procedure called Diff ",
"in the homalgTable of the non-internal ring\n" );
fi;
TryNextMethod( );
end );