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 ModularProduct #354

Merged
merged 12 commits into from
Dec 22, 2020
42 changes: 42 additions & 0 deletions doc/oper.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1740,3 +1740,45 @@ gap> DigraphDijkstra(D, 1, 2);
</Description>
</ManSection>
<#/GAPDoc>

wilfwilson marked this conversation as resolved.
Show resolved Hide resolved
<#GAPDoc Label="ModularProduct">
<ManSection>
<Oper Name="ModularProduct" Arg="D1, D2"/>
<Returns>A digraph.</Returns>
<Description>
If <A>D1</A> and <A>D2</A> are digraphs without multiple edges, then
<C>ModularProduct</C> calculates the <E>modular product digraph</E>
(<C>MPD</C>) of <A>D1</A>and <A>D2</A>.

<C>MPD</C> has vertex set <C>V1 x V2</C> where <C>V1</C> is the vertex set of
<A>D1</A> and <C>V2</C> is the vertex set of <A>D2</A> (a vertex
<C>[a, b]</C> has label <C>(a - 1) * |V2| + b</C> in the output). There is
an edge from <C>[a, b]</C> to <C>[c, d]</C> precisely when the following
two conditions are satisfied:
<List>
<Item>
The vertices <C>a</C> and <C>c</C> of <A>D1</A> are equal if and only if
the vertices <C>b</C> and <C>d</C> of <A>D2</A> are equal.
</Item>
<Item>
There is an edge from <C>a</C> to <C>c</C> in <A>D1</A> if and only if
there is an edge from <C>b</C> to <C>d</C> in <A>D2</A>.
</Item>
</List>

Notably, the complete (with loops) subdigraphs of <C>MPD</C> are
precisely the partial isomorphisms from <A>D1</A> to <A>D2</A>.

<Example><![CDATA[
gap> ModularProduct(Digraph([[1], [1, 2]]), Digraph([[], [2]]));
<immutable digraph with 4 vertices, 4 edges>
gap> OutNeighbours(last);
[ [ 4 ], [ 2, 3 ], [ ], [ 4 ] ]
gap> ModularProduct(PetersenGraph(), DigraphSymmetricClosure(CycleDigraph(5)));
<immutable digraph with 50 vertices, 950 edges>
gap> ModularProduct(NullDigraph(0), CompleteDigraph(10));
<immutable empty digraph with 0 vertices>
]]></Example>
</Description>
</ManSection>
<#/GAPDoc>
2 changes: 2 additions & 0 deletions gap/oper.gd
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ DeclareGlobalFunction("DigraphJoin");
DeclareGlobalFunction("DigraphEdgeUnion");
DeclareGlobalFunction("DigraphCartesianProduct");
DeclareGlobalFunction("DigraphDirectProduct");
DeclareOperation("ModularProduct", [IsDigraph, IsDigraph]);

DeclareGlobalFunction("DIGRAPHS_CombinationOperProcessArgs");

# 4. Actions . . .
Expand Down
47 changes: 46 additions & 1 deletion gap/oper.gi
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#
# 1. Adding and removing vertices
# 2. Adding, removing, and reversing edges
# 3. Adding and removing vertices
# 3. Ways of combining digraphs
# 4. Actions
# 5. Substructures and quotients
# 6. In and out degrees, neighbours, and edges of vertices
Expand Down Expand Up @@ -612,6 +612,51 @@ function(arg)
return D;
end);

InstallMethod(ModularProduct, "for a digraph and digraph",
[IsDigraph, IsDigraph],
function(D1, D2)
local m, n, E1, E2, edges, next, map, u, v, w, x;

if IsMultiDigraph(D1) or IsMultiDigraph(D2) then
ErrorNoReturn("ModularProduct does not support multidigraphs,");
fi;

m := DigraphNrVertices(D1);
n := DigraphNrVertices(D2);

E1 := DigraphDual(D1);
E2 := DigraphDual(D2);

edges := EmptyPlist(m * n);
next := 0;

map := function(a, b)
return (a - 1) * n + b;
end;

for u in [1 .. m] do
for v in [1 .. n] do
next := next + 1;
edges[next] := [];
for w in OutNeighbours(D1)[u] do
for x in OutNeighbours(D2)[v] do
if (u = w) = (v = x) then
Add(edges[next], map(w, x));
fi;
od;
od;
for w in OutNeighbours(E1)[u] do
for x in OutNeighbours(E2)[v] do
if (u = w) = (v = x) then
Add(edges[next], map(w, x));
fi;
od;
od;
od;
od;
return DigraphNC(edges);
end);

###############################################################################
# 4. Actions
###############################################################################
Expand Down
68 changes: 68 additions & 0 deletions tst/standard/oper.tst
Original file line number Diff line number Diff line change
Expand Up @@ -2043,6 +2043,74 @@ gap> DigraphDijkstra(gr, 1, 2);
gap> DigraphDijkstra(gr, 1, 3);
[ [ 0, 1, 1, 1 ], [ -1, 1, 1, 1 ] ]

#ModularProduct
gap> ModularProduct(NullDigraph(0), CompleteDigraph(10));
<immutable empty digraph with 0 vertices>
gap> ModularProduct(PetersenGraph(), CompleteDigraph(10));
<immutable digraph with 100 vertices, 2800 edges>
gap> ModularProduct(NullDigraph(10), CompleteDigraph(10));
<immutable digraph with 100 vertices, 100 edges>
gap> ModularProduct(Digraph([[1], [1, 2]]), Digraph([[], [2]]));
<immutable digraph with 4 vertices, 4 edges>
gap> OutNeighbours(last);
[ [ 4 ], [ 2, 3 ], [ ], [ 4 ] ]
gap> ModularProduct(PetersenGraph(), DigraphSymmetricClosure(CycleDigraph(5)));
<immutable digraph with 50 vertices, 950 edges>
gap> OutNeighbours(last);
[ [ 7, 10, 22, 25, 27, 30, 1, 13, 14, 18, 19, 33, 34, 38, 39, 43, 44, 48, 49 ]
, [ 6, 8, 21, 23, 26, 28, 2, 14, 15, 19, 20, 34, 35, 39, 40, 44, 45, 49,
50 ],
[ 7, 9, 22, 24, 27, 29, 3, 11, 15, 16, 20, 31, 35, 36, 40, 41, 45, 46, 50 ],
[ 8, 10, 23, 25, 28, 30, 4, 11, 12, 16, 17, 31, 32, 36, 37, 41, 42, 46, 47 ]
, [ 6, 9, 21, 24, 26, 29, 5, 12, 13, 17, 18, 32, 33, 37, 38, 42, 43, 47,
48 ],
[ 2, 5, 12, 15, 32, 35, 6, 18, 19, 23, 24, 28, 29, 38, 39, 43, 44, 48, 49 ],
[ 1, 3, 11, 13, 31, 33, 7, 19, 20, 24, 25, 29, 30, 39, 40, 44, 45, 49, 50 ],
[ 2, 4, 12, 14, 32, 34, 8, 16, 20, 21, 25, 26, 30, 36, 40, 41, 45, 46, 50 ],
[ 3, 5, 13, 15, 33, 35, 9, 16, 17, 21, 22, 26, 27, 36, 37, 41, 42, 46, 47 ],
[ 1, 4, 11, 14, 31, 34, 10, 17, 18, 22, 23, 27, 28, 37, 38, 42, 43, 47, 48 ]
, [ 7, 10, 17, 20, 37, 40, 3, 4, 11, 23, 24, 28, 29, 33, 34, 43, 44, 48,
49 ], [ 6, 8, 16, 18, 36, 38, 4, 5, 12, 24, 25, 29, 30, 34, 35, 44, 45,
49, 50 ],
[ 7, 9, 17, 19, 37, 39, 1, 5, 13, 21, 25, 26, 30, 31, 35, 41, 45, 46, 50 ],
[ 8, 10, 18, 20, 38, 40, 1, 2, 14, 21, 22, 26, 27, 31, 32, 41, 42, 46, 47 ],
[ 6, 9, 16, 19, 36, 39, 2, 3, 15, 22, 23, 27, 28, 32, 33, 42, 43, 47, 48 ],
[ 12, 15, 22, 25, 42, 45, 3, 4, 8, 9, 16, 28, 29, 33, 34, 38, 39, 48, 49 ],
[ 11, 13, 21, 23, 41, 43, 4, 5, 9, 10, 17, 29, 30, 34, 35, 39, 40, 49, 50 ],
[ 12, 14, 22, 24, 42, 44, 1, 5, 6, 10, 18, 26, 30, 31, 35, 36, 40, 46, 50 ],
[ 13, 15, 23, 25, 43, 45, 1, 2, 6, 7, 19, 26, 27, 31, 32, 36, 37, 46, 47 ],
[ 11, 14, 21, 24, 41, 44, 2, 3, 7, 8, 20, 27, 28, 32, 33, 37, 38, 47, 48 ],
[ 2, 5, 17, 20, 47, 50, 8, 9, 13, 14, 21, 28, 29, 33, 34, 38, 39, 43, 44 ],
[ 1, 3, 16, 18, 46, 48, 9, 10, 14, 15, 22, 29, 30, 34, 35, 39, 40, 44, 45 ],
[ 2, 4, 17, 19, 47, 49, 6, 10, 11, 15, 23, 26, 30, 31, 35, 36, 40, 41, 45 ],
[ 3, 5, 18, 20, 48, 50, 6, 7, 11, 12, 24, 26, 27, 31, 32, 36, 37, 41, 42 ],
[ 1, 4, 16, 19, 46, 49, 7, 8, 12, 13, 25, 27, 28, 32, 33, 37, 38, 42, 43 ],
[ 2, 5, 37, 40, 42, 45, 8, 9, 13, 14, 18, 19, 23, 24, 26, 33, 34, 48, 49 ],
[ 1, 3, 36, 38, 41, 43, 9, 10, 14, 15, 19, 20, 24, 25, 27, 34, 35, 49, 50 ],
[ 2, 4, 37, 39, 42, 44, 6, 10, 11, 15, 16, 20, 21, 25, 28, 31, 35, 46, 50 ],
[ 3, 5, 38, 40, 43, 45, 6, 7, 11, 12, 16, 17, 21, 22, 29, 31, 32, 46, 47 ],
[ 1, 4, 36, 39, 41, 44, 7, 8, 12, 13, 17, 18, 22, 23, 30, 32, 33, 47, 48 ],
[ 7, 10, 42, 45, 47, 50, 3, 4, 13, 14, 18, 19, 23, 24, 28, 29, 31, 38, 39 ],
[ 6, 8, 41, 43, 46, 48, 4, 5, 14, 15, 19, 20, 24, 25, 29, 30, 32, 39, 40 ],
[ 7, 9, 42, 44, 47, 49, 1, 5, 11, 15, 16, 20, 21, 25, 26, 30, 33, 36, 40 ],
[ 8, 10, 43, 45, 48, 50, 1, 2, 11, 12, 16, 17, 21, 22, 26, 27, 34, 36, 37 ],
[ 6, 9, 41, 44, 46, 49, 2, 3, 12, 13, 17, 18, 22, 23, 27, 28, 35, 37, 38 ],
[ 12, 15, 27, 30, 47, 50, 3, 4, 8, 9, 18, 19, 23, 24, 33, 34, 36, 43, 44 ],
[ 11, 13, 26, 28, 46, 48, 4, 5, 9, 10, 19, 20, 24, 25, 34, 35, 37, 44, 45 ],
[ 12, 14, 27, 29, 47, 49, 1, 5, 6, 10, 16, 20, 21, 25, 31, 35, 38, 41, 45 ],
[ 13, 15, 28, 30, 48, 50, 1, 2, 6, 7, 16, 17, 21, 22, 31, 32, 39, 41, 42 ],
[ 11, 14, 26, 29, 46, 49, 2, 3, 7, 8, 17, 18, 22, 23, 32, 33, 40, 42, 43 ],
[ 17, 20, 27, 30, 32, 35, 3, 4, 8, 9, 13, 14, 23, 24, 38, 39, 41, 48, 49 ],
[ 16, 18, 26, 28, 31, 33, 4, 5, 9, 10, 14, 15, 24, 25, 39, 40, 42, 49, 50 ],
[ 17, 19, 27, 29, 32, 34, 1, 5, 6, 10, 11, 15, 21, 25, 36, 40, 43, 46, 50 ],
[ 18, 20, 28, 30, 33, 35, 1, 2, 6, 7, 11, 12, 21, 22, 36, 37, 44, 46, 47 ],
[ 16, 19, 26, 29, 31, 34, 2, 3, 7, 8, 12, 13, 22, 23, 37, 38, 45, 47, 48 ],
[ 22, 25, 32, 35, 37, 40, 3, 4, 8, 9, 13, 14, 18, 19, 28, 29, 43, 44, 46 ],
[ 21, 23, 31, 33, 36, 38, 4, 5, 9, 10, 14, 15, 19, 20, 29, 30, 44, 45, 47 ],
[ 22, 24, 32, 34, 37, 39, 1, 5, 6, 10, 11, 15, 16, 20, 26, 30, 41, 45, 48 ],
[ 23, 25, 33, 35, 38, 40, 1, 2, 6, 7, 11, 12, 16, 17, 26, 27, 41, 42, 49 ],
[ 21, 24, 31, 34, 36, 39, 2, 3, 7, 8, 12, 13, 17, 18, 27, 28, 42, 43, 50 ] ]

#DIGRAPHS_UnbindVariables
gap> Unbind(a);
gap> Unbind(adj);
Expand Down