From a12432f4300ee60390afc97eb483efab4e87e772 Mon Sep 17 00:00:00 2001 From: Finn Buck Date: Wed, 10 Feb 2021 16:47:23 +0100 Subject: [PATCH] Add HaarGraph (PR #408) --- doc/examples.xml | 47 +++++++++++++++++++++++++++++++++++++++ doc/z-chap2.xml | 1 + gap/examples.gd | 4 ++++ gap/examples.gi | 41 ++++++++++++++++++++++++++++++++++ gap/utils.gd | 2 ++ gap/utils.gi | 18 +++++++++++++++ tst/standard/examples.tst | 22 ++++++++++++++++++ 7 files changed, 135 insertions(+) diff --git a/doc/examples.xml b/doc/examples.xml index 242215678..ba6145326 100644 --- a/doc/examples.xml +++ b/doc/examples.xml @@ -389,3 +389,50 @@ gap> KnightsGraph(IsMutable, 3, 9); <#/GAPDoc> + +<#GAPDoc Label="HaarGraph"> + + + A digraph. + + If n is a positive integer then this operation returns + the Haar graph H(n).

+ + From + https://mathworld.wolfram.com/HaarGraph.html: +

+ + A Haar graph H(n) is a bipartite regular vertex-transitive graph + indexed by a positive integer and obtained by a simple binary encoding of + cyclically adjacent vertices. Haar graphs may be connected or + disconnected.

+ + The number of vertices in the Haar graph H(n) is + equal to twice m, where m is the number of digits + required to represent n in binary. + These vertices are arranged into bicomponents + [1..m] and [m+1..2*m]. + Vertices i and j in different bicomponents are + adjacent by a symmetric pair of edges if and only if + the binary representation of n has a 1 in position + (j-i modulo m) + 1 from the left.

+ + If the optional first argument filt is present, then this should + specify the category or representation the digraph being created will + belong to. For example, if filt is , + then the digraph being created will be mutable, if filt is , then the digraph will be immutable. + If the optional first argument filt is not present, then is used by default.

+ + HaarGraph(3); + +gap> D := HaarGraph(16); + +]]> + + +<#/GAPDoc> diff --git a/doc/z-chap2.xml b/doc/z-chap2.xml index 7d4d28826..7beb2b584 100644 --- a/doc/z-chap2.xml +++ b/doc/z-chap2.xml @@ -87,6 +87,7 @@ <#Include Label="JohnsonDigraph"> <#Include Label="PetersenGraph"> <#Include Label="GeneralisedPetersenGraph"> + <#Include Label="HaarGraph"> <#Include Label="KnightsGraph"> <#Include Label="StarDigraph"> diff --git a/gap/examples.gd b/gap/examples.gd index e3a1e15d6..60f5eec7e 100644 --- a/gap/examples.gd +++ b/gap/examples.gd @@ -56,3 +56,7 @@ DeclareOperation("StarDigraph", [IsFunction, IsPosInt]); DeclareConstructor("KnightsGraphCons", [IsDigraph, IsPosInt, IsPosInt]); DeclareOperation("KnightsGraph", [IsPosInt, IsPosInt]); DeclareOperation("KnightsGraph", [IsFunction, IsPosInt, IsPosInt]); + +DeclareConstructor("HaarGraphCons", [IsDigraph, IsPosInt]); +DeclareOperation("HaarGraph", [IsPosInt]); +DeclareOperation("HaarGraph", [IsFunction, IsPosInt]); diff --git a/gap/examples.gi b/gap/examples.gi index b829bd2af..24ba8cafc 100644 --- a/gap/examples.gi +++ b/gap/examples.gi @@ -446,3 +446,44 @@ KnightsGraphCons); InstallMethod(KnightsGraph, "for two positive integers", [IsPosInt, IsPosInt], {m, n} -> KnightsGraphCons(IsImmutableDigraph, m, n)); + +InstallMethod(HaarGraphCons, +"for IsMutableDigraph and a positive integer", +[IsMutableDigraph, IsPosInt], +function(filt, n) + local m, binaryList, D, i, j; + m := Log(n, 2) + 1; + binaryList := DIGRAPHS_BlistNumber(n + 1, m); + D := EmptyDigraph(IsMutableDigraph, 2 * m); + + for i in [1 .. m] do + for j in [1 .. m] do + if binaryList[((j - i) mod m) + 1] then + DigraphAddEdge(D, [i, m + j]); + fi; + od; + od; + + return DigraphSymmetricClosure(D); +end); + +InstallMethod(HaarGraphCons, +"for IsImmutableDigraph and a positive integer", +[IsImmutableDigraph, IsPosInt], +function(filt, n) + local D; + D := MakeImmutable(HaarGraphCons(IsMutableDigraph, n)); + SetIsMultiDigraph(D, false); + SetIsSymmetricDigraph(D, true); + SetIsRegularDigraph(D, true); + SetIsVertexTransitive(D, true); + SetIsBipartiteDigraph(D, true); + return D; +end); + +InstallMethod(HaarGraph, "for a function and a positive integer", +[IsFunction, IsPosInt], +HaarGraphCons); + +InstallMethod(HaarGraph, "for a positive integer", [IsPosInt], +{n} -> HaarGraphCons(IsImmutableDigraph, n)); diff --git a/gap/utils.gd b/gap/utils.gd index 6dc45dc79..61d352c3c 100644 --- a/gap/utils.gd +++ b/gap/utils.gd @@ -23,3 +23,5 @@ DeclareGlobalFunction("DigraphsTestExtreme"); DeclareGlobalFunction("DigraphsTestInstall"); DeclareGlobalFunction("DigraphsTestStandard"); DeclareGlobalFunction("DigraphsTestManualExamples"); + +DeclareGlobalFunction("DIGRAPHS_BlistNumber"); diff --git a/gap/utils.gi b/gap/utils.gi index 0bc647dfd..8ae2f37af 100644 --- a/gap/utils.gi +++ b/gap/utils.gi @@ -555,3 +555,21 @@ DIGRAPHS_CheckManualConsistency := function() DIGRAPHS_CheckDocCoverage(doc); return DIGRAPHS_CheckManSectionTypes(doc, true); end; + +InstallGlobalFunction(DIGRAPHS_BlistNumber, +function(nr, n) + local x, q, i; + + x := BlistList([1 .. n], []); + nr := nr - 1; # to be in [0 .. 2 ^ n - 1] + for i in [n, n - 1 .. 1] do + q := nr mod 2; + if q = 0 then + x[i] := false; + else + x[i] := true; + fi; + nr := (nr - q) / 2; + od; + return x; +end); diff --git a/tst/standard/examples.tst b/tst/standard/examples.tst index c281eb55e..c15910428 100644 --- a/tst/standard/examples.tst +++ b/tst/standard/examples.tst @@ -252,6 +252,28 @@ false gap> KnightsGraph(IsMutable, 3, 9); +# DIGRAPHS_HaarGraph +gap> HaarGraph(1); + +gap> OutNeighbours(last); +[ [ 2 ], [ 1 ] ] +gap> HaarGraph(2); + +gap> OutNeighbours(last); +[ [ 3 ], [ 4 ], [ 1 ], [ 2 ] ] +gap> HaarGraph(3); + +gap> OutNeighbours(last); +[ [ 3, 4 ], [ 3, 4 ], [ 1, 2 ], [ 1, 2 ] ] +gap> D := HaarGraph(16); + +gap> IsBipartiteDigraph(D); +true + # gap> DIGRAPHS_StopTest(); gap> STOP_TEST("Digraphs package: standard/examples.tst", 0);