# SPDX-License-Identifier: GPL-2.0-or-later # GradedModules: A homalg based package for the Abelian category of finitely presented graded modules over computable graded rings # # Implementations #
## Implementation stuff for some other graded functors.
## <#GAPDoc Label="GeneratorsOfHomogeneousPart"> ## <ManSection> ## <Oper Arg="d, M" Name="GeneratorsOfHomogeneousPart"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## The resulting &homalg; matrix consists of a generating set (over <M>R</M>) of the <A>d</A>-th homogeneous part ## of the finitely generated &homalg; <M>S</M>-module <A>M</A>, where <M>R</M> is the coefficients ring ## of the graded ring <M>S</M> with <M>S_0=R</M>. ## <#Include Label="GeneratorsOfHomogeneousPart:example"> ## Compare with <Ref Oper="MonomialMap"/>. ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallMethod( GeneratorsOfHomogeneousPart, "for homalg modules",
[ IsInt, IsHomalgModule ],
function( d, M )
local homogeneous_parts, p, bases, p_old, T, M_d, diff, bas, source, S, weights, set_weights, n, deg, set_deg;
if IsBound( M!.HomogeneousParts ) then
homogeneous_parts := M!.HomogeneousParts; else
homogeneous_parts := rec( );
M!.HomogeneousParts := homogeneous_parts; fi;
p := PositionOfTheDefaultPresentation( M );
if IsBound( homogeneous_parts!.(d) ) then
bases := homogeneous_parts!.(d);
if IsBound( bases.(String( p )) ) then
return bases.(String( p )); fi;
p_old := Int( RecNames( bases )[1] );
if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then
T := TransitionMatrix( M, p_old, p );
bas := bases.(String( p_old )) * T; else
T := TransitionMatrix( M, p, p_old );
bas := T * bases.(String( p_old )); fi;
else
bases := rec( );
homogeneous_parts!.(d) := bases;
# try out some heuristics
S := HomalgRing( M );
weights := List( WeightsOfIndeterminates( S ), HomalgElementToInteger );
set_weights := Set( weights );
n := Length( weights );
deg := List( DegreesOfGenerators( M ), HomalgElementToInteger );
set_deg := Set( deg );
# socle over exterior algebra if HasIsExteriorRing( S ) and IsExteriorRing( S ) and
set_weights = [ -1 ] and Length( Set( deg ) ) = 1 and deg[1] - n = d and
HasIsFree( UnderlyingModule( M ) ) and IsFree( UnderlyingModule( M ) ) then
bas := HomalgIdentityMatrix( Length( deg ), S );
bas := ProductOfIndeterminates( S ) * bas;
# only generators of module are needed elif not ( 0 in set_weights ) and
( ( ForAll( set_weights, a -> a > 0 ) and ForAll( set_deg, a -> a >= d ) ) or
( ForAll( set_weights, a -> a < 0 ) and ForAll( set_deg, a -> a <= d ) ) ) and #this last condition states that there are no relations between generators of degree d
not ( d in DegreesOfGenerators( Source( PresentationMorphism( M ) ) ) ) then
bas := HomalgIdentityMatrix( Length( deg ), S );
if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then
bas := CertainRows( bas, Filtered( [ 1 .. Length( deg ) ], a -> deg[a] = d ) ); else
bas := CertainColumns( bas, Filtered( [ 1 .. Length( deg ) ], a -> deg[a] = d ) ); fi;
# fallback else
## the map of generating monomials of degree d
M_d := MonomialMap( d, M );
## the matrix of generating monomials of degree d
M_d := MatrixOfMap( M_d );
# M_d is already a generating set. # In the case of fields as coefficients, the following trick is used to find a minimal set of generators. # In the case of general rings of coefficients, this is only a heuristical approach that removed superfluous generators. # The trick is the following: # If a generator can be reduced, than it is superfluous.
## the generating monomials are not altered by reduction
diff := M_d - DecideZero( M_d, M );
if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then
bas := ZeroRows( diff );
bas := CertainRows( M_d, bas ); else
bas := ZeroColumns( diff );
bas := CertainColumns( M_d, bas ); fi;
return GeneratorsOfHomogeneousPart( HomalgElementToInteger( d ), M );
end );
## ## RepresentationMapOfRingElement ##
## <#GAPDoc Label="RepresentationMapOfRingElement"> ## <ManSection> ## <Oper Arg="r, M, d" Name="RepresentationMapOfRingElement"/> ## <Returns>a &homalg; matrix</Returns> ## <Description> ## The graded map induced by the homogeneous degree <E><M>1</M></E> ring element <A>r</A> ## (of the underlying &homalg; graded ring <M>S</M>) regarded as a <M>R</M>-linear map ## between the <A>d</A>-th and the <M>(</M><A>d</A><M>+1)</M>-st homogeneous part of the graded finitely generated ## &homalg; <M>S</M>-module <M>M</M>, where <M>R</M> is the coefficients ring of the graded ring <M>S</M> ## with <M>S_0=R</M>. The generating set of both modules is given by <Ref Oper="GeneratorsOfHomogeneousPart"/>. The ## entries of the matrix presenting the map lie in the coefficients ring <M>R</M>. ## <#Include Label="RepresentationMapOfRingElement:example"> ## </Description> ## </ManSection> ## <#/GAPDoc> ##
BindGlobal( "_Functor_RepresentationMapOfRingElement_OnGradedModules", ### defines: RepresentationMapOfRingElement (object part)
function( l, M )
local S, R, r, d, bd, bdp1, r_mult;
S := HomalgRing( M );
if HasBaseRing( S ) then
R := BaseRing( S ); else
R := CoefficientsRing( S ); fi;
if Length( l ) <> 2then
Error( "expected a ring element and an integer as zeroth parameter" ); fi;
r := l[1];
d := l[2];
d := HomalgElementToInteger( d );
if not IsRingElement( r ) or not IsInt( d ) then
Error( "expected a ring element and an integer as zeroth parameter" ); fi;
bd := SubmoduleGeneratedByHomogeneousPartEmbed( d, M );
bdp1 := SubmoduleGeneratedByHomogeneousPartEmbed( d + HomalgElementToInteger( DegreeOfRingElement( r ) ), M );
r_mult := GradedMap(
R * MatrixOfMap( r_mult ),
HomogeneousPartOverCoefficientsRing( d, M ),
HomogeneousPartOverCoefficientsRing( d + HomalgElementToInteger( DegreeOfRingElement( r ) ), M ) );
SetDegreeOfMorphism( r_mult, DegreeOfRingElement( r ) );
## <#GAPDoc Label="SubmoduleGeneratedByHomogeneousPart"> ## <ManSection> ## <Oper Arg="d, M" Name="SubmoduleGeneratedByHomogeneousPart"/> ## <Returns>a &homalg; module</Returns> ## <Description> ## The submodule of the &homalg; module <A>M</A> generated by the image of the <A>d</A>-th monomial map ## (&see; <Ref Oper="MonomialMap"/>), or equivalently, by the generating set of the <A>d</A>-th homogeneous part of <A>M</A>. ## <#Include Label="SubmoduleGeneratedByHomogeneousPart:example"> ## </Description> ## </ManSection> ## <#/GAPDoc> ##
BindGlobal( "_Functor_SubmoduleGeneratedByHomogeneousPart_OnGradedModules", ### defines: SubmoduleGeneratedByHomogeneousPart (object part)
function( d, M )
local deg, submodule;
deg := DegreesOfGenerators( M );
deg := List( deg, HomalgElementToInteger );
submodule := ImageSubobject( EmbeddingOfSubmoduleGeneratedByHomogeneousPart( d, M ) );
if Length( deg ) = 0 or ( Length( deg ) = 1 and deg[1] = d ) then
SetEmbeddingInSuperObject( submodule, TheIdentityMorphism( M ) );
result := CompleteImageSquare( F_source!.map_having_subobject_as_its_image, phi, F_target!.map_having_subobject_as_its_image );
if HasIsMorphism( phi ) and IsMorphism( phi ) then
Assert( 3, IsMorphism( result ) );
SetIsMorphism( result, true ); fi; if HasIsEpimorphism( phi ) and IsEpimorphism( phi ) then
Assert( 3, IsEpimorphism( result ) );
SetIsEpimorphism( result, true ); fi; if HasIsIsomorphism( phi ) and IsIsomorphism( phi ) then
Assert( 3, IsIsomorphism( result ) );
SetIsIsomorphism( result, true );
UpdateObjectsByMorphism( result ); fi; if HasIsAutomorphism( phi ) and IsAutomorphism( phi ) then
Assert( 3, IsAutomorphism( result ) );
SetIsAutomorphism( result, true ); fi; if HasIsZero( phi ) and IsZero( phi ) then
Assert( 3, IsZero( result ) );
SetIsZero( result, true ); fi;
return TruncatedSubmoduleRecursiveEmbed( HomalgElementToInteger( d ), M );
end );
## ## HomogeneousPartOverCoefficientsRing ##
## <#GAPDoc Label="HomogeneousPartOverCoefficientsRing"> ## <ManSection> ## <Oper Arg="d, M" Name="HomogeneousPartOverCoefficientsRing"/> ## <Returns>a &homalg; module</Returns> ## <Description> ## The degree <M>d</M> homogeneous part of the graded <M>R</M>-module <A>M</A> ## as a module over the coefficient ring or field of <M>R</M>. ## <#Include Label="HomogeneousPartOverCoefficientsRing:example"> ## </Description> ## </ManSection> ## <#/GAPDoc> ##
InstallMethod( RepresentationOfMorphismOnHomogeneousParts, "for homalg ring elements",
[ IsMapOfGradedModulesRep, IsInt, IsInt ],
function( phi, m, n )
local S, M, N, M_le_m, M_le_m_epi, N_le_n, N_le_n_epi, phi_le_m;
if m > n then
Error( "The first given degree needs to be larger then the second one" ); fi;
S := HomalgRing( phi );
M := Source( phi );
N := Range( phi );
M_le_m := SubmoduleGeneratedByHomogeneousPart( m, M );
function( d, M )
local S, k_graded, k, deg, emb, mat, map_having_submodule_as_its_image,
N, gen, l, rel, pos, V, map, submodule, V_weights, degree_group;
S := HomalgRing( M );
if HasBaseRing( S ) then
k_graded := BaseRing( S ); else
k_graded := CoefficientsRing( S ); fi;
k := UnderlyingNonGradedRing( k_graded );
deg := DegreesOfGenerators( M );
deg := List( deg, HomalgElementToInteger );
if HasEmbeddingOfTruncatedModuleInSuperModule( M ) and deg <> [] and Minimum( deg ) <= d and
not ( HasIsAutomorphism( EmbeddingOfTruncatedModuleInSuperModule( M ) ) and IsAutomorphism( EmbeddingOfTruncatedModuleInSuperModule( M ) ) ) then
# make sure that a truncated module and its super moduleS # have the same homogeneous parts
emb := EmbeddingOfTruncatedModuleInSuperModule( M );
map_having_submodule_as_its_image := EmbeddingOfSubmoduleGeneratedByHomogeneousPart( d, Range( emb ) );
map_having_submodule_as_its_image := map_having_submodule_as_its_image / emb;
V := HomogeneousPartOverCoefficientsRing( d, Range( emb ) );
else
# the generic case
mat := GeneratorsOfHomogeneousPart( d, M );
map_having_submodule_as_its_image := GradedMap( mat, "free", M );
Assert( 4, IsMorphism( map_having_submodule_as_its_image ) );
SetIsMorphism( map_having_submodule_as_its_image, true );
if deg = [] or ( Length( Set( deg ) ) = 1 and deg[1] = d ) then
Assert( 3, IsEpimorphism( map_having_submodule_as_its_image ) );
SetIsEpimorphism( map_having_submodule_as_its_image, true ); fi;
N := ImageSubobject( map_having_submodule_as_its_image );
gen := GeneratorsOfModule( N );
gen := NewHomalgGenerators( MatrixOfGenerators( gen ), gen );
gen!.ring := k;
l := NrGenerators( gen );
if HasIsFieldForHomalg( k_graded ) and IsFieldForHomalg( k_graded ) then
if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then
rel := HomalgZeroMatrix( 0, l, k );
rel := HomalgRelationsForLeftModule( rel ); else
rel := HomalgZeroMatrix( l, 0, k );
rel := HomalgRelationsForRightModule( rel ); fi;
else
## Corresponds to Algorithm 3.1 in arXiv:1409.6100
rel := MatrixOfRelations( UnderlyingObject( N ) );
if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then
deg := NonTrivialDegreePerRow( rel, DegreesOfGenerators( N ) ); else
deg := NonTrivialDegreePerColumn( rel, DegreesOfGenerators( N ) ); fi;
deg := List( deg, HomalgElementToInteger );
pos := Filtered( [ 1 .. Length( deg ) ], p -> deg[p] = d );
if IsHomalgLeftObjectOrMorphismOfLeftObjects( M ) then
rel := k * CertainRows( rel, pos );
rel := HomalgRelationsForLeftModule( rel ); else
rel := k * CertainColumns( rel, pos );
rel := HomalgRelationsForRightModule( rel ); fi;
fi;
degree_group := DegreeGroup( S );
V_weights := List( [ 1 .. NrGenerators( gen ) ], i -> HomalgModuleElement( [ d ], degree_group ) );
V := GradedModule( Presentation( gen, rel ), V_weights, k_graded );
## this map is usually not well-defined in the relative case:
map := GradedMap( HomalgIdentityMatrix( l, S ),
S * V, Source( map_having_submodule_as_its_image ) );
## ..., but this one is:
map_having_submodule_as_its_image := PreCompose( map, map_having_submodule_as_its_image );
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.