Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AlgebraWithOneByStructureConstants #5491

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
1 change: 1 addition & 0 deletions doc/ref/algebra.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@

<#Include Label="[2]{algebra}">
<#Include Label="AlgebraByStructureConstants">
<#Include Label="AlgebraWithOneByStructureConstants">
<#Include Label="StructureConstantsTable">
<#Include Label="EmptySCTable">
<#Include Label="SetEntrySCTable">
Expand Down
46 changes: 46 additions & 0 deletions lib/algebra.gd
Original file line number Diff line number Diff line change
Expand Up @@ -1646,6 +1646,52 @@ DeclareGlobalFunction( "FreeAssociativeAlgebraWithOne" );
DeclareGlobalFunction( "AlgebraByStructureConstants" );


#############################################################################
##
#F AlgebraWithOneByStructureConstants( <R>, <sctable>[, <nameinfo>],
#F <onecoeffs> )
##
## <#GAPDoc Label="AlgebraWithOneByStructureConstants">
## <ManSection>
## <Func Name="AlgebraWithOneByStructureConstants"
## Arg="R, sctable[, nameinfo], onecoeffs"/>
##
## <Description>
## The only differences between this function and
## <Ref Func="AlgebraByStructureConstants"/> are that
## <Ref Func="AlgebraWithOneByStructureConstants"/> takes an additional
## argument <A>onecoeffs</A>, the coefficients vector over the ring <A>R</A>
## that describes the unique multiplicative identity element of the returned
## algebra w. r. t. the defining basis of this algebra,
## and that the returned algebra is an algebra-with-one
## (see <Ref Func="IsAlgebraWithOne"/>).
## <P/>
## <Example><![CDATA[
## gap> A:= GF(2)^[2,2];;
## gap> B:= Basis( A );;
## gap> onecoeffs:= Coefficients( B, One( A ) );
## [ Z(2)^0, 0*Z(2), 0*Z(2), Z(2)^0 ]
## gap> T:= StructureConstantsTable( B );;
## gap> sc1:= AlgebraByStructureConstants( GF(2), T );
## <algebra of dimension 4 over GF(2)>
## gap> HasOne( sc1 );
## false
## gap> One( sc1 );
## v.1+v.4
## gap> sc2:= AlgebraWithOneByStructureConstants( GF(2), T, onecoeffs );
## <algebra-with-one of dimension 4 over GF(2)>
## gap> HasOne( sc2 );
## true
## gap> One( sc2 );
## v.1+v.4
## ]]></Example>
## </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareGlobalFunction( "AlgebraWithOneByStructureConstants" );


#############################################################################
##
#F LieAlgebraByStructureConstants( <R>, <sctable>[, <nameinfo>] )
Expand Down
31 changes: 22 additions & 9 deletions lib/algsc.gi
Original file line number Diff line number Diff line change
Expand Up @@ -525,15 +525,17 @@ InstallMethod( \in,
## where `$c_{ijk}$ = <sctable>[i][j][1][i_k]'
## and `<sctable>[i][j][2][i_k] = k'.
##
BindGlobal( "AlgebraByStructureConstantsArg", function( arglist, filter )
BindGlobal( "AlgebraByStructureConstantsArg",
function( arglist, filter, one_coeffs... )
local T, # structure constants table
n, # dimensions of structure matrices
R, # coefficients ring
zero, # zero of `R'
names, # names of the algebra generators
Fam, # the family of algebra elements
A, # the algebra, result
gens; # algebra generators of `A'
gens, # algebra generators of `A'
one; # multiplicative identity, if available

# Check the argument list.
if not 1 < Length( arglist ) and IsRing( arglist[1] )
Expand Down Expand Up @@ -626,6 +628,14 @@ BindGlobal( "AlgebraByStructureConstantsArg", function( arglist, filter )
SetIsTrivial( A, true );
SetDimension( A, 0 );
fi;
if Length( one_coeffs ) = 1 then
# We want to construct an algebra-with_one.
one:= ObjByExtRep( Fam, one_coeffs[1] );
SetOne( Fam, one );
SetOne( A, one );
SetFilterObj( A, IsMagmaWithOne );
SetGeneratorsOfAlgebraWithOne( A, gens );
fi;
Fam!.basisVectors:= gens;
#T where is this needed?

Expand All @@ -643,6 +653,11 @@ InstallGlobalFunction( AlgebraByStructureConstants, function( arg )
return AlgebraByStructureConstantsArg( arg, IsSCAlgebraObj );
end );

InstallGlobalFunction( AlgebraWithOneByStructureConstants, function( arg )
return AlgebraByStructureConstantsArg( arg{ [ 1 .. Length( arg )-1 ] },
IsSCAlgebraObj, arg[ Length( arg ) ] );
end );

InstallGlobalFunction( LieAlgebraByStructureConstants, function( arg )
local A;
A:= AlgebraByStructureConstantsArg( arg, IsSCAlgebraObj and IsJacobianElement );
Expand Down Expand Up @@ -690,7 +705,7 @@ InstallAccessToGenerators( IsSCAlgebraObjCollection and IsFullSCAlgebra,
#F QuaternionAlgebra( <F>[, <a>, <b>] )
##
InstallGlobalFunction( QuaternionAlgebra, function( arg )
local F, a, b, e, stored, filter, A;
local F, a, b, e, z, stored, filter, A;

if Length( arg ) = 1 and IsRing( arg[1] ) then
F:= arg[1];
Expand All @@ -715,6 +730,7 @@ InstallGlobalFunction( QuaternionAlgebra, function( arg )
if e = fail then
Error( "<F> must have an identity element" );
fi;
z:= Zero( F );

# Generators in the right family may be already available.
stored := GET_FROM_SORTED_CACHE( QuaternionAlgebraData, [ a, b, FamilyObj( F ) ],
Expand All @@ -734,18 +750,15 @@ InstallGlobalFunction( QuaternionAlgebra, function( arg )
fi;

# Construct the algebra.
A:= AlgebraByStructureConstantsArg(
return AlgebraByStructureConstantsArg(
[ F,
[ [ [[1],[e]], [[2],[ e]], [[3],[ e]], [[4],[ e]] ],
[ [[2],[e]], [[1],[ a]], [[4],[ e]], [[3],[ a]] ],
[ [[3],[e]], [[4],[-e]], [[1],[ b]], [[2],[ -b]] ],
[ [[4],[e]], [[3],[-a]], [[2],[ b]], [[1],[-a*b]] ],
0, Zero(F) ],
0, z ],
"e", "i", "j", "k" ],
filter );
SetFilterObj( A, IsAlgebraWithOne );
#T better introduce AlgebraWithOneByStructureConstants?
return A;
filter, [ e, z, z, z ] );
end );

A:= AlgebraWithOne( F, GeneratorsOfAlgebra( stored ), "basis" );
Expand Down
90 changes: 90 additions & 0 deletions tst/testinstall/algsc.tst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ gap> q:= QuotientFromSCTable( T0, id, v );
[ 0, -1/3, -1/3, -1/3 ]
gap> v = QuotientFromSCTable( T0, id, q );
true

# Compute with an algebra by structure constants.
gap> a:= AlgebraByStructureConstants( Rationals, T0 );
<algebra of dimension 4 over Rationals>
gap> Dimension( a );
Expand All @@ -33,6 +35,8 @@ gap> IsWholeFamily( a );
false
gap> IsWholeFamily( AlgebraByStructureConstants( Cyclotomics, T0 ) );
true
gap> IsMagmaWithOne( a );
false

#
gap> fam:= ElementsFamily( FamilyObj( a ) );
Expand Down Expand Up @@ -104,7 +108,89 @@ gap> v:= Subspace( a, [ v, 0*v, v^0, w ] );
gap> Dimension( v );
3

# And now do the same for an algebra-with-one.
gap> a:= AlgebraWithOneByStructureConstants( Rationals, T0, id );
<algebra-with-one of dimension 4 over Rationals>
gap> Dimension( a );
4
gap> IsFullSCAlgebra( a );
true
gap> IsWholeFamily( a );
false
gap> IsMagmaWithOne( a );
true

#
gap> fam:= ElementsFamily( FamilyObj( a ) );
<Family: "SCAlgebraObjFamily">
gap> ObjByExtRep( fam, [ 0, 1, 0, 1 ] * Z(2) );
Error, family of <coeffs> does not fit to <Fam>
gap> ObjByExtRep( fam, [ 0, 1, 0 ] );
Error, <coeffs> must be a list of length 4
gap> v:= ObjByExtRep( fam, [ 0, 1, 0, 1 ] );
v.2+v.4
gap> t:= AlgebraByStructureConstants( Rationals, [ 0, 0 ] );
<algebra of dimension 0 over Rationals>
gap> String(v);
"v.2+v.4"
gap> One( fam ); One( v ); v^0; String(v^0);
v.1
v.1
v.1
"v.1"
gap> Zero( fam ); Zero( v ); 0*v; String(0*v);
0*v.1
0*v.1
0*v.1
"0*v.1"
gap> 0*v = v*0;
true
gap> 1*v = v;
true
gap> v*1 = v;
true
gap> (1/2 * v) * 2 = v;
true
gap> 2 * (v * 1/2) = v;
true

#
gap> Inverse( v ); v^-1; String( v^-1 );
(-1/2)*v.2+(-1/2)*v.4
(-1/2)*v.2+(-1/2)*v.4
"(-1/2)*v.2+(-1/2)*v.4"
gap> Inverse( Zero( v) );
fail
gap> AdditiveInverse( v ); -v; String( -v );
(-1)*v.2+(-1)*v.4
(-1)*v.2+(-1)*v.4
"(-1)*v.2+(-1)*v.4"
gap> b:= Basis( a );
CanonicalBasis( <algebra-with-one of dimension 4 over Rationals> )
gap> Coefficients( b, v );
[ 0, 1, 0, 1 ]
gap> w:= LinearCombination( b, [ 1, 2, 3, 4 ] );
v.1+(2)*v.2+(3)*v.3+(4)*v.4
gap> v + w;
v.1+(3)*v.2+(3)*v.3+(5)*v.4
gap> v * w;
(-6)*v.1+(-2)*v.2+(-2)*v.3+(4)*v.4
gap> v = w;
false
gap> v < w;
true
gap> w < v;
false
gap> s:= Subalgebra( a, [ v, 0*v, v^0, w ] );
<algebra over Rationals, with 4 generators>
gap> Dimension( s );
4
gap> v:= Subspace( a, [ v, 0*v, v^0, w ] );
<vector space over Rationals, with 4 generators>
gap> Dimension( v );
3

# Special case: QuaternionAlgebra
gap> a:= QuaternionAlgebra( Rationals, -2, -3 );;
gap> gens:= GeneratorsOfAlgebra( a );
[ e, i, j, k ]
Expand Down Expand Up @@ -777,6 +863,10 @@ gap> A:= QuaternionAlgebra( GF(5) );
<algebra-with-one of dimension 4 over GF(5)>
gap> A = QuaternionAlgebra( [Z(5)] );
true
gap> IsDivisionRing( QuaternionAlgebra( Rationals ) );
true
gap> IsDivisionRing( QuaternionAlgebra( CF(4) ) );
false

#
gap> A:= QuaternionAlgebra( Rationals, 2, 3 );
Expand Down