GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
############################################################################# ## ## ToricDivisors.gi ToricVarieties Sebastian Gutsche ## ## Copyright 2011 Lehrstuhl B für Mathematik, RWTH Aachen ## ## The Category of the Divisors of a toric Variety ## ############################################################################# ################################# ## ## Representations ## ################################# DeclareRepresentation( "IsToricDivisorRep", IsToricDivisor and IsAttributeStoringRep, [ AmbientToricVariety, UnderlyingGroupElement ] ); BindGlobal( "TheFamilyOfToricDivisors", NewFamily( "TheFamilyOfToricDivisors" , IsToricDivisor ) ); BindGlobal( "TheTypeToricDivisor", NewType( TheFamilyOfToricDivisors, IsToricDivisorRep ) ); ################################# ## ## Properties ## ################################# ## InstallMethod( IsPrincipal, "for toric divisors", [ IsToricDivisor ], function( divisor ) return IsZero( ClassOfDivisor( divisor ) ); end ); ## InstallMethod( IsPrimedivisor, "for toric divisors", [ IsToricDivisor ], function( divisor ) divisor := UnderlyingGroupElement( divisor ); divisor := UnderlyingListOfRingElements( divisor ); if ForAll( divisor, i -> i = 1 or i = 0 ) and Sum( divisor ) = 1 then return true; fi; return false; end ); ## InstallMethod( IsCartier, "for toric divisors", [ IsToricDivisor ], function( divisor ) local raysincones, rays, n, i, m, j, M, groupel, rayel, cartdata; rays := RayGenerators( FanOfVariety( AmbientToricVariety( divisor ) ) ); raysincones := RaysInMaximalCones( FanOfVariety( AmbientToricVariety( divisor ) ) ); n := Length( raysincones ); m := Length( rays ); cartdata := [ 1 .. n ]; groupel := UnderlyingListOfRingElements( UnderlyingGroupElement( divisor ) ); for i in [ 1 .. n ] do M := [ ]; rayel := [ ]; for j in [ 1 .. m ] do if raysincones[ i ][ j ] = 1 then Add( M, rays[ j ] ); Add( rayel, - groupel[ j ] ); fi; od; j := HomalgMatrix( rayel, Length( M ), 1, HOMALG_MATRICES.ZZ ); M := HomalgMatrix( M, HOMALG_MATRICES.ZZ ); j := LeftDivide( M, j ); if j = fail then return false; fi; cartdata[ i ] := EntriesOfHomalgMatrix( j ); od; SetCartierData( divisor, cartdata ); return true; end ); ## InstallMethod( IsAmple, " for toric divisors", [ IsToricDivisor ], function( divisor ) local rays, raysincones, cartdata, groupel, l, i, multlist, j; rays := AmbientToricVariety( divisor ); if not IsComplete( rays ) or not IsNormalVariety( rays ) then Error( "computation may be wrong up to unfulfilled preconditions\n" ); fi; if not IsBasepointFree( divisor ) then return false; fi; groupel := UnderlyingListOfRingElements( UnderlyingGroupElement( divisor ) ); l := Length( groupel ); Apply( groupel, i -> -i ); rays := RayGenerators( FanOfVariety( AmbientToricVariety( divisor ) ) ); cartdata := CartierData( divisor ); raysincones := RaysInMaximalCones( FanOfVariety( AmbientToricVariety( divisor ) ) ); for i in [ 1 .. Length( cartdata ) ] do for j in [ 1 .. l ] do if raysincones[ i ][ j ] = 0 then multlist := Sum( List( [ 1 .. Length( cartdata[ i ] ) ], k -> rays[ j ][ k ] * cartdata[ i ][ k ] ) ); if multlist <= groupel[ j ] then return false; fi; fi; od; od; return true; end ); ## InstallMethod( IsBasepointFree, "for toric divisors", [ IsToricDivisor ], function( divisor ) local rays, cartdata, groupel, l, i, multlist, j; if HasTorusfactor( AmbientToricVariety( divisor ) ) then Error( "variety has torusfactors, computation may be wrong\n" ); fi; # # if not IsComplete( AmbientToricVariety( divisor ) ) then # # # # Error( "variety is not complete, computation may be wrong." ); # # # # fi; if not IsCartier( divisor ) then return false; fi; groupel := UnderlyingListOfRingElements( UnderlyingGroupElement( divisor ) ); l := Length( groupel ); Apply( groupel, i -> -i ); rays := RayGenerators( FanOfVariety( AmbientToricVariety( divisor ) ) ); cartdata := CartierData( divisor ); for i in cartdata do multlist := List( rays, k -> Sum( [ 1 .. Length( k ) ], j -> k[j]*i[j] ) ); if not ForAll( [ 1..l ], j -> multlist[ j ] >= groupel[ j ] ) then return false; fi; od; return true; end ); ## InstallMethod( IsVeryAmple, "for toric divisors", [ IsToricDivisor and IsAmple ], function( divisor ) return IsVeryAmple( PolytopeOfDivisor( divisor ) ); end ); ## ## RedispatchOnCondition( IsVeryAmple, true, [ IsToricDivisor and IsAmple ], [ PolytopeOfDivisor ], 1 ); ## RedispatchOnCondition( IsVeryAmple, true, [ IsToricDivisor ], [ IsAmple ], 0 ); ################################# ## ## Attributes ## ################################# ## InstallMethod( ClassOfDivisor, "for toric divisors", [ IsToricDivisor ], function( divisor ) local groupelem, coker; coker := CokernelEpi( MapFromCharacterToPrincipalDivisor( AmbientToricVariety( divisor ) ) ); groupelem := ApplyMorphismToElement( coker, UnderlyingGroupElement( divisor ) ); return groupelem; end ); ## InstallMethod( CartierData, "for toric divisors", [ IsToricDivisor and IsCartier ], function( divisor ) local raysincones, rays, n, i, m, j, M, groupel, rayel, cartdata; rays := RayGenerators( FanOfVariety( AmbientToricVariety( divisor ) ) ); raysincones := RaysInMaximalCones( FanOfVariety( AmbientToricVariety( divisor ) ) ); n := Length( raysincones ); m := Length( rays ); cartdata := [ 1 .. n ]; groupel := UnderlyingListOfRingElements( UnderlyingGroupElement( divisor ) ); for i in [ 1 .. n ] do M := [ ]; rayel := [ ]; for j in [ 1 .. m ] do if raysincones[ i ][ j ] = 1 then Add( M, rays[ j ] ); Add( rayel, - groupel[ j ] ); fi; od; j := HomalgMatrix( rayel, Length( M ), 1, HOMALG_MATRICES.ZZ ); M := HomalgMatrix( M, HOMALG_MATRICES.ZZ ); j := LeftDivide( M, j ); if j = fail then return false; fi; cartdata[ i ] := HomalgModuleElement( j, CharacterLattice( AmbientToricVariety( divisor ) ) ); od; return cartdata; end ); ## InstallMethod( PolytopeOfDivisor, "for toric divisors", [ IsToricDivisor ], function( divisor ) local rays, divlist; rays := RayGenerators( FanOfVariety( AmbientToricVariety( divisor ) ) ); divlist := UnderlyingListOfRingElements( UnderlyingGroupElement( divisor ) ); divlist := List( [ 1 .. Length( rays ) ], i -> Concatenation( [ divlist[ i ] ], rays[ i ] ) ); return PolytopeByInequalities( divlist ); end ); ## InstallMethod( BasisOfGlobalSections, "for toric divisors", [ IsToricDivisor ], function( divisor ) local points, divisor_polytope; divisor_polytope := PolytopeOfDivisor( divisor ); if not IsBounded( divisor_polytope ) then Error( "list is infinite, cannot compute characters\n" ); fi; points := LatticePoints( divisor_polytope ); return List( points, i -> CharacterToRationalFunction( i, AmbientToricVariety( divisor ) ) ); end ); ## InstallMethod( IntegerForWhichIsSureVeryAmple, "for toric divisors", [ IsToricDivisor and IsAmple ], function( divisor ) local vari; vari := AmbientToricVariety( divisor ); if IsSmooth( vari ) and IsComplete( vari ) then return 1; fi; if Dimension( vari ) >= 2 then return Dimension( vari ) - 1; fi; TryNextMethod(); end ); ## InstallMethod( UnderlyingToricVariety, "for prime divisors", [ IsToricDivisor and IsPrimedivisor ], function( divisor ) local pos, vari, cones, i, neuvar, ray; pos := Position( UnderlyingListOfRingElements( UnderlyingGroupElement( divisor ) ), 1 ); vari := AmbientToricVariety( divisor ); vari := FanOfVariety( vari ); cones := RaysInMaximalCones( vari ); neuvar := [ ]; for i in [ 1 .. Length( cones ) ] do if cones[ i ][ pos ] = 1 then neuvar := Concatenation( neuvar, [ i ] ); fi; od; ray := Rays( vari )[ pos ]; ray := ByASmallerPresentation( FactorGridMorphism( ray ) ); cones := MaximalCones( vari ){ neuvar }; cones := List( cones, HilbertBasis ); cones := List( cones, i -> List( i, j -> HomalgMap( HomalgMatrix( [ j ], HOMALG_MATRICES.ZZ ), 1 * HOMALG_MATRICES.ZZ, ContainingGrid( vari ) ) ) ); cones := List( cones, i -> List( i, j -> UnderlyingListOfRingElements( ApplyMorphismToElement( ray, HomalgElement( j ) ) ) ) ); cones := Fan( cones ); neuvar := ToricSubvariety( ToricVariety( cones ), AmbientToricVariety( divisor ) ); SetIsClosedSubvariety( neuvar, true ); SetIsOpen( neuvar, false ); return neuvar; end ); ## InstallMethod( DegreeOfDivisor, "for toric divisors", [ IsToricDivisor ], function( divisor ) return Sum( UnderlyingListOfRingElements( UnderlyingGroupElement( divisor ) ) ); end ); ## InstallMethod( MonomsOfCoxRingOfDegree, " for toric divisorsors", [ IsToricDivisor ], function( divisor ) local cox_ring, ring, points, rays, n, i, j, mons, mon; if not HasCoxRing( AmbientToricVariety( divisor ) ) then Error( "specify cox ring first\n" ); fi; cox_ring := CoxRing( AmbientToricVariety( divisor ) ); ring := ListOfVariablesOfCoxRing( AmbientToricVariety( divisor ) ); if not IsBounded( PolytopeOfDivisor( divisor ) ) then Error( "list is infinite, cannot compute basis because it is not finite\n" ); fi; points := LatticePoints( PolytopeOfDivisor( divisor ) ); rays := RayGenerators( FanOfVariety( AmbientToricVariety( divisor ) ) ); divisor := UnderlyingListOfRingElements( UnderlyingGroupElement( divisor ) ); n := Length( rays ); mons := [ ]; for i in points do mon := List( [ 1 .. n ], j -> JoinStringsWithSeparator( [ ring[ j ], String( ( Sum( List( [ 1 .. Length( i ) ], m -> rays[ j ][ m ] * i[ m ] ) ) ) + divisor[ j ] ) ], "^" ) ); mon := JoinStringsWithSeparator( mon, "*" ); Add( mons, HomalgRingElement( mon, cox_ring ) ); od; return mons; end ); ## InstallMethod( CoxRingOfTargetOfDivisorMorphism, "for basepoint free divisors", [ IsToricDivisor ], function( divisor ) return CoxRingOfTargetOfDivisorMorphism( divisor, TORIC_VARIETIES.CoxRingIndet ); end ); ## InstallMethod( RingMorphismOfDivisor, "for basepoint free divisors", [ IsToricDivisor ], function( divisor ) local coxring, images, var_coxring; coxring := CoxRingOfTargetOfDivisorMorphism( divisor ); var_coxring := CoxRing( AmbientToricVariety( divisor ) ); images := MonomsOfCoxRingOfDegree( divisor ); return RingMap( images, coxring, var_coxring ); end ); ################################# ## ## Methods ## ################################# ## InstallMethod( CharactersForClosedEmbedding, "for toric varieties.", [ IsToricDivisor and IsVeryAmple ], function( divisor ) return BasisOfGlobalSections( divisor ); end ); ## RedispatchOnCondition( CharactersForClosedEmbedding, true, [ IsToricDivisor ], [ IsVeryAmple ], 0 ); ## InstallMethod( VeryAmpleMultiple, " for ample toric divisorsors.", [ IsToricDivisor and IsAmple ], function( divisor ) return IntegerForWhichIsSureVeryAmple( divisor ) * divisor; end ); ## RedispatchOnCondition( VeryAmpleMultiple, true, [ IsToricDivisor ], [ IsAmple ], 0 ); ## InstallMethod( VarietyOfDivisorpolytope, " for ample divisorsors", [ IsToricDivisor and IsBasepointFree ], function( divisor ) return ToricVariety( PolytopeOfDivisor( divisor ) ); end ); ## InstallMethod( MonomsOfCoxRingOfDegree, " for homalg elements", [ IsToricVariety, IsHomalgElement ], function( vari, elem ) local pos; if not IsIdenticalObj( Range( UnderlyingMorphism( elem ) ), ClassGroup( vari ) ) then Error( "wrong element\n" ); fi; pos := UnderlyingListOfRingElements( elem ); pos := CreateDivisor( pos, vari ); return MonomsOfCoxRingOfDegree( pos ); end ); ## InstallMethod( MonomsOfCoxRingOfDegree, " for lists", [ IsToricVariety, IsList ], function( vari, lis ) local pos, elem, mor; elem := HomalgMatrix( lis, 1, Length( lis ), HOMALG_MATRICES.ZZ ); elem := HomalgMap( elem, 1 * HOMALG_MATRICES.ZZ, TorusInvariantDivisorGroup( vari ) ); elem := HomalgElement( elem ); mor := CokernelEpi( MapFromCharacterToPrincipalDivisor( vari ) ); elem := ApplyMorphismToElement( mor, elem ); return MonomsOfCoxRingOfDegree( vari, elem ); end ); ## InstallMethod( CoxRingOfTargetOfDivisorMorphism, "for toric divisors", [ IsToricDivisor, IsString ], function( divisor, variable ) local nrpoints, classgroup, degrees, coxring; if not IsBasepointFree( divisor ) then Error( "no embedding in projective variety defined\n" ); fi; nrpoints := Length( LatticePoints( Polytope( divisor ) ) ); classgroup := 1 * HOMALG_MATRICES.ZZ; coxring := DefaultFieldForToricVarieties() * JoinStringsWithSeparator( [ variable, JoinStringsWithSeparator( [ "1", String( nrpoints ) ], ".." ) ], "_" ); coxring := GradedRing( coxring ); SetDegreeGroup( coxring, classgroup ); degrees := List( [ 1 .. nrpoints ], i -> GeneratingElements( classgroup )[ 1 ] ); SetWeightsOfIndeterminates( coxring, degrees ); return coxring; end ); ## InstallMethod( \+, "for toric divisors", [ IsToricDivisor, IsToricDivisor ], function( divisor1, divisor2 ) local sum_of_divisors; if not IsIdenticalObj( AmbientToricVariety( divisor1 ), AmbientToricVariety( divisor2 ) ) then Error( "cannot add these divisors\n" ); return 0; fi; sum_of_divisors := CreateDivisor( UnderlyingGroupElement( divisor1 ) + UnderlyingGroupElement( divisor2 ), AmbientToricVariety( divisor1 ) ); SetClassOfDivisor( sum_of_divisors, ClassOfDivisor( divisor1 ) + ClassOfDivisor( divisor2 ) ); return sum_of_divisors; end ); ## InstallMethod( \-, "for toric divisor", [ IsToricDivisor , IsToricDivisor ], function( divisor1, divisor2 ) return divisor1 + ( -1 ) * divisor2; end ); ## InstallMethod( \*, "for toric divisorsors", [ IsInt, IsToricDivisor ], function( a, divisor ) local divisor1; divisor1 := CreateDivisor( a * UnderlyingGroupElement( divisor ), AmbientToricVariety( divisor ) ); SetClassOfDivisor( divisor1, a * ClassOfDivisor( divisor ) ); return divisor1; end ); ## InstallMethod( AddDivisorToItsAmbientVariety, "for toric divisors", [ IsToricDivisor ], function( divisor ) local ambient_variety; ambient_variety := AmbientToricVariety( divisor ); Add( ambient_variety!.WeilDivisors, divisor ); end ); ## InstallMethod( Polytope, "for toric divisors", [ IsToricDivisor ], function( divisor ) return PolytopeOfDivisor( divisor ); end ); ## InstallMethod( \=, "for toric divisors", [ IsToricDivisor, IsToricDivisor ], function( divi1, divi2 ) return UnderlyingGroupElement( divi1 ) = UnderlyingGroupElement( divi2 ); end ); ################################## ## ## Constructors ## ################################## ## InstallMethod( CreateDivisor, " for toric varieties", [ IsHomalgElement, IsToricVariety ], function( group_element, variety ) local divisor; divisor := rec( ); ObjectifyWithAttributes( divisor, TheTypeToricDivisor, AmbientToricVariety, variety, UnderlyingGroupElement, group_element ); AddDivisorToItsAmbientVariety( divisor ); return divisor; end ); ## InstallMethod( CreateDivisor, "for toric varieties", [ IsList, IsToricVariety ], function( group_element, variety ) local elem; group_element := HomalgMatrix( [ group_element ], HOMALG_MATRICES.ZZ ); group_element := HomalgMap( group_element, 1 * HOMALG_MATRICES.ZZ, TorusInvariantDivisorGroup( variety ) ); group_element := HomalgElement( group_element ); return CreateDivisor( group_element, variety ); end ); ## InstallMethod( DivisorOfCharacter, " for toric varieties", [ IsHomalgElement, IsToricVariety ], function( character, variety ) local group_element, divisor; group_element := ApplyMorphismToElement( MapFromCharacterToPrincipalDivisor( variety ), character ); divisor := CreateDivisor( group_element, variety ); SetIsPrincipal( divisor, true ); SetCharacterOfPrincipalDivisor( divisor, character ); SetIsCartier( divisor, true ); SetCartierData( divisor, List( MaximalCones( FanOfVariety( variety ) ), i -> ( -1 )* UnderlyingListOfRingElements( character ) ) ); SetClassOfDivisor( divisor, TheZeroElement( ClassGroup( variety ) ) ); AddDivisorToItsAmbientVariety( divisor ); return divisor; end ); ## InstallMethod( DivisorOfCharacter, " for toric varieties.", [ IsList, IsToricVariety ], function( character, variety ) character := HomalgMatrix( [ character ], HOMALG_MATRICES.ZZ ); character := HomalgMap( character, 1 * HOMALG_MATRICES.ZZ, CharacterLattice( variety ) ); character := HomalgElement( character ); return DivisorOfCharacter( character, variety ); end ); ################################# ## ## View ## ################################# ## InstallMethod( ViewObj, "for toric divisors", [ IsToricDivisor ], function( divisor ) local prin; prin := false; Print( "<A" ); if HasIsAmple( divisor ) then if HasIsVeryAmple( divisor ) then if IsVeryAmple( divisor ) then Print( " very ample" ); elif IsAmple( divisor ) then Print( "n ample" ); fi; elif IsAmple( divisor ) then Print( "n ample" ); fi; fi; if HasIsBasepointFree( divisor ) then if IsBasepointFree( divisor ) then Print( " basepoint free" ); fi; fi; if HasIsPrincipal( divisor ) then if IsPrincipal( divisor ) then Print( " principal" ); prin := true; fi; fi; if HasIsCartier( divisor ) then if IsCartier( divisor ) and not prin then Print( " Cartier" ); fi; fi; if HasIsPrimedivisor( divisor ) then if IsPrimedivisor( divisor ) then Print( " prime" ); fi; fi; Print( " divisor of a toric variety with coordinates " ); ViewObj( UnderlyingGroupElement( divisor ) ); Print( ">" ); end ); ## InstallMethod( Display, "for toric divisors", [ IsToricDivisor ], function( divisor ) local prin; prin := false; Print( "A" ); if HasIsAmple( divisor ) then if HasIsVeryAmple( divisor ) then if IsVeryAmple( divisor ) then Print( " very ample" ); elif IsAmple( divisor ) then Print( "n ample" ); fi; elif IsAmple( divisor ) then Print( "n ample" ); fi; fi; if HasIsBasepointFree( divisor ) then if IsBasepointFree( divisor ) then Print( " basepoint free" ); fi; fi; if HasIsPrincipal( divisor ) then if IsPrincipal( divisor ) then Print( " principal" ); prin := true; fi; fi; if HasIsCartier( divisor ) then if IsCartier( divisor ) and not prin then Print( " Cartier" ); fi; fi; Print( " divisor of a toric variety" ); Print( ".\n" ); end );