Skip to content

Commit

Permalink
lib: add IsDirectProductDomain objects and ...
Browse files Browse the repository at this point in the history
... some related functions, operations, attributes, and methods.

TODO
- doc
- examples
- maybe put the "move DirectProductFamily around" part into its own
  commit?

Creates new files `lib/productdomain.g{d,i}`, `tst/testinstall/productdomain.tst`.
Moves the declaration, definition, and tests of `DirectProductFamily` from
`lib/tuples.g{d,i}` and `hpcgap/lib/tuples.gi` into the new files.

Adds the new files to `doc/ref/makedocreldata.g` and to `read3.g` and
`read5.g`.

Adds:
- a filter IsDirectProductDomain
- an operation DirectProductDomain to create IsDirectProductDomain
  domains and methods for DirectProductDomain
- attributes and methods for IsDirectProductDomain objects:
  - ComponentsOfDirectProductDomain, this defines the domain
  - DimensionOfDirectProductDomain, the number of components
  - PrintObj
  - Size
  - \in
  • Loading branch information
ssiccha committed Aug 7, 2019
1 parent 9975332 commit 0f86f3c
Show file tree
Hide file tree
Showing 10 changed files with 267 additions and 90 deletions.
2 changes: 2 additions & 0 deletions doc/ref/makedocreldata.g
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ GAPInfo.ManualDataRef:= rec(
"../../lib/pquot.gd",
"../../lib/primality.gd",
"../../lib/process.gd",
"../../lib/productdomain.gd",
"../../lib/productdomain.gi",
"../../lib/profile.g",
"../../lib/proto.gd",
"../../lib/randiso.gd",
Expand Down
14 changes: 0 additions & 14 deletions hpcgap/lib/tuples.gi
Original file line number Diff line number Diff line change
Expand Up @@ -513,17 +513,3 @@ InstallOtherMethod( \*,
fi;
return DirectProductElement( List( dpelm, entry -> nonlist * entry ) );
end );


#############################################################################
##
##
InstallGlobalFunction( DirectProductFamily,
function( args )
if not IsDenseList(args) or not ForAll(args, IsCollectionFamily) then
ErrorNoReturn("<args> must be a dense list of collection families");
fi;
return CollectionsFamily(
DirectProductElementsFamily( List( args, ElementsFamily ) )
);
end );
57 changes: 57 additions & 0 deletions lib/productdomain.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#############################################################################
##
## This file declares everything we need to work with IsDirectProductDomain
## objects.
##
## <#GAPDoc Label="DirectProductFamily">
## <ManSection>
## <Func Name="DirectProductFamily" Arg='args'/>
##
## <Description>
## <A>args</A> must be a dense list of <Ref Attr="CollectionsFamily"/>
## families, otherwise the function raises an error.
## <P/>
## <Ref Func="DirectProductFamily"/> returns <C>fam</C>, a collections
## family of <Ref Filt="IsDirectProductElement"/> objects.
## <P/>
## <C>fam</C> is the <Ref Filt="CollectionsFamily"/> of
## <Ref Filt="IsDirectProductElement"/> objects
## whose <C>i</C>-th component is in <C>ElementsFamily(args[i])</C>.
## <P/>
## Note that a collection in <C>fam</C> may not itself be a
## direct product; it just is a subcollection of a direct product.
## <P/>
## <Example><![CDATA[
## gap> D8 := DihedralGroup(IsPermGroup, 8);;
## gap> FamilyObj(D8) = CollectionsFamily(PermutationsFamily);
## true
## gap> fam := DirectProductFamily([FamilyObj(D8), FamilyObj(D8)]);;
## gap> ComponentsOfDirectProductElementsFamily(ElementsFamily(fam));
## [ <Family: "PermutationsFamily">, <Family: "PermutationsFamily"> ]
## ]]></Example>
## Also note that not all direct products in &GAP; are created via these
## families. For example if the arguments to <Ref Func="DirectProduct"/>
## are permutation groups, then it returns a permutation group as well, whose
## elements are not <Ref Filt="IsDirectProductElement"/> objects.
## <P/>
## <Example><![CDATA[
## gap> fam = FamilyObj(DirectProduct(D8, D8));
## false
## gap> D4 := DihedralGroup(IsPcGroup, 4);;
## gap> fam2 := DirectProductFamily([FamilyObj(D8), FamilyObj(D4)]);;
## gap> fam2 = FamilyObj(DirectProduct(D8, D4));
## true
## ]]></Example>
## </Description>
## </ManSection>
## <#/GAPDoc>
DeclareGlobalFunction( "DirectProductFamily",
"for a dense list of collection families" );

DeclareCategory("IsDirectProductDomain",
IsDirectProductElementCollection and IsDomain);

DeclareOperation("DirectProductDomain", [IsDenseList]);

DeclareAttribute("ComponentsOfDirectProductDomain", IsDirectProductDomain);
DeclareAttribute("DimensionOfDirectProductDomain", IsDirectProductDomain);
101 changes: 101 additions & 0 deletions lib/productdomain.gi
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#############################################################################
##
## The rest of this file implements the operations for IsDirectProductDomain
## domains.
##
InstallGlobalFunction(DirectProductFamily,
function(args)
if not IsDenseList(args) or not ForAll(args, IsCollectionFamily) then
ErrorNoReturn("<args> must be a dense list of collection families");
fi;
return CollectionsFamily(
DirectProductElementsFamily(List(args, ElementsFamily))
);
end);


#############################################################################
##
InstallMethod(DirectProductDomain,
"for a dense list (of domains)",
[IsDenseList],
function(args)
local directProductFamily, type;
if not ForAll(args, IsDomain) then
ErrorNoReturn("args must be a dense list of domains");
fi;
directProductFamily := DirectProductFamily(List(args, FamilyObj));
type := NewType(directProductFamily,
IsDirectProductDomain and IsAttributeStoringRep);
return ObjectifyWithAttributes(rec(), type,
ComponentsOfDirectProductDomain, args);
end);

InstallOtherMethod(DirectProductDomain,
"for a domain and a nonnegative integer",
[IsDomain, IsInt],
function(dom, k)
local directProductFamily, type;
if k < 0 then
ErrorNoReturn("<k> must be a nonnegative integer");
fi;
directProductFamily := DirectProductFamily(
ListWithIdenticalEntries(k, FamilyObj(dom))
);
type := NewType(directProductFamily,
IsDirectProductDomain and IsAttributeStoringRep);
return ObjectifyWithAttributes(rec(),
type,
ComponentsOfDirectProductDomain,
ListWithIdenticalEntries(k, dom));
end);

InstallMethod(PrintObj,
"for an IsDirectProductDomain",
[IsDirectProductDomain],
function(dom)
local components, i;
Print("DirectProductDomain([ ");
components := ComponentsOfDirectProductDomain(dom);
for i in [1 .. Length(components)] do
PrintObj(components[i]);
if i < Length(components) then
Print(", ");
fi;
od;
Print(" ])");
end);

InstallMethod(Size,
"for an IsDirectProductDomain",
[IsDirectProductDomain],
function(dom)
local size, comp;
size := 1;
for comp in ComponentsOfDirectProductDomain(dom) do
size := Size(comp) * size;
od;
return size;
end);

InstallMethod(DimensionOfDirectProductDomain,
"for an IsDirectProductDomain",
[IsDirectProductDomain],
dom -> Length(ComponentsOfDirectProductDomain(dom)));

InstallMethod(\in,
"for an IsDirectProductDomain",
[IsDirectProductElement, IsDirectProductDomain],
function(elm, dom)
local components, i;
if Length(elm) <> DimensionOfDirectProductDomain(dom) then
return false;
fi;
components := ComponentsOfDirectProductDomain(dom);
for i in [1 .. Length(components)] do
if not elm[i] in components[i] then
return false;
fi;
od;
return true;
end);
1 change: 1 addition & 0 deletions lib/read3.g
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ ReadLib( "bitfields.gd" );
ReadLib( "mapping.gd" );
ReadLib( "mapphomo.gd" );
ReadLib( "relation.gd");
ReadLib( "productdomain.gd" );

ReadLib( "magma.gd" );
ReadLib( "mgmideal.gd" );
Expand Down
1 change: 1 addition & 0 deletions lib/read5.g
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ ReadLib( "mapping.gi" );
ReadLib( "mapprep.gi" );
ReadLib( "mapphomo.gi" );
ReadLib( "relation.gi" );
ReadLib( "productdomain.gi" );

ReadLib( "magma.gi" );
ReadLib( "mgmideal.gi" );
Expand Down
49 changes: 0 additions & 49 deletions lib/tuples.gd
Original file line number Diff line number Diff line change
Expand Up @@ -178,52 +178,3 @@ direct product elements families" );
DeclareOperation( "DirectProductElement", [ IsList ]);
DeclareOperation( "DirectProductElementNC",
[ IsDirectProductElementFamily, IsList ]);


#############################################################################
##
##
## <#GAPDoc Label="DirectProductFamily">
## <ManSection>
## <Func Name="DirectProductFamily" Arg='args'/>
##
## <Description>
## <A>args</A> must be a dense list of <Ref Attr="CollectionsFamily"/>
## families, otherwise the function raises an error.
## <P/>
## <Ref Func="DirectProductFamily"/> returns <C>fam</C>, a collections
## family of <Ref Filt="IsDirectProductElement"/> objects.
## <P/>
## <C>fam</C> is the <Ref Filt="CollectionsFamily"/> of
## <Ref Filt="IsDirectProductElement"/> objects
## whose <C>i</C>-th component is in <C>ElementsFamily(args[i])</C>.
## <P/>
## Note that a collection in <C>fam</C> may not itself be a
## direct product; it just is a subcollection of a direct product.
## <P/>
## <Example><![CDATA[
## gap> D8 := DihedralGroup(IsPermGroup, 8);;
## gap> FamilyObj(D8) = CollectionsFamily(PermutationsFamily);
## true
## gap> fam := DirectProductFamily([FamilyObj(D8), FamilyObj(D8)]);;
## gap> ComponentsOfDirectProductElementsFamily(ElementsFamily(fam));
## [ <Family: "PermutationsFamily">, <Family: "PermutationsFamily"> ]
## ]]></Example>
## Also note that not all direct products in &GAP; are created via these
## families. For example if the arguments to <Ref Func="DirectProduct"/>
## are permutation groups, then it returns a permutation group as well, whose
## elements are not <Ref Filt="IsDirectProductElement"/> objects.
## <P/>
## <Example><![CDATA[
## gap> fam = FamilyObj(DirectProduct(D8, D8));
## false
## gap> D4 := DihedralGroup(IsPcGroup, 4);;
## gap> fam2 := DirectProductFamily([FamilyObj(D8), FamilyObj(D4)]);;
## gap> fam2 = FamilyObj(DirectProduct(D8, D4));
## true
## ]]></Example>
## </Description>
## </ManSection>
## <#/GAPDoc>
DeclareGlobalFunction( "DirectProductFamily",
"for a dense list of collection families" );
14 changes: 0 additions & 14 deletions lib/tuples.gi
Original file line number Diff line number Diff line change
Expand Up @@ -506,17 +506,3 @@ InstallOtherMethod( \*,
fi;
return DirectProductElement( List( dpelm, entry -> nonlist * entry ) );
end );


#############################################################################
##
##
InstallGlobalFunction( DirectProductFamily,
function( args )
if not IsDenseList(args) or not ForAll(args, IsCollectionFamily) then
ErrorNoReturn("<args> must be a dense list of collection families");
fi;
return CollectionsFamily(
DirectProductElementsFamily( List( args, ElementsFamily ) )
);
end );
105 changes: 105 additions & 0 deletions tst/testinstall/productdomain.tst
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#@local D8, fam, dpf, d, emptyDPDDim2, emptyDPDDim3, dpdDim0, dpd
#@local range1, range2, g1, g2, dpdOfGroups, bijToRange, inv, tups
#@local dpdNotAttributeStoring
gap> START_TEST("productdomain.tst");

# DirectProductFamily
gap> D8 := DihedralGroup(IsPermGroup, 8);;
gap> fam := FamilyObj(D8);
<Family: "CollectionsFamily(...)">
gap> ElementsFamily(fam);
<Family: "PermutationsFamily">
gap> dpf := DirectProductFamily([fam, fam]);
<Family: "CollectionsFamily(...)">
gap> IsDirectProductElementFamily(ElementsFamily(dpf));
true
gap> DirectProductFamily([CyclotomicsFamily, ]);
Error, <args> must be a dense list of collection families

# DirectProductDomain
# of empty domains, dim 2
gap> d := Domain(FamilyObj([1]), []);
Domain([ ])
gap> emptyDPDDim2 := DirectProductDomain([d, d]);
DirectProductDomain([ Domain([ ]), Domain([ ]) ])
gap> Size(emptyDPDDim2);
0
gap> IsEmpty(emptyDPDDim2);
true
gap> DimensionOfDirectProductDomain(emptyDPDDim2);
2
gap> DirectProductElement([]) in emptyDPDDim2;
false

# of empty domains, dim 3
gap> emptyDPDDim3 := DirectProductDomain(d, 3);
DirectProductDomain([ Domain([ ]), Domain([ ]), Domain([ ]) ])
gap> Size(emptyDPDDim3);
0
gap> IsEmpty(emptyDPDDim3);
true
gap> DimensionOfDirectProductDomain(emptyDPDDim3);
3
gap> DirectProductElement([]) in emptyDPDDim3;
false

# of dimension 0
gap> range1 := Domain([1..5]);
Domain([ 1 .. 5 ])
gap> dpdDim0 := DirectProductDomain(range1, 0);
DirectProductDomain([ ])
gap> Size(dpdDim0);
1
gap> IsEmpty(dpdDim0);
false
gap> DimensionOfDirectProductDomain(dpdDim0);
0
gap> DirectProductElement([]) in dpdDim0;
true

# of domains of ranges
gap> range1;
Domain([ 1 .. 5 ])
gap> range2 := Domain([3..7]);
Domain([ 3 .. 7 ])
gap> dpd := DirectProductDomain([range1, range2]);
DirectProductDomain([ Domain([ 1 .. 5 ]), Domain([ 3 .. 7 ]) ])
gap> Size(dpd);
25
gap> DimensionOfDirectProductDomain(dpd);
2
gap> DirectProductElement([]) in dpd;
false
gap> DirectProductElement([6, 3]) in dpd;
false
gap> DirectProductElement([1, 3]) in dpd;
true

# DirectProductDomain
# of groups
gap> g1 := DihedralGroup(4);
<pc group of size 4 with 2 generators>
gap> g2 := DihedralGroup(IsPermGroup, 4);
Group([ (1,2), (3,4) ])
gap> dpdOfGroups := DirectProductDomain([g1, g2]);
DirectProductDomain([ Group( [ f1, f2 ] ), Group( [ (1,2), (3,4) ] ) ])
gap> Size(dpdOfGroups);
16
gap> DimensionOfDirectProductDomain(dpdOfGroups);
2
gap> DirectProductElement([]) in dpdOfGroups;
false
gap> DirectProductElement([1, 3]) in dpdOfGroups;
false
gap> DirectProductElement([g1.1, g2.1]) in dpdOfGroups;
true

# DirectProductDomain
# error handling
gap> DirectProductDomain([CyclotomicsFamily]);
Error, args must be a dense list of domains
gap> DirectProductDomain(dpd, -1);
Error, <k> must be a nonnegative integer

#
gap> STOP_TEST("productdomain.tst");
13 changes: 0 additions & 13 deletions tst/testinstall/tuples.tst

This file was deleted.

0 comments on commit 0f86f3c

Please sign in to comment.