From 244f94d0775fba6ecd4bd6e99860455f9917429f Mon Sep 17 00:00:00 2001 From: cdwensley Date: Mon, 28 Sep 2026 10:01:49 +0100 Subject: [PATCH 01/19] added SetDirectSumInfo for algebras --- lib/algebra.gi | 11 ++++++++++- lib/algmat.gi | 10 ++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/algebra.gi b/lib/algebra.gi index 09c4e754f4..a64365408c 100644 --- a/lib/algebra.gi +++ b/lib/algebra.gi @@ -3072,8 +3072,12 @@ InstallOtherMethod( DirectSumOfAlgebras, T[n + 1] := 1; fi; - L:= AlgebraByStructureConstants( LeftActingDomain( A1 ), T ); +Print("here\n"); + SetDirectSumInfo( L, rec( algebras := [A1,A2], + first := A1, + embeddings := [], + projections := [] ) ); # Maintain useful information. if HasIsLieAlgebra( A1 ) and HasIsLieAlgebra( A2 ) @@ -3218,6 +3222,11 @@ InstallMethod( DirectSumOfAlgebras, A:= DirectSumOfAlgebras( A, list[i] ); od; + SetDirectSumInfo( A, rec( algebras := list, + first := list[1], + embeddings := [], + projections := [] ) ); + return A; end ); diff --git a/lib/algmat.gi b/lib/algmat.gi index 374f27ee02..137ef4152d 100644 --- a/lib/algmat.gi +++ b/lib/algmat.gi @@ -1372,6 +1372,11 @@ InstallOtherMethod( DirectSumOfAlgebras, SetIsAssociative( A, true ); #T nec. ? + SetDirectSumInfo( A, rec( algebras := [A1,A2], + first := A1, + embeddings := [], + projections := [] ) ); + return A; end ); @@ -1436,6 +1441,11 @@ InstallOtherMethod( DirectSumOfAlgebras, fi; SetIsLieAlgebra( A, true ); + SetDirectSumInfo( A, rec( algebras := [A1,A2], + first := A1, + embeddings := [], + projections := [] ) ); + return A; end ); From d50a0e03a48d6b321d853e100f82bce4a3018539 Mon Sep 17 00:00:00 2001 From: cdwensley Date: Mon, 28 Sep 2026 14:40:14 +0100 Subject: [PATCH 02/19] first attempt at embeddings --- lib/algebra.gi | 51 ++++++++++++++++++++++++++++++++++++++++++++------ lib/algmat.gi | 19 +++++++++++++++++-- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/lib/algebra.gi b/lib/algebra.gi index a64365408c..e7adfa0349 100644 --- a/lib/algebra.gi +++ b/lib/algebra.gi @@ -3073,9 +3073,10 @@ InstallOtherMethod( DirectSumOfAlgebras, fi; L:= AlgebraByStructureConstants( LeftActingDomain( A1 ), T ); -Print("here\n"); + SetDirectSumInfo( L, rec( algebras := [A1,A2], - first := A1, + first := [1,n1+1,n1+n2+1], + type := "basis vectors", embeddings := [], projections := [] ) ); @@ -3204,7 +3205,7 @@ InstallMethod( DirectSumOfAlgebras, "for list of algebras", [ IsDenseList ], function( list ) - local R, A, i; + local R, A, i, dim, first; if IsEmpty( list ) then Error( " must be nonempty" ); @@ -3218,19 +3219,57 @@ InstallMethod( DirectSumOfAlgebras, od; A:= list[1]; + first:= [ 1, Dimension( A ) + 1 ]; for i in [ 2 .. Length( list ) ] do + dim:= Dimension( list[i] ); + Add( first, first[i] + dim ); A:= DirectSumOfAlgebras( A, list[i] ); od; - SetDirectSumInfo( A, rec( algebras := list, - first := list[1], + first := first, + type := "basis vectors", embeddings := [], projections := [] ) ); - return A; end ); +############################################################################# +## +#A Embedding +## +InstallMethod( Embedding, "algebra direct sum and integer", + [ IsAlgebra and HasDirectSumInfo, IsPosInt ], + function( D, i ) + local info, type, first, A, imgs, map, gens; + + # check + info := DirectSumInfo( D ); + if IsBound( info.embeddings[i] ) then + return info.embeddings[i]; + fi; + type := info.type; + if not ( type = "basis vectors" ) then + Error( "type = generators not yet catered for" ); + fi; + + first := info.first; + if not ( i < Length(first) ) then + Error( "value of second parameter is too large" ); + fi; + info.onelist:=List(info.algebras,One); + # compute embedding + A := info.algebras[i]; + gens := BasisVectors( Basis( A ) ); + imgs := BasisVectors( Basis( D ) ){[first[i] .. first[i+1]-1]}; + map := AlgebraGeneralMappingByImages( A, D, gens, imgs ); + SetIsInjective( map, true ); + + # store information + info.embeddings[i] := map; + return map; +end ); + ############################################################################# ## #O IsCentral( , ) . . . . . . . . test if is centralized by diff --git a/lib/algmat.gi b/lib/algmat.gi index 137ef4152d..a0a01a8674 100644 --- a/lib/algmat.gi +++ b/lib/algmat.gi @@ -1326,7 +1326,10 @@ InstallOtherMethod( DirectSumOfAlgebras, function( A1, A2 ) local b1, # Basis vectors of `A1'. + d1, # Dimension of `A1'. b2, # Basis vectors of `A2'. + d2, # Dimension of `A2'. + type, # basis vectors or generators. p1, # Length of the matrices of `b1'. p2, # Length of the matrices of `b2'. B, # A basis of `A1 \oplus A2'. @@ -1344,11 +1347,15 @@ InstallOtherMethod( DirectSumOfAlgebras, if HasBasis( A1 ) and HasBasis( A2 ) then b1:= BasisVectors( Basis( A1 ) ); b2:= BasisVectors( Basis( A2 ) ); + type:= "basis vectors"; else b1:= GeneratorsOfAlgebra( A1 ); b2:= GeneratorsOfAlgebra( A2 ); + type:= "geberators"; fi; + d1:= Length( b1 ); + d2:= Length( b2 ); p1:= DimensionOfVectors( A1 )[1]; p2:= DimensionOfVectors( A2 )[1]; @@ -1373,7 +1380,8 @@ InstallOtherMethod( DirectSumOfAlgebras, #T nec. ? SetDirectSumInfo( A, rec( algebras := [A1,A2], - first := A1, + first := [1,d1+1,d1+d2+1], + type := type, embeddings := [], projections := [] ) ); @@ -1397,7 +1405,10 @@ InstallOtherMethod( DirectSumOfAlgebras, function( A1, A2 ) local b1, # Basis vectors of `A1'. + d1, # Dimension of `A1'. b2, # Basis vectors of `A2'. + d2, # Dimension of `A2'. + type, # basis vectors or generators. p1, # Length of the matrices of `b1'. p2, # Length of the matrices of `b2'. B, # A basis of `A1 \oplus A2'. @@ -1415,11 +1426,15 @@ InstallOtherMethod( DirectSumOfAlgebras, if HasBasis( A1 ) and HasBasis( A2 ) then b1:= BasisVectors( Basis( A1 ) ); b2:= BasisVectors( Basis( A2 ) ); + type:= "basis vectors"; else b1:= GeneratorsOfAlgebra( A1 ); b2:= GeneratorsOfAlgebra( A2 ); + type:= "generators"; fi; + d1:= Length( b1 ); + d2:= Length( b2 ); p1:= DimensionOfVectors( A1 )[1]; p2:= DimensionOfVectors( A2 )[1]; @@ -1442,7 +1457,7 @@ InstallOtherMethod( DirectSumOfAlgebras, SetIsLieAlgebra( A, true ); SetDirectSumInfo( A, rec( algebras := [A1,A2], - first := A1, + first := [1,d1+1,d1+d2+1], embeddings := [], projections := [] ) ); From 3c399943246ec2a91907c61120377df206a06261 Mon Sep 17 00:00:00 2001 From: cdwensley Date: Mon, 28 Sep 2026 19:00:17 +0100 Subject: [PATCH 03/19] first attempt at projections --- lib/algebra.gi | 64 ++++++++++++++++++++++++++++++++++++++++++++------ lib/algmat.gi | 2 +- 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/lib/algebra.gi b/lib/algebra.gi index e7adfa0349..0dae897db7 100644 --- a/lib/algebra.gi +++ b/lib/algebra.gi @@ -3076,7 +3076,7 @@ InstallOtherMethod( DirectSumOfAlgebras, SetDirectSumInfo( L, rec( algebras := [A1,A2], first := [1,n1+1,n1+n2+1], - type := "basis vectors", + type := "basis vectors", embeddings := [], projections := [] ) ); @@ -3249,10 +3249,6 @@ InstallMethod( Embedding, "algebra direct sum and integer", return info.embeddings[i]; fi; type := info.type; - if not ( type = "basis vectors" ) then - Error( "type = generators not yet catered for" ); - fi; - first := info.first; if not ( i < Length(first) ) then Error( "value of second parameter is too large" ); @@ -3260,8 +3256,15 @@ InstallMethod( Embedding, "algebra direct sum and integer", info.onelist:=List(info.algebras,One); # compute embedding A := info.algebras[i]; - gens := BasisVectors( Basis( A ) ); - imgs := BasisVectors( Basis( D ) ){[first[i] .. first[i+1]-1]}; + if ( type = "basis vectors" ) then + gens := BasisVectors( Basis( A ) ); + imgs := BasisVectors( Basis( D ) ){[first[i] .. first[i+1]-1]}; + elif ( type = "generators" ) then + gens := GeneratorsOfAlgebra( A ); + imgs := GeneratorsOfAlgebra( D ){[first[i] .. first[i+1]-1]}; + else + Error( "unknown type" ); + fi; map := AlgebraGeneralMappingByImages( A, D, gens, imgs ); SetIsInjective( map, true ); @@ -3270,6 +3273,53 @@ InstallMethod( Embedding, "algebra direct sum and integer", return map; end ); +############################################################################# +## +#A Projection +## +InstallMethod( Projection, "algebra direct sum and integer", + [ IsAlgebra and HasDirectSumInfo, IsPosInt ], + function( D, i ) + local info, type, first, len, A, genA, genD, imgs, map, N; + + # check + info := DirectSumInfo( D ); + if IsBound( info.projections[i] ) then + return info.projections[i]; + fi; + type := info.type; + first := info.first; + len := Length( first ); + if not ( i < len ) then + Error( "value of second parameter is too large" ); + fi; + # compute projection + A := info.algebras[i]; + if ( type = "basis vectors" ) then + genA := BasisVectors( Basis( A ) ); + genD := BasisVectors( Basis( D ) ); + elif ( type = "generators" ) then + genA := GeneratorsOfAlgebra( A ); + genD := GeneratorsOfAlgebra( D ); + else + Error( "unknown type" ); + fi; + imgs := Concatenation( + List( [1..first[i]-1], x -> One(A) ), + genA, + List( [first[i+1]..first[len]-1], x -> One(A) ) ); + map := AlgebraGeneralMappingByImages( D, A, genD, imgs ); + + N := Subalgebra( D, genD{Concatenation( [1..first[i]-1], + [first[i+1]..first[len]-1] )} ); + SetIsSurjective( map, true ); + SetKernelOfMultiplicativeGeneralMapping( map, N ); + + # store information + info.projections[i] := map; + return map; +end ); + ############################################################################# ## #O IsCentral( , ) . . . . . . . . test if is centralized by diff --git a/lib/algmat.gi b/lib/algmat.gi index a0a01a8674..c9d7eb89a3 100644 --- a/lib/algmat.gi +++ b/lib/algmat.gi @@ -1351,7 +1351,7 @@ InstallOtherMethod( DirectSumOfAlgebras, else b1:= GeneratorsOfAlgebra( A1 ); b2:= GeneratorsOfAlgebra( A2 ); - type:= "geberators"; + type:= "generators"; fi; d1:= Length( b1 ); From 5b3c968282310b645f4cdb4658b77b094e50a903 Mon Sep 17 00:00:00 2001 From: cdwensley Date: Wed, 30 Sep 2026 19:37:15 +0100 Subject: [PATCH 04/19] added test file tst/testextra/alg-dsum.tst --- lib/algebra.gi | 105 +++++++++++++++++++++++++++--------- lib/algmat.gi | 94 +++++++++++++++++++++++++------- tst/testextra/alg-dsum.tst | 107 +++++++++++++++++++++++++++++++++++++ 3 files changed, 264 insertions(+), 42 deletions(-) create mode 100644 tst/testextra/alg-dsum.tst diff --git a/lib/algebra.gi b/lib/algebra.gi index 0dae897db7..e7f66406b3 100644 --- a/lib/algebra.gi +++ b/lib/algebra.gi @@ -3018,27 +3018,50 @@ InstallOtherMethod( DirectSumOfAlgebras, "for two algebras", [ IsAlgebra, IsAlgebra ], function( A1, A2 ) - local n, # The dimension of the resulting algebra. + local n1, # The dimension of A1. + n2, # The dimension of A2. + n, # The dimension of the resulting algebra. i,j, # Loop variables. T, # The table of structure constants of the direct sum. - scT, # - n1, # The dimension of A1. - n2, # The dimension of A2. - ll, # A list of structure constants. + scT,ll,# A list of structure constants. L, # result. - sym, # if both products are (anti)symmetric, then the result - # will have the same property. + sym, # if both products are (anti)symmetric, + # then the result will have the same property. R1,R2, # Root systems of A1,A2. f1,f2, # Embeddings of A1,A2 in L. R, # Root system of L. RV, # List of various things. r, - pos; # List of positions. + pos, # List of positions. + info1, # direct sum info for A1 if it exists. + info2, # direct sum info for A2 if it exists. + alg, # list of component algebras. + first; # positions where bases start in the full basis if LeftActingDomain( A1 ) <> LeftActingDomain( A2 ) then Error( " and must be written over the same field" ); fi; + # this method constructs a direct sum of type "basis vectors" + # if it should so happen that one of A1,A2 is already a direct sum + # of type "generators" then we reconstruct it using "basis vectors" + if HasDirectSumInfo( A1 ) and DirectSumInfo( A1 ).type = "generators" then + info1 := DirectSumInfo( A1 ); + L := A2; + for i in [1..Length( info1.algebras )] do + L := DirectSumOfAlgebras( L, info1.algebras[i] ); + od; + return L; + fi; + if HasDirectSumInfo( A2 ) and DirectSumInfo( A2 ).type = "generators" then + info2 := DirectSumInfo( A2 ); + L := A1; + for i in [1..Length( info2.algebras )] do + L := DirectSumOfAlgebras( L, info2.algebras[i] ); + od; + return L; + fi; + n1:= Dimension( A1 ); n2:= Dimension( A2 ); n:= n1+n2; @@ -3074,8 +3097,35 @@ InstallOtherMethod( DirectSumOfAlgebras, L:= AlgebraByStructureConstants( LeftActingDomain( A1 ), T ); - SetDirectSumInfo( L, rec( algebras := [A1,A2], - first := [1,n1+1,n1+n2+1], + # if one of A1,A2 is already a direct sum then make adjustments + if HasDirectSumInfo( A1 ) then + info1 := DirectSumInfo( A1 ); + i := Length( info1.first ); + if HasDirectSumInfo( A2 ) then + info2 := DirectSumInfo( A2 ); + alg := Concatenation( info1.algebras, info2.algebras ); + first := ShallowCopy( info1.first ){[1..i-1]}; + j := info1.first[i] - 1; + first := Concatenation( first, info2.first + j ); + else + alg := Concatenation( info1.algebras, [A2] ); + first := ShallowCopy( info1.first ); + Add( first, first[i] + n2 ); + fi; + elif HasDirectSumInfo( A2 ) then + info2 := DirectSumInfo( A2 ); + alg := Concatenation( [A1], info2.algebras ); + first := ShallowCopy( info2.first ); + first := Concatenation( [1], first + n1 ); + else + alg := [A1,A2]; + first := [1,n1+1,n1+n2+1]; + fi; + + + + SetDirectSumInfo( L, rec( algebras := alg, + first := first, type := "basis vectors", embeddings := [], projections := [] ) ); @@ -3265,8 +3315,10 @@ InstallMethod( Embedding, "algebra direct sum and integer", else Error( "unknown type" ); fi; - map := AlgebraGeneralMappingByImages( A, D, gens, imgs ); + map := AlgebraHomomorphismByImages( A, D, gens, imgs ); SetIsInjective( map, true ); + SetIsTotal( map, true ); + SetIsSingleValued( map, true ); # store information info.embeddings[i] := map; @@ -3280,21 +3332,22 @@ end ); InstallMethod( Projection, "algebra direct sum and integer", [ IsAlgebra and HasDirectSumInfo, IsPosInt ], function( D, i ) - local info, type, first, len, A, genA, genD, imgs, map, N; + local infoD, type, first, oneA, len, A, genA, genD, imgs, j, k, map, N; # check - info := DirectSumInfo( D ); - if IsBound( info.projections[i] ) then - return info.projections[i]; + infoD := DirectSumInfo( D ); + if IsBound( infoD.projections[i] ) then + return infoD.projections[i]; fi; - type := info.type; - first := info.first; + type := infoD.type; + first := infoD.first; len := Length( first ); if not ( i < len ) then Error( "value of second parameter is too large" ); fi; # compute projection - A := info.algebras[i]; + A := infoD.algebras[i]; + oneA := One( A ); if ( type = "basis vectors" ) then genA := BasisVectors( Basis( A ) ); genD := BasisVectors( Basis( D ) ); @@ -3304,19 +3357,23 @@ InstallMethod( Projection, "algebra direct sum and integer", else Error( "unknown type" ); fi; - imgs := Concatenation( - List( [1..first[i]-1], x -> One(A) ), - genA, - List( [first[i+1]..first[len]-1], x -> One(A) ) ); + imgs := ListWithIdenticalEntries( first[len]-1, oneA ); + j := first[i] - 1; + for k in [first[i]..first[i+1]-1] do + imgs[k] := genA[k-j]; + od; map := AlgebraGeneralMappingByImages( D, A, genD, imgs ); + if not IsTotal( map ) and IsSurjective( map ) then + Error( "map is not total and surjective" ); + fi; N := Subalgebra( D, genD{Concatenation( [1..first[i]-1], [first[i+1]..first[len]-1] )} ); - SetIsSurjective( map, true ); +## SetIsSurjective( map, true ); SetKernelOfMultiplicativeGeneralMapping( map, N ); # store information - info.projections[i] := map; + infoD.projections[i] := map; return map; end ); diff --git a/lib/algmat.gi b/lib/algmat.gi index c9d7eb89a3..f8c52d7e87 100644 --- a/lib/algmat.gi +++ b/lib/algmat.gi @@ -1333,9 +1333,13 @@ InstallOtherMethod( DirectSumOfAlgebras, p1, # Length of the matrices of `b1'. p2, # Length of the matrices of `b2'. B, # A basis of `A1 \oplus A2'. - i, # Loop variable. + i,j, # Loop variables. Q, # A matrix. - A; # result + A, # result + info1, # direct sum info for A1 if it exists. + info2, # direct sum info for A2 if it exists. + alg, # list of component algebras. + first; # positions where bases start in the full basis. if LeftActingDomain( A1 ) <> LeftActingDomain( A2 ) then Error( " and must be written over the same domain" ); @@ -1379,8 +1383,33 @@ InstallOtherMethod( DirectSumOfAlgebras, SetIsAssociative( A, true ); #T nec. ? - SetDirectSumInfo( A, rec( algebras := [A1,A2], - first := [1,d1+1,d1+d2+1], + # if one of A1,A2 is already a direct sum then make adjustments + if HasDirectSumInfo( A1 ) then + info1 := DirectSumInfo( A1 ); + i := Length( info1.first ); + if HasDirectSumInfo( A2 ) then + info2 := DirectSumInfo( A2 ); + alg := Concatenation( info1.algebras, info2.algebras ); + first := ShallowCopy( info1.first ){[1..i-1]}; + j := info1.first[i] - 1; + first := Concatenation( first, info2.first + j ); + else + alg := Concatenation( info1.algebras, [A2] ); + first := ShallowCopy( info1.first ); + Add( first, first[i] + d2 ); + fi; + elif HasDirectSumInfo( A2 ) then + info2 := DirectSumInfo( A2 ); + alg := Concatenation( [A1], info2.algebras ); + first := ShallowCopy( info2.first ); + first := Concatenation( [1], first + d1 ); + else + alg := [A1,A2]; + first := [1,d1+1,d1+d2+1]; + fi; + + SetDirectSumInfo( A, rec( algebras := alg, + first := first, type := type, embeddings := [], projections := [] ) ); @@ -1404,17 +1433,21 @@ InstallOtherMethod( DirectSumOfAlgebras, IsMatrixFLMLOR and IsLieAlgebra ], 0, function( A1, A2 ) - local b1, # Basis vectors of `A1'. - d1, # Dimension of `A1'. - b2, # Basis vectors of `A2'. - d2, # Dimension of `A2'. - type, # basis vectors or generators. - 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 + local b1, # Basis vectors of `A1'. + d1, # Dimension of `A1'. + b2, # Basis vectors of `A2'. + d2, # Dimension of `A2'. + type, # basis vectors or generators. + p1, # Length of the matrices of `b1'. + p2, # Length of the matrices of `b2'. + B, # A basis of `A1 \oplus A2'. + i,j, # Loop variables. + Q, # A matrix. + A, # result + info1, # direct sum info for A1 if it exists. + info2, # direct sum info for A2 if it exists. + alg, # list of component algebras. + first; # positions where bases start in the full basis. if LeftActingDomain( A1 ) <> LeftActingDomain( A2 ) then Error( " and must be written over the same domain" ); @@ -1456,11 +1489,36 @@ InstallOtherMethod( DirectSumOfAlgebras, fi; SetIsLieAlgebra( A, true ); - SetDirectSumInfo( A, rec( algebras := [A1,A2], - first := [1,d1+1,d1+d2+1], + # if one of A1,A2 is already a direct sum then make adjustments + if HasDirectSumInfo( A1 ) then + info1 := DirectSumInfo( A1 ); + i := Length( info1.first ); + if HasDirectSumInfo( A2 ) then + info2 := DirectSumInfo( A2 ); + alg := Concatenation( info1.algebras, info2.algebras ); + first := ShallowCopy( info1.first ){[1..i-1]}; + j := info1.first[i] - 1; + first := Concatenation( first, info2.first + j ); + else + alg := Concatenation( info1.algebras, [A2] ); + first := ShallowCopy( info1.first ); + Add( first, first[i] + d2 ); + fi; + elif HasDirectSumInfo( A2 ) then + info2 := DirectSumInfo( A2 ); + alg := Concatenation( [A1], info2.algebras ); + first := ShallowCopy( info2.first ); + first := Concatenation( [1], first + d1 ); + else + alg := [A1,A2]; + first := [1,d1+1,d1+d2+1]; + fi; + + SetDirectSumInfo( A, rec( algebras := alg, + first := first, + type := type, embeddings := [], projections := [] ) ); - return A; end ); diff --git a/tst/testextra/alg-dsum.tst b/tst/testextra/alg-dsum.tst new file mode 100644 index 0000000000..38f9133955 --- /dev/null +++ b/tst/testextra/alg-dsum.tst @@ -0,0 +1,107 @@ +gap> START_TEST("alg-dsum.tst"); +gap> # direct sums of type "basis vectors" +gap> genc5 := [ (5,6,7,8,9) ];; +gap> c5 := Group( genc5 );; +gap> SetName( c5, "c5" );; +gap> A5 := GroupRing( Rationals, c5 );; +gap> SetName( A5, "A5" );; +gap> embc5 := Embedding( c5, A5 );; +gap> BasisVectors( Basis( A5 ) ); +[ (1)*(), (1)*(5,6,7,8,9), (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), (1)*(5,9,8,7,6) ] +gap> gens3 := [ (1,2), (2,3) ];; +gap> s3 := Group( gens3 );; +gap> SetName( s3, "s3" );; +gap> A6 := GroupRing( Rationals, s3 );; +gap> SetName( A6, "A6" );; +gap> embs3 := Embedding( s3, A6 );; +gap> BasisVectors( Basis( A6 ) ); +[ (1)*(), (1)*(2,3), (1)*(1,2), (1)*(1,2,3), (1)*(1,3,2), (1)*(1,3) ] +gap> A56 := DirectSumOfAlgebras( A5, A6 );; +gap> info56 := DirectSumInfo( A56 ); +rec( algebras := [ A5, A6 ], embeddings := [ ], first := [ 1, 6, 12 ], + projections := [ ], type := "basis vectors" ) +gap> SetName( A56, "A56" ); +gap> A656 := DirectSumOfAlgebras( A6, A56 );; +gap> info656 := DirectSumInfo( A656 ); +rec( algebras := [ A6, A5, A6 ], embeddings := [ ], + first := [ 1, 7, 12, 18 ], projections := [ ], type := "basis vectors" ) +gap> A565 := DirectSumOfAlgebras( A56, A5 );; +gap> info565 := DirectSumInfo( A565 ); +rec( algebras := [ A5, A6, A5 ], embeddings := [ ], + first := [ 1, 6, 12, 17 ], projections := [ ], type := "basis vectors" ) +gap> A5656 := DirectSumOfAlgebras( A56, A56 );; +gap> info5656 := DirectSumInfo( A5656 ); +rec( algebras := [ A5, A6, A5, A6 ], embeddings := [ ], + first := [ 1, 6, 12, 17, 23 ], projections := [ ], type := "basis vectors" ) +gap> emb5 := Embedding( A56, 1 ); +[ (1)*(), (1)*(5,6,7,8,9), (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), (1)*(5,9,8,7,6) ] + -> [ v.1, v.2, v.3, v.4, v.5 ] +gap> g := ImageElm( embc5, (5,7,9,6,8) ); +(1)*(5,7,9,6,8) +gap> ImageElm( emb5, g ); +v.3 +gap> pro6 := Projection( A56, 2 ); +[ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8, v.9, v.10, v.11 ] -> +[ (1)*(), (1)*(), (1)*(), (1)*(), (1)*(), (1)*(), (1)*(2,3), (1)*(1,2), + (1)*(1,2,3), (1)*(1,3,2), (1)*(1,3) ] +gap> bas56 := BasisVectors( Basis( A56 ) ); +[ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8, v.9, v.10, v.11 ] +gap> ## ImageElm( pro6, bas56[9] ); + +gap> # direct sums of type "generators" +gap> m1 := [ [0,1,0,0], [0,0,1,0], [0,0,0,1], [1,0,0,0] ];; +gap> A1 := Algebra( Rationals, [m1] );; +gap> SetName( A1, "A1" );; +gap> GeneratorsOfAlgebra( A1 ); +[ [ [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ], [ 1, 0, 0, 0 ] ] ] +gap> m2 := [ [0,1,1], [0,0,1], [0,0,0] ];; +gap> m3 := [ [-1,0,0], [0,0,0], [0,0,-1] ];; +gap> m4 := [ [0,0,0], [1,0,0], [1,1,0] ];; +gap> A2 := Algebra( Rationals, [m2,m3,m4] );; +gap> SetName( A2, "A2" );; +gap> GeneratorsOfAlgebra( A2 ); +[ [ [ 0, 1, 1 ], [ 0, 0, 1 ], [ 0, 0, 0 ] ], + [ [ -1, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, -1 ] ], + [ [ 0, 0, 0 ], [ 1, 0, 0 ], [ 1, 1, 0 ] ] ] +gap> A12 := DirectSumOfAlgebras( A1, A2 );; +gap> info12 := DirectSumInfo( A12 ); +rec( algebras := [ A1, A2 ], embeddings := [ ], first := [ 1, 2, 5 ], + projections := [ ], type := "generators" ) +gap> SetName( A12, "A12" ); +gap> A212 := DirectSumOfAlgebras( A2, A12 );; +gap> info212 := DirectSumInfo( A212 ); +rec( algebras := [ A2, A1, A2 ], embeddings := [ ], first := [ 1, 4, 5, 8 ], + projections := [ ], type := "generators" ) +gap> A121 := DirectSumOfAlgebras( A12, A1 );; +gap> info121 := DirectSumInfo( A121 ); +rec( algebras := [ A1, A2, A1 ], embeddings := [ ], first := [ 1, 2, 5, 6 ], + projections := [ ], type := "generators" ) +gap> A1212 := DirectSumOfAlgebras( A12, A12 );; +gap> info1212 := DirectSumInfo( A1212 ); +rec( algebras := [ A1, A2, A1, A2 ], embeddings := [ ], + first := [ 1, 2, 5, 6, 9 ], projections := [ ], type := "generators" ) +gap> emb1 := Embedding( A12, 1 ); +[ [ [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ], [ 1, 0, 0, 0 ] ] ] -> +[ [ [ 0, 1, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0, 0 ], + [ 1, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ], + [ 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ] ] ] +gap> m1^3; +[ [ 0, 0, 0, 1 ], [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ] ] +gap> ImageElm( emb1, m1^3 ); +[ [ 0, 0, 0, 1, 0, 0, 0 ], [ 1, 0, 0, 0, 0, 0, 0 ], [ 0, 1, 0, 0, 0, 0, 0 ], + [ 0, 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ], + [ 0, 0, 0, 0, 0, 0, 0 ] ] +gap> pro2 := Projection( A12, 2 );; +gap> ## Print( "pro2 maps = ", m2*m4, " to: ", ImageElm( pro2, m2*m4 ), "\n" ); + +gap> # mix the two types together +gap> A5612 := DirectSumOfAlgebras( A56, A12 );; +gap> info5612 := DirectSumInfo( A5612 ); +rec( algebras := [ A5, A6, A1, A2 ], embeddings := [ ], + first := [ 1, 6, 12, 16, 25 ], projections := [ ], type := "basis vectors" ) +gap> A1256 := DirectSumOfAlgebras( A12, A56 );; +gap> info1256 := DirectSumInfo( A1256 ); +rec( algebras := [ A5, A6, A1, A2 ], embeddings := [ ], + first := [ 1, 6, 12, 16, 25 ], projections := [ ], type := "basis vectors" ) + +gap> STOP_TEST("alg-dsum.tst"); From 0c9634afb29df9327efe3e68526ce086d0089dc3 Mon Sep 17 00:00:00 2001 From: cdwensley Date: Thu, 1 Oct 2026 15:14:43 +0100 Subject: [PATCH 05/19] fixed problem with Projection --- lib/algebra.gd | 27 +++++++++++++++++++++++++++ lib/algebra.gi | 8 +++----- lib/algmat.gi | 4 ---- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/lib/algebra.gd b/lib/algebra.gd index d32539e7fd..88a9c72c6c 100644 --- a/lib/algebra.gd +++ b/lib/algebra.gd @@ -593,6 +593,33 @@ DeclareOperation( "ProductSpace", [ IsFreeLeftModule, IsFreeLeftModule ] ); DeclareOperation( "DirectSumOfAlgebras", [ IsDenseList ] ); +############################################################################# +## +#A DirectSumInfo( ) +## +## <#GAPDoc Label="DirectSumInfo:algebras"> +## +## +## +## +## From &GAP; 4.17.0 a direct sum of algebras comes equipped with +## an information record having fields algebras; first; +## type; embeddings and projections. +##

+## A2 := GroupRing( Rationals, Group( (1,2) ) );; SetName( A2, "A2" ); +## gap> A3 := GroupRing( Rationals, Group( (3,4,5) ) );; SetName( A3, "A3" ); +## gap> A23 := DirectSumOfAlgebras( A2, A3 );; +## gap> DirectSumInfo( A23 ); +## rec( algebras := [ A2, A3 ], embeddings := [ ], first := [ 1, 3, 6 ], +## projections := [ ], type := "basis vectors" ) +## ]]> +## +## +## <#/GAPDoc> + + ############################################################################# ## #F FullMatrixAlgebraCentralizer( , ) diff --git a/lib/algebra.gi b/lib/algebra.gi index e7f66406b3..9dae91dfd3 100644 --- a/lib/algebra.gi +++ b/lib/algebra.gi @@ -3012,8 +3012,6 @@ InstallMethod( GeneratorsOfLeftOperatorRingWithOne, ## Construct a s.c. algebra. ## (There are special methods for the sum of appropriate matrix algebras.) ## -#T embeddings/projections should be provided! -## InstallOtherMethod( DirectSumOfAlgebras, "for two algebras", [ IsAlgebra, IsAlgebra ], @@ -3332,7 +3330,7 @@ end ); InstallMethod( Projection, "algebra direct sum and integer", [ IsAlgebra and HasDirectSumInfo, IsPosInt ], function( D, i ) - local infoD, type, first, oneA, len, A, genA, genD, imgs, j, k, map, N; + local infoD, type, first, zA, len, A, genA, genD, imgs, j, k, map, N; # check infoD := DirectSumInfo( D ); @@ -3347,7 +3345,7 @@ InstallMethod( Projection, "algebra direct sum and integer", fi; # compute projection A := infoD.algebras[i]; - oneA := One( A ); + zA := Zero( A ); if ( type = "basis vectors" ) then genA := BasisVectors( Basis( A ) ); genD := BasisVectors( Basis( D ) ); @@ -3357,7 +3355,7 @@ InstallMethod( Projection, "algebra direct sum and integer", else Error( "unknown type" ); fi; - imgs := ListWithIdenticalEntries( first[len]-1, oneA ); + imgs := ListWithIdenticalEntries( first[len]-1, zA ); j := first[i] - 1; for k in [first[i]..first[i+1]-1] do imgs[k] := genA[k-j]; diff --git a/lib/algmat.gi b/lib/algmat.gi index f8c52d7e87..f0e6c270e0 100644 --- a/lib/algmat.gi +++ b/lib/algmat.gi @@ -1316,8 +1316,6 @@ end ); ## ## Construct an associative matrix FLMLOR. ## -#T embeddings/projections should be provided! -## InstallOtherMethod( DirectSumOfAlgebras, "for two associative matrix FLMLORs", IsIdenticalObj, @@ -1424,8 +1422,6 @@ InstallOtherMethod( DirectSumOfAlgebras, ## ## Construct a matrix Lie FLMLOR. ## -#T embeddings/projections should be provided! -## InstallOtherMethod( DirectSumOfAlgebras, "for two matrix Lie FLMLORs", IsIdenticalObj, From 69c7dc168118d974c30c41ce6769dd90b4e4df5b Mon Sep 17 00:00:00 2001 From: cdwensley Date: Thu, 1 Oct 2026 15:16:53 +0100 Subject: [PATCH 06/19] fixed problem with Projection --- doc/ref/algebra.xml | 1 + tst/testextra/alg-dsum.tst | 35 +++++++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/doc/ref/algebra.xml b/doc/ref/algebra.xml index 8f5a784182..081f45e88a 100644 --- a/doc/ref/algebra.xml +++ b/doc/ref/algebra.xml @@ -191,6 +191,7 @@ true <#Include Label="MutableBasisOfNonassociativeAlgebra"> <#Include Label="MutableBasisOfIdealInNonassociativeAlgebra"> <#Include Label="DirectSumOfAlgebras"> +<#Include Label="DirectSumInfo:algebras"> <#Include Label="FullMatrixAlgebraCentralizer"> <#Include Label="RadicalOfAlgebra"> <#Include Label="CentralIdempotentsOfAlgebra"> diff --git a/tst/testextra/alg-dsum.tst b/tst/testextra/alg-dsum.tst index 38f9133955..741d4fe6e2 100644 --- a/tst/testextra/alg-dsum.tst +++ b/tst/testextra/alg-dsum.tst @@ -42,12 +42,12 @@ gap> ImageElm( emb5, g ); v.3 gap> pro6 := Projection( A56, 2 ); [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8, v.9, v.10, v.11 ] -> -[ (1)*(), (1)*(), (1)*(), (1)*(), (1)*(), (1)*(), (1)*(2,3), (1)*(1,2), - (1)*(1,2,3), (1)*(1,3,2), (1)*(1,3) ] +[ of ..., of ..., of ..., of ..., of ..., + (1)*(), (1)*(2,3), (1)*(1,2), (1)*(1,2,3), (1)*(1,3,2), (1)*(1,3) ] gap> bas56 := BasisVectors( Basis( A56 ) ); [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8, v.9, v.10, v.11 ] -gap> ## ImageElm( pro6, bas56[9] ); - +gap> ImageElm( pro6, bas56[9] ); +(1)*(1,2,3) gap> # direct sums of type "generators" gap> m1 := [ [0,1,0,0], [0,0,1,0], [0,0,0,1], [1,0,0,0] ];; gap> A1 := Algebra( Rationals, [m1] );; @@ -92,8 +92,12 @@ gap> ImageElm( emb1, m1^3 ); [ 0, 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ] ] gap> pro2 := Projection( A12, 2 );; -gap> ## Print( "pro2 maps = ", m2*m4, " to: ", ImageElm( pro2, m2*m4 ), "\n" ); - +gap> m0 := GeneratorsOfAlgebra( A12 )[2]; +[ [ 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ], + [ 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 1, 1 ], [ 0, 0, 0, 0, 0, 0, 1 ], + [ 0, 0, 0, 0, 0, 0, 0 ] ] +gap> ImageElm( pro2, m0 ); +[ [ 0, 1, 1 ], [ 0, 0, 1 ], [ 0, 0, 0 ] ] gap> # mix the two types together gap> A5612 := DirectSumOfAlgebras( A56, A12 );; gap> info5612 := DirectSumInfo( A5612 ); @@ -104,4 +108,23 @@ gap> info1256 := DirectSumInfo( A1256 ); rec( algebras := [ A5, A6, A1, A2 ], embeddings := [ ], first := [ 1, 6, 12, 16, 25 ], projections := [ ], type := "basis vectors" ) +gap> ## Lie algebra example +gap> L := FullMatrixLieAlgebra( Rationals, 2 ); + +gap> SetName( L, "L" ); +gap> L2 := DirectSumOfAlgebras( L, L ); + +gap> DirectSumInfo(L2); +rec( algebras := [ L, L ], embeddings := [ ], first := [ 1, 4, 7 ], + projections := [ ], type := "generators" ) +gap> Embedding( L2, 1 ); +[ LieObject( [ [ 1, 0 ], [ 0, 0 ] ] ), LieObject( [ [ 0, 1 ], [ 0, 0 ] ] ), + LieObject( [ [ 0, 0 ], [ 1, 0 ] ] ) ] -> +[ LieObject( [ [ 1, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] + ] ), + LieObject( [ [ 0, 1, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] + ] ), + LieObject( [ [ 0, 0, 0, 0 ], [ 1, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] + ] ) ] + gap> STOP_TEST("alg-dsum.tst"); From 1f6860d8e83b381bdda9b5b1714f1fdcf2f7bb5a Mon Sep 17 00:00:00 2001 From: cdwensley Date: Thu, 1 Oct 2026 16:32:55 +0100 Subject: [PATCH 07/19] added some documentation --- doc/ref/algebra.xml | 2 + lib/algebra.gd | 89 +++++++++++++++++++++++++++++++++++++++++---- lib/algebra.gi | 2 +- 3 files changed, 85 insertions(+), 8 deletions(-) diff --git a/doc/ref/algebra.xml b/doc/ref/algebra.xml index 081f45e88a..980887f057 100644 --- a/doc/ref/algebra.xml +++ b/doc/ref/algebra.xml @@ -192,6 +192,8 @@ true <#Include Label="MutableBasisOfIdealInNonassociativeAlgebra"> <#Include Label="DirectSumOfAlgebras"> <#Include Label="DirectSumInfo:algebras"> +<#Include Label="Embedding:algebras"> +<#Include Label="Projection:algebras"> <#Include Label="FullMatrixAlgebraCentralizer"> <#Include Label="RadicalOfAlgebra"> <#Include Label="CentralIdempotentsOfAlgebra"> diff --git a/lib/algebra.gd b/lib/algebra.gd index 88a9c72c6c..ce782747eb 100644 --- a/lib/algebra.gd +++ b/lib/algebra.gd @@ -567,8 +567,8 @@ DeclareOperation( "ProductSpace", [ IsFreeLeftModule, IsFreeLeftModule ] ); ## Label="for a list of algebras"/> ## ## -## is the direct sum of the two algebras A1 and A2 -## respectively of the algebras in the list list. +## This is the direct sum of the two algebras A1 and A2 +## or of the algebras in the list list. ##

## If all involved algebras are associative algebras then the result is also ## known to be associative. @@ -607,12 +607,24 @@ DeclareOperation( "DirectSumOfAlgebras", [ IsDenseList ] ); ## an information record having fields algebras; first; ## type; embeddings and projections. ##

+## In the example the dimensions of A3 and A5 are 3 +## and 5, so field first has value [1,1+3,1+3+5], +## showing where the basis vectors of each component start in the basis +## of A35. +##

+## The field type is either "basis vectors" or +## "generators", depending on how the algebras are formed. +##

+## As embeddings and projections are created (see below) +## they are stored in the fields embeddings and projections. +##

## A2 := GroupRing( Rationals, Group( (1,2) ) );; SetName( A2, "A2" ); -## gap> A3 := GroupRing( Rationals, Group( (3,4,5) ) );; SetName( A3, "A3" ); -## gap> A23 := DirectSumOfAlgebras( A2, A3 );; -## gap> DirectSumInfo( A23 ); -## rec( algebras := [ A2, A3 ], embeddings := [ ], first := [ 1, 3, 6 ], +## gap> A3 := GroupRing( Rationals, c3 );; SetName( A3, "A3" ); +## gap> c5 := Group( (5,6,7,8,9) );; SetName( c5, "c5" ); +## gap> A5 := GroupRing( Rationals, c5 );; SetName( A5, "A5" ); +## gap> A35 := DirectSumOfAlgebras( A3, A5 );; +## gap> DirectSumInfo( A35 ); +## rec( algebras := [ A3, A5 ], embeddings := [ ], first := [ 1, 4, 9 ], ## projections := [ ], type := "basis vectors" ) ## ]]> ## @@ -620,6 +632,69 @@ DeclareOperation( "DirectSumOfAlgebras", [ IsDenseList ] ); ## <#/GAPDoc> +############################################################################# +## +#A Embedding( ) +## +## <#GAPDoc Label="Embedding:algebras"> +## +## +## +## +## If algebra A is the direct sum of algebras [A_1,\ldots,A_k] +## then Embedding(A,i) for 1 \leq i \leq k returns an algebra +## homomorphism mapping A_i into A. +##

+## emb1 := Embedding( A35, 1 ); +## [ (1)*(), (1)*(1,2,3), (1)*(1,3,2) ] -> [ v.1, v.2, v.3 ] +## gap> ec3 := Embedding( c3, A3 );; +## gap> ( (1,3,2)^ec3 )^emb1; +## v.3 +## ]]> +## +## +## <#/GAPDoc> + + +############################################################################# +## +#A Projection( ) +## +## <#GAPDoc Label="Projection:algebras"> +## +## +## +## +## If algebra A is the direct sum of algebras [A_1,\ldots,A_k] +## then Projection(A,i) for 1 \leq i \leq k returns an algebra +## homomorphism mapping A onto A_i. +##

+## pro1 := Projection( A35, 1 ); +## [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8 ] -> +## [ (1)*(), (1)*(1,2,3), (1)*(1,3,2), of ..., of ..., +## of ..., of ..., of ... ] +## gap> DirectSumInfo( A35 ); +## rec( algebras := [ A3, A5 ], +## embeddings := +## [ , +## [ (1)*(), (1)*(5,6,7,8,9), (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), +## (1)*(5,9,8,7,6) ] -> [ v.4, v.5, v.6, v.7, v.8 ] ], +## first := [ 1, 4, 9 ], onelist := [ (1)*(), (1)*() ], +## projections := +## [ [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8 ] -> +## [ (1)*(), (1)*(1,2,3), (1)*(1,3,2), of ..., of ..., +## of ..., of ..., of ... ] ], +## type := "basis vectors" ) +## ]]> +## +## +## <#/GAPDoc> + + ############################################################################# ## #F FullMatrixAlgebraCentralizer( , ) diff --git a/lib/algebra.gi b/lib/algebra.gi index 9dae91dfd3..f83f218930 100644 --- a/lib/algebra.gi +++ b/lib/algebra.gi @@ -3301,7 +3301,7 @@ InstallMethod( Embedding, "algebra direct sum and integer", if not ( i < Length(first) ) then Error( "value of second parameter is too large" ); fi; - info.onelist:=List(info.algebras,One); + ## info.onelist:=List(info.algebras,One); # compute embedding A := info.algebras[i]; if ( type = "basis vectors" ) then From 19afbf1e16788d429bf6c0bf364b573152ded644 Mon Sep 17 00:00:00 2001 From: cdwensley Date: Thu, 1 Oct 2026 22:06:09 +0100 Subject: [PATCH 08/19] added missing line in example --- lib/algebra.gd | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/lib/algebra.gd b/lib/algebra.gd index ce782747eb..4d5045d4c8 100644 --- a/lib/algebra.gd +++ b/lib/algebra.gd @@ -619,12 +619,13 @@ DeclareOperation( "DirectSumOfAlgebras", [ IsDenseList ] ); ## they are stored in the fields embeddings and projections. ##

## c3 := Group( (1,2,3) );; SetName( c3, "c3" ); ## gap> A3 := GroupRing( Rationals, c3 );; SetName( A3, "A3" ); -## gap> c5 := Group( (5,6,7,8,9) );; SetName( c5, "c5" ); +## gap> c5 := Group( (5,6,7,8,9) );; SetName( c5, "c5" ); ## gap> A5 := GroupRing( Rationals, c5 );; SetName( A5, "A5" ); -## gap> A35 := DirectSumOfAlgebras( A3, A5 );; -## gap> DirectSumInfo( A35 ); -## rec( algebras := [ A3, A5 ], embeddings := [ ], first := [ 1, 4, 9 ], +## gap> A35 := DirectSumOfAlgebras( A3, A5 );; +## gap> DirectSumInfo( A35 ); +## rec( algebras := [ A3, A5 ], embeddings := [ ], first := [ 1, 4, 9 ], ## projections := [ ], type := "basis vectors" ) ## ]]> ## @@ -673,21 +674,21 @@ DeclareOperation( "DirectSumOfAlgebras", [ IsDenseList ] ); ## homomorphism mapping A onto A_i. ##

## pro1 := Projection( A35, 1 ); -## [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8 ] -> -## [ (1)*(), (1)*(1,2,3), (1)*(1,3,2), of ..., of ..., +## gap> pro1 := Projection( A35, 1 ); +## [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8 ] -> +## [ (1)*(), (1)*(1,2,3), (1)*(1,3,2), of ..., of ..., ## of ..., of ..., of ... ] -## gap> DirectSumInfo( A35 ); -## rec( algebras := [ A3, A5 ], -## embeddings := -## [ , -## [ (1)*(), (1)*(5,6,7,8,9), (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), -## (1)*(5,9,8,7,6) ] -> [ v.4, v.5, v.6, v.7, v.8 ] ], -## first := [ 1, 4, 9 ], onelist := [ (1)*(), (1)*() ], -## projections := -## [ [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8 ] -> -## [ (1)*(), (1)*(1,2,3), (1)*(1,3,2), of ..., of ..., -## of ..., of ..., of ... ] ], +## gap> DirectSumInfo( A35 ); +## rec( algebras := [ A3, A5 ], +## embeddings := +## [ , +## [ (1)*(), (1)*(5,6,7,8,9), (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), +## (1)*(5,9,8,7,6) ] -> [ v.4, v.5, v.6, v.7, v.8 ] ], +## first := [ 1, 4, 9 ], onelist := [ (1)*(), (1)*() ], +## projections := +## [ [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8 ] -> +## [ (1)*(), (1)*(1,2,3), (1)*(1,3,2), of ..., of ..., +## of ..., of ..., of ... ] ], ## type := "basis vectors" ) ## ]]> ## From 133f0d27caa60db24584dd9782b7430278a462ff Mon Sep 17 00:00:00 2001 From: cdwensley Date: Fri, 2 Oct 2026 18:01:00 +0100 Subject: [PATCH 09/19] now starting info.first at 0, not 1 --- lib/algebra.gd | 50 ++++++++++++++++++-------------------- lib/algebra.gi | 26 +++++++++----------- lib/algmat.gi | 13 +++++----- lib/ringsc.gd | 25 +++++++++++++++++++ lib/ringsc.gi | 1 - tst/testextra/alg-dsum.tst | 22 ++++++++--------- 6 files changed, 77 insertions(+), 60 deletions(-) diff --git a/lib/algebra.gd b/lib/algebra.gd index 4d5045d4c8..0023b71b88 100644 --- a/lib/algebra.gd +++ b/lib/algebra.gd @@ -582,9 +582,12 @@ DeclareOperation( "ProductSpace", [ IsFreeLeftModule, IsFreeLeftModule ] ); ## algebras or both are associative then the result is again a ## matrix algebra of the appropriate type. ## A:= QuaternionAlgebra( Rationals );; -## gap> DirectSumOfAlgebras( [A, A, A] ); -## +## gap> c3 := Group( (1,2,3) );; SetName( c3, "c3" ); +## gap> A3 := GroupRing( Rationals, c3 );; SetName( A3, "A3" ); +## gap> c5 := Group( (5,6,7,8,9) );; SetName( c5, "c5" ); +## gap> A5 := GroupRing( Rationals, c5 );; SetName( A5, "A5" ); +## gap> A35 := DirectSumOfAlgebras( A3, A5 ); +## ## ]]> ## ## @@ -603,13 +606,16 @@ DeclareOperation( "DirectSumOfAlgebras", [ IsDenseList ] ); ## Label="for a direct sum of algebras"/> ## ## -## From &GAP; 4.17.0 a direct sum of algebras comes equipped with -## an information record having fields algebras; first; +## The operation DirectSum () is defined for +## rings and comes with the attribute DirctSumInfo +## () which is an information record. +## From &GAP; 4.17.0 a direct sum of algebras is equipped with +## a similar record, having fields algebras; first; ## type; embeddings and projections. ##

## In the example the dimensions of A3 and A5 are 3 -## and 5, so field first has value [1,1+3,1+3+5], -## showing where the basis vectors of each component start in the basis +## and 5, so field first has value [0,3,3+5], +## showing where the basis vectors of each component finish in the basis ## of A35. ##

## The field type is either "basis vectors" or @@ -619,13 +625,8 @@ DeclareOperation( "DirectSumOfAlgebras", [ IsDenseList ] ); ## they are stored in the fields embeddings and projections. ##

## c3 := Group( (1,2,3) );; SetName( c3, "c3" ); -## gap> A3 := GroupRing( Rationals, c3 );; SetName( A3, "A3" ); -## gap> c5 := Group( (5,6,7,8,9) );; SetName( c5, "c5" ); -## gap> A5 := GroupRing( Rationals, c5 );; SetName( A5, "A5" ); -## gap> A35 := DirectSumOfAlgebras( A3, A5 );; ## gap> DirectSumInfo( A35 ); -## rec( algebras := [ A3, A5 ], embeddings := [ ], first := [ 1, 4, 9 ], +## rec( algebras := [ A3, A5 ], embeddings := [ ], first := [ 0, 3, 8 ], ## projections := [ ], type := "basis vectors" ) ## ]]> ## @@ -674,22 +675,19 @@ DeclareOperation( "DirectSumOfAlgebras", [ IsDenseList ] ); ## homomorphism mapping A onto A_i. ##

## pro1 := Projection( A35, 1 ); -## [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8 ] -> -## [ (1)*(), (1)*(1,2,3), (1)*(1,3,2), of ..., of ..., -## of ..., of ..., of ... ] +## gap> pro2 := Projection( A35, 2 ); +## [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8 ] -> [ of ..., of ..., +## of ..., (1)*(), (1)*(5,6,7,8,9), (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), +## (1)*(5,9,8,7,6) ] ## gap> DirectSumInfo( A35 ); ## rec( algebras := [ A3, A5 ], -## embeddings := -## [ , -## [ (1)*(), (1)*(5,6,7,8,9), (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), -## (1)*(5,9,8,7,6) ] -> [ v.4, v.5, v.6, v.7, v.8 ] ], -## first := [ 1, 4, 9 ], onelist := [ (1)*(), (1)*() ], +## embeddings := [ [ (1)*(), (1)*(1,2,3), (1)*(1,3,2) ] -> [ v.1, v.2, v.3 ] ], +## first := [ 0, 3, 8 ], ## projections := -## [ [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8 ] -> -## [ (1)*(), (1)*(1,2,3), (1)*(1,3,2), of ..., of ..., -## of ..., of ..., of ... ] ], -## type := "basis vectors" ) +## [ , [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8 ] -> +## [ of ..., of ..., of ..., (1)*(), +## (1)*(5,6,7,8,9), (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), (1)*(5,9,8,7,6) +## ] ], type := "basis vectors" ) ## ]]> ## ## diff --git a/lib/algebra.gi b/lib/algebra.gi index f83f218930..de666deef5 100644 --- a/lib/algebra.gi +++ b/lib/algebra.gi @@ -3083,7 +3083,6 @@ InstallOtherMethod( DirectSumOfAlgebras, od; od; - # Set the (anti)symmetric flag if scT[n2 + 1] = sym then T[n + 1] := sym; @@ -3103,7 +3102,7 @@ InstallOtherMethod( DirectSumOfAlgebras, info2 := DirectSumInfo( A2 ); alg := Concatenation( info1.algebras, info2.algebras ); first := ShallowCopy( info1.first ){[1..i-1]}; - j := info1.first[i] - 1; + j := info1.first[i]; first := Concatenation( first, info2.first + j ); else alg := Concatenation( info1.algebras, [A2] ); @@ -3114,14 +3113,11 @@ InstallOtherMethod( DirectSumOfAlgebras, info2 := DirectSumInfo( A2 ); alg := Concatenation( [A1], info2.algebras ); first := ShallowCopy( info2.first ); - first := Concatenation( [1], first + n1 ); + first := Concatenation( [0], first + n1 ); else alg := [A1,A2]; - first := [1,n1+1,n1+n2+1]; + first := [0,n1,n1+n2]; fi; - - - SetDirectSumInfo( L, rec( algebras := alg, first := first, type := "basis vectors", @@ -3267,7 +3263,7 @@ InstallMethod( DirectSumOfAlgebras, od; A:= list[1]; - first:= [ 1, Dimension( A ) + 1 ]; + first:= [ 0, Dimension( A ) ]; for i in [ 2 .. Length( list ) ] do dim:= Dimension( list[i] ); Add( first, first[i] + dim ); @@ -3306,10 +3302,10 @@ InstallMethod( Embedding, "algebra direct sum and integer", A := info.algebras[i]; if ( type = "basis vectors" ) then gens := BasisVectors( Basis( A ) ); - imgs := BasisVectors( Basis( D ) ){[first[i] .. first[i+1]-1]}; + imgs := BasisVectors( Basis( D ) ){[first[i]+1 .. first[i+1]]}; elif ( type = "generators" ) then gens := GeneratorsOfAlgebra( A ); - imgs := GeneratorsOfAlgebra( D ){[first[i] .. first[i+1]-1]}; + imgs := GeneratorsOfAlgebra( D ){[first[i]+1 .. first[i+1]]}; else Error( "unknown type" ); fi; @@ -3344,7 +3340,7 @@ InstallMethod( Projection, "algebra direct sum and integer", Error( "value of second parameter is too large" ); fi; # compute projection - A := infoD.algebras[i]; + A := infoD.algebras[i]; zA := Zero( A ); if ( type = "basis vectors" ) then genA := BasisVectors( Basis( A ) ); @@ -3356,8 +3352,8 @@ InstallMethod( Projection, "algebra direct sum and integer", Error( "unknown type" ); fi; imgs := ListWithIdenticalEntries( first[len]-1, zA ); - j := first[i] - 1; - for k in [first[i]..first[i+1]-1] do + j := first[i]; + for k in [first[i]+1..first[i+1]] do imgs[k] := genA[k-j]; od; map := AlgebraGeneralMappingByImages( D, A, genD, imgs ); @@ -3365,8 +3361,8 @@ InstallMethod( Projection, "algebra direct sum and integer", Error( "map is not total and surjective" ); fi; - N := Subalgebra( D, genD{Concatenation( [1..first[i]-1], - [first[i+1]..first[len]-1] )} ); + N := Subalgebra( D, genD{Concatenation( [1..first[i]], + [first[i+1]+1..first[len]] )} ); ## SetIsSurjective( map, true ); SetKernelOfMultiplicativeGeneralMapping( map, N ); diff --git a/lib/algmat.gi b/lib/algmat.gi index f0e6c270e0..2bbee9d3f6 100644 --- a/lib/algmat.gi +++ b/lib/algmat.gi @@ -1389,7 +1389,7 @@ InstallOtherMethod( DirectSumOfAlgebras, info2 := DirectSumInfo( A2 ); alg := Concatenation( info1.algebras, info2.algebras ); first := ShallowCopy( info1.first ){[1..i-1]}; - j := info1.first[i] - 1; + j := info1.first[i]; first := Concatenation( first, info2.first + j ); else alg := Concatenation( info1.algebras, [A2] ); @@ -1400,12 +1400,11 @@ InstallOtherMethod( DirectSumOfAlgebras, info2 := DirectSumInfo( A2 ); alg := Concatenation( [A1], info2.algebras ); first := ShallowCopy( info2.first ); - first := Concatenation( [1], first + d1 ); + first := Concatenation( [0], first + d1 ); else alg := [A1,A2]; - first := [1,d1+1,d1+d2+1]; + first := [0,d1,d1+d2]; fi; - SetDirectSumInfo( A, rec( algebras := alg, first := first, type := type, @@ -1493,7 +1492,7 @@ InstallOtherMethod( DirectSumOfAlgebras, info2 := DirectSumInfo( A2 ); alg := Concatenation( info1.algebras, info2.algebras ); first := ShallowCopy( info1.first ){[1..i-1]}; - j := info1.first[i] - 1; + j := info1.first[i]; first := Concatenation( first, info2.first + j ); else alg := Concatenation( info1.algebras, [A2] ); @@ -1504,10 +1503,10 @@ InstallOtherMethod( DirectSumOfAlgebras, info2 := DirectSumInfo( A2 ); alg := Concatenation( [A1], info2.algebras ); first := ShallowCopy( info2.first ); - first := Concatenation( [1], first + d1 ); + first := Concatenation( [0], first + d1 ); else alg := [A1,A2]; - first := [1,d1+1,d1+d2+1]; + first := [0,d1,d1+d2]; fi; SetDirectSumInfo( A, rec( algebras := alg, diff --git a/lib/ringsc.gd b/lib/ringsc.gd index 0a3660e480..e614ec0f0e 100644 --- a/lib/ringsc.gd +++ b/lib/ringsc.gd @@ -207,6 +207,31 @@ DeclareGlobalFunction("SmallRing"); ## DeclareGlobalFunction( "DirectSum" ); DeclareOperation( "DirectSumOp", [ IsList, IsRing ] ); + +############################################################################# +## +#A DirectSumInfo( ) +## +## <#GAPDoc Label="DirectSumInfo:rings"> +## +## +## +## +## A direct sum of rings comes equipped with an information record +## having fields rings; first; +## embeddings and projections. +##

+## As embeddings and projections are created (see below) +## they are stored in the fields embeddings and projections. +##

+## DirectSumInfo( R57 ); +## rec( embeddings := [ ], first := [ 0, 1, 2 ], projections := [ ], +## rings := [ R5, R7 ] ) +## ]]> +## +## +## <#/GAPDoc> DeclareAttribute( "DirectSumInfo", IsRing, "mutable" ); ############################################################################# diff --git a/lib/ringsc.gi b/lib/ringsc.gi index 42c82b2f28..05f9881b49 100644 --- a/lib/ringsc.gi +++ b/lib/ringsc.gi @@ -1232,7 +1232,6 @@ InstallMethod( Embedding, "ring direct sum and integer", imgs := GeneratorsOfRing( D ){[first[i]+1 .. first[i+1]]}; map := RingHomomorphismByImages( R, D, gens, imgs ); SetIsInjective( map, true ); - # store information info.embeddings[i] := map; return map; diff --git a/tst/testextra/alg-dsum.tst b/tst/testextra/alg-dsum.tst index 741d4fe6e2..b32a6d5715 100644 --- a/tst/testextra/alg-dsum.tst +++ b/tst/testextra/alg-dsum.tst @@ -18,21 +18,21 @@ gap> BasisVectors( Basis( A6 ) ); [ (1)*(), (1)*(2,3), (1)*(1,2), (1)*(1,2,3), (1)*(1,3,2), (1)*(1,3) ] gap> A56 := DirectSumOfAlgebras( A5, A6 );; gap> info56 := DirectSumInfo( A56 ); -rec( algebras := [ A5, A6 ], embeddings := [ ], first := [ 1, 6, 12 ], +rec( algebras := [ A5, A6 ], embeddings := [ ], first := [ 0, 5, 11 ], projections := [ ], type := "basis vectors" ) gap> SetName( A56, "A56" ); gap> A656 := DirectSumOfAlgebras( A6, A56 );; gap> info656 := DirectSumInfo( A656 ); rec( algebras := [ A6, A5, A6 ], embeddings := [ ], - first := [ 1, 7, 12, 18 ], projections := [ ], type := "basis vectors" ) + first := [ 0, 6, 11, 17 ], projections := [ ], type := "basis vectors" ) gap> A565 := DirectSumOfAlgebras( A56, A5 );; gap> info565 := DirectSumInfo( A565 ); rec( algebras := [ A5, A6, A5 ], embeddings := [ ], - first := [ 1, 6, 12, 17 ], projections := [ ], type := "basis vectors" ) + first := [ 0, 5, 11, 16 ], projections := [ ], type := "basis vectors" ) gap> A5656 := DirectSumOfAlgebras( A56, A56 );; gap> info5656 := DirectSumInfo( A5656 ); rec( algebras := [ A5, A6, A5, A6 ], embeddings := [ ], - first := [ 1, 6, 12, 17, 23 ], projections := [ ], type := "basis vectors" ) + first := [ 0, 5, 11, 16, 22 ], projections := [ ], type := "basis vectors" ) gap> emb5 := Embedding( A56, 1 ); [ (1)*(), (1)*(5,6,7,8,9), (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), (1)*(5,9,8,7,6) ] -> [ v.1, v.2, v.3, v.4, v.5 ] @@ -65,21 +65,21 @@ gap> GeneratorsOfAlgebra( A2 ); [ [ 0, 0, 0 ], [ 1, 0, 0 ], [ 1, 1, 0 ] ] ] gap> A12 := DirectSumOfAlgebras( A1, A2 );; gap> info12 := DirectSumInfo( A12 ); -rec( algebras := [ A1, A2 ], embeddings := [ ], first := [ 1, 2, 5 ], +rec( algebras := [ A1, A2 ], embeddings := [ ], first := [ 0, 1, 4 ], projections := [ ], type := "generators" ) gap> SetName( A12, "A12" ); gap> A212 := DirectSumOfAlgebras( A2, A12 );; gap> info212 := DirectSumInfo( A212 ); -rec( algebras := [ A2, A1, A2 ], embeddings := [ ], first := [ 1, 4, 5, 8 ], +rec( algebras := [ A2, A1, A2 ], embeddings := [ ], first := [ 0, 3, 4, 7 ], projections := [ ], type := "generators" ) gap> A121 := DirectSumOfAlgebras( A12, A1 );; gap> info121 := DirectSumInfo( A121 ); -rec( algebras := [ A1, A2, A1 ], embeddings := [ ], first := [ 1, 2, 5, 6 ], +rec( algebras := [ A1, A2, A1 ], embeddings := [ ], first := [ 0, 1, 4, 5 ], projections := [ ], type := "generators" ) gap> A1212 := DirectSumOfAlgebras( A12, A12 );; gap> info1212 := DirectSumInfo( A1212 ); rec( algebras := [ A1, A2, A1, A2 ], embeddings := [ ], - first := [ 1, 2, 5, 6, 9 ], projections := [ ], type := "generators" ) + first := [ 0, 1, 4, 5, 8 ], projections := [ ], type := "generators" ) gap> emb1 := Embedding( A12, 1 ); [ [ [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ], [ 1, 0, 0, 0 ] ] ] -> [ [ [ 0, 1, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0, 0 ], @@ -102,11 +102,11 @@ gap> # mix the two types together gap> A5612 := DirectSumOfAlgebras( A56, A12 );; gap> info5612 := DirectSumInfo( A5612 ); rec( algebras := [ A5, A6, A1, A2 ], embeddings := [ ], - first := [ 1, 6, 12, 16, 25 ], projections := [ ], type := "basis vectors" ) + first := [ 0, 5, 11, 15, 24 ], projections := [ ], type := "basis vectors" ) gap> A1256 := DirectSumOfAlgebras( A12, A56 );; gap> info1256 := DirectSumInfo( A1256 ); rec( algebras := [ A5, A6, A1, A2 ], embeddings := [ ], - first := [ 1, 6, 12, 16, 25 ], projections := [ ], type := "basis vectors" ) + first := [ 0, 5, 11, 15, 24 ], projections := [ ], type := "basis vectors" ) gap> ## Lie algebra example gap> L := FullMatrixLieAlgebra( Rationals, 2 ); @@ -115,7 +115,7 @@ gap> SetName( L, "L" ); gap> L2 := DirectSumOfAlgebras( L, L ); gap> DirectSumInfo(L2); -rec( algebras := [ L, L ], embeddings := [ ], first := [ 1, 4, 7 ], +rec( algebras := [ L, L ], embeddings := [ ], first := [ 0, 3, 6 ], projections := [ ], type := "generators" ) gap> Embedding( L2, 1 ); [ LieObject( [ [ 1, 0 ], [ 0, 0 ] ] ), LieObject( [ [ 0, 1 ], [ 0, 0 ] ] ), From c9a235a59955af02d0ae7c1d0621066a7cf1573b Mon Sep 17 00:00:00 2001 From: cdwensley Date: Fri, 2 Oct 2026 18:09:07 +0100 Subject: [PATCH 10/19] trying to push after a rebase --- tst/testextra/alg-dsum.tst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tst/testextra/alg-dsum.tst b/tst/testextra/alg-dsum.tst index b32a6d5715..dac633eff7 100644 --- a/tst/testextra/alg-dsum.tst +++ b/tst/testextra/alg-dsum.tst @@ -99,6 +99,9 @@ gap> m0 := GeneratorsOfAlgebra( A12 )[2]; gap> ImageElm( pro2, m0 ); [ [ 0, 1, 1 ], [ 0, 0, 1 ], [ 0, 0, 0 ] ] gap> # mix the two types together +gap> # A56 has type "basis vectors" and A12 has type "generators" +gap> # so both A5612 and A1256 have type "basis vectors" +gap> # and both are ordered [ A5, AS6, A12, A2 ] with the generators last. gap> A5612 := DirectSumOfAlgebras( A56, A12 );; gap> info5612 := DirectSumInfo( A5612 ); rec( algebras := [ A5, A6, A1, A2 ], embeddings := [ ], From d5d819c34ff863f9284dbc82e5d864b165f336e3 Mon Sep 17 00:00:00 2001 From: cdwensley Date: Fri, 2 Oct 2026 18:19:17 +0100 Subject: [PATCH 11/19] fixed errors reported by lint --- lib/algebra.gd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/algebra.gd b/lib/algebra.gd index 0023b71b88..c6d93efb55 100644 --- a/lib/algebra.gd +++ b/lib/algebra.gd @@ -686,7 +686,7 @@ DeclareOperation( "DirectSumOfAlgebras", [ IsDenseList ] ); ## projections := ## [ , [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8 ] -> ## [ of ..., of ..., of ..., (1)*(), -## (1)*(5,6,7,8,9), (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), (1)*(5,9,8,7,6) +## (1)*(5,6,7,8,9), (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), (1)*(5,9,8,7,6) ## ] ], type := "basis vectors" ) ## ]]> ## From 4b869ce865f087c0c9f71c242e3460f14b114824 Mon Sep 17 00:00:00 2001 From: cdwensley Date: Tue, 6 Oct 2026 20:13:39 +0100 Subject: [PATCH 12/19] revert lib/ringsc.*, changes to be moved to another PR --- doc/ref/rings.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/ref/rings.xml b/doc/ref/rings.xml index a0af13c815..4c58a042b4 100644 --- a/doc/ref/rings.xml +++ b/doc/ref/rings.xml @@ -194,7 +194,6 @@ see . <#Include Label="Projection:rings"> <#Include Label="RingByStructureConstants"> - From 17b6924f48fb19aa1f44787fc5b05b53e8887011 Mon Sep 17 00:00:00 2001 From: cdwensley Date: Wed, 7 Oct 2026 19:42:23 +0100 Subject: [PATCH 13/19] moved the test file; removed flattening; etc. --- doc/ref/algebra.xml | 1 - lib/algebra.gd | 47 --------- lib/algebra.gi | 61 ++---------- lib/algmat.gi | 31 +----- tst/{testextra => testinstall}/alg-dsum.tst | 103 ++++++++++++++------ 5 files changed, 81 insertions(+), 162 deletions(-) rename tst/{testextra => testinstall}/alg-dsum.tst (53%) diff --git a/doc/ref/algebra.xml b/doc/ref/algebra.xml index 980887f057..a3abc0d7c4 100644 --- a/doc/ref/algebra.xml +++ b/doc/ref/algebra.xml @@ -191,7 +191,6 @@ true <#Include Label="MutableBasisOfNonassociativeAlgebra"> <#Include Label="MutableBasisOfIdealInNonassociativeAlgebra"> <#Include Label="DirectSumOfAlgebras"> -<#Include Label="DirectSumInfo:algebras"> <#Include Label="Embedding:algebras"> <#Include Label="Projection:algebras"> <#Include Label="FullMatrixAlgebraCentralizer"> diff --git a/lib/algebra.gd b/lib/algebra.gd index c6d93efb55..6437b0bbee 100644 --- a/lib/algebra.gd +++ b/lib/algebra.gd @@ -596,44 +596,6 @@ DeclareOperation( "ProductSpace", [ IsFreeLeftModule, IsFreeLeftModule ] ); DeclareOperation( "DirectSumOfAlgebras", [ IsDenseList ] ); -############################################################################# -## -#A DirectSumInfo( ) -## -## <#GAPDoc Label="DirectSumInfo:algebras"> -## -## -## -## -## The operation DirectSum () is defined for -## rings and comes with the attribute DirctSumInfo -## () which is an information record. -## From &GAP; 4.17.0 a direct sum of algebras is equipped with -## a similar record, having fields algebras; first; -## type; embeddings and projections. -##

-## In the example the dimensions of A3 and A5 are 3 -## and 5, so field first has value [0,3,3+5], -## showing where the basis vectors of each component finish in the basis -## of A35. -##

-## The field type is either "basis vectors" or -## "generators", depending on how the algebras are formed. -##

-## As embeddings and projections are created (see below) -## they are stored in the fields embeddings and projections. -##

-## DirectSumInfo( A35 ); -## rec( algebras := [ A3, A5 ], embeddings := [ ], first := [ 0, 3, 8 ], -## projections := [ ], type := "basis vectors" ) -## ]]> -## -## -## <#/GAPDoc> - - ############################################################################# ## #A Embedding( ) @@ -679,15 +641,6 @@ DeclareOperation( "DirectSumOfAlgebras", [ IsDenseList ] ); ## [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8 ] -> [ of ..., of ..., ## of ..., (1)*(), (1)*(5,6,7,8,9), (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), ## (1)*(5,9,8,7,6) ] -## gap> DirectSumInfo( A35 ); -## rec( algebras := [ A3, A5 ], -## embeddings := [ [ (1)*(), (1)*(1,2,3), (1)*(1,3,2) ] -> [ v.1, v.2, v.3 ] ], -## first := [ 0, 3, 8 ], -## projections := -## [ , [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8 ] -> -## [ of ..., of ..., of ..., (1)*(), -## (1)*(5,6,7,8,9), (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), (1)*(5,9,8,7,6) -## ] ], type := "basis vectors" ) ## ]]> ## ## diff --git a/lib/algebra.gi b/lib/algebra.gi index de666deef5..aeffb910af 100644 --- a/lib/algebra.gi +++ b/lib/algebra.gi @@ -3032,34 +3032,12 @@ InstallOtherMethod( DirectSumOfAlgebras, r, pos, # List of positions. info1, # direct sum info for A1 if it exists. - info2, # direct sum info for A2 if it exists. - alg, # list of component algebras. - first; # positions where bases start in the full basis + info2; # direct sum info for A2 if it exists. if LeftActingDomain( A1 ) <> LeftActingDomain( A2 ) then Error( " and must be written over the same field" ); fi; - # this method constructs a direct sum of type "basis vectors" - # if it should so happen that one of A1,A2 is already a direct sum - # of type "generators" then we reconstruct it using "basis vectors" - if HasDirectSumInfo( A1 ) and DirectSumInfo( A1 ).type = "generators" then - info1 := DirectSumInfo( A1 ); - L := A2; - for i in [1..Length( info1.algebras )] do - L := DirectSumOfAlgebras( L, info1.algebras[i] ); - od; - return L; - fi; - if HasDirectSumInfo( A2 ) and DirectSumInfo( A2 ).type = "generators" then - info2 := DirectSumInfo( A2 ); - L := A1; - for i in [1..Length( info2.algebras )] do - L := DirectSumOfAlgebras( L, info2.algebras[i] ); - od; - return L; - fi; - n1:= Dimension( A1 ); n2:= Dimension( A2 ); n:= n1+n2; @@ -3094,32 +3072,8 @@ InstallOtherMethod( DirectSumOfAlgebras, L:= AlgebraByStructureConstants( LeftActingDomain( A1 ), T ); - # if one of A1,A2 is already a direct sum then make adjustments - if HasDirectSumInfo( A1 ) then - info1 := DirectSumInfo( A1 ); - i := Length( info1.first ); - if HasDirectSumInfo( A2 ) then - info2 := DirectSumInfo( A2 ); - alg := Concatenation( info1.algebras, info2.algebras ); - first := ShallowCopy( info1.first ){[1..i-1]}; - j := info1.first[i]; - first := Concatenation( first, info2.first + j ); - else - alg := Concatenation( info1.algebras, [A2] ); - first := ShallowCopy( info1.first ); - Add( first, first[i] + n2 ); - fi; - elif HasDirectSumInfo( A2 ) then - info2 := DirectSumInfo( A2 ); - alg := Concatenation( [A1], info2.algebras ); - first := ShallowCopy( info2.first ); - first := Concatenation( [0], first + n1 ); - else - alg := [A1,A2]; - first := [0,n1,n1+n2]; - fi; - SetDirectSumInfo( L, rec( algebras := alg, - first := first, + SetDirectSumInfo( L, rec( algebras := [A1,A2], + first := [0,n1,n1+n2], type := "basis vectors", embeddings := [], projections := [] ) ); @@ -3351,15 +3305,12 @@ InstallMethod( Projection, "algebra direct sum and integer", else Error( "unknown type" ); fi; - imgs := ListWithIdenticalEntries( first[len]-1, zA ); + imgs := ListWithIdenticalEntries( first[len], zA ); j := first[i]; - for k in [first[i]+1..first[i+1]] do + for k in [j+1..first[i+1]] do imgs[k] := genA[k-j]; od; - map := AlgebraGeneralMappingByImages( D, A, genD, imgs ); - if not IsTotal( map ) and IsSurjective( map ) then - Error( "map is not total and surjective" ); - fi; + map := AlgebraHomomorphismByImages( D, A, genD, imgs ); N := Subalgebra( D, genD{Concatenation( [1..first[i]], [first[i+1]+1..first[len]] )} ); diff --git a/lib/algmat.gi b/lib/algmat.gi index 2bbee9d3f6..a0a932b3f4 100644 --- a/lib/algmat.gi +++ b/lib/algmat.gi @@ -1379,38 +1379,11 @@ InstallOtherMethod( DirectSumOfAlgebras, fi; SetIsAssociative( A, true ); -#T nec. ? - - # if one of A1,A2 is already a direct sum then make adjustments - if HasDirectSumInfo( A1 ) then - info1 := DirectSumInfo( A1 ); - i := Length( info1.first ); - if HasDirectSumInfo( A2 ) then - info2 := DirectSumInfo( A2 ); - alg := Concatenation( info1.algebras, info2.algebras ); - first := ShallowCopy( info1.first ){[1..i-1]}; - j := info1.first[i]; - first := Concatenation( first, info2.first + j ); - else - alg := Concatenation( info1.algebras, [A2] ); - first := ShallowCopy( info1.first ); - Add( first, first[i] + d2 ); - fi; - elif HasDirectSumInfo( A2 ) then - info2 := DirectSumInfo( A2 ); - alg := Concatenation( [A1], info2.algebras ); - first := ShallowCopy( info2.first ); - first := Concatenation( [0], first + d1 ); - else - alg := [A1,A2]; - first := [0,d1,d1+d2]; - fi; - SetDirectSumInfo( A, rec( algebras := alg, - first := first, + SetDirectSumInfo( A, rec( algebras := [A1,A2], + first := [0,d1,d1+d2], type := type, embeddings := [], projections := [] ) ); - return A; end ); diff --git a/tst/testextra/alg-dsum.tst b/tst/testinstall/alg-dsum.tst similarity index 53% rename from tst/testextra/alg-dsum.tst rename to tst/testinstall/alg-dsum.tst index dac633eff7..7fd344258d 100644 --- a/tst/testextra/alg-dsum.tst +++ b/tst/testinstall/alg-dsum.tst @@ -21,18 +21,6 @@ gap> info56 := DirectSumInfo( A56 ); rec( algebras := [ A5, A6 ], embeddings := [ ], first := [ 0, 5, 11 ], projections := [ ], type := "basis vectors" ) gap> SetName( A56, "A56" ); -gap> A656 := DirectSumOfAlgebras( A6, A56 );; -gap> info656 := DirectSumInfo( A656 ); -rec( algebras := [ A6, A5, A6 ], embeddings := [ ], - first := [ 0, 6, 11, 17 ], projections := [ ], type := "basis vectors" ) -gap> A565 := DirectSumOfAlgebras( A56, A5 );; -gap> info565 := DirectSumInfo( A565 ); -rec( algebras := [ A5, A6, A5 ], embeddings := [ ], - first := [ 0, 5, 11, 16 ], projections := [ ], type := "basis vectors" ) -gap> A5656 := DirectSumOfAlgebras( A56, A56 );; -gap> info5656 := DirectSumInfo( A5656 ); -rec( algebras := [ A5, A6, A5, A6 ], embeddings := [ ], - first := [ 0, 5, 11, 16, 22 ], projections := [ ], type := "basis vectors" ) gap> emb5 := Embedding( A56, 1 ); [ (1)*(), (1)*(5,6,7,8,9), (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), (1)*(5,9,8,7,6) ] -> [ v.1, v.2, v.3, v.4, v.5 ] @@ -68,18 +56,6 @@ gap> info12 := DirectSumInfo( A12 ); rec( algebras := [ A1, A2 ], embeddings := [ ], first := [ 0, 1, 4 ], projections := [ ], type := "generators" ) gap> SetName( A12, "A12" ); -gap> A212 := DirectSumOfAlgebras( A2, A12 );; -gap> info212 := DirectSumInfo( A212 ); -rec( algebras := [ A2, A1, A2 ], embeddings := [ ], first := [ 0, 3, 4, 7 ], - projections := [ ], type := "generators" ) -gap> A121 := DirectSumOfAlgebras( A12, A1 );; -gap> info121 := DirectSumInfo( A121 ); -rec( algebras := [ A1, A2, A1 ], embeddings := [ ], first := [ 0, 1, 4, 5 ], - projections := [ ], type := "generators" ) -gap> A1212 := DirectSumOfAlgebras( A12, A12 );; -gap> info1212 := DirectSumInfo( A1212 ); -rec( algebras := [ A1, A2, A1, A2 ], embeddings := [ ], - first := [ 0, 1, 4, 5, 8 ], projections := [ ], type := "generators" ) gap> emb1 := Embedding( A12, 1 ); [ [ [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ], [ 1, 0, 0, 0 ] ] ] -> [ [ [ 0, 1, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0, 0 ], @@ -104,12 +80,79 @@ gap> # so both A5612 and A1256 have type "basis vectors" gap> # and both are ordered [ A5, AS6, A12, A2 ] with the generators last. gap> A5612 := DirectSumOfAlgebras( A56, A12 );; gap> info5612 := DirectSumInfo( A5612 ); -rec( algebras := [ A5, A6, A1, A2 ], embeddings := [ ], - first := [ 0, 5, 11, 15, 24 ], projections := [ ], type := "basis vectors" ) -gap> A1256 := DirectSumOfAlgebras( A12, A56 );; -gap> info1256 := DirectSumInfo( A1256 ); -rec( algebras := [ A5, A6, A1, A2 ], embeddings := [ ], - first := [ 0, 5, 11, 15, 24 ], projections := [ ], type := "basis vectors" ) +rec( algebras := [ A56, A12 ], embeddings := [ ], first := [ 0, 11, 24 ], + projections := [ ], type := "basis vectors" ) +gap> A51 := DirectSumOfAlgebras( A5, A1 );; +gap> info51 := DirectSumInfo( A51 ); +rec( algebras := [ A5, A1 ], embeddings := [ ], first := [ 0, 5, 9 ], + projections := [ ], type := "basis vectors" ) +gap> Embedding( A51, 2 ); +[ [ [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ], [ 1, 0, 0, 0 ] ], + [ [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ], [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ] ], + [ [ 0, 0, 0, 1 ], [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ] ], + [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ] ] -> +[ v.6, v.7, v.8, v.9 ] +gap> Embedding( A51, 1 ); +[ (1)*(), (1)*(5,6,7,8,9), (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), (1)*(5,9,8,7,6) + ] -> [ v.1, v.2, v.3, v.4, v.5 ] +gap> Projection( A51, 1 ); +[ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8, v.9 ] -> +[ (1)*(), (1)*(5,6,7,8,9), (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), (1)*(5,9,8,7,6), + of ..., of ..., of ..., of ... ] +gap> Projection( A51, 2 ); +[ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8, v.9 ] -> +[ [ [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] ], + [ [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ], [ 1, 0, 0, 0 ] ], + [ [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ], [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ] ], + [ [ 0, 0, 0, 1 ], [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ] ], + [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ] ] +gap> A26 := DirectSumOfAlgebras( A2, A6 );; +gap> Embedding( A26, 1 );; +gap> Embedding( A26, 2 );; +gap> Projection( A26, 1 );; +gap> Projection( A26, 2 );; +gap> info26 := DirectSumInfo( A26 ); +rec( algebras := [ A2, A6 ], + embeddings := + [ + [ [ [ 0, 1, 1 ], [ 0, 0, 1 ], [ 0, 0, 0 ] ], + [ [ 1, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 1 ] ], + [ [ 0, 0, 0 ], [ 1, 0, 0 ], [ 1, 1, 0 ] ], + [ [ 0, 0, 1 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ], + [ [ 0, 0, 0 ], [ 0, 0, 1 ], [ 0, 0, 0 ] ], + [ [ 0, 0, 0 ], [ 0, 1, 0 ], [ -1, -1, -2 ] ], + [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 1, 1, 0 ] ], + [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 1 ] ], + [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 1, 0 ] ] ] -> + [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8, v.9 ], + [ (1)*(), (1)*(2,3), (1)*(1,2), (1)*(1,2,3), (1)*(1,3,2), (1)*(1,3) + ] -> [ v.10, v.11, v.12, v.13, v.14, v.15 ] ], first := [ 0, 9, 15 ], + projections := + [ [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8, v.9, v.10, v.11, v.12, v.13, + v.14, v.15 ] -> [ [ [ 0, 1, 1 ], [ 0, 0, 1 ], [ 0, 0, 0 ] ], + [ [ 1, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 1 ] ], + [ [ 0, 0, 0 ], [ 1, 0, 0 ], [ 1, 1, 0 ] ], + [ [ 0, 0, 1 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ], + [ [ 0, 0, 0 ], [ 0, 0, 1 ], [ 0, 0, 0 ] ], + [ [ 0, 0, 0 ], [ 0, 1, 0 ], [ -1, -1, -2 ] ], + [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 1, 1, 0 ] ], + [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 1 ] ], + [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 1, 0 ] ], + [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ], + [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ], + [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ], + [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ], + [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ], + [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ] ], + [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8, v.9, v.10, v.11, v.12, v.13, + v.14, v.15 ] -> [ of ..., of ..., of ..., + of ..., of ..., of ..., of ..., + of ..., of ..., (1)*(), (1)*(2,3), (1)*(1,2), + (1)*(1,2,3), (1)*(1,3,2), (1)*(1,3) ] ], type := "basis vectors" ) gap> ## Lie algebra example gap> L := FullMatrixLieAlgebra( Rationals, 2 ); From 87085b3858716c23cf80e63e1120471697fef25a Mon Sep 17 00:00:00 2001 From: cdwensley Date: Wed, 7 Oct 2026 20:32:24 +0100 Subject: [PATCH 14/19] dealt with more of Max' suggestions --- lib/algebra.gd | 20 ++++++++++---------- lib/algebra.gi | 6 ++---- tst/testinstall/alg-dsum.tst | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/lib/algebra.gd b/lib/algebra.gd index 6437b0bbee..783ef5321b 100644 --- a/lib/algebra.gd +++ b/lib/algebra.gd @@ -598,17 +598,17 @@ DeclareOperation( "DirectSumOfAlgebras", [ IsDenseList ] ); ############################################################################# ## -#A Embedding( ) +#O Embedding( , ) ## ## <#GAPDoc Label="Embedding:algebras"> ## -## ## ## -## If algebra A is the direct sum of algebras [A_1,\ldots,A_k] -## then Embedding(A,i) for 1 \leq i \leq k returns an algebra -## homomorphism mapping A_i into A. +## If algebra A is the direct sum of algebras [A_1,\ldots,A_k] +## then Embedding(A,i) for 1 \leq i \leq k returns an algebra +## homomorphism mapping A_i into A. ##

## emb1 := Embedding( A35, 1 ); @@ -624,17 +624,17 @@ DeclareOperation( "DirectSumOfAlgebras", [ IsDenseList ] ); ############################################################################# ## -#A Projection( ) +#O Projection( , ) ## ## <#GAPDoc Label="Projection:algebras"> ## -## ## ## -## If algebra A is the direct sum of algebras [A_1,\ldots,A_k] -## then Projection(A,i) for 1 \leq i \leq k returns an algebra -## homomorphism mapping A onto A_i. +## If algebra A is the direct sum of algebras [A_1,\ldots,A_k] +## then Projection(A,i) for 1 \leq i \leq k returns an algebra +## homomorphism mapping A onto A_i. ##

## pro2 := Projection( A35, 2 ); diff --git a/lib/algebra.gi b/lib/algebra.gi index aeffb910af..5c8855955f 100644 --- a/lib/algebra.gi +++ b/lib/algebra.gi @@ -3251,7 +3251,6 @@ InstallMethod( Embedding, "algebra direct sum and integer", if not ( i < Length(first) ) then Error( "value of second parameter is too large" ); fi; - ## info.onelist:=List(info.algebras,One); # compute embedding A := info.algebras[i]; if ( type = "basis vectors" ) then @@ -3263,7 +3262,7 @@ InstallMethod( Embedding, "algebra direct sum and integer", else Error( "unknown type" ); fi; - map := AlgebraHomomorphismByImages( A, D, gens, imgs ); + map := AlgebraHomomorphismByImagesNC( A, D, gens, imgs ); SetIsInjective( map, true ); SetIsTotal( map, true ); SetIsSingleValued( map, true ); @@ -3310,11 +3309,10 @@ InstallMethod( Projection, "algebra direct sum and integer", for k in [j+1..first[i+1]] do imgs[k] := genA[k-j]; od; - map := AlgebraHomomorphismByImages( D, A, genD, imgs ); + map := AlgebraHomomorphismByImagesNC( D, A, genD, imgs ); N := Subalgebra( D, genD{Concatenation( [1..first[i]], [first[i+1]+1..first[len]] )} ); -## SetIsSurjective( map, true ); SetKernelOfMultiplicativeGeneralMapping( map, N ); # store information diff --git a/tst/testinstall/alg-dsum.tst b/tst/testinstall/alg-dsum.tst index 7fd344258d..aa27851fd8 100644 --- a/tst/testinstall/alg-dsum.tst +++ b/tst/testinstall/alg-dsum.tst @@ -153,6 +153,22 @@ rec( algebras := [ A2, A6 ], of ..., of ..., of ..., of ..., of ..., of ..., (1)*(), (1)*(2,3), (1)*(1,2), (1)*(1,2,3), (1)*(1,3,2), (1)*(1,3) ] ], type := "basis vectors" ) +gap> A1256 := DirectSumOfAlgebras( [ A1, A2, A5, A6 ] );; +gap> info1256 := DirectSumInfo( A1256 ); +rec( algebras := [ A1, A2, A5, A6 ], embeddings := [ ], + first := [ 0, 4, 13, 18, 24 ], projections := [ ], type := "basis vectors" ) +gap> e3 := Embedding( A1256, 3 ); +[ (1)*(), (1)*(5,6,7,8,9), (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), (1)*(5,9,8,7,6) ] -> [ v.14, v.15, v.16, v.17, v.18 ] +gap> p3 := Projection( A1256, 3 ); +[ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8, v.9, v.10, v.11, v.12, v.13, v.14, + v.15, v.16, v.17, v.18, v.19, v.20, v.21, v.22, v.23, v.24 ] -> +[ of ..., of ..., of ..., of ..., of ..., + of ..., of ..., of ..., of ..., of ..., + of ..., of ..., of ..., (1)*(), (1)*(5,6,7,8,9), + (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), (1)*(5,9,8,7,6), of ..., + of ..., of ..., of ..., of ..., of ... ] +gap> e3 * p3 = IdentityMapping( A5 ); +true gap> ## Lie algebra example gap> L := FullMatrixLieAlgebra( Rationals, 2 ); @@ -163,7 +179,7 @@ gap> L2 := DirectSumOfAlgebras( L, L ); gap> DirectSumInfo(L2); rec( algebras := [ L, L ], embeddings := [ ], first := [ 0, 3, 6 ], projections := [ ], type := "generators" ) -gap> Embedding( L2, 1 ); +gap> Embedding( L2, 1 ); [ LieObject( [ [ 1, 0 ], [ 0, 0 ] ] ), LieObject( [ [ 0, 1 ], [ 0, 0 ] ] ), LieObject( [ [ 0, 0 ], [ 1, 0 ] ] ) ] -> [ LieObject( [ [ 1, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] @@ -172,5 +188,21 @@ gap> Embedding( L2, 1 ); ] ), LieObject( [ [ 0, 0, 0, 0 ], [ 1, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] ] ) ] +gap> Projection( L2, 2 ); +[ LieObject( [ [ 1, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] + ] ), + LieObject( [ [ 0, 1, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] + ] ), + LieObject( [ [ 0, 0, 0, 0 ], [ 1, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] + ] ), + LieObject( [ [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 0 ] + ] ), + LieObject( [ [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 1 ], [ 0, 0, 0, 0 ] + ] ), + LieObject( [ [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 1, 0 ] + ] ) ] -> [ LieObject( [ [ 0, 0 ], [ 0, 0 ] ] ), + LieObject( [ [ 0, 0 ], [ 0, 0 ] ] ), LieObject( [ [ 0, 0 ], [ 0, 0 ] ] ), + LieObject( [ [ 1, 0 ], [ 0, 0 ] ] ), LieObject( [ [ 0, 1 ], [ 0, 0 ] ] ), + LieObject( [ [ 0, 0 ], [ 1, 0 ] ] ) ] gap> STOP_TEST("alg-dsum.tst"); From bd7aa77958d69e88536365e2a70d6360bbbce082 Mon Sep 17 00:00:00 2001 From: cdwensley Date: Thu, 8 Oct 2026 16:21:11 +0100 Subject: [PATCH 15/19] adjusted the DirectSum method nin algmat.gi --- lib/algebra.gi | 22 ++++++++++++++++++---- lib/algmat.gi | 13 +++++++------ tst/testinstall/alg-dsum.tst | 23 +++++------------------ 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/lib/algebra.gi b/lib/algebra.gi index 5c8855955f..779be1ef6b 100644 --- a/lib/algebra.gi +++ b/lib/algebra.gi @@ -3203,7 +3203,7 @@ InstallMethod( DirectSumOfAlgebras, "for list of algebras", [ IsDenseList ], function( list ) - local R, A, i, dim, first; + local R, A, i, dim, type, first; if IsEmpty( list ) then Error( " must be nonempty" ); @@ -3216,16 +3216,30 @@ InstallMethod( DirectSumOfAlgebras, fi; od; + if ForAll( list, A -> IsMatrixFLMLOR( A ) and IsAssociative( A ) ) then + type := "generators"; + else + type := "basis vectors"; + fi; + A:= list[1]; - first:= [ 0, Dimension( A ) ]; + if ( type = "generators" ) then + first := [ 0, Length( GeneratorsOfAlgebra( A ) ) ]; + else + first:= [ 0, Dimension( A ) ]; + fi; for i in [ 2 .. Length( list ) ] do - dim:= Dimension( list[i] ); + if ( type = "generators" ) then + dim := Length( GeneratorsOfAlgebra( list[i] ) ); + else + dim:= Dimension( list[i] ); + fi; Add( first, first[i] + dim ); A:= DirectSumOfAlgebras( A, list[i] ); od; SetDirectSumInfo( A, rec( algebras := list, first := first, - type := "basis vectors", + type := type, embeddings := [], projections := [] ) ); return A; diff --git a/lib/algmat.gi b/lib/algmat.gi index a0a932b3f4..f1b2f2df25 100644 --- a/lib/algmat.gi +++ b/lib/algmat.gi @@ -1346,15 +1346,16 @@ InstallOtherMethod( DirectSumOfAlgebras, # 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 ) ); - type:= "basis vectors"; - else +## Surely this method should always deal with generators, so comment out: +## if HasBasis( A1 ) and HasBasis( A2 ) then +## b1:= BasisVectors( Basis( A1 ) ); +## b2:= BasisVectors( Basis( A2 ) ); +## type:= "basis vectors"; +## else b1:= GeneratorsOfAlgebra( A1 ); b2:= GeneratorsOfAlgebra( A2 ); type:= "generators"; - fi; +## fi; d1:= Length( b1 ); d2:= Length( b2 ); diff --git a/tst/testinstall/alg-dsum.tst b/tst/testinstall/alg-dsum.tst index aa27851fd8..cfb318eb8d 100644 --- a/tst/testinstall/alg-dsum.tst +++ b/tst/testinstall/alg-dsum.tst @@ -76,8 +76,7 @@ gap> ImageElm( pro2, m0 ); [ [ 0, 1, 1 ], [ 0, 0, 1 ], [ 0, 0, 0 ] ] gap> # mix the two types together gap> # A56 has type "basis vectors" and A12 has type "generators" -gap> # so both A5612 and A1256 have type "basis vectors" -gap> # and both are ordered [ A5, AS6, A12, A2 ] with the generators last. +gap> # so A5612 has type "basis vectors" gap> A5612 := DirectSumOfAlgebras( A56, A12 );; gap> info5612 := DirectSumInfo( A5612 ); rec( algebras := [ A56, A12 ], embeddings := [ ], first := [ 0, 11, 24 ], @@ -153,22 +152,10 @@ rec( algebras := [ A2, A6 ], of ..., of ..., of ..., of ..., of ..., of ..., (1)*(), (1)*(2,3), (1)*(1,2), (1)*(1,2,3), (1)*(1,3,2), (1)*(1,3) ] ], type := "basis vectors" ) -gap> A1256 := DirectSumOfAlgebras( [ A1, A2, A5, A6 ] );; -gap> info1256 := DirectSumInfo( A1256 ); -rec( algebras := [ A1, A2, A5, A6 ], embeddings := [ ], - first := [ 0, 4, 13, 18, 24 ], projections := [ ], type := "basis vectors" ) -gap> e3 := Embedding( A1256, 3 ); -[ (1)*(), (1)*(5,6,7,8,9), (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), (1)*(5,9,8,7,6) ] -> [ v.14, v.15, v.16, v.17, v.18 ] -gap> p3 := Projection( A1256, 3 ); -[ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8, v.9, v.10, v.11, v.12, v.13, v.14, - v.15, v.16, v.17, v.18, v.19, v.20, v.21, v.22, v.23, v.24 ] -> -[ of ..., of ..., of ..., of ..., of ..., - of ..., of ..., of ..., of ..., of ..., - of ..., of ..., of ..., (1)*(), (1)*(5,6,7,8,9), - (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), (1)*(5,9,8,7,6), of ..., - of ..., of ..., of ..., of ..., of ... ] -gap> e3 * p3 = IdentityMapping( A5 ); -true +gap> ## the following fails because internal DirectSumOfAlgebras( A1, A2 ) +gap> ## has a basis with 4 matrices instead of 12 (which A12 has) +gap> A125 := DirectSumOfAlgebras( [ A1, A2, A5 ] );; +Error, the module of the basis must be closed under multiplication gap> ## Lie algebra example gap> L := FullMatrixLieAlgebra( Rationals, 2 ); From 1dff052042527926df364aeeb58be7b625e0745d Mon Sep 17 00:00:00 2001 From: cdwensley Date: Thu, 8 Oct 2026 18:53:17 +0100 Subject: [PATCH 16/19] attempted to deal with the comments from Max --- doc/ref/rings.xml | 1 + lib/algebra.gd | 12 ++++--- lib/algebra.gi | 34 +++----------------- lib/algmat.gi | 54 +++++++------------------------ tst/testinstall/alg-dsum.tst | 62 +++++++----------------------------- 5 files changed, 37 insertions(+), 126 deletions(-) diff --git a/doc/ref/rings.xml b/doc/ref/rings.xml index 4c58a042b4..a0af13c815 100644 --- a/doc/ref/rings.xml +++ b/doc/ref/rings.xml @@ -194,6 +194,7 @@ see . <#Include Label="Projection:rings"> <#Include Label="RingByStructureConstants"> + diff --git a/lib/algebra.gd b/lib/algebra.gd index 783ef5321b..2b846e9733 100644 --- a/lib/algebra.gd +++ b/lib/algebra.gd @@ -569,6 +569,8 @@ DeclareOperation( "ProductSpace", [ IsFreeLeftModule, IsFreeLeftModule ] ); ## ## This is the direct sum of the two algebras A1 and A2 ## or of the algebras in the list list. +## In the latter case, DirectSumOfAlgebras(A1,A2,A3,...,An) +## returns (...((A_1 \oplus A_2) \oplus A3)...) \oplus A_n. ##

## If all involved algebras are associative algebras then the result is also ## known to be associative. @@ -582,12 +584,14 @@ DeclareOperation( "ProductSpace", [ IsFreeLeftModule, IsFreeLeftModule ] ); ## algebras or both are associative then the result is again a ## matrix algebra of the appropriate type. ## c3 := Group( (1,2,3) );; SetName( c3, "c3" ); -## gap> A3 := GroupRing( Rationals, c3 );; SetName( A3, "A3" ); -## gap> c5 := Group( (5,6,7,8,9) );; SetName( c5, "c5" ); -## gap> A5 := GroupRing( Rationals, c5 );; SetName( A5, "A5" ); +## gap> c3 := Group( (1,2,3) );; +## gap> A3 := GroupRing( Rationals, c3 );; +## gap> c5 := Group( (5,6,7,8,9) );; +## gap> A5 := GroupRing( Rationals, c5 );; ## gap> A35 := DirectSumOfAlgebras( A3, A5 ); ## +## gap> A353 := DirectSumOfAlgebras( [ A3, A5, A3 ] ); +## ## ]]> ## ## diff --git a/lib/algebra.gi b/lib/algebra.gi index 779be1ef6b..e207cc05e4 100644 --- a/lib/algebra.gi +++ b/lib/algebra.gi @@ -3030,9 +3030,7 @@ InstallOtherMethod( DirectSumOfAlgebras, R, # Root system of L. RV, # List of various things. r, - pos, # List of positions. - info1, # direct sum info for A1 if it exists. - info2; # direct sum info for A2 if it exists. + pos; # List of positions. if LeftActingDomain( A1 ) <> LeftActingDomain( A2 ) then Error( " and must be written over the same field" ); @@ -3189,6 +3187,9 @@ InstallOtherMethod( DirectSumOfAlgebras, and IsAssociative( A1 ) and IsAssociative( A2 ) then SetIsAssociative( L, true ); fi; + if HasName( A1 ) and HasName( A2 ) then + SetName( L, Concatenation( Name(A1), "(+)", Name(A2 ) ) ); + fi; # Return the result. return L; @@ -3216,32 +3217,11 @@ InstallMethod( DirectSumOfAlgebras, fi; od; - if ForAll( list, A -> IsMatrixFLMLOR( A ) and IsAssociative( A ) ) then - type := "generators"; - else - type := "basis vectors"; - fi; - A:= list[1]; - if ( type = "generators" ) then - first := [ 0, Length( GeneratorsOfAlgebra( A ) ) ]; - else - first:= [ 0, Dimension( A ) ]; - fi; for i in [ 2 .. Length( list ) ] do - if ( type = "generators" ) then - dim := Length( GeneratorsOfAlgebra( list[i] ) ); - else - dim:= Dimension( list[i] ); - fi; - Add( first, first[i] + dim ); A:= DirectSumOfAlgebras( A, list[i] ); od; - SetDirectSumInfo( A, rec( algebras := list, - first := first, - type := type, - embeddings := [], - projections := [] ) ); + return A; end ); @@ -3325,10 +3305,6 @@ InstallMethod( Projection, "algebra direct sum and integer", od; map := AlgebraHomomorphismByImagesNC( D, A, genD, imgs ); - N := Subalgebra( D, genD{Concatenation( [1..first[i]], - [first[i+1]+1..first[len]] )} ); - SetKernelOfMultiplicativeGeneralMapping( map, N ); - # store information infoD.projections[i] := map; return map; diff --git a/lib/algmat.gi b/lib/algmat.gi index f1b2f2df25..521ad125a5 100644 --- a/lib/algmat.gi +++ b/lib/algmat.gi @@ -1333,11 +1333,7 @@ InstallOtherMethod( DirectSumOfAlgebras, B, # A basis of `A1 \oplus A2'. i,j, # Loop variables. Q, # A matrix. - A, # result - info1, # direct sum info for A1 if it exists. - info2, # direct sum info for A2 if it exists. - alg, # list of component algebras. - first; # positions where bases start in the full basis. + A; # result if LeftActingDomain( A1 ) <> LeftActingDomain( A2 ) then Error( " and must be written over the same domain" ); @@ -1412,11 +1408,7 @@ InstallOtherMethod( DirectSumOfAlgebras, B, # A basis of `A1 \oplus A2'. i,j, # Loop variables. Q, # A matrix. - A, # result - info1, # direct sum info for A1 if it exists. - info2, # direct sum info for A2 if it exists. - alg, # list of component algebras. - first; # positions where bases start in the full basis. + A; # result if LeftActingDomain( A1 ) <> LeftActingDomain( A2 ) then Error( " and must be written over the same domain" ); @@ -1425,15 +1417,16 @@ InstallOtherMethod( DirectSumOfAlgebras, # 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 ) ); - type:= "basis vectors"; - else +## Surely this method should always deal with generators, so comment out: +## if HasBasis( A1 ) and HasBasis( A2 ) then +## b1:= BasisVectors( Basis( A1 ) ); +## b2:= BasisVectors( Basis( A2 ) ); +## type:= "basis vectors"; +## else b1:= GeneratorsOfAlgebra( A1 ); b2:= GeneratorsOfAlgebra( A2 ); type:= "generators"; - fi; +## fi; d1:= Length( b1 ); d2:= Length( b2 ); @@ -1458,33 +1451,8 @@ InstallOtherMethod( DirectSumOfAlgebras, fi; SetIsLieAlgebra( A, true ); - # if one of A1,A2 is already a direct sum then make adjustments - if HasDirectSumInfo( A1 ) then - info1 := DirectSumInfo( A1 ); - i := Length( info1.first ); - if HasDirectSumInfo( A2 ) then - info2 := DirectSumInfo( A2 ); - alg := Concatenation( info1.algebras, info2.algebras ); - first := ShallowCopy( info1.first ){[1..i-1]}; - j := info1.first[i]; - first := Concatenation( first, info2.first + j ); - else - alg := Concatenation( info1.algebras, [A2] ); - first := ShallowCopy( info1.first ); - Add( first, first[i] + d2 ); - fi; - elif HasDirectSumInfo( A2 ) then - info2 := DirectSumInfo( A2 ); - alg := Concatenation( [A1], info2.algebras ); - first := ShallowCopy( info2.first ); - first := Concatenation( [0], first + d1 ); - else - alg := [A1,A2]; - first := [0,d1,d1+d2]; - fi; - - SetDirectSumInfo( A, rec( algebras := alg, - first := first, + SetDirectSumInfo( A, rec( algebras := [A1,A2], + first := [0,d1,d1+d2], type := type, embeddings := [], projections := [] ) ); diff --git a/tst/testinstall/alg-dsum.tst b/tst/testinstall/alg-dsum.tst index cfb318eb8d..33ba5dfd27 100644 --- a/tst/testinstall/alg-dsum.tst +++ b/tst/testinstall/alg-dsum.tst @@ -22,8 +22,8 @@ rec( algebras := [ A5, A6 ], embeddings := [ ], first := [ 0, 5, 11 ], projections := [ ], type := "basis vectors" ) gap> SetName( A56, "A56" ); gap> emb5 := Embedding( A56, 1 ); -[ (1)*(), (1)*(5,6,7,8,9), (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), (1)*(5,9,8,7,6) ] - -> [ v.1, v.2, v.3, v.4, v.5 ] +[ (1)*(), (1)*(5,6,7,8,9), (1)*(5,7,9,6,8), (1)*(5,8,6,9,7), (1)*(5,9,8,7,6) + ] -> [ v.1, v.2, v.3, v.4, v.5 ] gap> g := ImageElm( embc5, (5,7,9,6,8) ); (1)*(5,7,9,6,8) gap> ImageElm( emb5, g ); @@ -58,9 +58,10 @@ rec( algebras := [ A1, A2 ], embeddings := [ ], first := [ 0, 1, 4 ], gap> SetName( A12, "A12" ); gap> emb1 := Embedding( A12, 1 ); [ [ [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ], [ 1, 0, 0, 0 ] ] ] -> -[ [ [ 0, 1, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0, 0 ], - [ 1, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ], - [ 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ] ] ] +[ + [ [ 0, 1, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 0, 0, 0, 0 ], [ 0, 0, 0, 1, 0, 0, 0 ], + [ 1, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ], + [ 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ] ] ] gap> m1^3; [ [ 0, 0, 0, 1 ], [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ] ] gap> ImageElm( emb1, m1^3 ); @@ -79,7 +80,7 @@ gap> # A56 has type "basis vectors" and A12 has type "generators" gap> # so A5612 has type "basis vectors" gap> A5612 := DirectSumOfAlgebras( A56, A12 );; gap> info5612 := DirectSumInfo( A5612 ); -rec( algebras := [ A56, A12 ], embeddings := [ ], first := [ 0, 11, 24 ], +rec( algebras := [ A5(+)A6, A12 ], embeddings := [ ], first := [ 0, 11, 24 ], projections := [ ], type := "basis vectors" ) gap> A51 := DirectSumOfAlgebras( A5, A1 );; gap> info51 := DirectSumInfo( A51 ); @@ -110,53 +111,15 @@ gap> Projection( A51, 2 ); [ [ 0, 0, 0, 1 ], [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ] ], [ [ 1, 0, 0, 0 ], [ 0, 1, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 1 ] ] ] gap> A26 := DirectSumOfAlgebras( A2, A6 );; -gap> Embedding( A26, 1 );; -gap> Embedding( A26, 2 );; -gap> Projection( A26, 1 );; -gap> Projection( A26, 2 );; -gap> info26 := DirectSumInfo( A26 ); -rec( algebras := [ A2, A6 ], - embeddings := - [ - [ [ [ 0, 1, 1 ], [ 0, 0, 1 ], [ 0, 0, 0 ] ], - [ [ 1, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 1 ] ], - [ [ 0, 0, 0 ], [ 1, 0, 0 ], [ 1, 1, 0 ] ], - [ [ 0, 0, 1 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ], - [ [ 0, 0, 0 ], [ 0, 0, 1 ], [ 0, 0, 0 ] ], - [ [ 0, 0, 0 ], [ 0, 1, 0 ], [ -1, -1, -2 ] ], - [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 1, 1, 0 ] ], - [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 1 ] ], - [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 1, 0 ] ] ] -> - [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8, v.9 ], - [ (1)*(), (1)*(2,3), (1)*(1,2), (1)*(1,2,3), (1)*(1,3,2), (1)*(1,3) - ] -> [ v.10, v.11, v.12, v.13, v.14, v.15 ] ], first := [ 0, 9, 15 ], - projections := - [ [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8, v.9, v.10, v.11, v.12, v.13, - v.14, v.15 ] -> [ [ [ 0, 1, 1 ], [ 0, 0, 1 ], [ 0, 0, 0 ] ], - [ [ 1, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 1 ] ], - [ [ 0, 0, 0 ], [ 1, 0, 0 ], [ 1, 1, 0 ] ], - [ [ 0, 0, 1 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ], - [ [ 0, 0, 0 ], [ 0, 0, 1 ], [ 0, 0, 0 ] ], - [ [ 0, 0, 0 ], [ 0, 1, 0 ], [ -1, -1, -2 ] ], - [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 1, 1, 0 ] ], - [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 1 ] ], - [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 1, 0 ] ], - [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ], - [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ], - [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ], - [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ], - [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ], - [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ] ], - [ v.1, v.2, v.3, v.4, v.5, v.6, v.7, v.8, v.9, v.10, v.11, v.12, v.13, - v.14, v.15 ] -> [ of ..., of ..., of ..., - of ..., of ..., of ..., of ..., - of ..., of ..., (1)*(), (1)*(2,3), (1)*(1,2), - (1)*(1,2,3), (1)*(1,3,2), (1)*(1,3) ] ], type := "basis vectors" ) +gap> e := Embedding( A26, 1 );; p := Projection( A26, 1 );; +gap> ForAll( BasisVectors( Basis( A2 ) ), x -> ( x ^ e ) ^ p = x ); +true +gap> ForAll( BasisVectors( Basis( A6 ) ), y -> IsZero( ( y ^ Embedding( A26, 2 ) ) ^ p ) ); +true gap> ## the following fails because internal DirectSumOfAlgebras( A1, A2 ) gap> ## has a basis with 4 matrices instead of 12 (which A12 has) gap> A125 := DirectSumOfAlgebras( [ A1, A2, A5 ] );; Error, the module of the basis must be closed under multiplication - gap> ## Lie algebra example gap> L := FullMatrixLieAlgebra( Rationals, 2 ); @@ -191,5 +154,4 @@ gap> Projection( L2, 2 ); LieObject( [ [ 0, 0 ], [ 0, 0 ] ] ), LieObject( [ [ 0, 0 ], [ 0, 0 ] ] ), LieObject( [ [ 1, 0 ], [ 0, 0 ] ] ), LieObject( [ [ 0, 1 ], [ 0, 0 ] ] ), LieObject( [ [ 0, 0 ], [ 1, 0 ] ] ) ] - gap> STOP_TEST("alg-dsum.tst"); From 580fb67b01d400317685208de6af839ba44b0d58 Mon Sep 17 00:00:00 2001 From: cdwensley Date: Thu, 8 Oct 2026 19:09:19 +0100 Subject: [PATCH 17/19] fix problems reported by lint --- lib/algebra.gi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/algebra.gi b/lib/algebra.gi index e207cc05e4..35826f6161 100644 --- a/lib/algebra.gi +++ b/lib/algebra.gi @@ -3204,7 +3204,7 @@ InstallMethod( DirectSumOfAlgebras, "for list of algebras", [ IsDenseList ], function( list ) - local R, A, i, dim, type, first; + local R, A, i; if IsEmpty( list ) then Error( " must be nonempty" ); @@ -3233,7 +3233,7 @@ InstallMethod( DirectSumOfAlgebras, InstallMethod( Embedding, "algebra direct sum and integer", [ IsAlgebra and HasDirectSumInfo, IsPosInt ], function( D, i ) - local info, type, first, A, imgs, map, gens; + local info, type, first, A, gens, imgs, map; # check info := DirectSumInfo( D ); @@ -3273,7 +3273,7 @@ end ); InstallMethod( Projection, "algebra direct sum and integer", [ IsAlgebra and HasDirectSumInfo, IsPosInt ], function( D, i ) - local infoD, type, first, zA, len, A, genA, genD, imgs, j, k, map, N; + local infoD, type, first, len, A, zA, genA, genD, imgs, j, k, map; # check infoD := DirectSumInfo( D ); From 993d3f236f3d802492caa2723431c4bbe5958a12 Mon Sep 17 00:00:00 2001 From: cdwensley Date: Sat, 17 Oct 2026 12:15:52 +0100 Subject: [PATCH 18/19] added DirectSumOfMatrixAlgebras to remove duplication in algmat.gi --- lib/algebra.gd | 2 + lib/algmat.gi | 121 +++++++++++------------------------ tst/testinstall/alg-dsum.tst | 33 ++++------ 3 files changed, 50 insertions(+), 106 deletions(-) diff --git a/lib/algebra.gd b/lib/algebra.gd index 2b846e9733..34b9908d31 100644 --- a/lib/algebra.gd +++ b/lib/algebra.gd @@ -558,6 +558,7 @@ DeclareOperation( "ProductSpace", [ IsFreeLeftModule, IsFreeLeftModule ] ); ## #O DirectSumOfAlgebras( , ) #O DirectSumOfAlgebras( ) +#O DirectSumOfAlgebrasByGenerators( , ) ## ## <#GAPDoc Label="DirectSumOfAlgebras"> ## @@ -598,6 +599,7 @@ DeclareOperation( "ProductSpace", [ IsFreeLeftModule, IsFreeLeftModule ] ); ## <#/GAPDoc> ## DeclareOperation( "DirectSumOfAlgebras", [ IsDenseList ] ); +DeclareOperation( "DirectSumOfMatrixAlgebras", [ IsAlgebra, IsAlgebra ] ); ############################################################################# diff --git a/lib/algmat.gi b/lib/algmat.gi index 521ad125a5..6a3ba186ba 100644 --- a/lib/algmat.gi +++ b/lib/algmat.gi @@ -1312,22 +1312,20 @@ end ); ############################################################################# ## -#M DirectSumOfAlgebras( , ) . . for two associative matrix FLMLORs +#M DirectSumOfMatrixAlgebras( , ) ## -## Construct an associative matrix FLMLOR. +## this is the special method for sirect sum used for matrix algebras ## -InstallOtherMethod( DirectSumOfAlgebras, - "for two associative matrix FLMLORs", +InstallMethod( DirectSumOfMatrixAlgebras, + "for two matrix algebras", IsIdenticalObj, - [ IsMatrixFLMLOR and IsAssociative, - IsMatrixFLMLOR and IsAssociative ], 0, + [ IsAlgebra, IsAlgebra ], function( A1, A2 ) - local b1, # Basis vectors of `A1'. - d1, # Dimension of `A1'. - b2, # Basis vectors of `A2'. - d2, # Dimension of `A2'. - type, # basis vectors or generators. + local b1, # Generators of `A1'. + d1, # Length of `b1'. + b2, # Generators of `A2'. + d2, # Length of `b2'. p1, # Length of the matrices of `b1'. p2, # Length of the matrices of `b2'. B, # A basis of `A1 \oplus A2'. @@ -1339,20 +1337,8 @@ InstallOtherMethod( DirectSumOfAlgebras, Error( " and 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?) -## Surely this method should always deal with generators, so comment out: -## if HasBasis( A1 ) and HasBasis( A2 ) then -## b1:= BasisVectors( Basis( A1 ) ); -## b2:= BasisVectors( Basis( A2 ) ); -## type:= "basis vectors"; -## else - b1:= GeneratorsOfAlgebra( A1 ); - b2:= GeneratorsOfAlgebra( A2 ); - type:= "generators"; -## fi; - + b1:= GeneratorsOfAlgebra( A1 ); + b2:= GeneratorsOfAlgebra( A2 ); d1:= Length( b1 ); d2:= Length( b2 ); p1:= DimensionOfVectors( A1 )[1]; @@ -1374,17 +1360,36 @@ InstallOtherMethod( DirectSumOfAlgebras, if HasBasis( A1 ) and HasBasis( A2 ) then UseBasis( A, B ); fi; - - SetIsAssociative( A, true ); SetDirectSumInfo( A, rec( algebras := [A1,A2], first := [0,d1,d1+d2], - type := type, + type := "generators", embeddings := [], projections := [] ) ); return A; end ); +############################################################################# +## +#M DirectSumOfAlgebras( , ) . . for two associative matrix FLMLORs +## +## Construct an associative matrix FLMLOR. +## +InstallOtherMethod( DirectSumOfAlgebras, + "for two associative matrix FLMLORs", + IsIdenticalObj, + [ IsMatrixFLMLOR and IsAssociative, + IsMatrixFLMLOR and IsAssociative ], 0, + function( A1, A2 ) + + local A; # result + + A := DirectSumOfMatrixAlgebras( A1, A2 ); + SetIsAssociative( A, true ); + return A; + end ); + + ############################################################################# ## #M DirectSumOfAlgebras( , ) . . . . . . for two matrix Lie FLMLORs @@ -1398,65 +1403,11 @@ InstallOtherMethod( DirectSumOfAlgebras, IsMatrixFLMLOR and IsLieAlgebra ], 0, function( A1, A2 ) - local b1, # Basis vectors of `A1'. - d1, # Dimension of `A1'. - b2, # Basis vectors of `A2'. - d2, # Dimension of `A2'. - type, # basis vectors or generators. - p1, # Length of the matrices of `b1'. - p2, # Length of the matrices of `b2'. - B, # A basis of `A1 \oplus A2'. - i,j, # Loop variables. - Q, # A matrix. - A; # result - - if LeftActingDomain( A1 ) <> LeftActingDomain( A2 ) then - Error( " and 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?) -## Surely this method should always deal with generators, so comment out: -## if HasBasis( A1 ) and HasBasis( A2 ) then -## b1:= BasisVectors( Basis( A1 ) ); -## b2:= BasisVectors( Basis( A2 ) ); -## type:= "basis vectors"; -## else - b1:= GeneratorsOfAlgebra( A1 ); - b2:= GeneratorsOfAlgebra( A2 ); - type:= "generators"; -## fi; + local A; # result - d1:= Length( b1 ); - d2:= Length( b2 ); - 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; + A := DirectSumOfMatrixAlgebras( A1, A2 ); SetIsLieAlgebra( A, true ); - - SetDirectSumInfo( A, rec( algebras := [A1,A2], - first := [0,d1,d1+d2], - type := type, - embeddings := [], - projections := [] ) ); - return A; + return A; end ); diff --git a/tst/testinstall/alg-dsum.tst b/tst/testinstall/alg-dsum.tst index 33ba5dfd27..ab21cc2c6f 100644 --- a/tst/testinstall/alg-dsum.tst +++ b/tst/testinstall/alg-dsum.tst @@ -132,26 +132,17 @@ rec( algebras := [ L, L ], embeddings := [ ], first := [ 0, 3, 6 ], gap> Embedding( L2, 1 ); [ LieObject( [ [ 1, 0 ], [ 0, 0 ] ] ), LieObject( [ [ 0, 1 ], [ 0, 0 ] ] ), LieObject( [ [ 0, 0 ], [ 1, 0 ] ] ) ] -> -[ LieObject( [ [ 1, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] - ] ), - LieObject( [ [ 0, 1, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] - ] ), - LieObject( [ [ 0, 0, 0, 0 ], [ 1, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] - ] ) ] +[ [ [ 1, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] ], + [ [ 0, 1, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0 ], [ 1, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] ] ] gap> Projection( L2, 2 ); -[ LieObject( [ [ 1, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] - ] ), - LieObject( [ [ 0, 1, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] - ] ), - LieObject( [ [ 0, 0, 0, 0 ], [ 1, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] - ] ), - LieObject( [ [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 0 ] - ] ), - LieObject( [ [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 1 ], [ 0, 0, 0, 0 ] - ] ), - LieObject( [ [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 1, 0 ] - ] ) ] -> [ LieObject( [ [ 0, 0 ], [ 0, 0 ] ] ), - LieObject( [ [ 0, 0 ], [ 0, 0 ] ] ), LieObject( [ [ 0, 0 ], [ 0, 0 ] ] ), - LieObject( [ [ 1, 0 ], [ 0, 0 ] ] ), LieObject( [ [ 0, 1 ], [ 0, 0 ] ] ), - LieObject( [ [ 0, 0 ], [ 1, 0 ] ] ) ] +[ [ [ 1, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] ], + [ [ 0, 1, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0 ], [ 1, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 1, 0 ], [ 0, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 1 ], [ 0, 0, 0, 0 ] ], + [ [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 0, 0 ], [ 0, 0, 1, 0 ] ] ] -> +[ LieObject( [ [ 0, 0 ], [ 0, 0 ] ] ), LieObject( [ [ 0, 0 ], [ 0, 0 ] ] ), + LieObject( [ [ 0, 0 ], [ 0, 0 ] ] ), LieObject( [ [ 1, 0 ], [ 0, 0 ] ] ), + LieObject( [ [ 0, 1 ], [ 0, 0 ] ] ), LieObject( [ [ 0, 0 ], [ 1, 0 ] ] ) ] gap> STOP_TEST("alg-dsum.tst"); From 058206da7f076f1fbe97bf564e39b7bde5141c5f Mon Sep 17 00:00:00 2001 From: cdwensley Date: Sat, 17 Oct 2026 12:18:58 +0100 Subject: [PATCH 19/19] added DirectSumOfMatrixAlgebras to remove duplication in algmat.gi --- lib/algmat.gi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/algmat.gi b/lib/algmat.gi index 6a3ba186ba..9432893ae7 100644 --- a/lib/algmat.gi +++ b/lib/algmat.gi @@ -1407,7 +1407,7 @@ InstallOtherMethod( DirectSumOfAlgebras, A := DirectSumOfMatrixAlgebras( A1, A2 ); SetIsLieAlgebra( A, true ); - return A; + return A; end );