Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
Project: cocalc-sagemath-dev-slelievre
Views: 418346############################################################################# ## ## HomalgGenerators.gi Modules package Mohamed Barakat ## ## Copyright 2007-2008 Lehrstuhl B für Mathematik, RWTH Aachen ## ## Implementation stuff for a set of generators. ## ############################################################################# ## <#GAPDoc Label="Generators:intro"> ## To present a left/right module it suffices to take a matrix <A>rel</A> and interpret its rows/columns ## as relations among <M>n</M> <E>abstract</E> generators, where <M>n</M> is the number of columns/rows ## of <A>rel</A>. Only that these abstract generators are useless when it comes to specific modules like ## modules of homomorphisms, where one expects the generators to be maps between modules. For this ## reason a presentation of a module in &homalg; is not merely a matrix of relations, but together with ## a set of generators. ## <P/> ## In &homalg; a set of generators of a left/right module is given by a matrix <A>gen</A> with rows/columns ## being interpreted as the generators. ## <P/> ## The data structure of a module in &homalg; is designed to contain not only one but several sets of generators ## (together with their sets of relations (&see; Chapter <Ref Chap="Relations"/>)). ## The different sets of generators are linked with so-called transition matrices (&see; Chapter <Ref Chap="Modules"/>). ## <#/GAPDoc> #################################### # # representations: # #################################### ## <#GAPDoc Label="IsGeneratorsOfModuleRep"> ## <ManSection> ## <Filt Type="Representation" Arg="rel" Name="IsGeneratorsOfModuleRep"/> ## <Returns><C>true</C> or <C>false</C></Returns> ## <Description> ## The &GAP; representation of a finite set of generators of a &homalg; module. <P/> ## (It is a representation of the &GAP; category <Ref Filt="IsHomalgGenerators"/>) ## <Listing Type="Code"><![CDATA[ DeclareRepresentation( "IsGeneratorsOfModuleRep", IsHomalgGenerators, [ "generators" ] ); ## ]]></Listing> ## </Description> ## </ManSection> ## <#/GAPDoc> ## <#GAPDoc Label="IsGeneratorsOfFinitelyGeneratedModuleRep"> ## <ManSection> ## <Filt Type="Representation" Arg="rel" Name="IsGeneratorsOfFinitelyGeneratedModuleRep"/> ## <Returns><C>true</C> or <C>false</C></Returns> ## <Description> ## The &GAP; representation of a finite set of generators of a finitely generated &homalg; module. <P/> ## (It is a representation of the &GAP; representation <Ref Filt="IsGeneratorsOfModuleRep"/>) ## <Listing Type="Code"><![CDATA[ DeclareRepresentation( "IsGeneratorsOfFinitelyGeneratedModuleRep", IsGeneratorsOfModuleRep, [ "generators", "relations_of_hullmodule" ] ); ## ]]></Listing> ## </Description> ## </ManSection> ## <#/GAPDoc> #################################### # # families and types: # #################################### # a new family: BindGlobal( "TheFamilyOfHomalgGenerators", NewFamily( "TheFamilyOfHomalgGenerators" ) ); # four new types: BindGlobal( "TheTypeHomalgGeneratorsOfLeftModule", NewType( TheFamilyOfHomalgGenerators, IsGeneratorsOfModuleRep and IsHomalgGeneratorsOfLeftModule ) ); BindGlobal( "TheTypeHomalgGeneratorsOfRightModule", NewType( TheFamilyOfHomalgGenerators, IsGeneratorsOfModuleRep and IsHomalgGeneratorsOfRightModule ) ); BindGlobal( "TheTypeHomalgGeneratorsOfFinitelyGeneratedLeftModule", NewType( TheFamilyOfHomalgGenerators, IsGeneratorsOfFinitelyGeneratedModuleRep and IsHomalgGeneratorsOfLeftModule ) ); BindGlobal( "TheTypeHomalgGeneratorsOfFinitelyGeneratedRightModule", NewType( TheFamilyOfHomalgGenerators, IsGeneratorsOfFinitelyGeneratedModuleRep and IsHomalgGeneratorsOfRightModule ) ); #################################### # # methods for operations: # #################################### ## InstallMethod( MatrixOfGenerators, "for sets of generators of homalg modules", [ IsHomalgGenerators ], function( gen ) return gen!.generators; end ); ## InstallMethod( HomalgRing, "for sets of generators of homalg modules", [ IsHomalgGenerators ], function( gen ) return HomalgRing( MatrixOfGenerators( gen ) ); end ); ## InstallMethod( GetGenerators, "for a set of homalg generators and a positive integer", [ IsGeneratorsOfFinitelyGeneratedModuleRep, IsPosInt ], function( gen, g ) local AdjustedGenerators, mat, G, proc; if not IsBound( gen!.AdjustedGenerators ) then gen!.AdjustedGenerators := [ ]; fi; AdjustedGenerators := gen!.AdjustedGenerators; if IsBound( AdjustedGenerators[g] ) then return AdjustedGenerators[g]; fi; mat := MatrixOfGenerators( gen ); if IsHomalgGeneratorsOfLeftModule( gen ) then G := CertainRows( mat, [ g ] ); else G := CertainColumns( mat, [ g ] ); fi; if HasProcedureToReadjustGenerators( gen ) then proc := ProcedureToReadjustGenerators( gen ); G := CallFuncList( proc[1], Concatenation( [ G ], proc{[ 2 .. Length( proc ) ]} ) ); fi; AdjustedGenerators[g] := G; return G; end ); ## InstallMethod( GetGenerators, "for a set of homalg generators and a list of positive integer", [ IsGeneratorsOfFinitelyGeneratedModuleRep, IsList ], function( gen, g ) return List( g, i -> GetGenerators( gen, i ) ); end ); ## InstallMethod( GetGenerators, "for homalg generators", [ IsGeneratorsOfFinitelyGeneratedModuleRep ], function( gen ) return GetGenerators( gen, [ 1 .. NrGenerators( gen ) ] ); end ); ## InstallMethod( RelationsOfHullModule, "for sets of generators of homalg modules", [ IsHomalgGenerators ], function( gen ) return gen!.relations_of_hullmodule; end ); ## InstallMethod( HasNrRelations, "for sets of generators of homalg modules", [ IsHomalgGenerators ], function( gen ) return HasNrRelations( RelationsOfHullModule( gen ) ); end ); ## InstallMethod( NrRelations, "for sets of generators of homalg modules", [ IsHomalgGenerators ], function( gen ) return NrRelations( RelationsOfHullModule( gen ) ); end ); ## InstallMethod( MatrixOfRelations, "for sets of generators of homalg modules", [ IsHomalgGenerators ], function( gen ) return EvaluatedMatrixOfRelations( RelationsOfHullModule( gen ) ); end ); ## InstallMethod( HasNrGenerators, "for sets of generators of homalg modules", [ IsHomalgGeneratorsOfRightModule ], function( gen ) return HasNrColumns( MatrixOfGenerators( gen ) ); end ); ## InstallMethod( HasNrGenerators, "for sets of generators of homalg modules", [ IsHomalgGeneratorsOfLeftModule ], function( gen ) return HasNrRows( MatrixOfGenerators( gen ) ); end ); ## InstallMethod( NrGenerators, ### defines: NrGenerators (NumberOfGenerators) "for sets of generators of homalg modules", [ IsHomalgGeneratorsOfRightModule ], function( gen ) return NrColumns( MatrixOfGenerators( gen ) ); end ); ## InstallMethod( NrGenerators, ### defines: NrGenerators (NumberOfGenerators) "for sets of generators of homalg modules", [ IsHomalgGeneratorsOfLeftModule ], function( gen ) return NrRows( MatrixOfGenerators( gen ) ); end ); ## InstallMethod( CertainGenerators, "for sets of generators of homalg modules", [ IsHomalgGeneratorsOfRightModule, IsList ], function( gen, list ) return CertainColumns( MatrixOfGenerators( gen ), list ); end ); ## InstallMethod( CertainGenerators, "for sets of generators of homalg modules", [ IsHomalgGeneratorsOfLeftModule, IsList ], function( gen, list ) return CertainRows( MatrixOfGenerators( gen ), list ); end ); ## InstallMethod( CertainGenerator, "for sets of generators of homalg modules", [ IsHomalgGenerators, IsPosInt ], function( gen, pos ) return CertainGenerators( gen, [ pos ] ); end ); ## InstallMethod( NewHomalgGenerators, "for sets of generators of homalg modules", [ IsHomalgMatrix, IsHomalgGenerators ], function( mat, gen ) local relations_of_hullmodule, gen_new; relations_of_hullmodule := RelationsOfHullModule( gen ); if IsHomalgGeneratorsOfLeftModule( gen ) then gen_new := HomalgGeneratorsForLeftModule( mat, relations_of_hullmodule ); else gen_new := HomalgGeneratorsForRightModule( mat, relations_of_hullmodule ); fi; if HasProcedureToReadjustGenerators( gen ) then SetProcedureToReadjustGenerators( gen_new, ProcedureToReadjustGenerators( gen ) ); fi; if HasProcedureToNormalizeGenerators( gen ) then SetProcedureToNormalizeGenerators( gen_new, ProcedureToNormalizeGenerators( gen ) ); fi; if IsBound( gen!.ring ) then gen_new!.ring := gen!.ring; fi; if IsBound( gen!.ConvertTransitionMatrix ) then gen_new!.ConvertTransitionMatrix := gen!.ConvertTransitionMatrix; fi; return gen_new; end ); ## InstallMethod( UnionOfRelations, "for sets of generators of homalg modules", [ IsHomalgGenerators, IsHomalgRelations ], function( gen, rel ) local gen_new, hull; gen_new := MatrixOfGenerators( gen ); hull := RelationsOfHullModule( gen ); hull := UnionOfRelations( hull, rel ); if IsHomalgGeneratorsOfLeftModule( gen ) and IsHomalgRelationsOfLeftModule( rel ) then gen_new := HomalgGeneratorsForLeftModule( gen_new, hull ); elif IsHomalgGeneratorsOfRightModule( gen ) and IsHomalgRelationsOfRightModule( rel ) then gen_new := HomalgGeneratorsForRightModule( gen_new, hull ); else Error( "the set of generators and the set of relations must either be both left or both right\n" ); fi; if HasProcedureToReadjustGenerators( gen ) then SetProcedureToReadjustGenerators( gen_new, ProcedureToReadjustGenerators( gen ) ); fi; if HasProcedureToNormalizeGenerators( gen ) then SetProcedureToNormalizeGenerators( gen_new, ProcedureToNormalizeGenerators( gen ) ); fi; if IsBound( gen!.ring ) then gen_new!.ring := gen!.ring; fi; if IsBound( gen!.ConvertTransitionMatrix ) then gen_new!.ConvertTransitionMatrix := gen!.ConvertTransitionMatrix; fi; return gen_new; end ); ## InstallMethod( DecideZero, "for sets of generators of homalg modules", [ IsHomalgGenerators ], function( gen ) local gen_old, gen_new; if not IsBound( gen!.DecideZero ) then ## IsReduced is not set, otherwise the method below would apply gen_old := MatrixOfGenerators( gen ); gen_new := DecideZero( gen_old, RelationsOfHullModule( gen ) ); if gen_new = gen_old then gen!.DecideZero := gen_old; SetIsReduced( gen, true ); return gen; fi; gen!.DecideZero := gen_new; SetIsReduced( gen, false ); fi; gen_new := NewHomalgGenerators( gen!.DecideZero, gen ); SetIsReduced( gen_new, true ); return gen_new; end ); ## InstallMethod( DecideZero, "for sets of generators of homalg modules", [ IsHomalgGenerators and IsReduced ], function( gen ) return gen; end ); ## InstallMethod( DecideZero, "for sets of generators of homalg modules", [ IsHomalgGenerators, IsHomalgRelations ], function( gen, rel ) if not IsBound( gen!.DecideZero ) then gen!.DecideZero := DecideZero( MatrixOfGenerators( gen ), rel ); SetIsReduced( gen, false ); fi; return gen!.DecideZero; end ); ## InstallMethod( GetRidOfZeroGenerators, ### defines: GetRidOfZeroGenerators (BetterBasis) "for sets of generators of homalg modules", [ IsHomalgGenerators ], function( _gen ) local R, RP, gen, nonzero; R := HomalgRing( _gen ); RP := homalgTable( R ); #=====# begin of the core procedure #=====# gen := DecideZero( _gen ); if IsHomalgGeneratorsOfLeftModule( gen ) then if IsBound(RP!.SimplifyBasisOfRows) then gen := RP!.SimplifyBasisOfRows( gen ); else gen := MatrixOfGenerators( gen ); fi; nonzero := NonZeroRows( gen ); gen := CertainRows( gen, nonzero ); else if IsBound(RP!.SimplifyBasisOfColumns) then gen := RP!.SimplifyBasisOfColumns( gen ); else gen := MatrixOfGenerators( gen ); fi; nonzero := NonZeroColumns( gen ); gen := CertainColumns( gen, nonzero ); fi; gen := NewHomalgGenerators( gen, _gen ); return gen; end ); ## InstallMethod( SyzygiesGenerators, "for sets of relations of homalg modules", [ IsHomalgGeneratorsOfRightModule, IsHomalgRelationsOfRightModule ], function( gen, rel ) return HomalgRelationsForRightModule( SyzygiesGeneratorsOfColumns, [ MatrixOfGenerators( gen ), MatrixOfRelations( rel ) ] ); end ); ## InstallMethod( SyzygiesGenerators, "for sets of relations of homalg modules", [ IsHomalgGeneratorsOfLeftModule, IsHomalgRelationsOfLeftModule ], function( gen, rel ) return HomalgRelationsForLeftModule( SyzygiesGeneratorsOfRows, [ MatrixOfGenerators( gen ), MatrixOfRelations( rel ) ] ); end ); ## InstallMethod( ReducedSyzygiesGenerators, "for sets of relations of homalg modules", [ IsHomalgGeneratorsOfRightModule, IsHomalgRelationsOfRightModule ], function( gen, rel ) return ReducedSyzygiesGenerators( MatrixOfGenerators( gen ), rel ); end ); ## InstallMethod( ReducedSyzygiesGenerators, "for sets of relations of homalg modules", [ IsHomalgGeneratorsOfLeftModule, IsHomalgRelationsOfLeftModule ], function( gen, rel ) return ReducedSyzygiesGenerators( MatrixOfGenerators( gen ), rel ); end ); ## InstallMethod( \*, "for sets of generators of homalg modules", [ IsHomalgMatrix, IsHomalgGenerators ], function( TI, gen ) local generators, R; generators := MatrixOfGenerators( gen ); R := HomalgRing( generators ); if not IsIdenticalObj( R, HomalgRing( TI ) ) then if IsBound( gen!.ConvertTransitionMatrix ) then TI := gen!.ConvertTransitionMatrix( TI ); elif IsBound( gen!.ring ) and IsIdenticalObj( gen!.ring, HomalgRing( TI ) ) then TI := TI * R; fi; fi; if IsHomalgMatrix( TI ) then if IsHomalgGeneratorsOfLeftModule( gen ) then generators := NewHomalgGenerators( TI * generators, gen ); ## the hull relations remain unchanged :) else generators := NewHomalgGenerators( generators * TI, gen ); ## the hull relations remain unchanged :) fi; elif IsFunction( TI ) then generators := NewHomalgGenerators( TI( generators ), gen ); ## the hull relations remain unchanged :) else Error( "unknown type of transition operation\n" ); fi; return generators; end ); ## InstallMethod( \*, "for sets of generators of homalg modules", [ IsHomalgGenerators, IsHomalgGenerators ], function( gen1, gen2 ) local gen; if not ( IsHomalgGeneratorsOfLeftModule( gen1 ) and IsHomalgGeneratorsOfLeftModule( gen2 ) ) and not ( IsHomalgGeneratorsOfRightModule( gen1 ) and IsHomalgGeneratorsOfRightModule( gen2 ) ) then Error( "the two sets of generators must either be both left or both right\n" ); fi; gen := MatrixOfGenerators( gen1 ) * gen2; return gen; end ); ## InstallMethod( \*, "for sets of generators of homalg modules", [ IsHomalgRelations, IsHomalgGenerators ], function( rel, gen ) local rel_mat, gen_mat, R; rel_mat := MatrixOfRelations( rel ); gen_mat := MatrixOfGenerators( gen ); R := HomalgRing( gen_mat ); if not IsIdenticalObj( R, HomalgRing( rel_mat ) ) then if IsBound( gen!.ring ) and IsIdenticalObj( gen!.ring, HomalgRing( rel_mat ) ) then rel_mat := rel_mat * R; fi; fi; if IsBound( gen!.ConvertTransitionMatrix ) then rel_mat := gen!.ConvertTransitionMatrix( rel_mat ); fi; if IsHomalgMatrix( rel_mat ) then if IsHomalgRelationsOfLeftModule( rel ) then if IsHomalgGeneratorsOfRightModule( gen ) then Error( "the set of generators and the set of relations must either be both left or both right\n" ); fi; return HomalgRelationsForLeftModule( rel_mat * gen_mat ); else if IsHomalgGeneratorsOfLeftModule( gen ) then Error( "the set of generators and the set of relations must either be both left or both right\n" ); fi; return HomalgRelationsForRightModule( gen_mat * rel_mat ); fi; elif IsFunction( rel_mat ) then if IsHomalgRelationsOfLeftModule( rel ) then return HomalgRelationsForLeftModule( rel_mat( gen_mat ) ); else return HomalgRelationsForRightModule( rel_mat( gen_mat ) ); fi; else Error( "unknown type of transition operation\n" ); fi; end ); #################################### # # constructor functions and methods: # #################################### ## InstallGlobalFunction( HomalgGeneratorsForLeftModule, function( arg ) local nargs, ar, R, generators, relations_of_hullmodule, gen; nargs := Length( arg ); for ar in arg{ [ 2 .. nargs ] } do if IsHomalgRing( ar ) then R := ar; break; fi; od; if IsHomalgMatrix( arg[1] ) then ResetFilterObj( arg[1], IsMutable ); generators := arg[1]; elif IsBound( R ) then generators := HomalgMatrix( arg[1], R ); else Error( "if the first argument isn't of type IsHomalgMatrix, then the last argument must be of type IsHomalgRing\n" ); fi; if not IsBound( R ) then R := HomalgRing( generators ); fi; for ar in arg{ [ 2 .. nargs ] } do if IsHomalgRelations( ar ) then if not IsHomalgRelationsOfLeftModule( ar ) then Error( "the set of relations of the hull module of the generators is not a set of relations of a left module\n" ); fi; relations_of_hullmodule := ar; break; elif IsHomalgMatrix( ar ) then relations_of_hullmodule := HomalgRelationsForLeftModule( ar ); break; elif IsList( ar ) and not IsStringRep( ar ) and IsBound( R ) then relations_of_hullmodule := HomalgRelationsForLeftModule( ar, R ); break; elif nargs > 2 then if IsBound( R ) then relations_of_hullmodule := HomalgRelationsForLeftModule( ar, R ); break; else Error( "if more than two arguments are provided and the second argument is neither of type IsHomalgRelations nor of type IsHomalgMatrix, then the last argument must be of type IsHomalgRing\n" ); fi; fi; od; if not IsBound( relations_of_hullmodule ) then relations_of_hullmodule := HomalgRelationsForLeftModule( HomalgZeroMatrix( 0, NrColumns( generators ), R ) ); fi; gen := rec( generators := generators, relations_of_hullmodule := relations_of_hullmodule ); ## Objectify: Objectify( TheTypeHomalgGeneratorsOfFinitelyGeneratedLeftModule, gen ); return gen; end ); ## InstallGlobalFunction( HomalgGeneratorsForRightModule, function( arg ) local nargs, ar, R, generators, relations_of_hullmodule, gen; nargs := Length( arg ); for ar in arg{ [ 2 .. nargs ] } do if IsHomalgRing( ar ) then R := ar; break; fi; od; if IsHomalgMatrix( arg[1] ) then ResetFilterObj( arg[1], IsMutable ); generators := arg[1]; elif IsBound( R ) then generators := HomalgMatrix( arg[1], R ); else Error( "if the first argument isn't of type IsHomalgMatrix, then the last argument must be of type IsHomalgRing\n" ); fi; if not IsBound( R ) then R := HomalgRing( generators ); fi; for ar in arg{ [ 2 .. nargs ] } do if IsHomalgRelations( ar ) then if not IsHomalgRelationsOfRightModule( ar ) then Error( "the set of relations of the hull module of the generators is not a set of relations of a right module\n" ); fi; relations_of_hullmodule := ar; break; elif IsHomalgMatrix( ar ) then relations_of_hullmodule := HomalgRelationsForRightModule( ar ); break; elif IsList( ar ) and not IsStringRep( ar ) and IsBound( R ) then relations_of_hullmodule := HomalgRelationsForRightModule( ar, R ); break; elif nargs > 2 then if IsBound( R ) then relations_of_hullmodule := HomalgRelationsForRightModule( ar, R ); break; else Error( "if more than two arguments are provided and the second argument is neither of type IsHomalgRelations nor of type IsHomalgMatrix, then the last argument must be of type IsHomalgRing\n" ); fi; fi; od; if not IsBound( relations_of_hullmodule ) then relations_of_hullmodule := HomalgRelationsForRightModule( HomalgZeroMatrix( NrRows( generators ), 0, R ) ); fi; gen := rec( generators := generators, relations_of_hullmodule := relations_of_hullmodule ); ## Objectify: Objectify( TheTypeHomalgGeneratorsOfFinitelyGeneratedRightModule, gen ); return gen; end ); ## InstallMethod( RingMap, "for homalg rings", [ IsHomalgGenerators, IsHomalgRing, IsHomalgRing ], function( images, S, T ) local R, psi; if IsIdenticalObj( HomalgRing( images ), T ) then psi := RingMap( MatrixOfGenerators( images ), S, T ); else psi := RingMap( T * MatrixOfGenerators( images ), S, T ); fi; if IsHomalgGeneratorsOfLeftModule( images ) then psi!.left := true; else psi!.left := false; fi; return psi; end ); #################################### # # View, Print, and Display methods: # #################################### InstallMethod( ViewObj, "for homalg generators", [ IsHomalgGenerators ], 100, function( o ) local g; g := NrGenerators( o ); if g = 0 then Print( "<An empty set of generators " ); elif g = 1 then Print( "<A set consisting of a single generator " ); else Print( "<A set of ", g, " generators " ); fi; Print( "of a homalg " ); if IsHomalgGeneratorsOfLeftModule( o ) then Print( "left " ); else Print( "right " ); fi; Print( "module>" ); end ); InstallMethod( Display, "for homalg generators", [ IsHomalgGenerators ], 100000, function( o ) local g; g := NrGenerators( o ); if g = 0 then Print( "an empty set of generators\n" ); else Display( MatrixOfGenerators( o ) ); Print( "\na set " ); if g = 1 then Print( "consisting of a single generator given by (the" ); else Print( "of ", g, " generators given by the" ); fi; if IsHomalgGeneratorsOfLeftModule( o ) then Print( " row" ); else Print( " column" ); fi; if g = 1 then Print( " of)" ); else Print( "s of" ); fi; Print( " the above matrix\n" ); fi; end ); InstallMethod( Display, "for homalg generators", [ IsHomalgGenerators and HasProcedureToReadjustGenerators ], 100000, function( o ) local g, mat, proc, l, i; g := NrGenerators( o ); if g = 0 then Print( "an empty set of generators\n" ); else mat := MatrixOfGenerators( o ); proc := ProcedureToReadjustGenerators( o ); l := Length( proc ); if IsHomalgGeneratorsOfLeftModule( o ) then for i in [ 1 .. NrGenerators( o ) ] do Display( CallFuncList( proc[1], Concatenation( [ CertainRows( mat, [ i ] ) ], proc{[ 2 .. l ]} ) ) ); Print( "\n" ); od; else for i in [ 1 .. NrGenerators( o ) ] do Display( CallFuncList( proc[1], Concatenation( [ CertainColumns( mat, [ i ] ) ], proc{[ 2 .. l ]} ) ) ); Print( "\n" ); od; fi; Print( "a set " ); if g = 1 then Print( "consisting of a single generator" ); else Print( "of ", g, " generators" ); fi; Print( " given by the the above " ); if g = 1 then Print( "matrix\n" ); else Print( "matrices\n" ); fi; fi; end );