From f4d018f0875124f223d7889ee3064dec7218b591 Mon Sep 17 00:00:00 2001 From: Marek Kaluba Date: Mon, 12 Feb 2024 12:37:33 +0100 Subject: [PATCH] update constructions to PG-0.6 --- Project.toml | 4 +- src/constructions/direct_power.jl | 64 +++++++++++++++++------------ src/constructions/direct_product.jl | 46 +++++++++++++-------- src/constructions/wreath_product.jl | 64 ++++++++++++++++------------- 4 files changed, 104 insertions(+), 74 deletions(-) diff --git a/Project.toml b/Project.toml index c89da1c..496628f 100644 --- a/Project.toml +++ b/Project.toml @@ -14,10 +14,10 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" [compat] -GroupsCore = "0.4" +GroupsCore = "0.5" KnuthBendix = "0.4" OrderedCollections = "1" -PermutationGroups = "0.4" +PermutationGroups = "0.6" StaticArrays = "1" julia = "1.6" diff --git a/src/constructions/direct_power.jl b/src/constructions/direct_power.jl index 7e69b68..3bb3114 100644 --- a/src/constructions/direct_power.jl +++ b/src/constructions/direct_power.jl @@ -59,15 +59,6 @@ end GroupsCore.ngens(G::DirectPower) = _nfold(G) * ngens(G.group) -function GroupsCore.gens(G::DirectPower, i::Integer) - k = ngens(G.group) - ci = CartesianIndices((k, _nfold(G))) - @boundscheck checkbounds(ci, i) - r, c = Tuple(ci[i]) - tup = ntuple(j -> j == c ? gens(G.group, r) : one(G.group), _nfold(G)) - return DirectPowerElement(tup, G) -end - function GroupsCore.gens(G::DirectPower) N = _nfold(G) S = gens(G.group) @@ -78,14 +69,6 @@ end Base.isfinite(G::DirectPower) = isfinite(G.group) -function Base.rand( - rng::Random.AbstractRNG, - rs::Random.SamplerTrivial{<:DirectPower}, -) - G = rs[] - return DirectPowerElement(rand(rng, G.group, _nfold(G)), G) -end - GroupsCore.parent(g::DirectPowerElement) = g.parent function Base.:(==)(g::DirectPowerElement, h::DirectPowerElement) @@ -94,13 +77,6 @@ end Base.hash(g::DirectPowerElement, h::UInt) = hash(g.elts, hash(parent(g), h)) -function Base.deepcopy_internal(g::DirectPowerElement, stackdict::IdDict) - return DirectPowerElement( - Base.deepcopy_internal(g.elts, stackdict), - parent(g), - ) -end - Base.inv(g::DirectPowerElement) = DirectPowerElement(inv.(g.elts), parent(g)) function Base.:(*)(g::DirectPowerElement, h::DirectPowerElement) @@ -108,6 +84,39 @@ function Base.:(*)(g::DirectPowerElement, h::DirectPowerElement) return DirectPowerElement(g.elts .* h.elts, parent(g)) end +# to make sure that parents are never copied i.e. +# g and deepcopy(g) share their parent +Base.deepcopy_internal(G::DirectPower, ::IdDict) = G + +################## Implementing Group Interface Done! + +function GroupsCore.gens(G::DirectPower, i::Integer) + k = ngens(G.group) + ci = CartesianIndices((k, _nfold(G))) + @boundscheck checkbounds(ci, i) + r, c = Tuple(ci[i]) + tup = ntuple(j -> j == c ? gens(G.group, r) : one(G.group), _nfold(G)) + return DirectPowerElement(tup, G) +end + +# Overloading rand: the PRA of GroupsCore is known for not performing +# well on direct sums +function Random.Sampler( + RNG::Type{<:Random.AbstractRNG}, + G::DirectPower, + repetition::Random.Repetition = Val(Inf), +) + return Random.SamplerTrivial(G) +end + +function Base.rand( + rng::Random.AbstractRNG, + rs::Random.SamplerTrivial{<:DirectPower}, +) + G = rs[] + return DirectPowerElement(rand(rng, G.group, _nfold(G)), G) +end + function GroupsCore.order(::Type{I}, g::DirectPowerElement) where {I<:Integer} return convert(I, reduce(lcm, (order(I, h) for h in g.elts); init = one(I))) end @@ -117,10 +126,13 @@ Base.isone(g::DirectPowerElement) = all(isone, g.elts) function Base.show(io::IO, G::DirectPower) n = _nfold(G) nn = n == 1 ? "1-st" : n == 2 ? "2-nd" : n == 3 ? "3-rd" : "$n-th" - return print(io, "Direct $(nn) power of $(G.group)") + return print(io, "Direct $(nn) power of ", G.group) end + function Base.show(io::IO, g::DirectPowerElement) - return print(io, "( ", join(g.elts, ", "), " )") + print(io, "( ") + join(io, g.elts, ", ") + return print(" )") end # convienience: diff --git a/src/constructions/direct_product.jl b/src/constructions/direct_product.jl index a522f6e..adfe0b7 100644 --- a/src/constructions/direct_product.jl +++ b/src/constructions/direct_product.jl @@ -72,14 +72,6 @@ end Base.isfinite(G::DirectProduct) = isfinite(G.first) && isfinite(G.last) -function Base.rand( - rng::Random.AbstractRNG, - rs::Random.SamplerTrivial{<:DirectProduct}, -) - G = rs[] - return DirectProductElement((rand(rng, G.first), rand(rng, G.last)), G) -end - GroupsCore.parent(g::DirectProductElement) = g.parent function Base.:(==)(g::DirectProductElement, h::DirectProductElement) @@ -88,13 +80,6 @@ end Base.hash(g::DirectProductElement, h::UInt) = hash(g.elts, hash(parent(g), h)) -function Base.deepcopy_internal(g::DirectProductElement, stackdict::IdDict) - return DirectProductElement( - Base.deepcopy_internal(g.elts, stackdict), - parent(g), - ) -end - function Base.inv(g::DirectProductElement) return DirectProductElement(inv.(g.elts), parent(g)) end @@ -104,6 +89,30 @@ function Base.:(*)(g::DirectProductElement, h::DirectProductElement) return DirectProductElement(g.elts .* h.elts, parent(g)) end +# to make sure that parents are never copied i.e. +# g and deepcopy(g) share their parent +Base.deepcopy_internal(G::DirectProduct, ::IdDict) = G + +################## Implementing Group Interface Done! + +# Overloading rand: the PRA of GroupsCore is known for not performing +# well on direct sums +function Random.Sampler( + RNG::Type{<:Random.AbstractRNG}, + G::DirectProduct, + repetition::Random.Repetition = Val(Inf), +) + return Random.SamplerTrivial(G) +end + +function Base.rand( + rng::Random.AbstractRNG, + rs::Random.SamplerTrivial{<:DirectProduct}, +) + G = rs[] + return DirectProductElement((rand(rng, G.first), rand(rng, G.last)), G) +end + function GroupsCore.order(::Type{I}, g::DirectProductElement) where {I<:Integer} return convert(I, lcm(order(I, first(g.elts)), order(I, last(g.elts)))) end @@ -111,10 +120,13 @@ end Base.isone(g::DirectProductElement) = all(isone, g.elts) function Base.show(io::IO, G::DirectProduct) - return print(io, "Direct product of $(G.first) and $(G.last)") + return print(io, "Direct product of ", G.first, " and ", G.last) end + function Base.show(io::IO, g::DirectProductElement) - return print(io, "( $(join(g.elts, ",")) )") + print(io, "( ") + join(io, g.elts, ", ") + return print(io, " )") end # convienience: diff --git a/src/constructions/wreath_product.jl b/src/constructions/wreath_product.jl index cf0608a..2f99208 100644 --- a/src/constructions/wreath_product.jl +++ b/src/constructions/wreath_product.jl @@ -1,7 +1,4 @@ -import PermutationGroups: - AbstractPermutationGroup, - AbstractPermutation, - degree +import PermutationGroups as PG """ WreathProduct(G::Group, P::AbstractPermutationGroup) <: Group @@ -16,20 +13,20 @@ product is defined as where `m^σ` denotes the action (from the right) of the permutation `σ` on `d`-tuples of elements from `G`. """ -struct WreathProduct{DP<:DirectPower,PGr<:AbstractPermutationGroup} <: +struct WreathProduct{DP<:DirectPower,PGr<:PG.AbstractPermutationGroup} <: GroupsCore.Group N::DP P::PGr - function WreathProduct(G::Group, P::AbstractPermutationGroup) - N = DirectPower{degree(P)}(G) + function WreathProduct(G::Group, P::PG.AbstractPermutationGroup) + N = DirectPower{PG.AP.degree(P)}(G) return new{typeof(N),typeof(P)}(N, P) end end struct WreathProductElement{ DPEl<:DirectPowerElement, - PEl<:AbstractPermutation, + PEl<:PG.AP.AbstractPermutation, Wr<:WreathProduct, } <: GroupsCore.GroupElement n::DPEl @@ -38,7 +35,7 @@ struct WreathProductElement{ function WreathProductElement( n::DirectPowerElement, - p::AbstractPermutation, + p::PG.AP.AbstractPermutation, W::WreathProduct, ) return new{typeof(n),typeof(p),typeof(W)}(n, p, W) @@ -97,14 +94,6 @@ end Base.isfinite(G::WreathProduct) = isfinite(G.N) && isfinite(G.P) -function Base.rand( - rng::Random.AbstractRNG, - rs::Random.SamplerTrivial{<:WreathProduct}, -) - G = rs[] - return WreathProductElement(rand(rng, G.N), rand(rng, G.P), G) -end - GroupsCore.parent(g::WreathProductElement) = g.parent function Base.:(==)(g::WreathProductElement, h::WreathProductElement) @@ -115,15 +104,7 @@ function Base.hash(g::WreathProductElement, h::UInt) return hash(g.n, hash(g.p, hash(g.parent, h))) end -function Base.deepcopy_internal(g::WreathProductElement, stackdict::IdDict) - return WreathProductElement( - Base.deepcopy_internal(g.n, stackdict), - Base.deepcopy_internal(g.p, stackdict), - parent(g), - ) -end - -function _act(p::AbstractPermutation, n::DirectPowerElement) +function _act(p::PG.AP.AbstractPermutation, n::DirectPowerElement) return DirectPowerElement( ntuple(i -> n.elts[i^p], length(n.elts)), parent(n), @@ -140,11 +121,36 @@ function Base.:(*)(g::WreathProductElement, h::WreathProductElement) return WreathProductElement(g.n * _act(g.p, h.n), g.p * h.p, parent(g)) end +# to make sure that parents are never copied i.e. +# g and deepcopy(g) share their parent +Base.deepcopy_internal(G::WreathProduct, ::IdDict) = G + +################## Implementing Group Interface Done! + +# Overloading rand: the PRA of GroupsCore is known for not performing +# well on direct sums +function Random.Sampler( + RNG::Type{<:Random.AbstractRNG}, + G::WreathProduct, + repetition::Random.Repetition = Val(Inf), +) + return Random.SamplerTrivial(G) +end + +function Base.rand( + rng::Random.AbstractRNG, + rs::Random.SamplerTrivial{<:WreathProduct}, +) + G = rs[] + return WreathProductElement(rand(rng, G.N), rand(rng, G.P), G) +end + Base.isone(g::WreathProductElement) = isone(g.n) && isone(g.p) function Base.show(io::IO, G::WreathProduct) - return print(io, "Wreath product of $(G.N.group) by $(G.P)") + return print(io, "Wreath product of ", G.N.group, " by ", G.P) end -Base.show(io::IO, g::WreathProductElement) = print(io, "( $(g.n)≀$(g.p) )") -Base.copy(g::WreathProductElement) = WreathProductElement(g.n, g.p, parent(g)) +function Base.show(io::IO, g::WreathProductElement) + return print(io, "( ", g.n, "≀", g.p, " )") +end