From c31b830137ad889fb93502dca3b37224c3d93672 Mon Sep 17 00:00:00 2001 From: "James D. Mitchell" Date: Tue, 25 Jun 2024 13:29:44 +0100 Subject: [PATCH 01/23] Some template improvements --- gap/attributes/isomorph.gi | 19 ++++++++++++++----- gap/attributes/isorms.gi | 2 +- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/gap/attributes/isomorph.gi b/gap/attributes/isomorph.gi index 5d28954a8..266516c5a 100644 --- a/gap/attributes/isomorph.gi +++ b/gap/attributes/isomorph.gi @@ -107,6 +107,16 @@ InstallMethod(IsIsomorphicSemigroup, "for semigroups", [IsSemigroup, IsSemigroup], {S, T} -> IsomorphismSemigroups(S, T) <> fail); +InstallMethod(IsIsomorphicSemigroup, "for semigroups", +[IsSimpleSemigroup, IsSimpleSemigroup], +function(S, T) + if not IsReesMatrixSemigroup(S) then + SS := Range(IsomorphismReesMatrixSemigroupOverPermGroup(S); + fi; + # Same for T + return CanonicalReesMatrixSemigroup(S) = CanonicalReesMatrixSemigroup(T); +end); + InstallMethod(IsomorphismSemigroups, "for finite simple semigroups", [IsSimpleSemigroup and IsFinite, IsSimpleSemigroup and IsFinite], function(S, T) @@ -279,13 +289,12 @@ function(S, T) return fail; fi; - DS := SEMIGROUPS.CanonicalDigraph(S); - DT := SEMIGROUPS.CanonicalDigraph(T); - p := IsomorphismDigraphs(DS[1], DT[1], DS[2], DT[2]); - if p = fail then + if CanonicalMultiplicationTable(S) <> CanonicalMultiplicationTable(T) then return fail; fi; - p := RestrictedPerm(p, [1 .. Size(S)]); + p := CanonicalMultiplicationTablePerm(S) + * CanonicalMultiplicationTablePerm(T) ^ -1; + map := x -> AsSSortedList(T)[PositionSorted(S, x) ^ p]; inv := x -> AsSSortedList(S)[PositionSorted(T, x) ^ (p ^ -1)]; return SemigroupIsomorphismByFunctionNC(S, T, map, inv); diff --git a/gap/attributes/isorms.gi b/gap/attributes/isorms.gi index 60e6e75b9..16eb327f8 100644 --- a/gap/attributes/isorms.gi +++ b/gap/attributes/isorms.gi @@ -1368,7 +1368,7 @@ function(S) end); InstallMethod(CanonicalReesMatrixSemigroup, -"for a Rees 0-matrix semigroup", +"for a Rees matrix semigroup", [IsReesMatrixSemigroup], function(S) local G, mat; From 43f85035967445e5c9ed8916f00a95629ad53d41 Mon Sep 17 00:00:00 2001 From: "James D. Mitchell" Date: Thu, 27 Jun 2024 13:45:05 +0100 Subject: [PATCH 02/23] More example isomorph code --- gap/attributes/isomorph.gi | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/gap/attributes/isomorph.gi b/gap/attributes/isomorph.gi index 266516c5a..2f39ec9cc 100644 --- a/gap/attributes/isomorph.gi +++ b/gap/attributes/isomorph.gi @@ -105,7 +105,16 @@ end); InstallMethod(IsIsomorphicSemigroup, "for semigroups", [IsSemigroup, IsSemigroup], -{S, T} -> IsomorphismSemigroups(S, T) <> fail); +function(S, T) + if IsSimpleSemigroup(S) and IsSimpleSemigroup(T) then + return IsIsomorphicSemigroup(Range(IsomorphismReesMatrixSemigroup(S)), ...); + fi; + return IsomorphismSemigroups(S, T) <> fail; +end); + +InstallMethod(IsIsomorphicSemigroup, "for Rees matrix semigroups", +[IsReesMatrixSemigroup, IsReesMatrixSemigroup], +IsIsomorphicRMS); InstallMethod(IsIsomorphicSemigroup, "for semigroups", [IsSimpleSemigroup, IsSimpleSemigroup], From 90aafa27b5d63cc547dea673cd63fbdf2215869d Mon Sep 17 00:00:00 2001 From: Tillman Froehlich Date: Fri, 28 Jun 2024 12:39:23 +0100 Subject: [PATCH 03/23] Added the isomtest file created in the meeting yesterday --- gap/attributes/isomtest.g | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 gap/attributes/isomtest.g diff --git a/gap/attributes/isomtest.g b/gap/attributes/isomtest.g new file mode 100644 index 000000000..757143164 --- /dev/null +++ b/gap/attributes/isomtest.g @@ -0,0 +1,39 @@ +RandomIsomorphicRMS := function(R) + local table, p, S; + if Size(R) > 384 then + ErrorNoReturn("Tillman what were thinking???"); + fi; + table := MultiplicationTable(R); + p := Random(SymmetricGroup(Size(R))); + S := SemigroupByMultiplicationTableNC(OnMultiplicationTable(table, p)); + return Range(IsomorphismReesMatrixSemigroup(S)); +end; + +# TODO check that this is faster than computing CanonicalMultiplicationTable + +IsIsomorphicRMS := function(R, S) + local uR, uS, map; + # TODO check that R and S have the same dimensions, and same size underlying group + R := CanonicalReesMatrixSemigroup(R); + uR := UnderlyingSemigroup(R); + uS := UnderlyingSemigroup(S); + # TODO check if uR, uS is a group + map := IsomorphismGroups(uS, uR); + if map = fail then + return false; + fi; + + mat := []; + for row in Matrix(S) do + next := []; + for entry in row do + Add(next, entry ^ map); + od; + Add(mat, next); + od; + S := ReesMatrixSemigroup(uR, mat); + S := CanonicalReesMatrixSemigroup(S); + return Matrix(R) = Matrix(S); +end; + +# TODO similar thing for RZMS From da909422cca7bcb1d40f6c813cb19a0110529ac3 Mon Sep 17 00:00:00 2001 From: Tillman Froehlich Date: Fri, 28 Jun 2024 12:55:52 +0100 Subject: [PATCH 04/23] Fixed some (but not all) syntax errors --- gap/attributes/isomorph.gi | 6 ++++-- gap/attributes/isomtest.g | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/gap/attributes/isomorph.gi b/gap/attributes/isomorph.gi index 2f39ec9cc..5f0fbd02e 100644 --- a/gap/attributes/isomorph.gi +++ b/gap/attributes/isomorph.gi @@ -107,7 +107,8 @@ InstallMethod(IsIsomorphicSemigroup, "for semigroups", [IsSemigroup, IsSemigroup], function(S, T) if IsSimpleSemigroup(S) and IsSimpleSemigroup(T) then - return IsIsomorphicSemigroup(Range(IsomorphismReesMatrixSemigroup(S)), ...); + return IsIsomorphicSemigroup(Range(IsomorphismReesMatrixSemigroup(S)), + Range(IsomorphismReesMatrixSemigroups(T))); fi; return IsomorphismSemigroups(S, T) <> fail; end); @@ -119,8 +120,9 @@ IsIsomorphicRMS); InstallMethod(IsIsomorphicSemigroup, "for semigroups", [IsSimpleSemigroup, IsSimpleSemigroup], function(S, T) + local SS; if not IsReesMatrixSemigroup(S) then - SS := Range(IsomorphismReesMatrixSemigroupOverPermGroup(S); + SS := Range(IsomorphismReesMatrixSemigroupOverPermGroup(S)); fi; # Same for T return CanonicalReesMatrixSemigroup(S) = CanonicalReesMatrixSemigroup(T); diff --git a/gap/attributes/isomtest.g b/gap/attributes/isomtest.g index 757143164..7d90e8d43 100644 --- a/gap/attributes/isomtest.g +++ b/gap/attributes/isomtest.g @@ -1,7 +1,7 @@ RandomIsomorphicRMS := function(R) local table, p, S; if Size(R) > 384 then - ErrorNoReturn("Tillman what were thinking???"); + ErrorNoReturn("Tillman what were you thinking???"); fi; table := MultiplicationTable(R); p := Random(SymmetricGroup(Size(R))); @@ -12,7 +12,7 @@ end; # TODO check that this is faster than computing CanonicalMultiplicationTable IsIsomorphicRMS := function(R, S) - local uR, uS, map; + local uR, uS, map, mat, next, row, entry; # TODO check that R and S have the same dimensions, and same size underlying group R := CanonicalReesMatrixSemigroup(R); uR := UnderlyingSemigroup(R); From ac959811def54e73c87067634a3d042b8ce6d137 Mon Sep 17 00:00:00 2001 From: Tillman Froehlich Date: Tue, 2 Jul 2024 10:22:19 +0100 Subject: [PATCH 05/23] Added reminder of which packages to load --- gap/attributes/isomtest.g | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gap/attributes/isomtest.g b/gap/attributes/isomtest.g index 7d90e8d43..a38ee8d3b 100644 --- a/gap/attributes/isomtest.g +++ b/gap/attributes/isomtest.g @@ -1,3 +1,6 @@ +# LoadPackage("Semigroups"); +# LoadPackage("smallsemi"); + RandomIsomorphicRMS := function(R) local table, p, S; if Size(R) > 384 then From 6bc39003ff8c7386e712034791b9d2d9dbf76a50 Mon Sep 17 00:00:00 2001 From: Tillman Froehlich Date: Tue, 2 Jul 2024 10:46:37 +0100 Subject: [PATCH 06/23] Removed useless comments --- gap/attributes/isomtest.g | 3 --- 1 file changed, 3 deletions(-) diff --git a/gap/attributes/isomtest.g b/gap/attributes/isomtest.g index a38ee8d3b..7d90e8d43 100644 --- a/gap/attributes/isomtest.g +++ b/gap/attributes/isomtest.g @@ -1,6 +1,3 @@ -# LoadPackage("Semigroups"); -# LoadPackage("smallsemi"); - RandomIsomorphicRMS := function(R) local table, p, S; if Size(R) > 384 then From 98f816f8b41ed1eaaa792d149409b85c415e2fb3 Mon Sep 17 00:00:00 2001 From: Tillman Froehlich Date: Tue, 2 Jul 2024 11:54:46 +0100 Subject: [PATCH 07/23] Commented out code that doesn't work yet --- gap/attributes/isomorph.gi | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/gap/attributes/isomorph.gi b/gap/attributes/isomorph.gi index 5f0fbd02e..c43fe624f 100644 --- a/gap/attributes/isomorph.gi +++ b/gap/attributes/isomorph.gi @@ -106,27 +106,27 @@ end); InstallMethod(IsIsomorphicSemigroup, "for semigroups", [IsSemigroup, IsSemigroup], function(S, T) - if IsSimpleSemigroup(S) and IsSimpleSemigroup(T) then - return IsIsomorphicSemigroup(Range(IsomorphismReesMatrixSemigroup(S)), - Range(IsomorphismReesMatrixSemigroups(T))); - fi; + #if IsSimpleSemigroup(S) and IsSimpleSemigroup(T) then + # return IsIsomorphicSemigroup(Range(IsomorphismReesMatrixSemigroup(S)), + # Range(IsomorphismReesMatrixSemigroup(T))); + #fi; return IsomorphismSemigroups(S, T) <> fail; end); -InstallMethod(IsIsomorphicSemigroup, "for Rees matrix semigroups", -[IsReesMatrixSemigroup, IsReesMatrixSemigroup], -IsIsomorphicRMS); - -InstallMethod(IsIsomorphicSemigroup, "for semigroups", -[IsSimpleSemigroup, IsSimpleSemigroup], -function(S, T) - local SS; - if not IsReesMatrixSemigroup(S) then - SS := Range(IsomorphismReesMatrixSemigroupOverPermGroup(S)); - fi; - # Same for T - return CanonicalReesMatrixSemigroup(S) = CanonicalReesMatrixSemigroup(T); -end); +#InstallMethod(IsIsomorphicSemigroup, "for Rees matrix semigroups", +#[IsReesMatrixSemigroup, IsReesMatrixSemigroup], +#IsIsomorphicRMS); + +#InstallMethod(IsIsomorphicSemigroup, "for semigroups", +#[IsSimpleSemigroup, IsSimpleSemigroup], +#function(S, T) +# local SS; +# if not IsReesMatrixSemigroup(S) then +# SS := Range(IsomorphismReesMatrixSemigroupOverPermGroup(S)); +# fi; +# # Same for T +# return CanonicalReesMatrixSemigroup(S) = CanonicalReesMatrixSemigroup(T); +#end); InstallMethod(IsomorphismSemigroups, "for finite simple semigroups", [IsSimpleSemigroup and IsFinite, IsSimpleSemigroup and IsFinite], From cfa3fc2fe25d23c1b7e9a7247ce8b2194f66d204 Mon Sep 17 00:00:00 2001 From: awesometillman Date: Wed, 3 Jul 2024 15:58:49 +0100 Subject: [PATCH 08/23] Added function to make some random Rees matrix semigroups. --- gap/attributes/isomtest.g | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/gap/attributes/isomtest.g b/gap/attributes/isomtest.g index 7d90e8d43..c4f49f6c8 100644 --- a/gap/attributes/isomtest.g +++ b/gap/attributes/isomtest.g @@ -37,3 +37,17 @@ IsIsomorphicRMS := function(R, S) end; # TODO similar thing for RZMS + +MakeSomeRMS := function(n) + local semigroups_list, S; + + semigroups_list := []; + while Length(semigroups_list) < n do + S := RandomSemigroup(IsReesMatrixSemigroup, 2, 2); + if Size(S) < 384 then + Append(semigroups_list, [S]); + fi; + od; + + return semigroups_list; +end; From caef41114d5b2e26dbfbb34a17b8e96fa0716387 Mon Sep 17 00:00:00 2001 From: awesometillman Date: Wed, 3 Jul 2024 16:54:24 +0100 Subject: [PATCH 09/23] Added testing function to compare isomorphism functions. --- gap/attributes/isomtest.g | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/gap/attributes/isomtest.g b/gap/attributes/isomtest.g index c4f49f6c8..fb44f2a27 100644 --- a/gap/attributes/isomtest.g +++ b/gap/attributes/isomtest.g @@ -1,6 +1,6 @@ RandomIsomorphicRMS := function(R) local table, p, S; - if Size(R) > 384 then + if Size(R) > 1000 then ErrorNoReturn("Tillman what were you thinking???"); fi; table := MultiplicationTable(R); @@ -39,15 +39,37 @@ end; # TODO similar thing for RZMS MakeSomeRMS := function(n) + # Returns a list of n small Rees matrix semigroups local semigroups_list, S; semigroups_list := []; while Length(semigroups_list) < n do - S := RandomSemigroup(IsReesMatrixSemigroup, 2, 2); - if Size(S) < 384 then + S := RandomSemigroup(IsReesMatrixSemigroup, 4, 5, AlternatingGroup(4)); + if Size(S) < 1000 then Append(semigroups_list, [S]); fi; od; return semigroups_list; end; + +TestRMS := function(S, n) + # Tests isomorphism algorithms on given semigroup S + # by comparing it to n random isomorphic RMS + local T, i, runtime; + + for i in [1 .. n] do + T := RandomIsomorphicRMS(S); + Print("Semigroup ", i, "\n"); + + Print("using IsIsomorphicRMS\n"); + runtime := Runtime(); + Print(IsIsomorphicRMS(S, T), "\n"); + Print(Runtime() - runtime, "\n"); + + Print("using IsIsomorphicSemigroup\n"); + runtime := Runtime(); + Print(IsIsomorphicSemigroup(S, T), "\n"); + Print(Runtime() - runtime, "\n"); + od; +end; \ No newline at end of file From dc79b2540783f8c722be2b3ca30c710765227ccd Mon Sep 17 00:00:00 2001 From: awesometillman Date: Wed, 3 Jul 2024 17:06:59 +0100 Subject: [PATCH 10/23] Improved testing function --- gap/attributes/isomtest.g | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/gap/attributes/isomtest.g b/gap/attributes/isomtest.g index fb44f2a27..cefb05317 100644 --- a/gap/attributes/isomtest.g +++ b/gap/attributes/isomtest.g @@ -56,20 +56,32 @@ end; TestRMS := function(S, n) # Tests isomorphism algorithms on given semigroup S # by comparing it to n random isomorphic RMS - local T, i, runtime; + local T, i, runtime, oldres, oldtime, newres, newtime, score, mismatches; + score := [0, 0]; + mismatches := 0; for i in [1 .. n] do T := RandomIsomorphicRMS(S); - Print("Semigroup ", i, "\n"); - Print("using IsIsomorphicRMS\n"); runtime := Runtime(); - Print(IsIsomorphicRMS(S, T), "\n"); - Print(Runtime() - runtime, "\n"); + newres := IsIsomorphicRMS(S, T); + newtime := Runtime() - runtime; - Print("using IsIsomorphicSemigroup\n"); runtime := Runtime(); - Print(IsIsomorphicSemigroup(S, T), "\n"); - Print(Runtime() - runtime, "\n"); + oldres := IsIsomorphicSemigroup(S, T); + oldtime := Runtime() - runtime; + + if not newres = oldres then + mismatches := mismatches + 1; + fi; + + if newtime < oldtime then + score[1] := score[1] + 1; + else + score[2] := score[2] + 1; + fi; od; + + Print("Score: ", score, "\n"); + Print("Mismatches: ", mismatches); end; \ No newline at end of file From e2f8ec98f67b07985d8e0f9b495e9ae3029c1285 Mon Sep 17 00:00:00 2001 From: awesometillman Date: Thu, 4 Jul 2024 15:06:39 +0100 Subject: [PATCH 11/23] Made testing function compare both isomorphic and non-isomorphic semigroups. --- gap/attributes/isomtest.g | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/gap/attributes/isomtest.g b/gap/attributes/isomtest.g index cefb05317..35934c456 100644 --- a/gap/attributes/isomtest.g +++ b/gap/attributes/isomtest.g @@ -39,7 +39,7 @@ end; # TODO similar thing for RZMS MakeSomeRMS := function(n) - # Returns a list of n small Rees matrix semigroups + # Makes n random Rees matrix semigroups which aren't too large local semigroups_list, S; semigroups_list := []; @@ -54,21 +54,30 @@ MakeSomeRMS := function(n) end; TestRMS := function(S, n) - # Tests isomorphism algorithms on given semigroup S - # by comparing it to n random isomorphic RMS - local T, i, runtime, oldres, oldtime, newres, newtime, score, mismatches; + # Runs both the new and old isomorphism algorithms on + # n semigroups isomorphic to S and n randomly generated + # Rees matrix semigroups, then compares times and answers + local T, i, runtime, oldres, oldtime, newres, newtime, score, mismatches, testlist; score := [0, 0]; mismatches := 0; + + testlist := MakeSomeRMS(n); for i in [1 .. n] do T := RandomIsomorphicRMS(S); + Append(testlist, [T]); + od; + + Print("Finished making test list \n"); + + for i in [1 .. (2*n)] do runtime := Runtime(); - newres := IsIsomorphicRMS(S, T); + newres := IsIsomorphicRMS(S, testlist[i]); newtime := Runtime() - runtime; runtime := Runtime(); - oldres := IsIsomorphicSemigroup(S, T); + oldres := IsIsomorphicSemigroup(S, testlist[i]); oldtime := Runtime() - runtime; if not newres = oldres then @@ -80,6 +89,9 @@ TestRMS := function(S, n) else score[2] := score[2] + 1; fi; + + Print("Finished test ", i, "\n"); + od; Print("Score: ", score, "\n"); From 1a745389c11ffdf8b2b2bb8846d9d8dfffce48d5 Mon Sep 17 00:00:00 2001 From: awesometillman Date: Thu, 4 Jul 2024 15:19:14 +0100 Subject: [PATCH 12/23] Added testing both isomorphism methods against comparing canonical multiplication tables --- gap/attributes/isomtest.g | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/gap/attributes/isomtest.g b/gap/attributes/isomtest.g index 35934c456..2fb5b1682 100644 --- a/gap/attributes/isomtest.g +++ b/gap/attributes/isomtest.g @@ -9,7 +9,12 @@ RandomIsomorphicRMS := function(R) return Range(IsomorphismReesMatrixSemigroup(S)); end; -# TODO check that this is faster than computing CanonicalMultiplicationTable +# TODO check that this is faster than computing CanonicalMultiplicationTable (CMT) + +IsIsomorphicByCMT := function(S, T) + # Checks if the canonical multiplication tables of S and T are the same + return CanonicalMultiplicationTable(S) = CanonicalMultiplicationTable(T); +end; IsIsomorphicRMS := function(R, S) local uR, uS, map, mat, next, row, entry; @@ -57,9 +62,9 @@ TestRMS := function(S, n) # Runs both the new and old isomorphism algorithms on # n semigroups isomorphic to S and n randomly generated # Rees matrix semigroups, then compares times and answers - local T, i, runtime, oldres, oldtime, newres, newtime, score, mismatches, testlist; + local T, i, runtime, oldres, oldtime, newres, newtime, badres, badtime, score, mismatches, testlist; - score := [0, 0]; + score := [0, 0, 0]; mismatches := 0; testlist := MakeSomeRMS(n); @@ -80,14 +85,26 @@ TestRMS := function(S, n) oldres := IsIsomorphicSemigroup(S, testlist[i]); oldtime := Runtime() - runtime; - if not newres = oldres then + runtime := Runtime(); + badres := IsIsomorphicByCMT(S, testlist[i]); + badtime := Runtime() - runtime; + + if not ((newres = oldres) and (newres = badres)) then mismatches := mismatches + 1; fi; if newtime < oldtime then - score[1] := score[1] + 1; + if newtime < badtime then + score[1] := score[1] + 1; + else; + score[3] := score[3] + 1; + fi; else - score[2] := score[2] + 1; + if oldtime < badtime then + score[2] := score[2] + 1; + else + score[3] := score[3] + 1; + fi; fi; Print("Finished test ", i, "\n"); From 3f672034b9c829dfff90dd6392c2eb00fb6f90c0 Mon Sep 17 00:00:00 2001 From: awesometillman Date: Fri, 5 Jul 2024 11:48:19 +0100 Subject: [PATCH 13/23] Finished writing IsIsomorphicRMS function, ready to add it to isomorph.gi --- gap/attributes/isomtest.g | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/gap/attributes/isomtest.g b/gap/attributes/isomtest.g index 2fb5b1682..60fabe39c 100644 --- a/gap/attributes/isomtest.g +++ b/gap/attributes/isomtest.g @@ -18,11 +18,27 @@ end; IsIsomorphicRMS := function(R, S) local uR, uS, map, mat, next, row, entry; - # TODO check that R and S have the same dimensions, and same size underlying group + R := CanonicalReesMatrixSemigroup(R); uR := UnderlyingSemigroup(R); uS := UnderlyingSemigroup(S); - # TODO check if uR, uS is a group + + if NrRows(Matrix(R)) <> NrRows(Matrix(S)) then + return false; + fi; + if NrCols(Matrix(R)) <> NrCols(Matrix(S)) then + return false; + fi; + if Size(uR) <> Size(uS) then + return false; + fi; + if not IsGroup(uR) then + return false; + fi; + if not IsGroup(uS) then + return false; + fi; + map := IsomorphismGroups(uS, uR); if map = fail then return false; From a74a7176b3d3c19db31b415739bc0cda9b76fa77 Mon Sep 17 00:00:00 2001 From: awesometillman Date: Fri, 5 Jul 2024 12:12:26 +0100 Subject: [PATCH 14/23] Added new isomorphism function to isomorph.gi --- gap/attributes/isomorph.gi | 84 ++++++++++++++++++++++++++++---------- 1 file changed, 63 insertions(+), 21 deletions(-) diff --git a/gap/attributes/isomorph.gi b/gap/attributes/isomorph.gi index c43fe624f..23cf6ef5f 100644 --- a/gap/attributes/isomorph.gi +++ b/gap/attributes/isomorph.gi @@ -105,28 +105,70 @@ end); InstallMethod(IsIsomorphicSemigroup, "for semigroups", [IsSemigroup, IsSemigroup], -function(S, T) - #if IsSimpleSemigroup(S) and IsSimpleSemigroup(T) then - # return IsIsomorphicSemigroup(Range(IsomorphismReesMatrixSemigroup(S)), - # Range(IsomorphismReesMatrixSemigroup(T))); - #fi; - return IsomorphismSemigroups(S, T) <> fail; -end); +{S, T} -> IsomorphismSemigroups(S, T) <> fail); + +InstallMethod(IsIsomorphicSemigroup, "for finite simple semigroups", +[IsSimpleSemigroup and IsFinite, IsSimpleSemigroup and IsFinite], +function(R, S) + local uR, uS, map, mat, next, row, entry, isoR, rmsR, isoS, rmsS; + + # Take an isomorphism of R to an RMS if appropriate + if not (IsReesMatrixSemigroup(R) and IsWholeFamily(R) + and IsPermGroup(UnderlyingSemigroup(R))) then + isoR := IsomorphismReesMatrixSemigroupOverPermGroup(R); + rmsR := Range(isoR); + else + rmsR := R; + fi; + # Take an isomorphism of S to an RMS if appropriate + if not (IsReesMatrixSemigroup(S) and IsWholeFamily(S) + and IsPermGroup(UnderlyingSemigroup(S))) then + isoS := IsomorphismReesMatrixSemigroupOverPermGroup(S); + rmsS := Range(isoS); + else + rmsS := S; + fi; + + rmsR := CanonicalReesMatrixSemigroup(rmsR); + uR := UnderlyingSemigroup(rmsR); + uS := UnderlyingSemigroup(rmsS); + + if Length(Rows(rmsR)) <> Length(Rows(rmsS)) then + return false; + fi; + if Length(Columns(rmsR)) <> Length(Columns(rmsS)) then + return false; + fi; + if Size(uR) <> Size(uS) then + return false; + fi; + if not IsGroup(uR) then + return false; + fi; + if not IsGroup(uS) then + return false; + fi; -#InstallMethod(IsIsomorphicSemigroup, "for Rees matrix semigroups", -#[IsReesMatrixSemigroup, IsReesMatrixSemigroup], -#IsIsomorphicRMS); - -#InstallMethod(IsIsomorphicSemigroup, "for semigroups", -#[IsSimpleSemigroup, IsSimpleSemigroup], -#function(S, T) -# local SS; -# if not IsReesMatrixSemigroup(S) then -# SS := Range(IsomorphismReesMatrixSemigroupOverPermGroup(S)); -# fi; -# # Same for T -# return CanonicalReesMatrixSemigroup(S) = CanonicalReesMatrixSemigroup(T); -#end); + map := IsomorphismGroups(uS, uR); + if map = fail then + return false; + fi; + + mat := []; + for row in Matrix(rmsS) do + next := []; + for entry in row do + Add(next, entry ^ map); + od; + Add(mat, next); + od; + + # Make sure underlying groups are the same, and then compare + # canonical Rees matrix semigroups of both R and S + rmsS := ReesMatrixSemigroup(uR, mat); + rmsS := CanonicalReesMatrixSemigroup(rmsS); + return Matrix(rmsR) = Matrix(rmsS); +end); InstallMethod(IsomorphismSemigroups, "for finite simple semigroups", [IsSimpleSemigroup and IsFinite, IsSimpleSemigroup and IsFinite], From 8952697f0f31c5962a28da96d8f8111ebcc7cd46 Mon Sep 17 00:00:00 2001 From: awesometillman Date: Fri, 5 Jul 2024 13:38:58 +0100 Subject: [PATCH 15/23] Added tests to isomorph.tst for new function --- tst/standard/attributes/isomorph.tst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tst/standard/attributes/isomorph.tst b/tst/standard/attributes/isomorph.tst index 92d9ae609..78d4d0165 100644 --- a/tst/standard/attributes/isomorph.tst +++ b/tst/standard/attributes/isomorph.tst @@ -118,6 +118,26 @@ gap> T := JonesMonoid(4); gap> IsIsomorphicSemigroup(S, T); false +# isomorph: IsIsomorphicSemigroup, for finite simple semigroups +gap> M := [[(1,2,3),()],[(),()],[(),()]]; +[ [ (1,2,3), () ], [ (), () ], [ (), () ] ] +gap> N := [[(1,3,2),()],[(),(1,2,3)],[(1,3,2),(1,3,2)]]; +[ [ (1,3,2), () ], [ (), (1,2,3) ], [ (1,3,2), (1,3,2) ] ] +gap> R := ReesMatrixSemigroup(AlternatingGroup([1..3]),M); + +gap> S := ReesMatrixSemigroup(Group([(1,2,3)]),N); + +gap> IsIsomorphicSemigroup(R,S); +true +gap> L := [[(),()],[(),()],[(1,2,3),()]]; +[ [ (), () ], [ (), () ], [ (1,2,3), () ] ] +gap> T := ReesMatrixSemigroup(SymmetricGroup([1..3]),L); + +gap> IsIsomorphicSemigroup(S,T); +false +gap> IsIsomorphicSemigroup(T,T); +true + # isomorph: IsomorphismSemigroups, for infinite semigroup(s) gap> S := FreeSemigroup(1);; gap> T := TrivialSemigroup();; From 549141ca3d898dc99d3e3ba59b3b8776eaf98dd2 Mon Sep 17 00:00:00 2001 From: awesometillman Date: Fri, 5 Jul 2024 13:43:58 +0100 Subject: [PATCH 16/23] Added local variables used in test --- tst/standard/attributes/isomorph.tst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tst/standard/attributes/isomorph.tst b/tst/standard/attributes/isomorph.tst index 78d4d0165..19ec8feed 100644 --- a/tst/standard/attributes/isomorph.tst +++ b/tst/standard/attributes/isomorph.tst @@ -9,7 +9,7 @@ ## #@local A, BruteForceInverseCheck, BruteForceIsoCheck, F, G, S, T, U, V, inv -#@local map, x, y +#@local map, x, y, M, N, R, L gap> START_TEST("Semigroups package: standard/attributes/isomorph.tst"); gap> LoadPackage("semigroups", false);; From 08f27cd888b251667b255957efa4dae7f94f832f Mon Sep 17 00:00:00 2001 From: awesometillman Date: Fri, 5 Jul 2024 14:19:42 +0100 Subject: [PATCH 17/23] Deleted isomtest.g --- gap/attributes/isomtest.g | 132 -------------------------------------- 1 file changed, 132 deletions(-) delete mode 100644 gap/attributes/isomtest.g diff --git a/gap/attributes/isomtest.g b/gap/attributes/isomtest.g deleted file mode 100644 index 60fabe39c..000000000 --- a/gap/attributes/isomtest.g +++ /dev/null @@ -1,132 +0,0 @@ -RandomIsomorphicRMS := function(R) - local table, p, S; - if Size(R) > 1000 then - ErrorNoReturn("Tillman what were you thinking???"); - fi; - table := MultiplicationTable(R); - p := Random(SymmetricGroup(Size(R))); - S := SemigroupByMultiplicationTableNC(OnMultiplicationTable(table, p)); - return Range(IsomorphismReesMatrixSemigroup(S)); -end; - -# TODO check that this is faster than computing CanonicalMultiplicationTable (CMT) - -IsIsomorphicByCMT := function(S, T) - # Checks if the canonical multiplication tables of S and T are the same - return CanonicalMultiplicationTable(S) = CanonicalMultiplicationTable(T); -end; - -IsIsomorphicRMS := function(R, S) - local uR, uS, map, mat, next, row, entry; - - R := CanonicalReesMatrixSemigroup(R); - uR := UnderlyingSemigroup(R); - uS := UnderlyingSemigroup(S); - - if NrRows(Matrix(R)) <> NrRows(Matrix(S)) then - return false; - fi; - if NrCols(Matrix(R)) <> NrCols(Matrix(S)) then - return false; - fi; - if Size(uR) <> Size(uS) then - return false; - fi; - if not IsGroup(uR) then - return false; - fi; - if not IsGroup(uS) then - return false; - fi; - - map := IsomorphismGroups(uS, uR); - if map = fail then - return false; - fi; - - mat := []; - for row in Matrix(S) do - next := []; - for entry in row do - Add(next, entry ^ map); - od; - Add(mat, next); - od; - S := ReesMatrixSemigroup(uR, mat); - S := CanonicalReesMatrixSemigroup(S); - return Matrix(R) = Matrix(S); -end; - -# TODO similar thing for RZMS - -MakeSomeRMS := function(n) - # Makes n random Rees matrix semigroups which aren't too large - local semigroups_list, S; - - semigroups_list := []; - while Length(semigroups_list) < n do - S := RandomSemigroup(IsReesMatrixSemigroup, 4, 5, AlternatingGroup(4)); - if Size(S) < 1000 then - Append(semigroups_list, [S]); - fi; - od; - - return semigroups_list; -end; - -TestRMS := function(S, n) - # Runs both the new and old isomorphism algorithms on - # n semigroups isomorphic to S and n randomly generated - # Rees matrix semigroups, then compares times and answers - local T, i, runtime, oldres, oldtime, newres, newtime, badres, badtime, score, mismatches, testlist; - - score := [0, 0, 0]; - mismatches := 0; - - testlist := MakeSomeRMS(n); - for i in [1 .. n] do - T := RandomIsomorphicRMS(S); - Append(testlist, [T]); - od; - - Print("Finished making test list \n"); - - for i in [1 .. (2*n)] do - - runtime := Runtime(); - newres := IsIsomorphicRMS(S, testlist[i]); - newtime := Runtime() - runtime; - - runtime := Runtime(); - oldres := IsIsomorphicSemigroup(S, testlist[i]); - oldtime := Runtime() - runtime; - - runtime := Runtime(); - badres := IsIsomorphicByCMT(S, testlist[i]); - badtime := Runtime() - runtime; - - if not ((newres = oldres) and (newres = badres)) then - mismatches := mismatches + 1; - fi; - - if newtime < oldtime then - if newtime < badtime then - score[1] := score[1] + 1; - else; - score[3] := score[3] + 1; - fi; - else - if oldtime < badtime then - score[2] := score[2] + 1; - else - score[3] := score[3] + 1; - fi; - fi; - - Print("Finished test ", i, "\n"); - - od; - - Print("Score: ", score, "\n"); - Print("Mismatches: ", mismatches); -end; \ No newline at end of file From 6febcf7eab8b2b378bae242192312d82cb7fc18b Mon Sep 17 00:00:00 2001 From: awesometillman Date: Tue, 9 Jul 2024 11:53:38 +0100 Subject: [PATCH 18/23] Fixed code styling --- gap/attributes/isomorph.gi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gap/attributes/isomorph.gi b/gap/attributes/isomorph.gi index 23cf6ef5f..a2a46b624 100644 --- a/gap/attributes/isomorph.gi +++ b/gap/attributes/isomorph.gi @@ -128,7 +128,7 @@ function(R, S) else rmsS := S; fi; - + rmsR := CanonicalReesMatrixSemigroup(rmsR); uR := UnderlyingSemigroup(rmsR); uS := UnderlyingSemigroup(rmsS); @@ -316,7 +316,7 @@ end; InstallMethod(IsomorphismSemigroups, "for semigroups", [IsSemigroup, IsSemigroup], function(S, T) - local invariants, map, DS, DT, p, inv; + local invariants, map, p, inv; # TODO(later) more invariants invariants := [IsFinite, IsSimpleSemigroup, IsZeroSimpleSemigroup, Size, From 74396f1fa03b3c9b0100de4976ee3aa8a90b889a Mon Sep 17 00:00:00 2001 From: awesometillman Date: Tue, 9 Jul 2024 12:01:12 +0100 Subject: [PATCH 19/23] Fixed styling in test file --- tst/standard/attributes/isomorph.tst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tst/standard/attributes/isomorph.tst b/tst/standard/attributes/isomorph.tst index 19ec8feed..e04fab6b9 100644 --- a/tst/standard/attributes/isomorph.tst +++ b/tst/standard/attributes/isomorph.tst @@ -119,23 +119,23 @@ gap> IsIsomorphicSemigroup(S, T); false # isomorph: IsIsomorphicSemigroup, for finite simple semigroups -gap> M := [[(1,2,3),()],[(),()],[(),()]]; +gap> M := [[(1, 2, 3), ()], [(), ()], [(), ()]]; [ [ (1,2,3), () ], [ (), () ], [ (), () ] ] -gap> N := [[(1,3,2),()],[(),(1,2,3)],[(1,3,2),(1,3,2)]]; +gap> N := [[(1, 3, 2), ()], [(), (1, 2, 3)], [(1, 3, 2), (1, 3, 2)]]; [ [ (1,3,2), () ], [ (), (1,2,3) ], [ (1,3,2), (1,3,2) ] ] -gap> R := ReesMatrixSemigroup(AlternatingGroup([1..3]),M); +gap> R := ReesMatrixSemigroup(AlternatingGroup([1 .. 3]), M); -gap> S := ReesMatrixSemigroup(Group([(1,2,3)]),N); +gap> S := ReesMatrixSemigroup(Group([(1, 2, 3)]), N); -gap> IsIsomorphicSemigroup(R,S); +gap> IsIsomorphicSemigroup(R, S); true -gap> L := [[(),()],[(),()],[(1,2,3),()]]; +gap> L := [[(), ()], [(), ()], [(1, 2, 3), ()]]; [ [ (), () ], [ (), () ], [ (1,2,3), () ] ] -gap> T := ReesMatrixSemigroup(SymmetricGroup([1..3]),L); +gap> T := ReesMatrixSemigroup(SymmetricGroup([1 .. 3]), L); -gap> IsIsomorphicSemigroup(S,T); +gap> IsIsomorphicSemigroup(S, T); false -gap> IsIsomorphicSemigroup(T,T); +gap> IsIsomorphicSemigroup(T, T); true # isomorph: IsomorphismSemigroups, for infinite semigroup(s) From 4e0431a1c409cea0d9da86c42db1c64a60759291 Mon Sep 17 00:00:00 2001 From: awesometillman Date: Wed, 24 Jul 2024 16:03:53 +0100 Subject: [PATCH 20/23] Changed order of processes to improve performance --- gap/attributes/isomorph.gi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gap/attributes/isomorph.gi b/gap/attributes/isomorph.gi index a2a46b624..c8f0408f1 100644 --- a/gap/attributes/isomorph.gi +++ b/gap/attributes/isomorph.gi @@ -129,7 +129,6 @@ function(R, S) rmsS := S; fi; - rmsR := CanonicalReesMatrixSemigroup(rmsR); uR := UnderlyingSemigroup(rmsR); uS := UnderlyingSemigroup(rmsS); @@ -165,6 +164,7 @@ function(R, S) # Make sure underlying groups are the same, and then compare # canonical Rees matrix semigroups of both R and S + rmsR := CanonicalReesMatrixSemigroup(rmsR); rmsS := ReesMatrixSemigroup(uR, mat); rmsS := CanonicalReesMatrixSemigroup(rmsS); return Matrix(rmsR) = Matrix(rmsS); From c51247b359c9373f85d1d1b638a3ca24b40b2399 Mon Sep 17 00:00:00 2001 From: awesometillman Date: Wed, 24 Jul 2024 16:31:36 +0100 Subject: [PATCH 21/23] Added test to make sure function works on simple semigroups that aren't RMS already --- tst/standard/attributes/isomorph.tst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tst/standard/attributes/isomorph.tst b/tst/standard/attributes/isomorph.tst index e04fab6b9..4577756c3 100644 --- a/tst/standard/attributes/isomorph.tst +++ b/tst/standard/attributes/isomorph.tst @@ -129,6 +129,10 @@ gap> S := ReesMatrixSemigroup(Group([(1, 2, 3)]), N); gap> IsIsomorphicSemigroup(R, S); true +gap> R := SemigroupByMultiplicationTable(MultiplicationTable(R));; +gap> S := SemigroupByMultiplicationTable(MultiplicationTable(S));; +gap> IsIsomorphicSemigroup(R, S); +true gap> L := [[(), ()], [(), ()], [(1, 2, 3), ()]]; [ [ (), () ], [ (), () ], [ (1,2,3), () ] ] gap> T := ReesMatrixSemigroup(SymmetricGroup([1 .. 3]), L); From 418ad14a8a189855829643a7b9aa86c48da55bcb Mon Sep 17 00:00:00 2001 From: "James D. Mitchell" Date: Mon, 29 Jul 2024 15:14:56 +0100 Subject: [PATCH 22/23] Remove slower code --- gap/attributes/isomorph.gi | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/gap/attributes/isomorph.gi b/gap/attributes/isomorph.gi index c8f0408f1..9ec48ec89 100644 --- a/gap/attributes/isomorph.gi +++ b/gap/attributes/isomorph.gi @@ -316,7 +316,7 @@ end; InstallMethod(IsomorphismSemigroups, "for semigroups", [IsSemigroup, IsSemigroup], function(S, T) - local invariants, map, p, inv; + local invariants, map, DS, DT, p, inv; # TODO(later) more invariants invariants := [IsFinite, IsSimpleSemigroup, IsZeroSimpleSemigroup, Size, @@ -342,12 +342,13 @@ function(S, T) return fail; fi; - if CanonicalMultiplicationTable(S) <> CanonicalMultiplicationTable(T) then + DS := SEMIGROUPS.CanonicalDigraph(S); + DT := SEMIGROUPS.CanonicalDigraph(T); + p := IsomorphismDigraphs(DS[1], DT[1], DS[2], DT[2]); + if p = fail then return fail; fi; - p := CanonicalMultiplicationTablePerm(S) - * CanonicalMultiplicationTablePerm(T) ^ -1; - + p := RestrictedPerm(p, [1 .. Size(S)]); map := x -> AsSSortedList(T)[PositionSorted(S, x) ^ p]; inv := x -> AsSSortedList(S)[PositionSorted(T, x) ^ (p ^ -1)]; return SemigroupIsomorphismByFunctionNC(S, T, map, inv); From b440972fed972b46019b232793fd89405546f2a2 Mon Sep 17 00:00:00 2001 From: "James D. Mitchell" Date: Mon, 29 Jul 2024 15:32:35 +0100 Subject: [PATCH 23/23] Final tweaks --- gap/attributes/isomorph.gi | 39 ++++++++++++---------------- tst/standard/attributes/isomorph.tst | 14 ++++++++++ 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/gap/attributes/isomorph.gi b/gap/attributes/isomorph.gi index 9ec48ec89..c785ec0eb 100644 --- a/gap/attributes/isomorph.gi +++ b/gap/attributes/isomorph.gi @@ -105,13 +105,18 @@ end); InstallMethod(IsIsomorphicSemigroup, "for semigroups", [IsSemigroup, IsSemigroup], -{S, T} -> IsomorphismSemigroups(S, T) <> fail); - -InstallMethod(IsIsomorphicSemigroup, "for finite simple semigroups", -[IsSimpleSemigroup and IsFinite, IsSimpleSemigroup and IsFinite], function(R, S) local uR, uS, map, mat, next, row, entry, isoR, rmsR, isoS, rmsS; + if not (IsFinite(R) and IsSimpleSemigroup(R) + and IsFinite(S) and IsSimpleSemigroup(S)) then + return IsomorphismSemigroups(R, S) <> fail; + fi; + + # Note that when experimenting the method for IsomorphismSemigroups for Rees + # 0-matrix semigroups is faster than the analogue of the below code, and so + # we do not special case finite 0-simple semigroups. + # Take an isomorphism of R to an RMS if appropriate if not (IsReesMatrixSemigroup(R) and IsWholeFamily(R) and IsPermGroup(UnderlyingSemigroup(R))) then @@ -129,30 +134,22 @@ function(R, S) rmsS := S; fi; - uR := UnderlyingSemigroup(rmsR); - uS := UnderlyingSemigroup(rmsS); - - if Length(Rows(rmsR)) <> Length(Rows(rmsS)) then - return false; - fi; - if Length(Columns(rmsR)) <> Length(Columns(rmsS)) then - return false; - fi; - if Size(uR) <> Size(uS) then - return false; - fi; - if not IsGroup(uR) then - return false; - fi; - if not IsGroup(uS) then + if Length(Rows(rmsR)) <> Length(Rows(rmsS)) + or (Length(Columns(rmsR)) <> Length(Columns(rmsS))) then return false; fi; + uR := UnderlyingSemigroup(rmsR); + uS := UnderlyingSemigroup(rmsS); + + # uS and uR must be groups because we made them so above. map := IsomorphismGroups(uS, uR); if map = fail then return false; fi; + # Make sure underlying groups are the same, and then compare + # canonical Rees matrix semigroups of both R and S mat := []; for row in Matrix(rmsS) do next := []; @@ -162,8 +159,6 @@ function(R, S) Add(mat, next); od; - # Make sure underlying groups are the same, and then compare - # canonical Rees matrix semigroups of both R and S rmsR := CanonicalReesMatrixSemigroup(rmsR); rmsS := ReesMatrixSemigroup(uR, mat); rmsS := CanonicalReesMatrixSemigroup(rmsS); diff --git a/tst/standard/attributes/isomorph.tst b/tst/standard/attributes/isomorph.tst index 4577756c3..428e3dd2d 100644 --- a/tst/standard/attributes/isomorph.tst +++ b/tst/standard/attributes/isomorph.tst @@ -141,6 +141,20 @@ gap> IsIsomorphicSemigroup(S, T); false gap> IsIsomorphicSemigroup(T, T); true +gap> M := [[(1, 2, 3), ()], [(), ()], [(), ()]]; +[ [ (1,2,3), () ], [ (), () ], [ (), () ] ] +gap> N := [[(1, 3, 2), ()], [(), (1, 2, 3)]]; +[ [ (1,3,2), () ], [ (), (1,2,3) ] ] +gap> R := ReesMatrixSemigroup(AlternatingGroup([1 .. 3]), M);; +gap> S := ReesMatrixSemigroup(AlternatingGroup([1 .. 3]), N);; +gap> IsIsomorphicSemigroup(R, S); +false +gap> R := ReesMatrixSemigroup(AlternatingGroup([1 .. 5]), +> [[(), ()], [(), (1, 3, 2, 4, 5)]]);; +gap> S := ReesMatrixSemigroup(AlternatingGroup([1 .. 5]), +> [[(1, 5, 4, 3, 2), ()], [(1, 4, 5), (1, 4)(3, 5)]]);; +gap> IsIsomorphicSemigroup(R, S); +false # isomorph: IsomorphismSemigroups, for infinite semigroup(s) gap> S := FreeSemigroup(1);;