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############################################################################# ## #W algfp.gi GAP library Alexander Hulpke ## ## #Y Copyright (C) 1997, Lehrstuhl D für Mathematik, RWTH Aachen, Germany #Y (C) 1998 School Math and Comp. Sci., University of St Andrews, Scotland #Y Copyright (C) 2002 The GAP Group ## ## This file contains the methods for finitely presented algebras. ## So far, there are not many. ## ############################################################################# ## #M ElementOfFpAlgebra( <Fam>, <elm> ) . . . . for family of f.p. alg.elms. ## InstallMethod(ElementOfFpAlgebra, "for family of fp. alg. elements and ring element", true, [ IsElementOfFpAlgebraFamily, IsRingElement ], 0, function( fam, elm ) return Objectify( fam!.defaultType, [ Immutable( elm ) ] ); end ); ############################################################################# ## #M ElementOfFpAlgebra( <Fam>, <elm> ) . . for family with nice normal form ## InstallMethod( ElementOfFpAlgebra, "for fp. alg. elms. family with normal form, and ring element", true, [ IsElementOfFpAlgebraFamily and HasNiceNormalFormByExtRepFunction, IsRingElement ], 0, function( Fam, elm ) return NiceNormalFormByExtRepFunction( Fam )( Fam, ExtRepOfObj( elm ) ); end ); ############################################################################# ## #M ExtRepOfObj( <elm> ) . . . . . . . . . . . . . for f.p. algebra element ## ## The external representation of elements in an f.p. algebra is defined as ## a list of length 2, the first entry being the zero coefficient, ## the second being a zipped list containing the external representations ## of the monomials and their coefficients. ## InstallMethod( ExtRepOfObj, "for f.p. algebra element", true, [ IsElementOfFpAlgebra and IsPackedElementDefaultRep ], 0, elm -> ExtRepOfObj( elm![1] ) ); ############################################################################# ## #M ObjByExtRep( <Fam>, <descr> ) . for f.p. alg. elms. fam. with normal form ## InstallMethod( ObjByExtRep, "for family of f.p. algebra elements with normal form", true, [ IsElementOfFpAlgebraFamily and HasNiceNormalFormByExtRepFunction, IsList ], 0, function( Fam, descr ) return NiceNormalFormByExtRepFunction( Fam )( Fam, descr ); end ); ############################################################################ ## #M MappedExpression( <expr>, <gens1>, <gens2> ) ## BindGlobal( "MappedExpressionForElementOfFreeAssociativeAlgebra", function( expr, gens1, gens2 ) local mapped, # the mapped expression, result gen, # one in `gens1' one, # 1 of the coefficients field MappedWord, # local function to map words i, # loop over summands pos; # position in a list expr:= ExtRepOfObj( expr )[2]; if IsEmpty( expr ) then return Zero( gens2[1] ); fi; # Get the numbers corresponding to the generators. gens1:= List( gens1, x -> ExtRepOfObj( x )[2] ); for i in [ 1 .. Length( gens1 ) ] do gen:= gens1[i]; if Length( gen ) = 2 and IsOne( gen[2] ) then gen:= gen[1]; if Length( gen ) = 0 then gens1[i]:= 0; elif Length( gen ) = 2 and gen[2] = 1 then gens1[i]:= gen[1]; else Error( "<gens1> must be list of generators or identity" ); fi; else Error( "<gens1> must be list of generators or identity" ); fi; od; #T This was quite expensive. #T Better introduce `MappedExpressions' to do this work not so often? one:= One( expr[2] ); MappedWord:= function( word ) local mapped, i; mapped:= gens2[ Position( gens1, word[1], 0 ) ] ^ word[2]; for i in [ 4, 6 .. Length( word ) ] do if word[i] = 1 then mapped:= mapped * gens2[ Position( gens1, word[i-1], 0 ) ]; else mapped:= mapped * gens2[ Position( gens1, word[i-1], 0 ) ] ^ word[i]; fi; od; return mapped; end; # The empty word can be at most at the first position. if IsEmpty( expr[1] ) then pos:= Position( gens1, 0, 0 ); if pos <> fail then mapped:= gens2[ pos ]; else mapped:= One( gens2[1] ); fi; else mapped:= MappedWord( expr[1] ); fi; # Avoid to multiply explicitly with 1 in order to avoid deep trees. if expr[2] <> one then mapped:= expr[2] * mapped; fi; for i in [ 4, 6 .. Length( expr ) ] do if expr[i] = one then mapped:= mapped + MappedWord( expr[ i-1 ] ); else mapped:= mapped + expr[i] * MappedWord( expr[ i-1 ] ); fi; od; return mapped; end ); #T special method for expression trees! (see GAP 3.5) InstallMethod( MappedExpression, "for element of f.p. algebra, and two lists of generators", IsElmsCollsX, [ IsElementOfFpAlgebra, IsHomogeneousList, IsHomogeneousList ], 0, #T install same method for free ass. algebra elements! MappedExpressionForElementOfFreeAssociativeAlgebra ); ############################################################################# ## #M \=( <x>, <y> ) . . . . . . . . for two normalized f.p. algebra elements ## InstallMethod( \=, "for two normalized f.p. algebra elements", IsIdenticalObj, [ IsElementOfFpAlgebra and IsNormalForm, IsElementOfFpAlgebra and IsNormalForm ], 0, function( x, y ) return ExtRepOfObj( x ) = ExtRepOfObj( y ); end ); #T missing: \= method to look for normal form in the family ############################################################################# ## #M \=( <x>, <y> ) . . . . . . . . . . . . . . for two f.p. algebra elements ## InstallMethod( \=, "for two f.p. algebra elements (try nice monomorphism)", IsIdenticalObj, [ IsElementOfFpAlgebra, IsElementOfFpAlgebra ], 0, function( x, y ) local hom; hom:= NiceAlgebraMonomorphism( FamilyObj( x )!.wholeAlgebra ); if hom = fail then TryNextMethod(); fi; return ImagesRepresentative( hom, x ) = ImagesRepresentative( hom, y ); end ); ############################################################################# ## #M \<( <x>, <y> ) . . . . . . . . for two normalized f.p. algebra elements ## ## The ordering is defined as follows. ## Expressions with less summands are shorter, ## and for expressions with the same number of summands, ## the words in algebra generators and the coefficients are compared ## according to the ordering in the external representation. ## InstallMethod( \<, "for two normalized f.p. algebra elements", IsIdenticalObj, [ IsElementOfFpAlgebra and IsNormalForm, IsElementOfFpAlgebra and IsNormalForm ], 0, function( x, y ) local lenx, leny, i; x:= ExtRepOfObj( x )[2]; y:= ExtRepOfObj( y )[2]; lenx:= Length( x ); leny:= Length( y ); # Compare the lengths. if lenx < leny then return true; elif leny < lenx then return false; fi; # For expressions of same length, compare the summands. for i in [ 1 .. lenx ] do if x[i] < y[i] then return true; elif y[i] < x[i] then return false; fi; od; # The operands are equal. return false; end ); ############################################################################# ## #M \<( <x>, <y> ) . . . . . . . . . . . . . . for two f.p. algebra elements ## InstallMethod( \<, "for two f.p. algebra elements (try nice monomorphism)", IsIdenticalObj, [ IsElementOfFpAlgebra, IsElementOfFpAlgebra ], 0, function( x, y ) local hom; hom:= NiceAlgebraMonomorphism( FamilyObj( x )!.wholeAlgebra ); if hom = fail then TryNextMethod(); fi; return ImagesRepresentative( hom, x ) < ImagesRepresentative( hom, y ); end ); ############################################################################# ## #M FactorFreeAlgebraByRelators( <F>, <rels> ) . . . factor of free algebra ## InstallGlobalFunction( FactorFreeAlgebraByRelators, function( F, rels ) local A, fam; # Create a new family. fam := NewFamily( "FamilyElementsFpAlgebra", IsElementOfFpAlgebra ); # Create the default type for the elements. fam!.defaultType := NewType( fam, IsElementOfFpAlgebra and IsPackedElementDefaultRep ); fam!.freeAlgebra := F; fam!.relators := Immutable( rels ); fam!.familyRing := FamilyObj(LeftActingDomain(F)); # We do not set the characteristic since this depends on the fact # whether or not we are 0-dimensional. # Create the algebra. if IsAlgebraWithOne( F ) then A := Objectify( NewType( CollectionsFamily( fam ), IsSubalgebraFpAlgebra and IsAlgebraWithOne and IsWholeFamily and IsAttributeStoringRep ), rec() ); SetLeftActingDomain( A, LeftActingDomain( F ) ); SetGeneratorsOfAlgebraWithOne( A, List( GeneratorsOfAlgebraWithOne( F ), i -> ElementOfFpAlgebra( fam, i ) ) ); else A := Objectify( NewType( CollectionsFamily( fam ), IsSubalgebraFpAlgebra and IsWholeFamily and IsAttributeStoringRep ), rec() ); SetLeftActingDomain( A, LeftActingDomain( F ) ); SetGeneratorsOfAlgebra( A, List( GeneratorsOfAlgebra( F ), i -> ElementOfFpAlgebra( fam, i ) ) ); fi; SetZero( fam, ElementOfFpAlgebra( fam, Zero( F ) ) ); UseFactorRelation( F, rels, A ); SetIsFullFpAlgebra( A, true ); fam!.wholeAlgebra:= A; return A; end ); ############################################################################# ## #M Characteristic( <A> ) #M Characteristic( <algelm> ) #M Characteristic( <algelmfam> ) ## ## (via delegations) ## InstallMethod( Characteristic, "for an elements family of an fp subalgebra", [ IsElementOfFpAlgebraFamily ], function( fam ) local A,n,one,x; A := fam!.wholeAlgebra; if IsAlgebraWithOne(A) then one := One(A); if Zero(A) = one then return 1; fi; else if Dimension(A) = 0 then return 1; fi; fi; if IsField(LeftActingDomain(A)) then return Characteristic(LeftActingDomain(A)); else if not IsAlgebraWithOne(A) then return fail; fi; # This might be horribly slow and might not terminate if the # characteristic is 0: n := 2; x := one+one; while not(IsZero(x)) do x := x + one; n := n + 1; od; return n; fi; end ); ############################################################################# ## #M FreeGeneratorsOfFpAlgebra( <A> ) ## InstallMethod( FreeGeneratorsOfFpAlgebra, "for a full f.p. algebra", true, [ IsSubalgebraFpAlgebra and IsFullFpAlgebra ], 0, function( A ) A:= ElementsFamily( FamilyObj( A ) )!.freeAlgebra; if IsMagmaWithOne( A ) then return GeneratorsOfAlgebraWithOne( A ); else return GeneratorsOfAlgebra( A ); fi; end ); ############################################################################ ## #M RelatorsOfFpAlgebra( <A> ) ## InstallMethod( RelatorsOfFpAlgebra, "for a full f.p. algebra", true, [ IsSubalgebraFpAlgebra and IsFullFpAlgebra ], 0, A -> ElementsFamily( FamilyObj( A ) )!.relators ); ############################################################################# ## #A FreeAlgebraOfFpAlgebra( <A> ) ## InstallMethod( FreeAlgebraOfFpAlgebra, "for a full f.p. algebra", true, [ IsSubalgebraFpAlgebra and IsFullFpAlgebra ], 0, A -> ElementsFamily( FamilyObj( A ) )!.freeAlgebra ); ############################################################################# ## #M IsFullFpAlgebra( <A> ) ## InstallOtherMethod( IsFullFpAlgebra, "for f. p. algebra", true, [ IsAlgebra and IsSubalgebraFpAlgebra ], 0, function( A ) local Fam; Fam:= ElementsFamily( FamilyObj( A ) ); return IsSubset( A, List( GeneratorsOfAlgebra( Fam!.freeAlgebra ), a -> ElementOfFpAlgebra( Fam, a ) ) ); end ); ############################################################################# ## #M NaturalHomomorphismByIdeal( <F>, <I> ) . . . . . for free alg. and ideal ## ## The algebra <F> can be also a free magma ring. ## If it is finite dimensional then we prefer not to regard it as a ## f.p. algebra (modulo relations); ## there is a method for but to work with bases of <A> and <I>. ## InstallMethod( NaturalHomomorphismByIdeal, "for free algebra and ideal", IsIdenticalObj, [ IsMagmaRingModuloRelations, IsFLMLOR ], function( F, I ) local image, hom; if IsInt( Dimension( F ) ) then TryNextMethod(); fi; image:= FactorFreeAlgebraByRelators( F, GeneratorsOfIdeal( I ) ); if IsMagmaWithOne( F ) then hom:= AlgebraWithOneHomomorphismByImagesNC( F, image, GeneratorsOfAlgebraWithOne( F ), GeneratorsOfAlgebraWithOne( image ) ); else hom:= AlgebraHomomorphismByImagesNC( F, image, GeneratorsOfAlgebra( F ), GeneratorsOfAlgebra( image ) ); fi; SetIsSurjective( hom, true ); return hom; end ); ############################################################################# ## #M Print(<fp alg elm>) ## InstallMethod(PrintObj, "fp algebra elements", true, [ IsElementOfFpAlgebra and IsPackedElementDefaultRep ], 0, function( e ) Print( "[", e![1], "]" ); end ); ############################################################################# ## #M \+( <fp alg elm>, <fp alg elm> ) ## InstallMethod( \+, "fp algebra elements", IsIdenticalObj, [ IsElementOfFpAlgebra and IsPackedElementDefaultRep, IsElementOfFpAlgebra and IsPackedElementDefaultRep ], 0, function( a, b ) return ElementOfFpAlgebra( FamilyObj( a ), a![1] + b![1] ); end ); ############################################################################# ## #M \-( <fp alg elm>, <fp alg elm> ) ## InstallMethod( \-, "fp algebra elements", IsIdenticalObj, [ IsElementOfFpAlgebra and IsPackedElementDefaultRep, IsElementOfFpAlgebra and IsPackedElementDefaultRep ], 0, function( a, b ) return ElementOfFpAlgebra( FamilyObj( a ), a![1] - b![1] ); end ); ############################################################################# ## #M AdditiveInverseOp( <fp alg elm> ) ## InstallMethod( AdditiveInverseOp, "fp algebra element", true, [ IsElementOfFpAlgebra and IsPackedElementDefaultRep ], 0, function( a ) return ElementOfFpAlgebra( FamilyObj( a ), AdditiveInverse( a![1] ) ); end ); ############################################################################# ## #M OneOp( <fp alg elm> ) ## InstallOtherMethod( OneOp, "for an f.p. algebra element", true, [ IsElementOfFpAlgebra and IsPackedElementDefaultRep ], 0, function( elm ) local one; one:= One( elm![1] ); if one <> fail then one:= ElementOfFpAlgebra( FamilyObj( elm ), one ); fi; return one; end ); ############################################################################# ## #M ZeroOp( <fp alg elm>) ## InstallMethod( ZeroOp, "for an f.p. algebra element", true, [ IsElementOfFpAlgebra and IsPackedElementDefaultRep ], 0, elm -> ElementOfFpAlgebra( FamilyObj( elm ), Zero( elm![1] ) ) ); ############################################################################# ## #M \*( <fp alg elm>, <fp alg elm> ) ## InstallMethod( \*, "fp algebra elements", IsIdenticalObj, [ IsElementOfFpAlgebra and IsPackedElementDefaultRep, IsElementOfFpAlgebra and IsPackedElementDefaultRep ], 0, function( a, b ) return ElementOfFpAlgebra( FamilyObj( a ), a![1] * b![1] ); end); ############################################################################# ## #M \*( <ring el>, <fp alg elm> ) ## InstallMethod( \*,"ring el *fp algebra el",IsRingsMagmaRings, [ IsRingElement, IsElementOfFpAlgebra and IsPackedElementDefaultRep ], 0, function( a, b ) return ElementOfFpAlgebra( FamilyObj( b ), a * b![1] ); end); ############################################################################# ## #M \*( <fp alg elm>, <ring el> ) ## InstallMethod( \*,"fp algebra el*ring el",IsMagmaRingsRings, [ IsElementOfFpAlgebra and IsPackedElementDefaultRep, IsRingElement ], 0, function( a, b ) return ElementOfFpAlgebra( FamilyObj( a ), a![1] * b ); end); #AH Embedding can only be defined reasonably if a `One' different from #AH the zero is present #AH (The factor may collaps). #T The `One' of the factor may be equal to the `Zero', #T so the ``embedding'' can be defined as a mapping from the ring #T to the algebra, #T but it is injective only if the `One' is not the `Zero'. ############################################################################# ## #M IsomorphismMatrixFLMLOR( <A> ) . . . . . . . . . . . . for a f.p. FLMLOR ## InstallMethod( IsomorphismMatrixFLMLOR, "for a f.p. FLMLOR", true, [ IsFLMLOR and IsSubalgebraFpAlgebra ], 0, A -> Error( "sorry, no method to compute a matrix algebra\n", "for a (not nec. associative) f.p. algebra" ) ); ############################################################################# ## #M IsomorphismMatrixFLMLOR( <A> ) . . . . . . for a full f.p. assoc. FLMLOR ## ## We compute the operation homomorphism for <A> acting on itself from the ## right. ## InstallMethod( IsomorphismMatrixFLMLOR, "for a full f.p. associative FLMLOR", true, [ IsFLMLORWithOne and IsSubalgebraFpAlgebra and IsAssociative and IsFullFpAlgebra ], 0, A -> OperationAlgebraHomomorphism( A, [ [ Zero( A ) ] ], OnRight ) ); #T change this: second argument should be the <A>-module itself! ############################################################################# ## #M OperationAlgebraHomomorphism( <A>, <C>, <opr> ) ## InstallOtherMethod( OperationAlgebraHomomorphism, "for a full f.p. associative FLMLOR, a collection, and a function", true, [ IsFLMLORWithOne and IsSubalgebraFpAlgebra and IsAssociative and IsFullFpAlgebra, IsCollection, IsFunction ], 0, function( A, C, opr ) Error( "this case will eventually be handled by the Vector Enumerator\n", "which is not available yet" ); end ); ############################################################################# ## #M NiceAlgebraMonomorphism( <A> ) . . . . . . for a full f.p. assoc. FLMLOR ## ## We delegate to `IsomorphismMatrixFLMLOR'. ## InstallMethod( NiceAlgebraMonomorphism, "for a full f.p. associative FLMLOR (call `IsomorphismMatrixFLMLOR')", true, [ IsFLMLORWithOne and IsSubalgebraFpAlgebra and IsAssociative and IsFullFpAlgebra ], 0, IsomorphismMatrixFLMLOR ); ############################################################################# ## #M IsFiniteDimensional( <A> ) #M Dimension( <A> ) ## #M NiceVector( <A>, <a> ) #M UglyVector( <A>, <r> ) ## ## Provided the f.~p. algebra <A> knows its `NiceAlgebraMonomorphism' value, ## it is handled via nice bases. ## So we have to treat the case that this value is not (yet) known. ## Note that `Dimension' may ask whether <A> is finite dimensional, ## so we must provide a (partial) method for it. ## ## The family of elements of <A> stores its whole algebra, ## so it is reasonable to look whether this algebra knows already a ## nice monomorphism. ## InstallMethod( IsFiniteDimensional, "for f.p. algebra", true, [ IsSubalgebraFpAlgebra ], 0, function( A ) local iso; if HasNiceAlgebraMonomorphism( ElementsFamily( FamilyObj( A ) )!.wholeAlgebra ) then iso:= NiceAlgebraMonomorphism( ElementsFamily( FamilyObj( A ) )!.wholeAlgebra ); else iso:= IsomorphismMatrixFLMLOR( A ); fi; if iso <> fail then if IsAlgebraHomomorphismFromFpRep( iso ) then SetNiceAlgebraMonomorphism( A, iso ); fi; return true; fi; TryNextMethod(); end ); ############################################################################# ## #M NiceFreeLeftModuleInfo( <V> ) #M NiceVector( <V>, <v> ) #M UglyVector( <V>, <r> ) ## InstallHandlingByNiceBasis( "IsFpAlgebraElementsSpace", rec( detect := function( F, gens, V, zero ) return IsElementOfFpAlgebraCollection( V ) and IsFreeLeftModule( V ); end, NiceFreeLeftModuleInfo := ReturnTrue, NiceVector := function( A, a ) local hom; hom:= NiceAlgebraMonomorphism( FamilyObj( a )!.wholeAlgebra ); if hom = fail then TryNextMethod(); fi; return ImagesRepresentative( hom, a ); end, UglyVector := function( A, r ) local hom; hom:= NiceAlgebraMonomorphism( ElementsFamily( FamilyObj( A ) )!.wholeAlgebra ); if hom = fail then TryNextMethod(); fi; return PreImagesRepresentative( hom, r ); end ) ); ############################################################################# ## #F FpAlgebraByGeneralizedCartanMatrix( <F>, <A> ) ## InstallGlobalFunction( FpAlgebraByGeneralizedCartanMatrix, function( F, A ) local n, # dimension of the matrix `A' i, j, k, # loop variables gensstrings, # names of algebra generators a, # algebra, result gens, # algebra generators e, h, f, # different portions of generators LieBracket, # function that computes the commutator rels, # list of relators rel; # one relator if not IsField( F ) then Error( "<F> must be a field" ); elif not IsGeneralizedCartanMatrix( A ) then Error( "<A> must be a generalized Cartan matrix" ); fi; n:= Length( A ); gensstrings:= []; for i in [ 1 .. n ] do gensstrings[ i ]:= Concatenation( "e", String(i) ); od; for i in [ 1 .. n ] do gensstrings[ n + i ]:= Concatenation( "h", String(i) ); od; for i in [ 1 .. n ] do gensstrings[ 2*n + i ]:= Concatenation( "f", String(i) ); od; a:= FreeAssociativeAlgebraWithOne( F, gensstrings ); gens:= GeneratorsOfAlgebraWithOne( a ); e:= gens{ [ 1 .. n ] }; h:= gens{ [ n + 1 .. 2*n ] }; f:= gens{ [ 2*n + 1 .. 3*n ] }; LieBracket:= function( A, B ) return A*B - B*A; end; rels:= []; for i in [ 1 .. n ] do for j in [ i+1 .. n ] do Add( rels, LieBracket( h[i], h[j] ) ); od; od; for i in [ 1 .. n ] do for j in [ 1 .. n ] do if i = j then Add( rels, LieBracket( e[i], f[i] ) - h[i] ); else Add( rels, LieBracket( e[i], f[j] ) ); fi; od; od; for i in [ 1 .. n ] do for j in [ 1 .. n ] do Add( rels, LieBracket( h[i], e[j] ) - A[i][j] * e[j] ); Add( rels, LieBracket( h[i], f[j] ) + A[i][j] * f[j] ); od; od; for i in [ 1 .. n ] do for j in [ i+1 .. n ] do if A[i][j] = 0 then Add( rels, LieBracket( e[i], e[j] ) ); Add( rels, LieBracket( f[i], f[j] ) ); fi; od; od; for i in [ 1 .. n ] do for j in [ 1 .. n ] do if i <> j then rel:= e[j]; for k in [ 1 .. 1 - A[i][j] ] do rel:= LieBracket( e[i], rel ); od; Add( rels, rel ); rel:= f[j]; for k in [ 1 .. 1 - A[i][j] ] do rel:= LieBracket( f[i], rel ); od; Add( rels, rel ); fi; od; od; # Return the algebra. return a / rels; end ); ############################################################################# ## #E