Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/ref/rings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ see <Ref Sect="Homomorphisms of Algebras"/>.
<#Include Label="Subrings">
<#Include Label="Ideals">
<#Include Label="DirectSum">
<#Include Label="Embedding:rings">
<#Include Label="Projection:rings">
<#Include Label="RingByStructureConstants">


Expand Down
60 changes: 57 additions & 3 deletions lib/ringsc.gd
Original file line number Diff line number Diff line change
Expand Up @@ -193,14 +193,68 @@ DeclareGlobalFunction("SmallRing");
## (This somewhat strange syntax allows the method selection to choose
## a reasonable method for special cases.)
## <Example><![CDATA[
## gap> DirectSum(SmallRing(5,1),SmallRing(5,1));
## <ring with 2 generators>
## gap> R7 := SmallRing( 7, 2 );; SetName( R7, "R7" );
## gap> R8 := SmallRing( 8, 52 );; SetName( R8, "R8" );
## gap> R78 := DirectSum( R7, R8 );
## <ring with 4 generators>
## gap> R9 := SmallRing( 9, 11 );; SetName( R9, "R9" );
## gap> R789 := DirectSum( [ R7, R8, R9 ] );
## <ring with 6 generators>
## ]]></Example>
## </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareGlobalFunction( "DirectSum" );
DeclareOperation( "DirectSumOp", [ IsList, IsRing ] );
DeclareAttribute( "DirectSumInfo", IsGroup, "mutable" );
DeclareAttribute( "DirectSumInfo", IsRing, "mutable" );

#############################################################################
##
#O Embedding( <R>,<i> )
##
## <#GAPDoc Label="Embedding:rings">
## <ManSection>
## <Oper Name="Embedding" Arg='R, i'
## Label="for a direct sum of rings and a positive integer"/>
##
## <Description>
## If ring <A>R</A> is the direct sum of rings <M>[R_1,\ldots,R_k]</M>
## then <C>Embedding(R,i)</C> for <M>1 \leq i \leq k</M> returns a ring
## homomorphism mapping <M>R_i</M> into <A>R</A>.
## <P/>
## <Example><![CDATA[
## gap> emb1 := Embedding( R78, 1 );
## [ a ] -> [ Aa ]
## gap> a := GeneratorsOfRing( R7 )[1];;
## gap> ImageElm( emb1, 3*a );
## 3*Aa
## ]]></Example>
## </Description>
## </ManSection>
## <#/GAPDoc>

#############################################################################
##
#O Projection( <R>,<i> )
##
## <#GAPDoc Label="Projection:rings">
## <ManSection>
## <Oper Name="Projection" Arg='R, i'
## Label="for a direct sum of rings and a positive integer"/>
##
## <Description>
## If ring <A>R</A> is the direct sum of rings <M>[R_1,\ldots,R_k]</M>
## then <C>Projection(R,i)</C> for <M>1 \leq i \leq k</M> returns a ring
## homomorphism mapping <A>R</A> onto <M>R_i</M>.
## <P/>
## <Example><![CDATA[
## gap> pro2 := Projection( R78, 2 );
## [ Aa, Ba, Bb, Bc ] -> [ 0*a, a, b, c ]
## gap> b := GeneratorsOfRing( R78 )[2];;
## gap> ImageElm( pro2, 5*b );
## a
## ]]></Example>
## </Description>
## </ManSection>
## <#/GAPDoc>
69 changes: 67 additions & 2 deletions lib/ringsc.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1101,7 +1101,7 @@ local ids, tup, first, i, G, gens, g, new, D;

ids := List( list, Zero );
tup := [];
first := [1];
first := [0];
for i in [1..Length( list )] do
G := list[i];
gens := GeneratorsOfRing( G );
Expand All @@ -1114,7 +1114,7 @@ local ids, tup, first, i, G, gens, g, new, D;
new := DirectProductElement( new );
Add( tup, new );
od;
Add( first, Length( tup )+1 );
Add( first, Length( tup ) );
od;

D := RingByGenerators( tup );
Expand Down Expand Up @@ -1208,6 +1208,71 @@ local ones,s, moduli, orders, offsets, o, p, newmod, t, nams, gens, e, f, D, i,
return D;
end );

#############################################################################
##
#M Embedding( <D>, <i> )
##
InstallMethod( Embedding, "ring direct sum and integer",
[ IsSubringSCRing and HasDirectSumInfo, IsPosInt ],
function( D, i )
local info, first, R, gens, imgs, map;

# check
info := DirectSumInfo( D );
if IsBound( info.embeddings[i] ) then
return info.embeddings[i];
fi;
first := info.first;
if not ( i < Length(first) ) then
Error( "value of second parameter is too large" );
fi;
# compute embedding
R := info.rings[i];
gens := StandardGeneratorsSubringSCRing( R )[3];
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;
end );

#############################################################################
##
#M Projection( <D>, <i> )
##
InstallMethod( Projection, "ring direct sum and integer",
[ IsSubringSCRing and HasDirectSumInfo, IsPosInt ],
function( D, i )
local infoD, first, zR, len, R, genR, genD, imgs, j, k, map;

infoD := DirectSumInfo( D );
if IsBound( infoD.projections[i] ) then
return infoD.projections[i];
fi;
first := infoD.first;
len := Length( first );
if not ( i < len ) then
Error( "value of second parameter is too large" );
fi;
# compute projection
R := infoD.rings[i];
zR := Zero( R );
genR := StandardGeneratorsSubringSCRing( R )[3];
genD := GeneratorsOfRing( D );
imgs := ListWithIdenticalEntries( first[len], zR );
j := first[i];
for k in [first[i]+1..first[i+1]] do
imgs[k] := genR[k-j];
od;
map := RingHomomorphismByImages( D, R, genD, imgs );

# store information
infoD.projections[i] := map;
return map;
end );

#############################################################################
##
#M \+( <R1>, <R2> ) . . . . . . . . . . . . . . . . sum of rings
Expand Down
86 changes: 86 additions & 0 deletions tst/testinstall/ring-dsum.tst
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
gap> START_TEST("ring-dsum.tst");
gap> # direct sums of small rings
gap> R7 := SmallRing( 7, 2 );; SetName( R7, "R7" );
gap> R8 := SmallRing( 8, 52 );; SetName( R8, "R8" );
gap> R9 := SmallRing( 9, 11 );; SetName( R9, "R9" );
gap> R78 := DirectSum( R7, R8 );
<ring with 4 generators>
gap> info78 := DirectSumInfo( R78 );
rec( embeddings := [ ], first := [ 0, 1, 4 ], projections := [ ],
rings := [ R7, R8 ] )
gap> R789 := DirectSum( [ R7, R8, R9 ] );
<ring with 6 generators>
gap> info789 := DirectSumInfo( R789 );
rec( embeddings := [ ], first := [ 0, 1, 4, 6 ], projections := [ ],
rings := [ R7, R8, R9 ] )
gap> #
gap> # embeddings and projections of small rings
gap> Embedding( R78, 2 );
[ a, b, c ] -> [ Ba, Bb, Bc ]
gap> e3 := Embedding( R789, 3 );
[ a, b ] -> [ Ca, Cb ]
gap> Projection( R78, 1 );
[ Aa, Ba, Bb, Bc ] -> [ a, 0*a, 0*a, 0*a ]
gap> p3 := Projection( R789, 3 );
[ Aa, Ba, Bb, Bc, Ca, Cb ] -> [ 0*a, 0*a, 0*a, 0*a, a, b ]
gap> genR9 := GeneratorsOfRing( R9 );;
gap> a := genR9[1];; b := genR9[2];;
gap> [ a*b^2, ImageElm( e3, a*b^2 ) ];
[ -a, -Ca ]
gap> ForAll( genR9, g -> ( g ^ e3 ) ^ p3 = g );
true
gap> genR789 := GeneratorsOfRing( R789 );;
gap> x := genR789[3];; y := genR789[6];;
gap> [ x^2, ImageElm( p3, x^2 ) ];
[ Ba+Bc, 0*a ]
gap> [ y^2, ImageElm( p3, y^2 ) ];
[ -Ca, -a ]
gap> #
gap> # other direct sums of rings
gap> R4 := ZmodnZ( 4 );;
gap> R5 := ZmodnZ( 5 );;
gap> R6 := ZmodnZ( 6 );;
gap> R45 := DirectSum( R4, R5 );
<ring with 3 generators>
gap> info45 := DirectSumInfo( R45 );
rec( embeddings := [ ], first := [ 0, 2, 3 ], projections := [ ],
rings := [ (Integers mod 4), GF(5) ] )
gap> R456 := DirectSum( [ R4, R5, R6 ] );
<ring with 5 generators>
gap> info456 := DirectSumInfo( R456 );
rec( embeddings := [ ], first := [ 0, 2, 3, 5 ], projections := [ ],
rings := [ (Integers mod 4), GF(5), (Integers mod 6) ] )
gap> #
gap> # embeddings and projections of these rings: methods for these
gap> # operations are only installed for rings of type IsSubringSCRing
gap> Embedding( R45, 1 );
Error, no method found! For debugging hints type ?Recovery from NoMethodFound
Error, no 1st choice method found for `Embedding' on 2 arguments
gap> Projection( R456, 2 );
Error, no method found! For debugging hints type ?Recovery from NoMethodFound
Error, no 1st choice method found for `Projection' on 2 arguments
gap> #
gap> # combine these all together:
gap> D := DirectSum( [R4,R5,R6,R7,R8,R9] );
<ring with 11 generators>
gap> DirectSumInfo( D );
rec( embeddings := [ ], first := [ 0, 2, 3, 5, 6, 9, 11 ],
projections := [ ],
rings := [ (Integers mod 4), GF(5), (Integers mod 6), R7, R8, R9 ] )
gap> #
gap> # subrings whose generators are not the standard generators
gap> R3 := SmallRing( 3, 2 );;
gap> T3 := Subring( R3, [ -GeneratorsOfRing( R3 )[1] ] );;
gap> D3 := DirectSum( T3, T3 );;
gap> e := Embedding( D3, 2 );; p := Projection( D3, 2 );;
gap> ForAll( T3, r -> ( r ^ e ) ^ p = r );
true
gap> ForAll( T3, r -> IsZero( ( r ^ e ) ^ Projection( D3, 1 ) ) );
true
gap> S4 := SmallRing( 4, 1 );; g := GeneratorsOfRing( S4 )[1];;
gap> T4 := Subring( S4, [ 2*g, g ] );;
gap> D4 := DirectSum( T4, R3 );;
gap> e := Embedding( D4, 1 );; p := Projection( D4, 1 );;
gap> ForAll( T4, r -> ( r ^ e ) ^ p = r );
true
gap> STOP_TEST("ring-dsum.tst");
Comment thread
cdwensley marked this conversation as resolved.
Loading