############################################################################# ## ## This file is part of GAP, a system for computational discrete algebra. ## This file's authors include Thomas Breuer, Martin Schönert, Frank Celler. ## ## Copyright of GAP belongs to its developers, whose names are too numerous ## to list here. Please refer to the COPYRIGHT file for details. ## ## SPDX-License-Identifier: GPL-2.0-or-later ## ## This file contains (representation dependent) ## ## 1. methods for general mappings in 'IsDefaultMappingRep' ## 2. methods for composition mappings, ## 3. methods for mappings by function, ## 4. methods for inverse mappings ## 5. methods for identity mappings ## 6. methods for zero mappings ##
############################################################################# ## ## 1. methods for general mappings in 'IsDefaultMappingRep' ##
############################################################################# ## #R IsDefaultGeneralMappingRep( <map> ) ## ## Source and range of such a general mapping are stored in its type, as ## 'DataType( TypeObj( <map> ) )[1]' resp. ## 'DataType( TypeObj( <map> ) )[2]'. ## ## Note that this representation does *not* decide whether <map> is ## a positional or a component object. ##
DeclareRepresentation( "IsDefaultGeneralMappingRep",
IsGeneralMapping and HasSource and HasRange,
[] ); #T methods to handle attributes 'One', 'Inverse', and 'InverseGeneralMapping', #T 'ImagesSource', 'PreImagesRange'?
# Do a cheap test whether the general mapping has equal source and range. if IsIdenticalObj( source, range ) then
filter:= filter and IsEndoGeneralMapping; fi;
# Construct the type.
Type:= NewType( GeneralMappingsFamily(
ElementsFamily( FamilyObj( source ) ),
ElementsFamily( FamilyObj( range ) ) ),
IsDefaultGeneralMappingRep and filter );
# Store source and range.
SetDataType( Type, [ source, range ] );
# Return the type.
return Type; end );
############################################################################# ## #M Range( <map> ) ##
InstallMethod( Range, "for default general mapping",
true,
[ IsGeneralMapping and IsDefaultGeneralMappingRep ],
GETTER_FLAGS + 1, # higher than the system getter!
map -> DataType( TypeObj( map ) )[2] );
############################################################################# ## #M Source( <map> ) ##
InstallMethod( Source, "for default general mapping",
true,
[ IsGeneralMapping and IsDefaultGeneralMappingRep ],
GETTER_FLAGS + 1, # higher than the system getter!
map -> DataType( TypeObj( map ) )[1] );
############################################################################# ## ## 2. methods for composition mappings, ##
############################################################################# ## #F ConstituentsCompositionMapping( <map> ) ##
InstallGlobalFunction(ConstituentsCompositionMapping,function(map) if not IsCompositionMappingRep(map) then
Error("<map> must be `IsCompositionMappingRep'"); fi;
return [map!.map1,map!.map2]; end);
############################################################################# ## #M CompositionMapping2( <map2>, <map1> ) . . . . . for two general mappings ##
InstallGlobalFunction(CompositionMapping2General, function( map2, map1 )
local com; # composition of <map1> and <map2>, result
# Make the general mapping. if IsSPGeneralMapping( map1 ) and IsSPGeneralMapping( map2 ) then
com:= Objectify( TypeOfDefaultGeneralMapping( Source( map1 ),
Range( map2 ),
IsCompositionMappingRep and IsSPGeneralMapping ),
rec() ); else
com:= Objectify( TypeOfDefaultGeneralMapping( Source( map1 ),
Range( map2 ),
IsCompositionMappingRep and IsNonSPGeneralMapping ),
rec() ); fi;
# Enter the identifying information. # (Maintenance of useful information is dealt with by the # wrapper function `CompositionMapping'.)
com!.map1:= map1;
com!.map2:= map2;
# Return the composition.
return com; end );
InstallMethod( CompositionMapping2, "for two general mappings",
FamSource1EqFamRange2,
[ IsGeneralMapping, IsGeneralMapping ], 0,
CompositionMapping2General);
############################################################################# ## #M IsInjective( <map> ) . . . . . . . . . . . . . . for composition mapping ##
InstallMethod( IsInjective, "for a composition mapping",
true,
[ IsCompositionMappingRep ], SUM_FLAGS, function( com ) if IsInjective( com!.map1 ) and IsInjective( com!.map2 ) then
return true; fi; if not IsInjective( com!.map1 ) and IsTotal( com!.map2 ) then
return false; fi; if IsSurjective( com!.map1 ) and IsSingleValued( com!.map1 )
and not IsInjective( com!.map2 ) then
return false; fi;
TryNextMethod(); end );
############################################################################# ## #M IsSingleValued( <map> ) . . . . . . . . . . . . for composition mapping ##
InstallMethod( IsSingleValued, "for a composition mapping",
true,
[ IsCompositionMappingRep ], SUM_FLAGS, function( com ) if IsSingleValued( com!.map1 ) and IsSingleValued( com!.map2 ) then
return true; fi; if not IsSingleValued( com!.map1 )
and IsInjective( com!.map2 ) and IsTotal( com!.map2 ) then
return false; fi; if IsSurjective( com!.map1 ) and not IsSingleValued( com!.map2 ) then
return false; fi;
TryNextMethod(); end );
############################################################################# ## #M IsSurjective( <map> ) . . . . . . . . . . . . . . for composition mapping ##
InstallMethod( IsSurjective, "for a composition mapping",
true,
[ IsCompositionMappingRep ], SUM_FLAGS, function( com ) if not IsSurjective( com!.map2 ) then
return false; elif IsSurjective( com!.map1 ) and
IsSubset( Range( com!.map1 ), PreImagesRange( com!.map2 ) ) then
return true; fi;
TryNextMethod(); end );
############################################################################# ## #M IsTotal( <map> ) . . . . . . . . . . . . . . . . for composition mapping ##
InstallMethod( IsTotal, "for a composition mapping",
true,
[ IsCompositionMappingRep ], SUM_FLAGS, function( com ) if not IsTotal( com!.map1 ) then
return false; elif IsTotal( com!.map2 ) and
IsSubset( Source( com!.map2 ), ImagesSource( com!.map1 ) ) then
return true; fi;
TryNextMethod(); end );
############################################################################# ## #M ImagesElm( <map>, <elm> ) . . . . . . . . . . . . for composition mapping ##
InstallMethod( ImagesElm, "for a composition mapping, and an element",
FamSourceEqFamElm,
[ IsCompositionMappingRep, IsObject ], 0, function( com, elm )
local im;
im:= ImagesElm( com!.map1, elm ); if not IsEmpty( im ) then
return ImagesSet( com!.map2, im ); else
return []; fi; end );
############################################################################# ## #M ImagesSet( <map>, <elms> ) . . . . . . . . . . . for composition mapping ##
InstallMethod( ImagesSet, "for a composition mapping, and a collection",
CollFamSourceEqFamElms,
[ IsCompositionMappingRep, IsCollection ], 0, function ( com, elms )
local im;
im:= ImagesSet( com!.map1, elms ); if not IsEmpty( im ) then
return ImagesSet( com!.map2, im ); else
return []; fi; end );
############################################################################# ## #M ImagesRepresentative( <map>, <elm> ) . . . . . . for composition mapping ##
InstallMethod( ImagesRepresentative, "for a composition mapping, and an element",
FamSourceEqFamElm,
[ IsCompositionMappingRep, IsObject ], 0, function( com, elm )
local im, rep;
im:= ImagesRepresentative( com!.map1, elm ); if im = fail then # 'elm' has no images under 'com!.map1', so it has none under 'com'.
return fail; else
im:= ImagesRepresentative( com!.map2, im ); if im <> fail then
return im; fi;
# It may happen that only the chosen representative has no images. for im in Enumerator( ImagesElm( com!.map1, elm ) ) do
rep:= ImagesRepresentative( com!.map2, im ); if rep <> fail then
return rep; fi;
od;
return fail; fi; end );
############################################################################# ## #M PreImagesElm( <map>, <elm> ) . . . . . . . . . . for composition mapping ##
InstallMethod( PreImagesElm, "for a composition mapping, and an element",
FamRangeEqFamElm,
[ IsCompositionMappingRep, IsObject ], 0, function( com, elm )
local im;
im:= PreImagesElm( com!.map2, elm ); if not IsEmpty( im ) then
return PreImagesSet( com!.map1, im ); else
return []; fi; end );
############################################################################# ## #M PreImagesSet( <map>, <elm> ) . . . . . . . . . . for composition mapping ##
InstallMethod( PreImagesSet, "for a composition mapping, and a collection",
CollFamRangeEqFamElms,
[ IsCompositionMappingRep, IsCollection ], 0, function( com, elms )
local im;
im:= PreImagesSet( com!.map2, elms ); if not IsEmpty( im ) then
return PreImagesSet( com!.map1, im ); else
return []; fi; end );
############################################################################# ## #M PreImagesRepresentative( <map>, <elm> ) . . . . . for composition mapping ##
InstallMethod( PreImagesRepresentative, "for a composition mapping, and an element",
FamRangeEqFamElm,
[ IsCompositionMappingRep, IsObject ], 0, function( com, elm )
local im, rep;
im:= PreImagesRepresentative( com!.map2, elm ); if im = fail then # 'elm' has no preimages under 'com!.map2', so it has none under 'com'.
return fail; else
im:= PreImagesRepresentative( com!.map1, im ); if im <> fail then
return im; fi;
# It may happen that only the chosen representative has no preimages. for im in Enumerator( PreImagesElm( com!.map2, elm ) ) do
rep:= PreImagesRepresentative( com!.map1, im ); if rep <> fail then
return rep; fi;
od;
return fail; fi; end );
############################################################################# ## #M KernelOfAdditiveGeneralMapping( <map> ) . . . . . for composition mapping ##
InstallMethod( KernelOfAdditiveGeneralMapping, "for a composition mapping that resp. add. and add.inv.",
true,
[ IsGeneralMapping and IsCompositionMappingRep
and RespectsAddition and RespectsAdditiveInverses ], 0, function( com ) if IsInjective( com!.map2 ) then
return KernelOfAdditiveGeneralMapping( com!.map1 ); else
return PreImagesSet( com!.map1,
KernelOfAdditiveGeneralMapping( com!.map2 ) ); fi; end );
############################################################################# ## #M CoKernelOfAdditiveGeneralMapping( <map> ) . . . . for composition mapping ##
InstallMethod( CoKernelOfAdditiveGeneralMapping, "for a composition mapping that resp. add. and add.inv.",
true,
[ IsGeneralMapping and IsCompositionMappingRep
and RespectsAddition and RespectsAdditiveInverses ], 0, function( com ) if IsSingleValued( com!.map1 ) then
return CoKernelOfAdditiveGeneralMapping( com!.map2 ); else
return ImagesSet( com!.map2,
CoKernelOfAdditiveGeneralMapping( com!.map1 ) ); fi; end );
############################################################################# ## #M KernelOfMultiplicativeGeneralMapping( <map> ) . . for composition mapping ##
InstallMethod( KernelOfMultiplicativeGeneralMapping, "for a composition mapping that resp. mult. and inv.",
true,
[ IsGeneralMapping and IsCompositionMappingRep
and RespectsMultiplication and RespectsInverses ], 0, function( com ) if IsInjective( com!.map2 ) then
return KernelOfMultiplicativeGeneralMapping( com!.map1 ); else
return PreImagesSet( com!.map1,
KernelOfMultiplicativeGeneralMapping( com!.map2 ) ); fi; end );
############################################################################# ## #M CoKernelOfMultiplicativeGeneralMapping( <map> ) . for composition mapping ##
InstallMethod( CoKernelOfMultiplicativeGeneralMapping, "for a composition mapping that resp. mult. and inv.",
true,
[ IsGeneralMapping and IsCompositionMappingRep
and RespectsMultiplication and RespectsInverses ], 0, function( com ) if IsSingleValued( com!.map1 ) then
return CoKernelOfMultiplicativeGeneralMapping( com!.map2 ); else
return ImagesSet( com!.map2,
CoKernelOfMultiplicativeGeneralMapping( com!.map1 ) ); fi; end );
############################################################################# ## #F MappingByFunction( <D>, <E>, <fun> ) . . . . . create map from function #F MappingByFunction( <D>, <E>, <fun>, <invfun> ) ##
InstallGlobalFunction( MappingByFunction, function ( arg )
local map; # mapping <map>, result
if not Length(arg) in [3,4,5] then # signal an error
Error( "usage: MappingByFunction( <D>, <E>, <fun>[, <inv>] )" ); fi;
# ensure that the source and range are domains if not (IsDomain(arg[1]) and IsDomain(arg[2])) then
Error("MappingByFunction: Source and Range must be domains"); fi;
# no inverse function given if Length(arg)<>4then
# make the general mapping
map:= Objectify( TypeOfDefaultGeneralMapping( arg[1], arg[2],
IsNonSPMappingByFunctionRep
and IsSingleValued
and IsTotal ),
rec( fun:= arg[3] ) ); if Length(arg)=5 and IsFunction(arg[5]) then
map!.prefun:=arg[5]; fi;
# inverse function given elif Length(arg) = 4then
# make the mapping
map:= Objectify( TypeOfDefaultGeneralMapping( arg[1], arg[2],
IsNonSPMappingByFunctionWithInverseRep
and IsBijective ),
rec( fun := arg[3],
invFun := arg[4],
prefun := arg[4]) );
fi;
# return the mapping
return map; end );
############################################################################# ## #M ImageElm( <map>, <elm> ) . . . . . . . . . . . . for mapping by function ##
InstallMethod( ImageElm, "for mapping by function",
FamSourceEqFamElm,
[ IsMappingByFunctionRep, IsObject ], 0, function ( map, elm )
return map!.fun( elm ); end );
############################################################################# ## #M ImagesElm( <map>, <elm> ) . . . . . . . . . . . . for mapping by function ##
InstallMethod( ImagesElm, "for mapping by function",
FamSourceEqFamElm,
[ IsMappingByFunctionRep, IsObject ], 0, function ( map, elm )
return [ map!.fun( elm ) ]; end );
############################################################################# ## #M ImagesRepresentative( <map>, <elm> ) . . . . . . for mapping by function ##
InstallMethod( ImagesRepresentative, "for mapping by function",
FamSourceEqFamElm,
[ IsMappingByFunctionRep, IsObject ], 0, function ( map, elm )
return map!.fun( elm ); end );
############################################################################# ## #M KernelOfMultiplicativeGeneralMapping( <map> ) . for mapping by function ##
InstallMethod(KernelOfMultiplicativeGeneralMapping,"hom by function",true,
[ IsMappingByFunctionRep and IsGroupHomomorphism ],0, function ( map )
return
KernelOfMultiplicativeGeneralMapping(AsGroupGeneralMappingByImages(map)); end );
############################################################################# ## #M PreImagesRepresentative( <map>, <elm> ) . . . . . for mapping by function ##
InstallMethod( PreImagesRepresentative, "for mapping by function",
FamRangeEqFamElm,
[ IsMappingByFunctionRep, IsObject ], 0, function ( map, elm ) if not IsBound(map!.prefun) then # no quick way known
TryNextMethod(); fi;
return map!.prefun( elm ); end );
############################################################################# ## #M PreImageElm( <map>, <elm> ) . . . . . . . . . . . for mapping by function ##
InstallMethod( PreImageElm, "for mapping by function",
FamRangeEqFamElm,
[ IsMappingByFunctionWithInverseRep, IsObject ], 0, function ( map, elm )
return map!.invFun( elm ); end );
############################################################################# ## #M PreImagesElm( <map>, <elm> ) . . . . . . . . . . for mapping by function ##
InstallMethod( PreImagesElm, "for mapping by function",
FamRangeEqFamElm,
[ IsMappingByFunctionWithInverseRep, IsObject ], 0, function ( map, elm )
return [ map!.invFun( elm ) ]; end );
############################################################################# ## #M PreImagesRepresentative( <map>, <elm> ) . . . . . for mapping by function ##
InstallMethod( PreImagesRepresentative, "for mapping by function with inverse",
FamRangeEqFamElm,
[ IsMappingByFunctionWithInverseRep, IsObject ], 0, function ( map, elm )
return map!.invFun( elm ); end );
############################################################################# ## ## Transfer information about the mapping map to its associated inverse ## mapping inv. For example, if map is total than inv is surjective and ## vice versa. ##
BindGlobal( "TransferMappingPropertiesToInverse", function ( map, inv ) # If possible, enter preimage and image. if HasImagesSource( map ) then
SetPreImagesRange( inv, ImagesSource( map ) ); fi; if HasPreImagesRange( map ) then
SetImagesSource( inv, PreImagesRange( map ) ); fi;
# Maintain important properties. if HasIsSingleValued( map ) then
SetIsInjective( inv, IsSingleValued( map ) ); fi; if HasIsInjective( map ) then
SetIsSingleValued( inv, IsInjective( map ) ); fi; if HasIsTotal( map ) then
SetIsSurjective( inv, IsTotal( map ) ); fi; if HasIsSurjective( map ) then
SetIsTotal( inv, IsSurjective( map ) ); fi; if HasIsEndoGeneralMapping( map ) then
SetIsEndoGeneralMapping( inv, IsEndoGeneralMapping( map ) ); fi;
# Maintain the maintainings w.r.t. multiplication. if HasRespectsMultiplication( map ) then
SetRespectsMultiplication( inv, RespectsMultiplication( map ) ); fi; if HasRespectsInverses( map ) then
SetRespectsInverses( inv, RespectsInverses( map ) ); elif HasRespectsOne( map ) then
SetRespectsOne( inv, RespectsOne( map ) ); fi;
# Maintain the maintainings w.r.t. addition. if HasRespectsAddition( map ) then
SetRespectsAddition( inv, RespectsAddition( map ) ); fi; if HasRespectsAdditiveInverses( map ) then
SetRespectsAdditiveInverses( inv, RespectsAdditiveInverses( map ) ); elif HasRespectsZero( map ) then
SetRespectsZero( inv, RespectsZero( map ) ); fi;
# Maintain respecting of scalar multiplication. # (Note the slight asymmetry, depending on the coefficient domains.) if HasRespectsScalarMultiplication( map )
and LeftActingDomain( Source( map ) )
= LeftActingDomain( Range( map ) ) then
SetRespectsScalarMultiplication( inv,
RespectsScalarMultiplication( map ) ); fi;
# We know the inverse general mapping of the inverse general mapping ;-).
SetInverseGeneralMapping( inv, map ); end );
############################################################################# ## #M InverseGeneralMapping( <map> ) . . . . . . . . . for mapping by function ##
InstallMethod( InverseGeneralMapping, "for mapping by function", true,
[ IsMappingByFunctionWithInverseRep ], 0, function ( map )
local inv;
inv:= MappingByFunction( Range( map ), Source( map ),
map!.invFun, map!.fun );
TransferMappingPropertiesToInverse( map, inv );
return inv; end );
InstallMethod( RestrictedInverseGeneralMapping, "for mapping by function", true,
[ IsMappingByFunctionWithInverseRep ], 0, function ( map )
local inv;
inv:= MappingByFunction( Image( map ), Source( map ),
map!.invFun, map!.fun );
TransferMappingPropertiesToInverse( map, inv );
return inv; end );
############################################################################# ## #M ViewObj( <map> ) . . . . . . . . . for mapping by function with inverse #M PrintObj( <map> ) . . . . . . . . . for mapping by function with inverse ##
InstallMethod( ViewObj, "for mapping by function with inverse",
true,
[ IsMappingByFunctionWithInverseRep ], 0, function ( map )
Print( "MappingByFunction( " );
View( Source( map ) );
Print( ", " );
View( Range( map ) );
Print( ", " );
View( map!.fun );
Print( ", " );
View( map!.invFun );
Print( " )" ); end );
InstallMethod( PrintObj, "for mapping by function with inverse",
true,
[ IsMappingByFunctionWithInverseRep ], 0, function ( map )
Print( "MappingByFunction( ",
Source( map ), ", ", Range( map ), ", ",
map!.fun, ", ", map!.invFun, " )" ); end );
############################################################################# ## ## 4. methods for inverse mappings ##
############################################################################# ## #R IsInverseGeneralMappingRep( <map> ) ## ## Note that if a mapping knows its inverse mapping then also the inverse ## mapping knows its inverse mapping. ## So we need this flag to avoid infinite recursion when a question is ## delegated to the inverse of a mapping. ##
DeclareRepresentation( "IsInverseGeneralMappingRep",
IsNonSPGeneralMapping,
[] );
############################################################################# ## #M InverseGeneralMapping( <map> ) . for a general mapping with known inverse ##
InstallImmediateMethod( InverseGeneralMapping,
IsGeneralMapping and HasInverse and IsAttributeStoringRep, 0, function( map ) if Inverse( map ) <> fail then
return Inverse( map ); else
TryNextMethod(); fi; end );
############################################################################# ## #M InverseGeneralMapping( <map> ) . . . . . . . . . . for a general mapping ##
InstallMethod( InverseGeneralMapping, "for a general mapping",
true,
[ IsGeneralMapping ], 0, function ( map )
local inv;
# Make the mapping.
inv:= Objectify( TypeOfDefaultGeneralMapping( Range( map ),
Source( map ),
IsInverseGeneralMappingRep
and IsAttributeStoringRep ),
rec() );
TransferMappingPropertiesToInverse( map, inv );
# Return the inverse general mapping.
return inv; end );
############################################################################# ## #M ImageElm( <invmap>, <map> ) . . . . . . . for inverse mapping and element ##
InstallMethod( ImageElm, "for an inverse mapping and an element",
FamSourceEqFamElm,
[ IsMapping and IsInverseGeneralMappingRep, IsObject ], 0, function ( inv, elm )
return PreImageElm( InverseGeneralMapping( inv ), elm ); end );
############################################################################# ## #M ImagesElm( <invmap>, <map> ) . . . . . . for inverse mapping and element ##
InstallMethod( ImagesElm, "for an inverse mapping and an element",
FamSourceEqFamElm,
[ IsGeneralMapping and IsInverseGeneralMappingRep, IsObject ], 0, function ( inv, elm )
return PreImagesElm( InverseGeneralMapping( inv ), elm ); end );
############################################################################# ## #M ImagesSet( <invmap>, <coll> ) . . . . for inverse mapping and collection ##
InstallMethod( ImagesSet, "for an inverse mapping and a collection",
CollFamSourceEqFamElms,
[ IsGeneralMapping and IsInverseGeneralMappingRep, IsCollection ], 0, function ( inv, elms )
return PreImagesSet( InverseGeneralMapping( inv ), elms ); end );
############################################################################# ## #M ImagesRepresentative( <invmap>, <coll> ) . . for inv. mapping and coll. ##
InstallMethod( ImagesRepresentative, "for an inverse mapping and an element",
FamSourceEqFamElm,
[ IsGeneralMapping and IsInverseGeneralMappingRep, IsObject ], 0, function ( inv, elm )
return PreImagesRepresentative( InverseGeneralMapping( inv ), elm ); end );
############################################################################# ## #M PreImageElm( <invmap>, <elm> ) . . . . . for inverse mapping and element ##
InstallMethod( PreImageElm, "for an inj. & surj. inverse mapping, and an element",
FamRangeEqFamElm,
[ IsGeneralMapping and IsInverseGeneralMappingRep
and IsInjective and IsSurjective, IsObject ], 0, function ( inv, elm )
return ImageElm( InverseGeneralMapping( inv ), elm ); end );
############################################################################# ## #M PreImagesElm( <invmap>, <elm> ) . . . . . for inverse mapping and element ##
InstallMethod( PreImagesElm, "for an inverse mapping and an element",
FamRangeEqFamElm,
[ IsGeneralMapping and IsInverseGeneralMappingRep, IsObject ], 0, function ( inv, elm )
return ImagesElm( InverseGeneralMapping( inv ), elm ); end );
############################################################################# ## #M PreImagesSet( <invmap>, <coll> ) . . for inverse mapping and collection ##
InstallMethod( PreImagesSet, "for an inverse mapping and a collection",
CollFamRangeEqFamElms,
[ IsGeneralMapping and IsInverseGeneralMappingRep, IsCollection ], 0, function ( inv, elms )
return ImagesSet( InverseGeneralMapping( inv ), elms ); end );
############################################################################# ## #M PreImagesRepresentative( <invmap>, <elm> ) . . for inv. mapping and elm. ##
InstallMethod( PreImagesRepresentative, "for an inverse mapping and an element",
FamRangeEqFamElm,
[ IsInverseGeneralMappingRep, IsObject ], 0, function ( inv, elm )
return ImagesRepresentative( InverseGeneralMapping( inv ), elm ); end );
InstallMethod( PrintObj, "for an inverse mapping",
true,
[ IsGeneralMapping and IsInverseGeneralMappingRep ], 100, function ( inv )
Print( "InverseGeneralMapping( ", InverseGeneralMapping( inv )," )" ); end );
############################################################################# ## ## 5. methods for identity mappings ## ## For each domain we need to construct only one identity mapping. ## In order to allow this to interact with other mappings of this domain ## (for example, with automorphisms of a field in a special representation), ## one needs to install methods to compare these mappings with the identity ## mapping via '\=' and '\<'. ## ## Methods for identity mappings are all installed with rank 'SUM_FLAGS'. ##
############################################################################# ## ## An identity mapping whose source has a nice structure gets the properties ## to respect this structure. ##
BindGlobal( "ImmediateImplicationsIdentityMapping", function( idmap )
local source;
source:= Source( idmap );
# multiplicative structure if IsMagma( source ) then
SetRespectsMultiplication( idmap, true ); if IsMagmaWithOne( source ) then
SetRespectsOne( idmap, true ); if IsMagmaWithInverses( source ) then
SetRespectsInverses( idmap, true ); fi; fi; fi;
# additive structure if IsAdditiveMagma( source ) then
SetRespectsAddition( idmap, true ); if IsAdditiveMagmaWithZero( source ) then
SetRespectsZero( idmap, true ); if IsAdditiveGroup( source ) then
SetRespectsAdditiveInverses( idmap, true );
# linear structure if IsLeftModule( source ) then
SetRespectsScalarMultiplication( idmap, true ); fi;
fi; fi; fi; end );
############################################################################# ## #M IdentityMapping( <D> ) . . . . . . . . identity mapping of a collection ##
InstallMethod( IdentityMapping, "for a collection",
true,
[ IsCollection ], 0, function( D )
local id;
# make the mapping
id := Objectify( TypeOfDefaultGeneralMapping( D, D,
IsSPGeneralMapping
and IsAdditiveElementWithInverse
and IsAttributeStoringRep
and IsOne ),
rec() );
# the identity mapping is self-inverse
SetInverseGeneralMapping( id, id );
# set the respectings
ImmediateImplicationsIdentityMapping( id );
# return the identity mapping
return id; end );
############################################################################# ## #M \^( <idmap>, <n> ) . . . . . . . . . . for identity mapping and integer ##
InstallMethod( \^, "for identity mapping and integer",
true,
[ IsGeneralMapping and IsOne, IsInt ],
SUM_FLAGS, # can't do better
ReturnFirst );
############################################################################# ## #M ImageElm( <idmap>, <elm> ) . . . . . . for identity mapping and element ##
InstallMethod( ImageElm, "for identity mapping and object",
FamSourceEqFamElm,
[ IsGeneralMapping and IsOne, IsObject ],
SUM_FLAGS, # can't do better function ( id, elm )
return elm; end );
############################################################################# ## #M ImagesElm( <idmap>, <elm> ) . . . . . . for identity mapping and element ##
InstallMethod( ImagesElm, "for identity mapping and object",
FamSourceEqFamElm,
[ IsGeneralMapping and IsOne, IsObject ],
SUM_FLAGS, # can't do better function ( id, elm )
return [ elm ]; end );
############################################################################# ## #M ImagesSet( <idmap>, <coll> ) . . . . for identity mapping and collection ##
InstallMethod( ImagesSet, "for identity mapping and collection",
CollFamSourceEqFamElms,
[ IsGeneralMapping and IsOne, IsCollection ],
SUM_FLAGS, # can't do better function ( id, elms )
return elms; end );
############################################################################# ## #M ImagesSource( <idmap> ) ##
InstallMethod( ImagesSource,"for identity mapping",true,
[ IsGeneralMapping and IsOne ], SUM_FLAGS, # can't do better function ( id )
return Source(id); end );
############################################################################# ## #M ImagesRepresentative( <idmap>, <elm> ) for identity mapping and element ##
InstallMethod( ImagesRepresentative, "for identity mapping and object",
FamSourceEqFamElm,
[ IsGeneralMapping and IsOne, IsObject ],
SUM_FLAGS, # can't do better function ( id, elm )
return elm; end );
############################################################################# ## #M PreImageElm( <idmap>, <elm> ) . . . . for identity mapping and element ##
InstallMethod( PreImageElm, "for identity mapping and object",
FamRangeEqFamElm,
[ IsGeneralMapping and IsOne, IsObject ],
SUM_FLAGS, # can't do better function ( id, elm )
return elm; end );
############################################################################# ## #M PreImagesElm( <idmap>, <elm> ) . . . . for identity mapping and element ##
InstallMethod( PreImagesElm, "for identity mapping and object",
FamRangeEqFamElm,
[ IsGeneralMapping and IsOne, IsObject ],
SUM_FLAGS, # can't do better function ( id, elm )
return [ elm ]; end );
############################################################################# ## #M PreImagesSet( <idmap>, <coll> ) . . . for identity mapping and collection ##
InstallMethod( PreImagesSet, "for identity mapping and collection",
CollFamRangeEqFamElms,
[ IsGeneralMapping and IsOne, IsCollection ],
SUM_FLAGS, # can't do better function ( id, elms )
return elms; end );
############################################################################# ## #M PreImagesRepresentative( <idmap>, <elm> ) ##
InstallMethod( PreImagesRepresentative, "for identity mapping and object",
FamRangeEqFamElm,
[ IsGeneralMapping and IsOne, IsObject ],
SUM_FLAGS, # can't do better function ( id, elm )
return elm; end );
############################################################################# ## #M ViewObj( <idmap> ) . . . . . . . . . . . . . . . . for identity mapping #M PrintObj( <idmap> ) . . . . . . . . . . . . . . . . for identity mapping #M String( <idmap> ) . . . . . . . . . . . . . . . . . for identity mapping ##
InstallMethod( ViewObj, "for identity mapping",
true,
[ IsGeneralMapping and IsOne ], # rank up, but just to exactly SUM_FLAGS, so that mappings in a special # representation with a custom printing method still get that, even if # the rank of IsGeneralMapping and IsOne happens to be increased a lot
{} -> SUM_FLAGS - RankFilter( IsGeneralMapping and IsOne ), function ( id )
Print( "IdentityMapping( " );
View( Source( id ) );
Print( " )" ); end );
InstallMethod( PrintObj, "for identity mapping",
true,
[ IsGeneralMapping and IsOne ], # rank up, but just to exactly SUM_FLAGS, so that mappings in a special # representation with a custom printing method still get that, even if # the rank of IsGeneralMapping and IsOne happens to be increased a lot
{} -> SUM_FLAGS - RankFilter( IsGeneralMapping and IsOne ), function ( id )
Print( "IdentityMapping( ", Source( id ), " )" ); end );
InstallMethod( String, "for identity mapping",
[ IsGeneralMapping and IsOne ], # rank up, but just to exactly SUM_FLAGS, so that mappings in a special # representation with a custom printing method still get that, even if # the rank of IsGeneralMapping and IsOne happens to be increased a lot
{} -> SUM_FLAGS - RankFilter( IsGeneralMapping and IsOne ), function ( id )
return StringFormatted( "IdentityMapping( {} )", Source(id) ); end );
############################################################################# ## #M CompositionMapping2( <map>, <idmap> ) . for gen. mapping and id. mapping ##
InstallMethod( CompositionMapping2, "for general mapping and identity mapping", FamSource1EqFamRange2,
[ IsGeneralMapping, IsGeneralMapping and IsOne ],
{} -> SUM_FLAGS + RankFilter( IsGeneralMapping and IsZero ), # should be higher than the rank for a zero mapping function ( map, id ) if not IsSubset(Range(id),Source(map)) then # if the identity is defined on something smaller, we need to take a # true `CompositionMapping'.
TryNextMethod(); fi;
return map; end );
############################################################################# ## #M CompositionMapping2( <idmap>, <map> ) . for id. mapping and gen. mapping ##
InstallMethod( CompositionMapping2, "for identity mapping and general mapping",FamSource1EqFamRange2,
[ IsGeneralMapping and IsOne, IsGeneralMapping ],
{} -> SUM_FLAGS + RankFilter( IsGeneralMapping and IsZero ), # should be higher than the rank for a zero mapping function( id, map ) if not IsSubset(Source(id),Range(map)) then # if the identity is defined on something smaller, we need to take a # true `CompositionMapping'.
TryNextMethod(); fi;
return map; end );
############################################################################# ## ## 6. methods for zero mappings ## ## methods for zero mappings are all installed with rank 'SUM_FLAGS' ## #T (use 'IsZero' in '\+' method for mappings ...)
############################################################################# ## ## A zero mapping whose source has a nice structure gets the properties ## to respect this structure. ##
BindGlobal( "ImmediateImplicationsZeroMapping", function( zeromap )
local source;
source:= Source( zeromap );
# multiplicative structure if IsMagma( source ) then
SetRespectsMultiplication( zeromap, true ); if IsMagmaWithOne( source ) then
SetRespectsOne( zeromap, false ); if IsMagmaWithInverses( source ) then
SetRespectsInverses( zeromap, false ); fi; fi; fi;
# additive structure if IsAdditiveMagma( source ) then
SetRespectsAddition( zeromap, true ); if IsAdditiveMagmaWithZero( source ) then
SetRespectsZero( zeromap, true ); if IsAdditiveGroup( source ) then
SetRespectsAdditiveInverses( zeromap, true ); fi; fi; fi;
# linear structure if IsLeftModule( source ) then
SetRespectsScalarMultiplication( zeromap, true ); fi; end );
############################################################################# ## #F ZeroMapping( <source>, <range> ) ## ## maps every element of <source> to 'Zero( <range> )'. ## This is independent of the structure of <source> and <range>. ##
InstallMethod( ZeroMapping, "for collection and additive-magma-with-zero",
true,
[ IsCollection, IsAdditiveMagmaWithZero ], 0, function( S, R )
local zero; # the zero mapping, result
# make the mapping
zero := Objectify( TypeOfDefaultGeneralMapping( S, R,
IsSPGeneralMapping
and IsAdditiveElementWithInverse
and IsAttributeStoringRep
and IsZero ),
rec() );
# set the respectings
ImmediateImplicationsZeroMapping( zero );
# return the zero mapping
return zero; end );
############################################################################# ## #M \^( <zeromap>, <n> ) . . . . . . . for zero mapping and positive integer ##
InstallMethod( \^, "for zero mapping and positive integer",
true,
[ IsGeneralMapping and IsZero, IsPosInt ], SUM_FLAGS, function( zero, n ) if Zero( Source( zero ) ) in Range( zero ) then
return zero; else
Error( "source and range of <zero> do not match" ); fi; end );
############################################################################# ## #M ImagesSource( <zeromap> ) . . . . . . . . . . . . . . . for zero mapping ##
InstallMethod( ImagesSource, "for zero mapping",
true,
[ IsGeneralMapping and IsZero ], SUM_FLAGS, function( zero ) if IsAdditiveMagmaWithZero( Range( zero ) ) then
return TrivialSubadditiveMagmaWithZero( Range( zero ) ); else
return [ Zero( Range( zero ) ) ]; fi; end );
############################################################################# ## #M ImageElm( <zeromap>, <elm> ) . . . . . . . for zero mapping and element ##
InstallMethod( ImageElm, "for zero mapping and object",
FamSourceEqFamElm,
[ IsGeneralMapping and IsZero, IsObject ], SUM_FLAGS, function( zero, elm )
return Zero( Range( zero ) ); end );
############################################################################# ## #M ImagesElm( <zeromap>, <elm> ) . . . . . . . for zero mapping and element ##
InstallMethod( ImagesElm, "for zero mapping and object",
FamSourceEqFamElm,
[ IsGeneralMapping and IsZero, IsObject ], SUM_FLAGS, function( zero, elm )
return [ Zero( Range( zero ) ) ]; end );
############################################################################# ## #M ImagesSet( <zeromap>, <coll> ) . . . . . for zero mapping and collection ##
InstallMethod( ImagesSet, "for zero mapping and collection",
CollFamSourceEqFamElms,
[ IsGeneralMapping and IsZero, IsCollection ], SUM_FLAGS, function( zero, elms )
return TrivialSubadditiveMagmaWithZero( Range( zero ) ); end );
############################################################################# ## #M ImagesRepresentative( <zeromap>, <elm> ) . for zero mapping and element ##
InstallMethod( ImagesRepresentative, "for zero mapping and object",
FamSourceEqFamElm,
[ IsGeneralMapping and IsZero, IsObject ], SUM_FLAGS, function( zero, elm )
return Zero( Range( zero ) ); end );
############################################################################# ## #M PreImagesElm( <zeromap>, <elm> ) . . . . . for zero mapping and element ##
InstallMethod( PreImagesElm, "for zero mapping and object",
FamRangeEqFamElm,
[ IsGeneralMapping and IsZero, IsObject ], SUM_FLAGS, function( zero, elm ) if IsZero( elm ) then
return Source( zero ); else
return []; fi; end );
############################################################################# ## #M PreImagesSet( <zeromap>, <elms> ) . . . . for zero mapping and collection ##
InstallMethod( PreImagesSet, "for zero mapping and collection",
CollFamRangeEqFamElms,
[ IsGeneralMapping and IsZero, IsCollection ], SUM_FLAGS, function( zero, elms ) if Zero( Range( zero ) ) in elms then
return Source( zero ); else
return []; fi; end );
############################################################################# ## #M PreImagesRepresentative( <zeromap>, <elm> ) ##
InstallMethod( PreImagesRepresentative, "for zero mapping and object",
FamRangeEqFamElm,
[ IsGeneralMapping and IsZero, IsObject ], SUM_FLAGS, function( zero, elm ) if IsZero( elm ) then
return Zero( Source( zero ) ); else
return fail; fi; end );
############################################################################# ## #M ViewObj( <zeromap> ) . . . . . . . . . . . . . . . . . for zero mapping #M PrintObj( <zeromap> ) . . . . . . . . . . . . . . . . . for zero mapping ##
InstallMethod( ViewObj, "for zero mapping",
true,
[ IsGeneralMapping and IsZero ], # rank up, but just to exactly SUM_FLAGS, so that mappings in a special # representation with a custom printing method still get that, even if # the rank of IsGeneralMapping and IsZero happens to be increased a lot
{} -> SUM_FLAGS - RankFilter( IsGeneralMapping and IsZero ), function( zero )
Print( "ZeroMapping( " );
View( Source( zero ) );
Print( ", " );
View( Range( zero ) );
Print( " )" ); end );
InstallMethod( PrintObj, "for zero mapping",
true,
[ IsGeneralMapping and IsZero ], # rank up, but just to exactly SUM_FLAGS, so that mappings in a special # representation with a custom printing method still get that, even if # the rank of IsGeneralMapping and IsZero happens to be increased a lot
{} -> SUM_FLAGS - RankFilter( IsGeneralMapping and IsZero ), function( zero )
Print( "ZeroMapping( ", Source( zero ), ", ", Range( zero ), " )" ); end );
############################################################################# ## #M CompositionMapping2( <map>, <zeromap> ) for gen. mapping and zero mapping ##
InstallMethod( CompositionMapping2, "for general mapping and zero mapping",
FamSource1EqFamRange2,
[ IsGeneralMapping, IsGeneralMapping and IsZero ], SUM_FLAGS, function( map, zero )
return ZeroMapping( Source( map ), Range( zero ) ); end );
############################################################################# ## #M CompositionMapping2( <zeromap>, <map> ) for zero mapping and gen. mapping ##
InstallMethod( CompositionMapping2, "for zero mapping and single-valued gen. mapping that resp. zero",
FamSource1EqFamRange2,
[ IsGeneralMapping and IsZero,
IsGeneralMapping and IsSingleValued and RespectsZero ],
SUM_FLAGS, function( zero, map )
return ZeroMapping( Source( zero ), Range( map ) ); end );
############################################################################# ## #M IsInjective( <zeromap> ) . . . . . . . . . . . . . . . for zero mapping ##
InstallMethod( IsInjective, "for zero mapping",
true,
[ IsGeneralMapping and IsZero ], 0,
zero -> Size( Source( zero ) ) = 1 );
############################################################################# ## #M IsSurjective( <zeromap> ) . . . . . . . . . . . . . . . for zero mapping ##
InstallMethod( IsSurjective, "for zero mapping",
true,
[ IsGeneralMapping and IsZero ], 0,
zero -> Size( Range( zero ) ) = 1 );
############################################################################# ## ## 7. methods for general restricted mappings, ##
# Make the general mapping. if IsSPGeneralMapping( map ) then
filter := IsSPGeneralMapping; else
filter := IsNonSPGeneralMapping; fi;
res:= Objectify( TypeOfDefaultGeneralMapping( s,r,
IsGeneralRestrictedMappingRep and filter ),
rec() );
# Enter the identifying information.
res!.map:= map;
for prop in [IsSingleValued, IsTotal, IsInjective, RespectsMultiplication, RespectsInverses,
RespectsAddition, RespectsAdditiveInverses, RespectsScalarMultiplication] do if Tester(prop)(map) and prop(map) then
Setter(prop)(res, true); fi;
od;
# Return the restriction.
return res; end );
############################################################################# ## #M ImagesElm( <map>, <elm> ) . . . . . . . . . . . . for restricted mapping ##
InstallMethod( ImagesElm, "for a restricted mapping, and an element",
FamSourceEqFamElm,
[ IsGeneralRestrictedMappingRep, IsObject ], 0, function( res, elm )
local im;
im:= ImagesElm( res!.map, elm ); if not ( (HasIsSingleValued(res) and IsSingleValued(res)) or
(HasIsSingleValued(res!.map) and IsSingleValued(res!.map)) ) then
im:=Intersection(Range(res),im); fi;
return im; end );
############################################################################# ## #M ImagesSet( <map>, <elms> ) . . . . . . . . . . . for restricted mapping ##
InstallMethod( ImagesSet, "for a restricted mapping, and a collection",
CollFamSourceEqFamElms,
[ IsGeneralRestrictedMappingRep, IsCollection ], 0, function ( res, elms )
local im;
im:= ImagesSet( res!.map, elms ); if not ( (HasIsSingleValued(res) and IsSingleValued(res)) or
(HasIsSingleValued(res!.map) and IsSingleValued(res!.map)) ) then
im:=Intersection(Range(res),im); fi;
return im; end );
############################################################################# ## #M ImagesRepresentative( <map>, <elm> ) . . . . . . for restricted mapping ##
InstallMethod( ImagesRepresentative, "for a restricted mapping, and an element",
FamSourceEqFamElm,
[ IsGeneralRestrictedMappingRep, IsObject ], 0, function( res, elm )
local im;
im:= ImagesRepresentative( res!.map, elm ); if im = fail then # 'elm' has no images under 'res!.map', so it has none under 'res'.
return fail; elif im in Range(res) then
return im; elif HasIsSingleValued(res!.map) and IsSingleValued(res!.map) then
return fail; # no other choice else # It may happen that only the chosen representative is not in im
im:= ImagesElm( res!.map, elm );
return First(im,i->i in Range(res)); fi; end );
############################################################################# ## #M PreImagesElm( <map>, <elm> ) . . . . . . . . . . for restricted mapping ##
InstallMethod( PreImagesElm, "for a restricted mapping, and an element",
FamRangeEqFamElm,
[ IsGeneralRestrictedMappingRep, IsObject ], 0, function( res, elm )
local preim;
preim:= PreImagesElm( res!.map, elm ); if not ( (HasIsInjective(res) and IsInjective(res)) or
(HasIsInjective(res!.map) and IsInjective(res!.map)) ) then
preim:=Intersection(Source(res),preim); fi;
return preim; end );
############################################################################# ## #M PreImagesSet( <map>, <elm> ) . . . . . . . . . . for restricted mapping ##
InstallMethod( PreImagesSet, "for a restricted mapping, and a collection",
CollFamRangeEqFamElms,
[ IsGeneralRestrictedMappingRep, IsCollection ], 0, function( res, elms )
local preim;
preim:= PreImagesSet( res!.map, elms ); if not ( (HasIsInjective(res) and IsInjective(res)) or
(HasIsInjective(res!.map) and IsInjective(res!.map)) ) then
preim:=Intersection(Source(res),preim); fi;
return preim; end );
############################################################################# ## #M PreImagesRepresentative( <map>, <elm> ) . . . . . for restricted mapping ##
InstallMethod( PreImagesRepresentative, "for a restricted mapping, and an element",
FamRangeEqFamElm,
[ IsGeneralRestrictedMappingRep, IsObject ], 0, function( res, elm )
local preim;
preim:= PreImagesRepresentative( res!.map, elm ); if preim = fail then # 'elm' has no preimages under 'res!.map', so it has none under 'res'.
return fail; elif preim in Source(res) then
return preim; elif HasIsInjective(res!.map) and IsInjective(res!.map) then
return fail; # no other choice else
preim:= PreImages( res!.map, elm );
return First(preim,x->x in Source(res)); fi; end );
############################################################################# ## #M KernelOfAdditiveGeneralMapping( <map> ) . . . . . for restricted mapping ##
InstallMethod( KernelOfAdditiveGeneralMapping, "for a restricted mapping that resp. add. and add.inv.", true,
[ IsGeneralMapping and IsGeneralRestrictedMappingRep
and RespectsAddition and RespectsAdditiveInverses ], 0, function( res )
return Intersection(Source(res),KernelOfAdditiveGeneralMapping( res!.map )); end );
############################################################################# ## #M CoKernelOfAdditiveGeneralMapping( <map> ) . . . . for restricted mapping ##
InstallMethod( CoKernelOfAdditiveGeneralMapping, "for a restricted mapping that resp. add. and add.inv.",
true,
[ IsGeneralMapping and IsGeneralRestrictedMappingRep
and RespectsAddition and RespectsAdditiveInverses ], 0, function( res )
return Intersection(Range(res),CoKernelOfAdditiveGeneralMapping( res!.map )); end );
############################################################################# ## #M KernelOfMultiplicativeGeneralMapping( <map> ) . . for restricted mapping ##
InstallMethod( KernelOfMultiplicativeGeneralMapping, "for a restricted mapping that resp. mult. and inv.",
true,
[ IsGeneralMapping and IsGeneralRestrictedMappingRep
and RespectsMultiplication and RespectsInverses ], 0, function( res )
return Intersection(Source(res),
KernelOfMultiplicativeGeneralMapping(res!.map)); end );
############################################################################# ## #M CoKernelOfMultiplicativeGeneralMapping( <map> ) . for restricted mapping ##
InstallMethod( CoKernelOfMultiplicativeGeneralMapping, "for a restricted mapping that resp. mult. and inv.",
true,
[ IsGeneralMapping and IsGeneralRestrictedMappingRep
and RespectsMultiplication and RespectsInverses ], 0, function( res )
return Intersection(Range(res),
CoKernelOfMultiplicativeGeneralMapping(res!.map)); end );
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.