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 algmat.gi GAP library Thomas Breuer #W Willem de Graaf ## ## #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 those functions that mainly deal with matrix algebras, ## that is, associative matrix algebras and matrix Lie algebras. ## ############################################################################# ## #M RingByGenerators( <mats> ) . . . . ring generated by a list of matrices ## ## If <mats> is a list of matrices over a field then we construct a matrix ## algebra over its prime field. ## InstallOtherMethod( RingByGenerators, "for a list of matrices over a finite field", true, [ IsFFECollCollColl ], 0, mats -> FLMLORByGenerators( GF( Characteristic( mats ) ), mats ) ); InstallOtherMethod( RingByGenerators, "for a list of matrices over the Cyclotomics", true, [ IsCyclotomicCollCollColl ], 0, mats -> FLMLORByGenerators( Integers, mats ) ); ############################################################################# ## #M DefaultRingByGenerators( <mats> ) . . ring containing a list of matrices ## ## If <mats> is a list of matrices over a field then we construct a matrix ## algebra over its prime field. ## (So this may differ from the result of `RingByGenerators' if the ## characteristic is zero.) ## InstallOtherMethod( DefaultRingByGenerators, "for a list of matrices over a finite field", true, [ IsFFECollCollColl ], 0, mats -> FLMLORByGenerators( GF( Characteristic( mats ) ), mats ) ); InstallOtherMethod( DefaultRingByGenerators, "for a list of matrices over the Cyclotomics", true, [ IsCyclotomicCollCollColl ], 0, mats -> FLMLORByGenerators( Rationals, mats ) ); ############################################################################# ## #M RingByGenerators( <mats> ) . . ring generated by a list of Lie matrices ## ## If <mats> is a list of Lie matrices over a finite field then we construct ## a matrix Lie algebra over its prime field. ## InstallOtherMethod( RingByGenerators, "for a list of Lie matrices over a finite field", true, [ IsLieObjectCollection and IsMatrixCollection ], 0, function( mats ) local Fam; # Check whether the matrices lie in the Lie family of a family of # ordinary matrices. Fam:= UnderlyingFamily( ElementsFamily( FamilyObj( mats ) ) ); if not HasElementsFamily( Fam ) then TryNextMethod(); fi; Fam:= ElementsFamily( Fam ); if not HasElementsFamily( Fam ) then TryNextMethod(); fi; Fam:= ElementsFamily( Fam ); # Handle the cases that the entries of the matrices # are FFEs or cyclotomics. if IsFFEFamily( Fam ) then return FLMLORByGenerators( GF( Characteristic( Fam ) ), mats ); elif IsIdenticalObj( Fam, CyclotomicsFamily ) then return FLMLORByGenerators( Integers, mats ); else TryNextMethod(); fi; end ); ############################################################################# ## #M DefaultRingByGenerators( <mats> ) . . ring cont. a list of Lie matrices ## ## If <mats> is a list of Lie matrices over a field then we construct ## a matrix Lie algebra over its prime field. ## (So this may differ from the result of `RingByGenerators' if the ## characteristic is zero.) ## InstallOtherMethod( DefaultRingByGenerators, "for a list of Lie matrices", true, [ IsLieObjectCollection and IsMatrixCollection ], 0, function( mats ) local Fam; # Check whether the matrices lie in the Lie family of a family of # ordinary matrices. Fam:= UnderlyingFamily( ElementsFamily( FamilyObj( mats ) ) ); if not HasElementsFamily( Fam ) then TryNextMethod(); fi; Fam:= ElementsFamily( Fam ); if not HasElementsFamily( Fam ) then TryNextMethod(); fi; Fam:= ElementsFamily( Fam ); # Handle the cases that the entries of the matrices # are FFEs or cyclotomics. if IsFFEFamily( Fam ) then return AlgebraByGenerators( GF( Characteristic( Fam ) ), mats ); elif IsIdenticalObj( Fam, CyclotomicsFamily ) then return AlgebraByGenerators( Rationals, mats ); else TryNextMethod(); fi; end ); ############################################################################# ## #M RingWithOneByGenerators( <mats> ) ring-with-one gen. by list of matrices ## ## If <mats> is a list of matrices over a field then we construct a matrix ## algebra over its prime field. ## InstallOtherMethod( RingWithOneByGenerators, "for a list of matrices over a finite field", true, [ IsFFECollCollColl ], 0, mats -> FLMLORWithOneByGenerators( GF( Characteristic(mats) ), mats ) ); InstallOtherMethod( RingWithOneByGenerators, "for a list of matrices over the Cyclotomics", true, [ IsCyclotomicCollCollColl ], 0, mats -> FLMLORWithOneByGenerators( Integers, mats ) ); #T how to formulate this for any field? ############################################################################# ## #M FLMLORByGenerators( <F>, <mats> ) #M FLMLORByGenerators( <F>, <empty>, <zero> ) #M FLMLORByGenerators( <F>, <mats>, <zero> ) ## InstallMethod( FLMLORByGenerators, "for division ring and list of ordinary matrices over it", IsElmsCollColls, [ IsDivisionRing, IsCollection and IsList ], 0, function( F, mats ) local dims, A; # Check that all entries in `mats' are square matrices of the same shape. if not IsOrdinaryMatrix( mats[1] ) then TryNextMethod(); fi; dims:= DimensionsMat( mats[1] ); if dims[1] <> dims[2] or not ForAll( mats, mat -> IsOrdinaryMatrix( mat ) and DimensionsMat( mat ) = dims ) then TryNextMethod(); fi; if ForAll( mats, mat -> ForAll( mat, row -> IsSubset( F, row ) ) ) then A:= Objectify( NewType( FamilyObj( mats ), IsFLMLOR and IsGaussianMatrixSpace and IsAttributeStoringRep ), rec() ); else A:= Objectify( NewType( FamilyObj( mats ), IsFLMLOR and IsVectorSpace and IsNonGaussianMatrixSpace and IsAttributeStoringRep ), rec() ); fi; SetLeftActingDomain( A, F ); SetGeneratorsOfLeftOperatorRing( A, AsList( mats ) ); SetDimensionOfVectors( A, dims ); # If the generators are associative elements then so is `A'. if ForAll( mats, IsAssociativeElement ) then SetIsAssociative( A, true ); fi; # Return the result. return A; end ); InstallOtherMethod( FLMLORByGenerators, "for division ring, empty list, and square ordinary matrix", function( FamF, Famempty, Famzero ) return IsElmsColls( FamF, Famzero ); end, [ IsDivisionRing, IsList and IsEmpty, IsOrdinaryMatrix ], 0, function( F, empty, zero ) local dims, A; # Check whether this method is the right one. dims:= DimensionsMat( zero ); if dims[1] <> dims[2] then Error( "<zero> must be a square matrix" ); fi; A:= Objectify( NewType( CollectionsFamily( FamilyObj( zero ) ), IsFLMLOR and IsGaussianMatrixSpace and IsTrivial and IsAttributeStoringRep ), rec() ); SetLeftActingDomain( A, F ); SetGeneratorsOfLeftModule( A, empty ); SetZero( A, zero ); SetDimensionOfVectors( A, dims ); # Return the result. return A; end ); InstallOtherMethod( FLMLORByGenerators, "for division ring, list of matrices over it, and ordinary matrix", function( FamF, Fammats, Famzero ) return IsElmsCollColls( FamF, Fammats ); end, [ IsDivisionRing, IsCollection and IsList, IsOrdinaryMatrix ], 0, function( F, mats, zero ) local dims, A; # Check that all entries in `mats' are matrices of the same shape. if not IsOrdinaryMatrix( mats[1] ) then TryNextMethod(); fi; dims:= DimensionsMat( mats[1] ); if dims[1] <> dims[2] or not ForAll( mats, mat -> IsOrdinaryMatrix( mat ) and DimensionsMat( mat ) = dims ) then TryNextMethod(); fi; if ForAll( mats, mat -> ForAll( mat, row -> IsSubset( F, row ) ) ) then A:= Objectify( NewType( FamilyObj( mats ), IsFLMLOR and IsGaussianMatrixSpace and IsAttributeStoringRep ), rec() ); else A:= Objectify( NewType( FamilyObj( mats ), IsFLMLOR and IsVectorSpace and IsNonGaussianMatrixSpace and IsAttributeStoringRep ), rec() ); fi; SetLeftActingDomain( A, F ); SetGeneratorsOfLeftOperatorRing( A, AsList( mats ) ); SetZero( A, zero ); SetDimensionOfVectors( A, dims ); # If the generators are associative elements then so is `A'. if ForAll( mats, IsAssociativeElement ) then SetIsAssociative( A, true ); fi; # Return the result. return A; end ); ############################################################################# ## #M FLMLORByGenerators( <F>, <lie-mats> ) #M FLMLORByGenerators( <F>, <empty>, <lie-zero> ) #M FLMLORByGenerators( <F>, <lie-mats>, <lie-zero> ) ## InstallMethod( FLMLORByGenerators, "for division ring and list of Lie matrices over it", IsElmsCollLieColls, [ IsDivisionRing, IsLieObjectCollection and IsList ], 0, function( F, mats ) local dims, A; # Check that all entries in `mats' are square matrices of the same shape. if not IsLieMatrix( mats[1] ) then TryNextMethod(); fi; dims:= DimensionsMat( mats[1] ); if dims[1] <> dims[2] or not ForAll( mats, mat -> IsLieMatrix( mat ) and DimensionsMat( mat ) = dims ) then TryNextMethod(); fi; if ForAll( mats, mat -> ForAll( mat, row -> IsSubset( F, row ) ) ) then A:= Objectify( NewType( FamilyObj( mats ), IsFLMLOR and IsGaussianMatrixSpace and IsAttributeStoringRep ), rec() ); else A:= Objectify( NewType( FamilyObj( mats ), IsFLMLOR and IsVectorSpace and IsNonGaussianMatrixSpace and IsAttributeStoringRep ), rec() ); fi; SetLeftActingDomain( A, F ); SetGeneratorsOfLeftOperatorRing( A, AsList( mats ) ); SetDimensionOfVectors( A, dims ); # `A' consists of Lie objects, so it is a Lie algebra. SetIsLieAlgebra( A, true ); # Return the result. return A; end ); InstallOtherMethod( FLMLORByGenerators, "for division ring, empty list, and Lie matrix", function( FamF, Famempty, Famzero ) return IsElmsLieColls( FamF, Famzero ); end, [ IsDivisionRing, IsList and IsEmpty, IsLieMatrix and IsLieObject ], 0, function( F, empty, zero ) local dims, A; # Check whether this method is the right one. dims:= DimensionsMat( zero ); if dims[1] <> dims[2] then Error( "<zero> must be a square matrix" ); fi; A:= Objectify( NewType( CollectionsFamily( FamilyObj( zero ) ), IsFLMLOR and IsGaussianMatrixSpace and IsTrivial and IsAttributeStoringRep ), rec() ); SetLeftActingDomain( A, F ); SetGeneratorsOfLeftModule( A, empty ); SetZero( A, zero ); SetDimensionOfVectors( A, dims ); # Return the result. return A; end ); InstallOtherMethod( FLMLORByGenerators, "for division ring, list of Lie matrices over it, and Lie matrix", function( FamF, Fammats, Famzero ) return IsElmsCollLieColls( FamF, Fammats ); end, [ IsDivisionRing, IsLieObjectCollection and IsList, IsLieObject and IsLieMatrix ], 0, function( F, mats, zero ) local dims, A; # Check that all entries in `mats' are matrices of the same shape. if not IsLieMatrix( mats[1] ) then TryNextMethod(); fi; dims:= DimensionsMat( mats[1] ); if dims[1] <> dims[2] or not ForAll( mats, mat -> IsLieMatrix( mat ) and DimensionsMat( mat ) = dims ) then TryNextMethod(); fi; if ForAll( mats, mat -> ForAll( mat, row -> IsSubset( F, row ) ) ) then A:= Objectify( NewType( FamilyObj( mats ), IsFLMLOR and IsGaussianMatrixSpace and IsAttributeStoringRep ), rec() ); else A:= Objectify( NewType( FamilyObj( mats ), IsFLMLOR and IsVectorSpace and IsNonGaussianMatrixSpace and IsAttributeStoringRep ), rec() ); fi; SetLeftActingDomain( A, F ); SetGeneratorsOfLeftOperatorRing( A, AsList( mats ) ); SetZero( A, zero ); SetDimensionOfVectors( A, dims ); # `A' consists of Lie objects, so it is a Lie algebra. SetIsLieAlgebra( A, true ); # Return the result. return A; end ); ############################################################################# ## #M FLMLORWithOneByGenerators( <F>, <mats> ) #M FLMLORWithOneByGenerators( <F>, <empty>, <zero> ) #M FLMLORWithOneByGenerators( <F>, <mats>, <zero> ) ## InstallMethod( FLMLORWithOneByGenerators, "for division ring and list of ordinary matrices over it", IsElmsCollColls, [ IsDivisionRing, IsCollection and IsList ], 0, function( F, mats ) local dims, A; # Check that all entries in `mats' are square matrices of the same shape. if not IsOrdinaryMatrix( mats[1] ) then TryNextMethod(); fi; dims:= DimensionsMat( mats[1] ); if dims[1] <> dims[2] or not ForAll( mats, mat -> IsOrdinaryMatrix( mat ) and DimensionsMat( mat ) = dims ) then TryNextMethod(); fi; if ForAll( mats, mat -> ForAll( mat, row -> IsSubset( F, row ) ) ) then A:= Objectify( NewType( FamilyObj( mats ), IsFLMLORWithOne and IsGaussianMatrixSpace and IsAttributeStoringRep ), rec() ); else A:= Objectify( NewType( FamilyObj( mats ), IsFLMLORWithOne and IsVectorSpace and IsNonGaussianMatrixSpace and IsAttributeStoringRep ), rec() ); fi; SetLeftActingDomain( A, F ); SetGeneratorsOfLeftOperatorRingWithOne( A, AsList( mats ) ); SetDimensionOfVectors( A, dims ); # If the generators are associative elements then so is `A'. if ForAll( mats, IsAssociativeElement ) then SetIsAssociative( A, true ); fi; # Return the result. return A; end ); InstallOtherMethod( FLMLORWithOneByGenerators, "for division ring, empty list, and square ordinary matrix", function( FamF, Famempty, Famzero ) return IsElmsColls( FamF, Famzero ); end, [ IsDivisionRing, IsList and IsEmpty, IsOrdinaryMatrix ], 0, function( F, empty, zero ) local A; # Check whether this method is the right one. if Length( zero ) <> Length( zero[1] ) then Error( "<zero> must be a square matrix" ); fi; A:= Objectify( NewType( CollectionsFamily( FamilyObj( zero ) ), IsFLMLORWithOne and IsGaussianMatrixSpace and IsAssociative and IsAttributeStoringRep ), rec() ); SetLeftActingDomain( A, F ); SetGeneratorsOfLeftOperatorRingWithOne( A, empty ); SetZero( A, zero ); SetDimensionOfVectors( A, DimensionsMat( zero ) ); # Return the result. return A; end ); InstallOtherMethod( FLMLORWithOneByGenerators, "for division ring, list of matrices over it, and ordinary matrix", function( FamF, Fammats, Famzero ) return HasCollectionsFamily( FamF ) and IsElmsColls( CollectionsFamily( FamF ), Fammats ); end, [ IsDivisionRing, IsCollection and IsList, IsOrdinaryMatrix ], 0, function( F, mats, zero ) local dims, A; # Check that all entries in `mats' are matrices of the same shape. if not IsOrdinaryMatrix( mats[1] ) then TryNextMethod(); fi; dims:= DimensionsMat( mats[1] ); if dims[1] <> dims[2] or not ForAll( mats, mat -> IsOrdinaryMatrix( mat ) and DimensionsMat( mat ) = dims ) then TryNextMethod(); fi; if ForAll( mats, mat -> ForAll( mat, row -> IsSubset( F, row ) ) ) then A:= Objectify( NewType( FamilyObj( mats ), IsFLMLORWithOne and IsGaussianMatrixSpace and IsAttributeStoringRep ), rec() ); else A:= Objectify( NewType( FamilyObj( mats ), IsFLMLORWithOne and IsVectorSpace and IsNonGaussianMatrixSpace and IsAttributeStoringRep ), rec() ); fi; SetLeftActingDomain( A, F ); SetGeneratorsOfLeftOperatorRingWithOne( A, AsList( mats ) ); SetZero( A, zero ); SetDimensionOfVectors( A, dims ); # If the generators are associative elements then so is `A'. if ForAll( mats, IsAssociativeElement ) then SetIsAssociative( A, true ); fi; # Return the result. return A; end ); ############################################################################# ## #M TwoSidedIdealByGenerators( <A>, <mats> ) ## InstallMethod( TwoSidedIdealByGenerators, "for Gaussian matrix algebra and list of matrices", IsIdenticalObj, [ IsMatrixFLMLOR and IsGaussianMatrixSpace, IsCollection and IsList ], 0, function( A, mats ) local dims, I; # Check that all entries in `mats' are square matrices of the same shape. dims:= DimensionOfVectors( A ); if not ForAll( mats, mat -> IsMatrix( mat ) and DimensionsMat( mat ) = dims ) then Error( "entries of <mats> do not have the right dimension" ); fi; I:= Objectify( NewType( FamilyObj( mats ), IsFLMLOR and IsGaussianMatrixSpace and IsAttributeStoringRep ), rec() ); SetLeftActingDomain( I, LeftActingDomain( A ) ); SetGeneratorsOfTwoSidedIdeal( I, mats ); SetLeftActingRingOfIdeal( I, A ); SetRightActingRingOfIdeal( I, A ); SetDimensionOfVectors( I, dims ); # Return the result. return I; end ); InstallMethod( TwoSidedIdealByGenerators, "for non-Gaussian matrix algebra and list of matrices", IsIdenticalObj, [ IsMatrixFLMLOR and IsNonGaussianMatrixSpace, IsCollection and IsList ], 0, function( A, mats ) local dims, I; # Check that all entries in `mats' are square matrices of the same shape. dims:= DimensionOfVectors( A ); if not ForAll( mats, mat -> IsMatrix( mat ) and DimensionsMat( mat ) = dims ) then Error( "entries of <mats> do not have the right dimension" ); fi; I:= Objectify( NewType( FamilyObj( mats ), IsFLMLOR and IsVectorSpace and IsNonGaussianMatrixSpace and IsAttributeStoringRep ), rec() ); SetLeftActingDomain( I, LeftActingDomain( A ) ); SetGeneratorsOfTwoSidedIdeal( I, mats ); SetLeftActingRingOfIdeal( I, A ); SetRightActingRingOfIdeal( I, A ); SetDimensionOfVectors( I, dims ); # Return the result. return I; end ); InstallMethod( TwoSidedIdealByGenerators, "for matrix algebra and empty list", true, [ IsMatrixFLMLOR, IsList and IsEmpty ], 0, function( A, mats ) local I; I:= Objectify( NewType( FamilyObj( mats ), IsFLMLOR and IsGaussianMatrixSpace and IsTrivial and IsAttributeStoringRep ), rec() ); SetLeftActingDomain( I, LeftActingDomain( A ) ); SetGeneratorsOfTwoSidedIdeal( I, mats ); SetGeneratorsOfLeftOperatorRing( I, mats ); SetGeneratorsOfLeftModule( I, mats ); SetLeftActingRingOfIdeal( I, A ); SetRightActingRingOfIdeal( I, A ); SetDimensionOfVectors( I, DimensionOfVectors( A ) ); # Return the result. return I; end ); ############################################################################# ## #M LeftIdealByGenerators( <A>, <mats> ) ## InstallMethod( LeftIdealByGenerators, "for Gaussian matrix algebra and list of matrices", IsIdenticalObj, [ IsMatrixFLMLOR and IsGaussianMatrixSpace, IsCollection and IsList ], 0, function( A, mats ) local dims, I; # Check that all entries in `mats' are square matrices of the same shape. dims:= DimensionOfVectors( A ); if not ForAll( mats, mat -> IsMatrix( mat ) and DimensionsMat( mat ) = dims ) then Error( "entries of <mats> do not have the right dimension" ); fi; I:= Objectify( NewType( FamilyObj( mats ), IsFLMLOR and IsGaussianMatrixSpace and IsAttributeStoringRep ), rec() ); SetLeftActingDomain( I, LeftActingDomain( A ) ); SetGeneratorsOfLeftIdeal( I, AsList( mats ) ); SetLeftActingRingOfIdeal( I, A ); SetDimensionOfVectors( I, dims ); # Return the result. return I; end ); InstallMethod( LeftIdealByGenerators, "for non-Gaussian matrix algebra and list of matrices", IsIdenticalObj, [ IsMatrixFLMLOR and IsNonGaussianMatrixSpace, IsCollection and IsList ], 0, function( A, mats ) local dims, I; # Check that all entries in `mats' are square matrices of the same shape. dims:= DimensionOfVectors( A ); if not ForAll( mats, mat -> IsMatrix( mat ) and DimensionsMat( mat ) = dims ) then Error( "entries of <mats> do not have the right dimension" ); fi; I:= Objectify( NewType( FamilyObj( mats ), IsFLMLOR and IsVectorSpace and IsNonGaussianMatrixSpace and IsAttributeStoringRep ), rec() ); SetLeftActingDomain( I, LeftActingDomain( A ) ); SetGeneratorsOfLeftIdeal( I, AsList( mats ) ); SetLeftActingRingOfIdeal( I, A ); SetDimensionOfVectors( I, dims ); # Return the result. return I; end ); InstallMethod( LeftIdealByGenerators, "for matrix algebra and empty list", true, [ IsMatrixFLMLOR, IsList and IsEmpty ], 0, function( A, mats ) local I; I:= Objectify( NewType( FamilyObj( mats ), IsFLMLOR and IsGaussianMatrixSpace and IsTrivial and IsAttributeStoringRep ), rec() ); SetLeftActingDomain( I, LeftActingDomain( A ) ); SetGeneratorsOfLeftIdeal( I, mats ); SetGeneratorsOfLeftOperatorRing( I, mats ); SetGeneratorsOfLeftModule( I, mats ); SetLeftActingRingOfIdeal( I, A ); SetDimensionOfVectors( I, DimensionOfVectors( A ) ); # Return the result. return I; end ); ############################################################################# ## #M RightIdealByGenerators( <A>, <mats> ) ## InstallMethod( RightIdealByGenerators, "for Gaussian matrix algebra and list of matrices", IsIdenticalObj, [ IsMatrixFLMLOR and IsGaussianMatrixSpace, IsCollection and IsList ], 0, function( A, mats ) local dims, I; # Check that all entries in `mats' are square matrices of the same shape. dims:= DimensionOfVectors( A ); if not ForAll( mats, mat -> IsMatrix( mat ) and DimensionsMat( mat ) = dims ) then Error( "entries of <mats> do not have the right dimension" ); fi; I:= Objectify( NewType( FamilyObj( mats ), IsFLMLOR and IsGaussianMatrixSpace and IsAttributeStoringRep ), rec() ); SetLeftActingDomain( I, LeftActingDomain( A ) ); SetGeneratorsOfRightIdeal( I, mats ); SetRightActingRingOfIdeal( I, A ); SetDimensionOfVectors( I, dims ); # Return the result. return I; end ); InstallMethod( RightIdealByGenerators, "for non-Gaussian matrix algebra and list of matrices", IsIdenticalObj, [ IsMatrixFLMLOR and IsNonGaussianMatrixSpace, IsCollection and IsList ], 0, function( A, mats ) local dims, I; # Check that all entries in `mats' are square matrices of the same shape. dims:= DimensionOfVectors( A ); if not ForAll( mats, mat -> IsMatrix( mat ) and DimensionsMat( mat ) = dims ) then Error( "entries of <mats> do not have the right dimension" ); fi; I:= Objectify( NewType( FamilyObj( mats ), IsFLMLOR and IsVectorSpace and IsNonGaussianMatrixSpace and IsAttributeStoringRep ), rec() ); SetLeftActingDomain( I, LeftActingDomain( A ) ); SetGeneratorsOfRightIdeal( I, mats ); SetRightActingRingOfIdeal( I, A ); SetDimensionOfVectors( I, dims ); # Return the result. return I; end ); InstallMethod( RightIdealByGenerators, "for matrix algebra and empty list", true, [ IsMatrixFLMLOR, IsList and IsEmpty ], 0, function( A, mats ) local I; I:= Objectify( NewType( FamilyObj( mats ), IsFLMLOR and IsGaussianMatrixSpace and IsTrivial and IsAttributeStoringRep ), rec() ); SetLeftActingDomain( I, LeftActingDomain( A ) ); SetGeneratorsOfRightIdeal( I, mats ); SetGeneratorsOfLeftOperatorRing( I, mats ); SetGeneratorsOfLeftModule( I, mats ); SetRightActingRingOfIdeal( I, A ); SetDimensionOfVectors( I, DimensionOfVectors( A ) ); # Return the result. return I; end ); ############################################################################# ## #M IsUnit( <A>, <mat> ) . . . . . . . . . . . for matrix FLMLOR and matrix ## InstallMethod( IsUnit, "for matrix FLMLOR and matrix", IsCollsElms, [ IsMatrixFLMLOR, IsMatrix ], 0, function ( A, m ) m:= m^-1; return m <> fail and m in A; end ); ############################################################################# ## #M RadicalOfAlgebra( <A> ) . . . . . . . . for an associative matrix algebra ## ## The radical of an associative algebra <A> defined as the ideal of all ## elements $x$ of <A> such that $x y$ is nilpotent for all $y$ in <A>. ## ## For Gaussian matrix algebras this is easy to calculate, ## for arbitrary associative algebras the task is reduced to the ## Gaussian matrix algebra case. ## ## The implementation of the characterisitc p>0 part is by Craig Struble. ## InstallMethod( RadicalOfAlgebra, "for associative Gaussian matrix algebra", true, [ IsAlgebra and IsGaussianMatrixSpace and IsMatrixFLMLOR ], 0, function( A ) local F, # the field of A p, # the characteristic of F q, # the size of F n, # the dimension of A ident, # the identity matrix bas, # a list of basis vectors of A minusOne, # -1 in F eqs, # equation set i,j, # loop variables G, # Gram matrix I, # a list of basis vectors of an ideal of A I_prime, # I \cup ident changed, # flag denoted if $I_i <> I_{i-1}$ in ideal sequence pexp, # a power of the prime p dim, # the dimension of the vector space where A acts on charPoly, # characteristic polynomials of elements in A invFrob, # inverse of the Frobenius map of F invFrobexp, # a power of the invFrob r, r_prime; # the length of I and I_prime # Check associativity. if not IsAssociative( A ) then TryNextMethod(); fi; if Dimension( A ) = 0 then return A; fi; F:= LeftActingDomain( A ); p:= Characteristic( F ); n:= Dimension( A ); bas:= BasisVectors( Basis( A ) ); if p = 0 then # First we treat the characteristic 0 case. # According to Dickson's theorem we have that in this case # the radical of `A' is $\{ x\in A \mid Tr(xy) = 0 \forall y \in A \}$, # so it can be computed by solving a system of linear equations. eqs:= List( [ 1 .. n ], x -> [] ); for i in [1..n] do for j in [i..n] do eqs[i][j]:= TraceMat( bas[i] * bas[j] ); eqs[j][i]:= eqs[i][j]; od; od; return SubalgebraNC( A, List( NullspaceMat( eqs ), x -> LinearCombination( bas, x ) ), "basis" ); else # If `p' is greater than 0, then the situation is more difficult. # We implement the algorithm presented in # "Cohen, Arjeh M, G\'{a}bor Ivanyos, and David B. Wales, # 'Finding the radical of an algebra of linear transformations,' # Journal of Pure and Applied Algebra 117 & 118 (1997), 177-193". q := Size( F ); dim := Length( bas[1] ); pexp := 1; invFrob := InverseGeneralMapping(FrobeniusAutomorphism(F)); invFrobexp := IdentityMapping(F); minusOne := -One(F); ident := IdentityMat( dim, F ); changed := true; I := ShallowCopy( bas ); # Compute the sequence of ideals $I_i$ (see the paper by Cohen, et.al.) while pexp <= dim do # These values need recomputation only when $I_i <> I_{i-1}$ if changed then I_prime := ShallowCopy( I ); if not ident in I_prime then Add( I_prime, ident ); fi; r := Length( I ); r_prime := Length( I_prime ); eqs := NullMat( r, r_prime, F ); charPoly := List( [1..r], x -> [] ); for i in [1..r] do for j in [1..r_prime] do charPoly[i][j] := CoefficientsOfUnivariatePolynomial( CharacteristicPolynomial( F, F, I[i]*I_prime[j] ) ); od; od; changed := false; fi; for i in [1..r] do for j in [1..r_prime] do eqs[i][j] := minusOne^pexp * charPoly[i][j][dim-pexp+1]; od; od; G := NullspaceMat( eqs ); if Length( G ) = 0 then return TrivialSubalgebra( A ); elif Length( G ) <> r then # $I_i <> I_{i-1}$, so compute the basis for $I_i$ changed := true; G := List( G, x -> List( x, y -> y^invFrobexp ) ); I := List( G, x -> LinearCombination( I, x ) ); fi; # prepare for next step invFrobexp := invFrobexp * invFrob; pexp := pexp*p; od; return SubalgebraNC( A, I, "basis" ); fi; end ); ############################################################################# ## #F CentralizerInAssociativeGaussianMatrixAlgebra( <base>, <gens> ) ## ## is a list of basis vectors of the $R$-FLMLOR that is the centralizer ## of the $R$-FLMLOR with generators <gens> in the $R$-FLMLOR ## with $R$-basis vectors <base>. ## ## View the centralizer condition for the matrix $a$ as an equation system ## \[ \sum_{b\in B} c_b ( b a - a b ) = 0 \ , \] ## where $B$ is a basis of <A> and $c_b$ in the coefficients field. ## Then the centralizer is spanned by the matrices ## $\sum_{b\in B} c_b b$ where the vector $c$ is a basis vector of ## the solution space. ## CentralizerInAssociativeGaussianMatrixAlgebra := function( base, gens ) #T better use structure constants ? local gen, mat, sol; for gen in gens do mat:= List( base, b -> Concatenation( b * gen - gen * b ) ); sol:= NullspaceMat( mat ); # Replace `base' by a vector space base of the centralizer. base:= List( sol, x -> LinearCombination( base, x ) ); od; return base; end; ############################################################################# ## #M Centralizer( <A>, <mat> ) . . . . . . . . . for matrix FLMLOR and matrix ## InstallMethod( CentralizerOp, "for associative Gaussian matrix FLMLOR, and ordinary matrix", IsCollsElms, [ IsMatrixFLMLOR and IsAssociative and IsGaussianSpace, IsOrdinaryMatrix ], 0, function( A, mat ) return SubalgebraNC( A, CentralizerInAssociativeGaussianMatrixAlgebra( BasisVectors( Basis( A ) ), [ mat ] ), "basis" ); end ); ############################################################################# ## #M Centralizer( <A>, <C> ) . . . . . . . for matrix FLMLOR and matrix FLMLOR ## InstallMethod( CentralizerOp, "for associative Gaussian matrix FLMLOR, and FLMLOR", IsIdenticalObj, [ IsMatrixFLMLOR and IsAssociative and IsGaussianSpace, IsMatrixFLMLOR ], 0, function( A, C ) return SubalgebraNC( A, CentralizerInAssociativeGaussianMatrixAlgebra( BasisVectors( Basis( A ) ), GeneratorsOfAlgebra( C ) ), "basis" ); end ); ############################################################################# ## #M Centralizer( <A>, <mat> ) . . . . . for matrix FLMLOR-with-one and matrix ## InstallMethod( CentralizerOp, "for associative Gaussian matrix FLMLOR-with-one, and ordinary matrix", IsCollsElms, [ IsMatrixFLMLOR and IsFLMLORWithOne and IsAssociative and IsGaussianSpace, IsOrdinaryMatrix ], 0, function( A, mat ) return SubalgebraWithOneNC( A, CentralizerInAssociativeGaussianMatrixAlgebra( BasisVectors( Basis( A ) ), [ mat ] ), "basis" ); end ); ############################################################################# ## #M Centralizer( <A>, <C> ) . . for matrix FLMLOR-with-one and matrix FLMLOR ## InstallMethod( CentralizerOp, "for associative Gaussian matrix FLMLOR-with-one, and FLMLOR", IsIdenticalObj, [ IsMatrixFLMLOR and IsFLMLORWithOne and IsAssociative and IsGaussianSpace, IsMatrixFLMLOR ], 0, function( A, C ) return SubalgebraWithOneNC( A, CentralizerInAssociativeGaussianMatrixAlgebra( BasisVectors( Basis( A ) ), GeneratorsOfAlgebra( C ) ), "basis" ); end ); ############################################################################# ## #F FullMatrixAlgebraCentralizer( <F>, <lst> ) ## ## Compute the centralizer of the list of matrices <lst> in the full ## matrix algebra over <F>. ## InstallGlobalFunction( FullMatrixAlgebraCentralizer, function( F, lst ) local len, # length of `lst' dims, # dimensions of the matrices n, # number of rows/columns n2, # square of `n' eq, # equation system u,i,j,k, # loop variables bc, # basis of solutions of the equation system Bcen, # basis vectors of the centralizer M; # one centralizing matrix len:= Length( lst ); if len = 0 then Error( "cannot compute the centralizer of an empty set" ); elif not (IsSubset( F, DefaultScalarDomainOfMatrixList( lst ) ) or IsSubset( F, FieldOfMatrixList( lst ) ) ) then Error( "not all entries of the matrices in <lst> lie in <F>" ); fi; dims:= DimensionsMat( lst[1] ); n:= dims[1]; n2:= n*n; # In the equations matrices are viewed as vectors of length `n*n'. # Position `(i,j)' in the matrix corresponds with position `(i-1)*n+j' # in the vector. eq:= NullMat( n2, n2 * len, F ); for u in [ 1 .. len ] do for i in [1..n] do for j in [1..n] do for k in [1..n] do eq[(i-1)*n+k][(u-1)*n2+(i-1)*n+j]:= eq[(i-1)*n+k][(u-1)*n2+(i-1)*n+j] + lst[u][k][j]; eq[(k-1)*n+j][(u-1)*n2+(i-1)*n+j]:= eq[(k-1)*n+j][(u-1)*n2+(i-1)*n+j] - lst[u][i][k]; od; od; od; od; # Translate the vectors back to matrices. bc:= NullspaceMat( eq ); Bcen:= []; for i in bc do M:= []; for j in [ 1 .. n ] do M[j]:= i{ [ (j-1)*n+1 .. j*n ] }; od; Add( Bcen, M ); od; return AlgebraWithOne( F, Bcen, "basis" ); end ); ############################################################################# ## #M CentralizerOp( <A>, <S> ) . . . . . . for full associative matrix algebra ## InstallMethod( CentralizerOp, "for full (associative) matrix FLMLOR, and FLMLOR", IsIdenticalObj, [ IsMatrixFLMLOR and IsFLMLORWithOne and IsAssociative and IsGaussianSpace and IsFullMatrixModule, IsMatrixFLMLOR ], 0, function( A, S ) if not IsAssociative( A ) then TryNextMethod(); fi; return FullMatrixAlgebraCentralizer( LeftActingDomain( A ), GeneratorsOfAlgebra( S ) ); end ); InstallMethod( CentralizerOp, "for full (associative) matrix FLMLOR, and left module", IsIdenticalObj, [ IsMatrixFLMLOR and IsFLMLORWithOne and IsAssociative and IsGaussianSpace and IsFullMatrixModule, IsLeftModule ], 0, function( A, S ) if not IsAssociative( A ) then TryNextMethod(); fi; return FullMatrixAlgebraCentralizer( LeftActingDomain( A ), GeneratorsOfLeftModule( S ) ); end ); InstallMethod( CentralizerOp, "for full (associative) matrix FLMLOR, and list of matrices", IsIdenticalObj, [ IsMatrixFLMLOR and IsFLMLORWithOne and IsAssociative and IsGaussianSpace and IsFullMatrixModule, IsCollection and IsList ], 0, function( A, S ) if not IsAssociative( A ) then TryNextMethod(); fi; return FullMatrixAlgebraCentralizer( LeftActingDomain( A ), S ); end ); InstallMethod( CentralizerOp, "for full (associative) matrix FLMLOR, and empty list", true, [ IsMatrixFLMLOR and IsFullMatrixModule, IsList and IsEmpty ], 0, function( A, S ) if not IsAssociative( A ) then TryNextMethod(); fi; return A; end ); ############################################################################# ## #F FullMatrixFLMLOR( <R>, <n> ) . . . FLMLOR of <n>-dim. matrices over <R> ## ## Let $E_{i,j}$ be the matrix with value 1 in row $i$ and $column $j$, and ## zero otherwise. ## Clearly the full associative matrix algebra is generated by all ## $E_{i,j}$, $i$ and $j$ ranging from 1 to <n>. ## Define the matrix $F$ as permutation matrix for the permutation ## $(1, 2, \ldots, n)$. Then $E_{i,j} = F^{i-1} E_{1,1} F^{1-j}$. ## Thus $F$ and $E_{1,1}$ are sufficient to generate the algebra. ## InstallGlobalFunction( FullMatrixFLMLOR, function( R, n ) local i, # loop over the rows gens, # list of generators one, # the identity of the field A; # algebra, result gens:= NullMat( n, n, R ); gens:= [ gens, List( gens, ShallowCopy ) ]; one:= One( R ); # Construct the generators. gens[1][1][1]:= one; gens[2][1][n]:= one; for i in [ 2 .. n ] do gens[2][i][i-1]:= one; od; # Construct the FLMLOR. A:= AlgebraWithOneByGenerators( R, gens ); SetIsFullMatrixModule( A, true ); SetRadicalOfAlgebra( A, TrivialSubalgebra( A ) ); # Return the FLMLOR. return A; end ); ############################################################################# ## #F FullMatrixLieAlgebra( <R>, <n> ) #F . . full matrix Lie algebra of <n>-dim. matrices over <R> ## ## The set $\{ E_{1,j}, E_{k,1}; 1 \leq j, k \leq n \}$ is a generating ## system. #T What is a nicer generating system ? ## InstallGlobalFunction( FullMatrixLieFLMLOR, function( F, n ) local null, # null matrix one, # identity of `F' gen, # one generator gens, # list of generators i, # loop over the rows A; # algebra, result # Construct the generators. null:= NullMat( n, n, F ); one:= One( F ); gen:= List( null, ShallowCopy ); gen[1][1]:= one; gens:= [ LieObject( gen ) ]; for i in [ 2 .. n ] do gen:= List( null, ShallowCopy ); gen[1][i]:= one; Add( gens, LieObject( gen ) ); gen:= List( null, ShallowCopy ); gen[i][1]:= one; Add( gens, LieObject( gen ) ); od; # construct the algebra A:= AlgebraByGenerators( F, gens ); SetIsFullMatrixModule( A, true ); # return the algebra return A; end ); ############################################################################# ## #M DirectSumOfAlgebras( <A1>, <A2> ) . . for two associative matrix FLMLORs ## ## Construct an associative matrix FLMLOR. ## #T embeddings/projections should be provided! ## InstallOtherMethod( DirectSumOfAlgebras, "for two associative matrix FLMLORs", IsIdenticalObj, [ IsMatrixFLMLOR and IsAssociative, IsMatrixFLMLOR and IsAssociative ], 0, function( A1, A2 ) local b1, # Basis vectors of `A1'. b2, # Basis vectors of `A2'. p1, # Length of the matrices of `b1'. p2, # Length of the matrices of `b2'. B, # A basis of `A1 \oplus A2'. i, # Loop variable. Q, # A matrix. A; # result if LeftActingDomain( A1 ) <> LeftActingDomain( A2 ) then Error( "<A1> and <A2> must be written over the same domain" ); fi; # We do not really need a basis for the arguments # but if we have one then we use it. #T Do we really have so many algebra generators? (distinguish from basis?) if HasBasis( A1 ) and HasBasis( A2 ) then b1:= BasisVectors( Basis( A1 ) ); b2:= BasisVectors( Basis( A2 ) ); else b1:= GeneratorsOfAlgebra( A1 ); b2:= GeneratorsOfAlgebra( A2 ); fi; p1:= DimensionOfVectors( A1 )[1]; p2:= DimensionOfVectors( A2 )[1]; B:= []; for i in b1 do Q:= NullMat( p1+p2, p1+p2, LeftActingDomain( A1 ) ); Q{ [ 1 .. p1 ] }{ [ 1 .. p1 ] }:= i; Add( B, Q ); od; for i in b2 do Q:= NullMat( p1+p2, p1+p2, LeftActingDomain( A1 ) ); Q{ [ p1+1 .. p1+p2 ] }{ [ p1+1 .. p1+p2 ] }:= i; Add( B, Q ); od; A:= AlgebraByGenerators( LeftActingDomain( A1 ), B ); if HasBasis( A1 ) and HasBasis( A2 ) then UseBasis( A, B ); fi; SetIsAssociative( A, true ); #T nec. ? return A; end ); ############################################################################# ## #M DirectSumOfAlgebras( <A1>, <A2> ) . . . . . . for two matrix Lie FLMLORs ## ## Construct a matrix Lie FLMLOR. ## #T embeddings/projections should be provided! ## InstallOtherMethod( DirectSumOfAlgebras, "for two matrix Lie FLMLORs", IsIdenticalObj, [ IsMatrixFLMLOR and IsLieAlgebra, IsMatrixFLMLOR and IsLieAlgebra ], 0, function( A1, A2 ) local b1, # Basis vectors of `A1'. b2, # Basis vectors of `A2'. p1, # Length of the matrices of `b1'. p2, # Length of the matrices of `b2'. B, # A basis of `A1 \oplus A2'. i, # Loop variable. Q, # A matrix. A; # result if LeftActingDomain( A1 ) <> LeftActingDomain( A2 ) then Error( "<A1> and <A2> must be written over the same domain" ); fi; # We do not really need a basis for the arguments # but if we have one then we use it. #T Do we really have so many algebra generators? (distinguish from basis?) if HasBasis( A1 ) and HasBasis( A2 ) then b1:= BasisVectors( Basis( A1 ) ); b2:= BasisVectors( Basis( A2 ) ); else b1:= GeneratorsOfAlgebra( A1 ); b2:= GeneratorsOfAlgebra( A2 ); fi; p1:= DimensionOfVectors( A1 )[1]; p2:= DimensionOfVectors( A2 )[1]; B:= []; for i in b1 do Q:= NullMat( p1+p2, p1+p2, LeftActingDomain( A1 ) ); Q{ [ 1 .. p1 ] }{ [ 1 .. p1 ] }:= i; Add( B, LieObject( Q ) ); od; for i in b2 do Q:= NullMat( p1+p2, p1+p2, LeftActingDomain( A1 ) ); Q{ [ p1+1 .. p1+p2 ] }{ [ p1+1 .. p1+p2 ] }:= i; Add( B, LieObject( Q ) ); od; A:= AlgebraByGenerators( LeftActingDomain( A1 ), B ); if HasBasis( A1 ) and HasBasis( A2 ) then UseBasis( A, B ); fi; SetIsLieAlgebra( A, true ); return A; end ); ############################################################################# ## #M Units( <A> ) . . . . . . for a full matrix algebra (over a finite field) ## InstallMethod( Units, "for a full matrix algebra (over a finite field)", [ IsAlgebra and IsFullMatrixModule and IsFFECollCollColl ], function( A ) local F; F:= LeftActingDomain( A ); if IsField( F ) and IsFinite( F ) then return GL( DimensionOfVectors( A )[1], Size( F ) ); else TryNextMethod(); fi; end ); ############################################################################# ## #F EmptyMatrix( <char> ) ## InstallGlobalFunction( EmptyMatrix, function( char ) local Fam, mat; # Get the right family. if char = 0 then Fam:= CollectionsFamily( CollectionsFamily( CyclotomicsFamily ) ); else Fam:= CollectionsFamily( CollectionsFamily( FFEFamily( char ) ) ); fi; # Construct the matrix. mat:= Objectify( NewType( Fam, IsList and IsEmpty and IsOrdinaryMatrix and IsZero and IsAssociativeElement and IsCommutativeElement and IsJacobianElement and IsAttributeStoringRep ), rec() ); SetName( mat, Concatenation( "EmptyMatrix( ", String( char ), " )" ) ); SetInverse( mat, mat ); SetAdditiveInverse( mat, mat ); SetDimensionsMat( mat, [ 0, 0 ] ); SetLength( mat, 0 ); return mat; end ); InstallMethod( \+, "for two empty matrices", IsIdenticalObj, [ IsMatrix and IsEmpty, IsMatrix and IsEmpty ], 0, function( m1, m2 ) return m1; end ); InstallOtherMethod( \*, "for two empty matrices", IsIdenticalObj, [ IsMatrix and IsEmpty, IsMatrix and IsEmpty ], 0, function( m1, m2 ) return m1; end ); InstallOtherMethod( \*, "for empty matrix, and empty list", true, [ IsMatrix and IsEmpty, IsList and IsEmpty ], 0, function( m1, m2 ) return []; end ); InstallOtherMethod( \*, "for empty list, and empty matrix", true, [ IsList and IsEmpty, IsMatrix and IsEmpty ], 0, function( m1, m2 ) return []; end ); InstallOtherMethod( \*, "for empty matrix, and ring element", true, [ IsMatrix and IsEmpty, IsRingElement ], 0, function( m, scalar ) return m; end ); InstallOtherMethod( \*, "for ring element, and empty matrix", true, [ IsRingElement, IsMatrix and IsEmpty ], 0, function( scalar, m ) return m; end ); InstallMethod( \^, "for empty matrix, and integer", true, [ IsMatrix and IsEmpty, IsInt ], 0, function( emptymat, n ) return emptymat; end ); ############################################################################# ## #M NullAlgebra( <R> ) . . . . . . . . . . . . . null algebra over ring <R> ## InstallMethod( NullAlgebra, "for a ring", true, [ IsRing ], 0, R -> FLMLORByGenerators( R, [], EmptyMatrix( Characteristic( R ) ) ) ); #T ############################################################################# #T ## #T #F Fingerprint( <A> ) . . . . . . . . . . . . . . fingerprint of algebra <A> #T #F Fingerprint( <A>, <list> ) . . . . . . . . . . fingerprint of algebra <A> #T ## #T ## If there is only one argument then the standard fingerprint is computed. #T ## This works for two-generator algebras acting only. #T ## #T Fingerprint := function( arg ) #T #T # Check the arguments. #T if Length( arg ) = 0 or Length( arg ) > 2 then #T Error( "usage: Fingerprint( <matalg> [, <list> ] )" ); #T fi; #T #T if Length( arg ) = 2 then #T #T return arg[1].operations.Fingerprint( arg[1], arg[2] ); #T #T elif Length( arg ) = 1 then #T #T if not IsBound( arg[1].fingerprint ) then #T arg[1].fingerprint:= #T arg[1].operations.Fingerprint( arg[1], "standard" ); #T fi; #T return arg[1].fingerprint; #T #T else #T Error( "number of generating matrices must be 2" ); #T fi; #T end; #T #T ############################################################################# #T ## #T #F Nullity( <mat> ) #T ## #T Nullity := function( mat ) #T return Dimensions( BaseNullspace( mat ) )[1]; #T end; #T #T ############################################################################# #T ## #T #F MatrixAssociativeAlgebraOps.Fingerprint( <A>, <list> ) #T ## #T MatrixAssociativeAlgebraOps.Fingerprint := function( A, list ) #T #T local fp, # fingerprint, result #T a, # first generator #T b, # second generator #T ab, # product of `a' and `b' #T word; # actual word #T #T if list = "standard" then #T #T if Length( AlgebraGenerators( A ) ) <> 2 then #T Error( "exactly two generators needed for standard finger print" ); #T fi; #T #T # Compute the nullities of the 6 standard elements. #T fp:= []; #T a:= AlgebraGenerators( A )[1]; #T b:= AlgebraGenerators( A )[2]; #T ab:= a * b; #T word:= ab + a + b; fp[1]:= Nullity( word ); #T word:= word + ab * b; fp[2]:= Nullity( word ); #T word:= a + b * word; fp[3]:= Nullity( word ); #T word:= b + word; fp[4]:= Nullity( word ); #T word:= ab + word; fp[5]:= Nullity( word ); #T word:= a + word; fp[6]:= Nullity( word ); #T #T else #T #T # Compute the nullities of the words with numbers in the list. #T fp:= List( list, x -> Nullity( ElementAlgebra( A, x ) ) ); #T #T fi; #T return fp; #T end; ############################################################################# ## #M RepresentativeLinearOperation( <A>, <v>, <w>, <opr> ) . . for matrix alg. ## ## Let <A> be a finite dimensional algebra over the ring $R$, ## and <v> and <w> vectors such that <A> acts on them via the *linear* ## operation <opr>. ## We compute an element of <A> that maps <v> to <w>. ## ## We compute the coefficients $a_i$ in the equation system ## $\sum_{i=1}^n a_i <opr>( <v>, b_i ) = <w>$, ## where $(b_1, b_2, \ldots, b_n)$ is a basis of <A>. ## ## For a tuple $(v_1, \ldots, v_k)$ of vectors we simply replace $v b_i$ by ## the concatenation of the $v_j b_i$ for all $j$, and replace $w$ by the ## concatenation $(w_1, \ldots, w_k)$, and solve this system. ## ## (Here we install methods for matrix algebras, acting on row vectors. ## There are also generic algebra methods for algebras acting on themselves ## or on their free modules via `OnRight' or `OnTuples'.) ## InstallMethod( RepresentativeLinearOperation, "for a matrix FLMLOR, two row vectors, and `OnRight'", IsCollCollsElmsElmsX, [ IsMatrixFLMLOR, IsRowVector, IsRowVector, IsFunction ], 0, function( A, v, w, opr ) local B, vectors, a; if not ( opr = OnRight or opr = OnPoints ) then TryNextMethod(); fi; if IsTrivial( A ) then if IsZero( w ) then return Zero( A ); else return fail; fi; fi; B:= Basis( A ); vectors:= BasisVectors( B ); # Compute the matrix of the equation system, # the coefficient vector $a$, \ldots a:= SolutionMat( List( vectors, x -> v * x ), w ); if a = fail then return fail; fi; # \ldots and the representative. return LinearCombination( B, a ); end ); InstallMethod( RepresentativeLinearOperation, "for a matrix FLMLOR, two lists of row vectors, and `OnTuples'", IsCollsElmsElmsX, [ IsFLMLOR, IsMatrix, IsMatrix, IsFunction ], 0, #T IsOrdinaryMatrix? function( A, vs, ws, opr ) local B, vectors, a; if not ( opr = OnTuples or opr = OnPairs ) then TryNextMethod(); fi; if IsTrivial( A ) then if IsZero( ws ) then return Zero( A ); else return fail; fi; fi; B:= Basis( A ); vectors:= BasisVectors( B ); # Compute the matrix of the equation system, # the coefficient vector $a$, \ldots a:= SolutionMat( List( vectors, x -> Concatenation( vs * x ) ), Concatenation( ws ) ); if a = fail then return fail; fi; # \ldots and the representative. return LinearCombination( B, a ); end ); ############################################################################# ## #M IsomorphismMatrixFLMLOR( <A> ) . . . . . . . . . . . for a matrix FLMLOR ## InstallMethod( IsomorphismMatrixFLMLOR, "for a matrix FLMLOR", true, [ IsMatrixFLMLOR ], 0, IdentityMapping ); #T ############################################################################# #T ## #T #F MatrixAssociativeAlgebraOps.NaturalModule( <A> ) #T ## #T MatrixAssociativeAlgebraOps.NaturalModule := function( A ) #T #T local gens, # module generators #T N; # natural module, result #T #T if Length( AlgebraGenerators( Parent( A ) ) ) = 0 then #T gens:= IdentityMat( A.field, Length( Zero( Parent( A ) ) ) ); #T else #T gens:= Parent( A ).algebraGenerators[1]^0; #T fi; #T #T wirklich Erzeuger angeben ? #T N:= Module( A, gens ); #T N.isNaturalModule:= true; #T N.spaceGenerators:= gens; #T return N; #T end; ############################################################################# ## #E