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

Creates new files `productdomain.g{d,i}`, `tst/testinstall/productdomain.tst`.
Moves the declaration, definition, and tests of `DirectProductFamily` there.

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

Adds:
- a filter IsDirectProductDomain
- an operation DirectProductDomain to create IsDirectProductDomain
  domains and methods for it
- attributes and methods for IsDirectProductDomain objects:
  - ComponentsOfDirectProductDomain, this defines the domain
  - DimensionOfDirectProductDomain, the number of components
  - PrintObj
  - Size
  - \in
  • Loading branch information
ssiccha committed May 27, 2019
1 parent f9a40e0 commit ea4aa40
Show file tree
Hide file tree
Showing 9 changed files with 261 additions and 70 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
51 changes: 51 additions & 0 deletions lib/productdomain.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#############################################################################
##
## 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 a collections family <C>fam</C>
## with the following property:
## Each collection <C>coll</C> in <C>fam</C> is a direct product
## whose <C>i</C>-th factors are collections in <C>args[i]</C>.
## This is modelled on the level of the elements by requiring that each
## <C>elm</C> of <C>coll</C> must be an <Ref Filt="IsDirectProductElement"/>
## object with <C>elm[i]</C> contained in <C>ElementsFamily(args[i])</C>.
## <P/>
## Note though that not all direct products in &GAP; are created via these
## families, see for example <Ref Func="DirectProduct"/> for permutation
## groups.
## <P/>
## <Example><![CDATA[
## gap> D8 := DihedralGroup(IsPermGroup, 8);;
## gap> fam := FamilyObj(D8);
## <Family: "CollectionsFamily(...)">
## gap> ElementsFamily(fam);
## <Family: "PermutationsFamily">
## gap> productFamily := DirectProductFamily([fam, fam]);
## <Family: "CollectionsFamily(...)">
## gap> elmsOfProductFamily := ElementsFamily(productFamily);
## <Family: "DirectProductElementsFamily( <<famlist>> )">
## gap> ComponentsOfDirectProductElementsFamily(elmsOfProductFamily);
## [ <Family: "PermutationsFamily">, <Family: "PermutationsFamily"> ]
## ]]></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
43 changes: 0 additions & 43 deletions lib/tuples.gd
Original file line number Diff line number Diff line change
Expand Up @@ -178,46 +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 a collections family <C>fam</C>
## with the following property:
## Each collection <C>coll</C> in <C>fam</C> is a direct product
## whose <C>i</C>-th factors are collections in <C>args[i]</C>.
## This is modelled on the level of the elements by requiring that each
## <C>elm</C> of <C>coll</C> must be an <Ref Filt="IsDirectProductElement"/>
## object with <C>elm[i]</C> contained in <C>ElementsFamily(args[i])</C>.
## <P/>
## Note though that not all direct products in &GAP; are created via these
## families, see for example <Ref Func="DirectProduct"/> for permutation
## groups.
## <P/>
## <Example><![CDATA[
## gap> D8 := DihedralGroup(IsPermGroup, 8);;
## gap> fam := FamilyObj(D8);
## <Family: "CollectionsFamily(...)">
## gap> ElementsFamily(fam);
## <Family: "PermutationsFamily">
## gap> productFamily := DirectProductFamily([fam, fam]);
## <Family: "CollectionsFamily(...)">
## gap> elmsOfProductFamily := ElementsFamily(productFamily);
## <Family: "DirectProductElementsFamily( <<famlist>> )">
## gap> ComponentsOfDirectProductElementsFamily(elmsOfProductFamily);
## [ <Family: "PermutationsFamily">, <Family: "PermutationsFamily"> ]
## ]]></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 ea4aa40

Please sign in to comment.