mirror of
https://github.com/kalmarek/Groups.jl.git
synced 2024-12-12 15:16:27 +01:00
Merge branch 'enh/type_ovehaul'
This commit is contained in:
commit
342d842585
@ -9,13 +9,14 @@ export DirectProductGroup, DirectProductGroupElem
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
doc"""
|
doc"""
|
||||||
DirectProductGroup(factors::Vector{Group}) <: Group
|
DirectProductGroup(G::Group, n::Int) <: Group
|
||||||
Implements direct product of groups as vector factors. The group operation is
|
Implements `n`-fold direct product of `G`. The group operation is
|
||||||
`*` distributed component-wise, with component-wise identity as neutral element.
|
`*` distributed component-wise, with component-wise identity as neutral element.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
immutable DirectProductGroup{T<:Group} <: Group
|
immutable DirectProductGroup{T<:Group} <: Group
|
||||||
factors::Vector{T}
|
group::T
|
||||||
|
n::Int
|
||||||
end
|
end
|
||||||
|
|
||||||
immutable DirectProductGroupElem{T<:GroupElem} <: GroupElem
|
immutable DirectProductGroupElem{T<:GroupElem} <: GroupElem
|
||||||
@ -28,11 +29,14 @@ end
|
|||||||
#
|
#
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
elem_type{T<:Group}(G::DirectProductGroup{T}) = DirectProductGroupElem{elem_type(first(G.factors))}
|
elem_type{T<:Group}(G::DirectProductGroup{T}) =
|
||||||
|
DirectProductGroupElem{elem_type(G.group)}
|
||||||
|
|
||||||
parent_type(::Type{DirectProductGroupElem}) = DirectProductGroup
|
parent_type{T<:GroupElem}(::Type{DirectProductGroupElem{T}}) =
|
||||||
|
DirectProductGroup{parent_type(T)}
|
||||||
|
|
||||||
parent(g::DirectProductGroupElem) = DirectProductGroup([parent(h) for h in g.elts])
|
parent(g::DirectProductGroupElem) =
|
||||||
|
DirectProductGroup(parent(first(g.elts)), length(g.elts))
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
#
|
#
|
||||||
@ -44,8 +48,9 @@ Base.size(g::DirectProductGroupElem) = size(g.elts)
|
|||||||
Base.linearindexing(::Type{DirectProductGroupElem}) = Base.LinearFast()
|
Base.linearindexing(::Type{DirectProductGroupElem}) = Base.LinearFast()
|
||||||
Base.getindex(g::DirectProductGroupElem, i::Int) = g.elts[i]
|
Base.getindex(g::DirectProductGroupElem, i::Int) = g.elts[i]
|
||||||
function Base.setindex!{T<:GroupElem}(g::DirectProductGroupElem{T}, v::T, i::Int)
|
function Base.setindex!{T<:GroupElem}(g::DirectProductGroupElem{T}, v::T, i::Int)
|
||||||
p.part[i] = v
|
parent(v) == parent(first(g.elts)) || throw("$g is not an element of $i-th factor of $(parent(G))")
|
||||||
return p
|
g.elts[i] = v
|
||||||
|
return g
|
||||||
end
|
end
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@ -54,9 +59,10 @@ end
|
|||||||
#
|
#
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
DirectProductGroup{T<:Group}(G::T, H::T) = DirectProductGroup{T}([G, H])
|
function ×(G::Group, H::Group)
|
||||||
|
G == H || throw("Direct products are defined only for the same groups")
|
||||||
×(G::Group, H::Group) = DirectProductGroup([G,H])
|
return DirectProductGroup(G,2)
|
||||||
|
end
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
#
|
#
|
||||||
@ -64,23 +70,25 @@ DirectProductGroup{T<:Group}(G::T, H::T) = DirectProductGroup{T}([G, H])
|
|||||||
#
|
#
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
(G::DirectProductGroup)() = G([H() for H in G.factors])
|
doc"""
|
||||||
|
(G::DirectProductGroup)(a::Vector, check::Bool=true)
|
||||||
|
> Constructs element of the $n$-fold direct product group `G` by coercing each
|
||||||
|
> element of vector `a` to `G.group`. If `check` flag is set to `false` neither
|
||||||
|
> check on the correctness nor coercion is performed.
|
||||||
|
"""
|
||||||
|
function (G::DirectProductGroup)(a::Vector, check::Bool=true)
|
||||||
|
if check
|
||||||
|
G.n == length(a) || throw("Can not coerce to DirectProductGroup: lengths differ")
|
||||||
|
a = G.group.(a)
|
||||||
|
end
|
||||||
|
return DirectProductGroupElem(a)
|
||||||
|
end
|
||||||
|
|
||||||
|
(G::DirectProductGroup)() = DirectProductGroupElem([G.group() for _ in 1:G.n])
|
||||||
|
|
||||||
(G::DirectProductGroup)(g::DirectProductGroupElem) = G(g.elts)
|
(G::DirectProductGroup)(g::DirectProductGroupElem) = G(g.elts)
|
||||||
|
|
||||||
doc"""
|
(G::DirectProductGroup){T<:GroupElem, N}(a::Vararg{T, N}) = G([a...])
|
||||||
(G::DirectProductGroup)(a::Vector; checked=true)
|
|
||||||
> Constructs element of the direct product group `G` by coercing each element
|
|
||||||
> of vector `a` to the corresponding factor of `G`. If `checked` flag is set to
|
|
||||||
> `false` no checks on the correctness are performed.
|
|
||||||
|
|
||||||
"""
|
|
||||||
function (G::DirectProductGroup){T<:GroupElem}(a::Vector{T})
|
|
||||||
length(a) == length(G.factors) || throw("Cannot coerce $a to $G: they have
|
|
||||||
different number of factors")
|
|
||||||
@assert elem_type(first(G.factors)) == T
|
|
||||||
return DirectProductGroupElem(a)
|
|
||||||
end
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
#
|
#
|
||||||
@ -94,20 +102,13 @@ function deepcopy_internal(g::DirectProductGroupElem, dict::ObjectIdDict)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function hash(G::DirectProductGroup, h::UInt)
|
function hash(G::DirectProductGroup, h::UInt)
|
||||||
return hash(G.factors, hash(DirectProductGroup,h))
|
return hash(G.group, hash(G.n, hash(DirectProductGroup,h)))
|
||||||
end
|
end
|
||||||
|
|
||||||
function hash(g::DirectProductGroupElem, h::UInt)
|
function hash(g::DirectProductGroupElem, h::UInt)
|
||||||
return hash(g.elts, hash(parent(g), hash(DirectProductGroupElem, h)))
|
return hash(g.elts, hash(parent(g), hash(DirectProductGroupElem, h)))
|
||||||
end
|
end
|
||||||
|
|
||||||
doc"""
|
|
||||||
eye(G::DirectProductGroup)
|
|
||||||
> Return the identity element for the given direct product of groups.
|
|
||||||
|
|
||||||
"""
|
|
||||||
eye(G::DirectProductGroup) = G()
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
#
|
#
|
||||||
# String I/O
|
# String I/O
|
||||||
@ -115,12 +116,11 @@ eye(G::DirectProductGroup) = G()
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
function show(io::IO, G::DirectProductGroup)
|
function show(io::IO, G::DirectProductGroup)
|
||||||
println(io, "Direct product of groups")
|
println(io, "$(G.n)-fold direct product of $(G.group)")
|
||||||
join(io, G.factors, ", ", " and ")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function show(io::IO, g::DirectProductGroupElem)
|
function show(io::IO, g::DirectProductGroupElem)
|
||||||
print(io, "("*join(g.elts,",")*")")
|
print(io, "($(join(g.elts,",")))")
|
||||||
end
|
end
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@ -129,65 +129,62 @@ end
|
|||||||
#
|
#
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
doc"""
|
||||||
|
==(g::DirectProductGroup, h::DirectProductGroup)
|
||||||
|
> Checks if two direct product groups are the same.
|
||||||
|
"""
|
||||||
function (==)(G::DirectProductGroup, H::DirectProductGroup)
|
function (==)(G::DirectProductGroup, H::DirectProductGroup)
|
||||||
G.factors == H.factors || return false
|
G.group == H.group || return false
|
||||||
|
G.n == G.n || return false
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
doc"""
|
doc"""
|
||||||
==(g::DirectProductGroupElem, h::DirectProductGroupElem)
|
==(g::DirectProductGroupElem, h::DirectProductGroupElem)
|
||||||
> Return `true` if the given elements of direct products are equal, otherwise return `false`.
|
> Checks if two direct product group elements are the same.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
function (==)(g::DirectProductGroupElem, h::DirectProductGroupElem)
|
function (==)(g::DirectProductGroupElem, h::DirectProductGroupElem)
|
||||||
parent(g) == parent(h) || return false
|
|
||||||
g.elts == h.elts || return false
|
g.elts == h.elts || return false
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
#
|
#
|
||||||
# Binary operators
|
# Group operations
|
||||||
#
|
#
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
function direct_mult(g::DirectProductGroupElem, h::DirectProductGroupElem)
|
|
||||||
G = parent(g)
|
|
||||||
# G == parent(h) || throw("Can't multiply elements from different groups: $G, $parent(h)")
|
|
||||||
if isa(first(G.factors), Ring)
|
|
||||||
return G(.+(g.elts,h.elts))
|
|
||||||
else
|
|
||||||
return G(.*(g.elts,h.elts))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
doc"""
|
doc"""
|
||||||
*(g::DirectProductGroupElem, h::DirectProductGroupElem)
|
*(g::DirectProductGroupElem, h::DirectProductGroupElem)
|
||||||
> Return the direct-product group operation of elements, i.e. component-wise
|
> Return the direct-product group operation of elements, i.e. component-wise
|
||||||
> operation as defined by `operations` field of the parent object.
|
> operation as defined by `operations` field of the parent object.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
(*)(g::DirectProductGroupElem, h::DirectProductGroupElem) = direct_mult(g,h)
|
# TODO: dirty hack around `+/*` operations
|
||||||
|
function *{T<:GroupElem}(g::DirectProductGroupElem{T}, h::DirectProductGroupElem{T}, check::Bool=true)
|
||||||
|
if check
|
||||||
|
parent(g) == parent(h) || throw("Can not multiply elements of different groups!")
|
||||||
|
end
|
||||||
|
return DirectProductGroupElem([a*b for (a,b) in zip(g.elts,h.elts)])
|
||||||
|
end
|
||||||
|
|
||||||
###############################################################################
|
function *{T<:RingElem}(g::DirectProductGroupElem{T}, h::DirectProductGroupElem{T}, check::Bool=true)
|
||||||
#
|
if check
|
||||||
# Inversion
|
parent(g) == parent(h) || throw("Can not multiply elements of different groups!")
|
||||||
#
|
end
|
||||||
###############################################################################
|
return DirectProductGroupElem(g.elts + h.elts)
|
||||||
|
end
|
||||||
|
|
||||||
doc"""
|
doc"""
|
||||||
inv(g::DirectProductGroupElem)
|
inv(g::DirectProductGroupElem)
|
||||||
> Return the inverse of the given element in the direct product group.
|
> Return the inverse of the given element in the direct product group.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# TODO: dirty hack around `+` operation
|
# TODO: dirty hack around `+/*` operation
|
||||||
function inv(g::DirectProductGroupElem)
|
function inv{T<:GroupElem}(g::DirectProductGroupElem{T})
|
||||||
G = parent(g)
|
|
||||||
if isa(first(G.factors), Ring)
|
|
||||||
return DirectProductGroupElem([-a for a in g.elts])
|
|
||||||
else
|
|
||||||
return DirectProductGroupElem([inv(a) for a in g.elts])
|
return DirectProductGroupElem([inv(a) for a in g.elts])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function inv{T<:RingElem}(g::DirectProductGroupElem{T})
|
||||||
|
return DirectProductGroupElem(-g.elts)
|
||||||
end
|
end
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@ -198,15 +195,15 @@ end
|
|||||||
|
|
||||||
doc"""
|
doc"""
|
||||||
elements(G::DirectProductGroup)
|
elements(G::DirectProductGroup)
|
||||||
> Returns `Task` that produces all elements of group `G` (provided that factors
|
> Returns `generator` that produces all elements of group `G` (provided that
|
||||||
> implement the elements function).
|
> `G.group` implements the `elements` method).
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# TODO: can Base.product handle generators?
|
# TODO: can Base.product handle generators?
|
||||||
# now it returns nothing's so we have to collect ellements...
|
# now it returns nothing's so we have to collect ellements...
|
||||||
function elements(G::DirectProductGroup)
|
function elements(G::DirectProductGroup)
|
||||||
cartesian_prod = Base.product([collect(elements(H)) for H in G.factors]...)
|
elts = collect(elements(G.group))
|
||||||
return (G(collect(elt)) for elt in cartesian_prod)
|
cartesian_prod = Base.product([elts for _ in 1:G.n]...)
|
||||||
|
return (DirectProductGroupElem([elt...]) for elt in cartesian_prod)
|
||||||
end
|
end
|
||||||
|
|
||||||
doc"""
|
doc"""
|
||||||
@ -214,4 +211,4 @@ doc"""
|
|||||||
> Returns the order (number of elements) in the group.
|
> Returns the order (number of elements) in the group.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
order(G::DirectProductGroup) = prod([order(H) for H in G.factors])
|
order(G::DirectProductGroup) = order(G.group)^G.n
|
||||||
|
@ -7,35 +7,38 @@ export WreathProduct, WreathProductElem
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
doc"""
|
doc"""
|
||||||
WreathProduct <: Group
|
WreathProduct{T<:Group} <: Group
|
||||||
> Implements Wreath product of a group N by permutation (sub)group P < Sₖ,
|
> Implements Wreath product of a group $N$ by permutation (sub)group $P < S_k$,
|
||||||
> usually written as $N \wr P$.
|
> usually written as $N \wr P$.
|
||||||
> The multiplication inside wreath product is defined as
|
> The multiplication inside wreath product is defined as
|
||||||
> (n, σ) * (m, τ) = (n*ψ(σ)(m), σ*τ),
|
> $$(n, \sigma) * (m, \tau) = (n\psi(\sigma)(m), \sigma\tau),$$
|
||||||
> where ψ:P → Aut(Nᵏ) is the permutation representation of Sₖ restricted to P.
|
> where $\psi:P → Aut(N^k)$ is the permutation representation of $S_k$
|
||||||
|
> restricted to $P$.
|
||||||
|
|
||||||
# Arguments:
|
# Arguments:
|
||||||
* `::Group` : the single factor of group N
|
* `::Group` : the single factor of group $N$
|
||||||
* `::PermutationGroup` : full PermutationGroup
|
* `::PermGroup` : full `PermutationGroup`
|
||||||
"""
|
"""
|
||||||
|
immutable WreathProduct{T<:Group} <: Group
|
||||||
|
N::DirectProductGroup{T}
|
||||||
|
P::PermGroup
|
||||||
|
|
||||||
type WreathProduct <: Group
|
function WreathProduct(G::Group, P::PermGroup)
|
||||||
N::DirectProductGroup
|
N = DirectProductGroup(G, P.n)
|
||||||
P::PermutationGroup
|
|
||||||
|
|
||||||
function WreathProduct(G::Group, P::PermutationGroup)
|
|
||||||
N = DirectProductGroup(typeof(G)[G for _ in 1:P.n])
|
|
||||||
return new(N, P)
|
return new(N, P)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
type WreathProductElem <: GroupElem
|
immutable WreathProductElem{T<:GroupElem} <: GroupElem
|
||||||
n::DirectProductGroupElem
|
n::DirectProductGroupElem{T}
|
||||||
p::perm
|
p::perm
|
||||||
parent::WreathProduct
|
# parent::WreathProduct
|
||||||
|
|
||||||
function WreathProductElem(n::DirectProductGroupElem, p::perm)
|
function WreathProductElem(n::DirectProductGroupElem, p::perm,
|
||||||
length(n.elts) == parent(p).n
|
check::Bool=true)
|
||||||
|
if check
|
||||||
|
length(n.elts) == parent(p).n || throw("Can't form WreathProductElem: lengths differ")
|
||||||
|
end
|
||||||
return new(n, p)
|
return new(n, p)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -46,11 +49,12 @@ end
|
|||||||
#
|
#
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
elem_type(::WreathProduct) = WreathProductElem
|
elem_type{T<:Group}(::WreathProduct{T}) = WreathProductElem{elem_type(T)}
|
||||||
|
|
||||||
parent_type(::WreathProductElem) = WreathProduct
|
parent_type{T<:GroupElem}(::Type{WreathProductElem{T}}) =
|
||||||
|
WreathProduct{parent_type(T)}
|
||||||
|
|
||||||
parent(g::WreathProductElem) = g.parent
|
parent(g::WreathProductElem) = WreathProduct(parent(g.n[1]), parent(g.p))
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
#
|
#
|
||||||
@ -58,7 +62,10 @@ parent(g::WreathProductElem) = g.parent
|
|||||||
#
|
#
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
# converts???
|
WreathProduct{T<:Group}(G::T, P::PermGroup) = WreathProduct{T}(G, P)
|
||||||
|
|
||||||
|
WreathProductElem{T<:GroupElem}(n::DirectProductGroupElem{T},
|
||||||
|
p::perm, check::Bool=true) = WreathProductElem{T}(n, p, check)
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
#
|
#
|
||||||
@ -67,39 +74,31 @@ parent(g::WreathProductElem) = g.parent
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
function (G::WreathProduct)(g::WreathProductElem)
|
function (G::WreathProduct)(g::WreathProductElem)
|
||||||
try
|
n = try
|
||||||
G.N(g.n)
|
G.N(g.n)
|
||||||
catch
|
catch
|
||||||
throw("Can't coerce $(g.n) to $(G.N) factor of $G")
|
throw("Can't coerce $(g.n) to $(G.N) factor of $G")
|
||||||
end
|
end
|
||||||
try
|
p = try
|
||||||
G.P(g.p)
|
G.P(g.p)
|
||||||
catch
|
catch
|
||||||
throw("Can't coerce $(g.p) to $(G.P) factor of $G")
|
throw("Can't coerce $(g.p) to $(G.P) factor of $G")
|
||||||
end
|
end
|
||||||
elt = WreathProductElem(G.N(g.n), G.P(g.p))
|
return WreathProductElem(n, p)
|
||||||
elt.parent = G
|
|
||||||
return elt
|
|
||||||
end
|
end
|
||||||
|
|
||||||
doc"""
|
doc"""
|
||||||
(G::WreathProduct)(n::DirectProductGroupElem, p::perm)
|
(G::WreathProduct)(n::DirectProductGroupElem, p::perm)
|
||||||
> Creates an element of wreath product `G` by coercing `n` and `p` to `G.N` and
|
> Creates an element of wreath product `G` by coercing `n` and `p` to `G.N` and
|
||||||
> `G.P`, respectively.
|
> `G.P`, respectively.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
function (G::WreathProduct)(n::DirectProductGroupElem, p::perm)
|
(G::WreathProduct)(n::DirectProductGroupElem, p::perm) = WreathProductElem(n,p)
|
||||||
result = WreathProductElem(n,p)
|
|
||||||
result.parent = G
|
|
||||||
return result
|
|
||||||
end
|
|
||||||
|
|
||||||
(G::WreathProduct)() = G(G.N(), G.P())
|
(G::WreathProduct)() = WreathProductElem(G.N(), G.P(), false)
|
||||||
|
|
||||||
doc"""
|
doc"""
|
||||||
(G::WreathProduct)(p::perm)
|
(G::WreathProduct)(p::perm)
|
||||||
> Returns the image of permutation `p` in `G` via embedding `p -> (id,p)`.
|
> Returns the image of permutation `p` in `G` via embedding `p -> (id,p)`.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
(G::WreathProduct)(p::perm) = G(G.N(), p)
|
(G::WreathProduct)(p::perm) = G(G.N(), p)
|
||||||
|
|
||||||
@ -107,7 +106,6 @@ doc"""
|
|||||||
(G::WreathProduct)(n::DirectProductGroupElem)
|
(G::WreathProduct)(n::DirectProductGroupElem)
|
||||||
> Returns the image of `n` in `G` via embedding `n -> (n,())`. This is the
|
> Returns the image of `n` in `G` via embedding `n -> (n,())`. This is the
|
||||||
> embedding that makes sequence `1 -> N -> G -> P -> 1` exact.
|
> embedding that makes sequence `1 -> N -> G -> P -> 1` exact.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
(G::WreathProduct)(n::DirectProductGroupElem) = G(n, G.P())
|
(G::WreathProduct)(n::DirectProductGroupElem) = G(n, G.P())
|
||||||
|
|
||||||
@ -118,8 +116,7 @@ doc"""
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
function deepcopy_internal(g::WreathProductElem, dict::ObjectIdDict)
|
function deepcopy_internal(g::WreathProductElem, dict::ObjectIdDict)
|
||||||
G = parent(g)
|
return WreathProductElem(deepcopy(g.n), deepcopy(g.p), false)
|
||||||
return G(deepcopy(g.n), deepcopy(g.p))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function hash(G::WreathProduct, h::UInt)
|
function hash(G::WreathProduct, h::UInt)
|
||||||
@ -127,7 +124,7 @@ function hash(G::WreathProduct, h::UInt)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function hash(g::WreathProductElem, h::UInt)
|
function hash(g::WreathProductElem, h::UInt)
|
||||||
return hash(g.n, hash(g.p, hash(parent(g), h)))
|
return hash(g.n, hash(g.p, hash(WreathProductElem, h)))
|
||||||
end
|
end
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@ -137,12 +134,10 @@ end
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
function show(io::IO, G::WreathProduct)
|
function show(io::IO, G::WreathProduct)
|
||||||
print(io, "Wreath Product of $(G.N.factors[1]) and $(G.P)")
|
print(io, "Wreath Product of $(G.N.group) by $(G.P)")
|
||||||
end
|
end
|
||||||
|
|
||||||
function show(io::IO, g::WreathProductElem)
|
function show(io::IO, g::WreathProductElem)
|
||||||
# println(io, "Element of WreathProduct over $T of size $(size(X)):")
|
|
||||||
# show(io, "text/plain", matrix_repr(X))
|
|
||||||
print(io, "($(g.n)≀$(g.p))")
|
print(io, "($(g.n)≀$(g.p))")
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -159,7 +154,6 @@ function (==)(G::WreathProduct, H::WreathProduct)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function (==)(g::WreathProductElem, h::WreathProductElem)
|
function (==)(g::WreathProductElem, h::WreathProductElem)
|
||||||
parent(g) == parent(h) || return false
|
|
||||||
g.n == h.n || return false
|
g.n == h.n || return false
|
||||||
g.p == h.p || return false
|
g.p == h.p || return false
|
||||||
return true
|
return true
|
||||||
@ -167,45 +161,32 @@ end
|
|||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
#
|
#
|
||||||
# Binary operators
|
# Group operations
|
||||||
#
|
#
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
function wreath_multiplication(g::WreathProductElem, h::WreathProductElem)
|
|
||||||
parent(g) == parent(h) || throw("Can not multiply elements from different
|
|
||||||
groups!")
|
|
||||||
G = parent(g)
|
|
||||||
w = G.N((h.n).elts[inv(g.p).d])
|
|
||||||
return G(g.n*w, g.p*h.p)
|
|
||||||
end
|
|
||||||
|
|
||||||
doc"""
|
doc"""
|
||||||
*(g::WreathProductElem, h::WreathProductElem)
|
*(g::WreathProductElem, h::WreathProductElem)
|
||||||
> Return the wreath product group operation of elements, i.e.
|
> Return the wreath product group operation of elements, i.e.
|
||||||
>
|
>
|
||||||
> g*h = (g.n*g.p(h.n), g.p*h.p),
|
> `g*h = (g.n*g.p(h.n), g.p*h.p)`,
|
||||||
>
|
>
|
||||||
> where g.p(h.n) denotes the action of `g.p::perm` on
|
> where `g.p(h.n)` denotes the action of `g.p::perm` on
|
||||||
> `h.n::DirectProductGroupElem` via standard permutation of coordinates.
|
> `h.n::DirectProductGroupElem` via standard permutation of coordinates.
|
||||||
"""
|
"""
|
||||||
(*)(g::WreathProductElem, h::WreathProductElem) = wreath_multiplication(g,h)
|
function *(g::WreathProductElem, h::WreathProductElem)
|
||||||
|
w = DirectProductGroupElem((h.n).elts[inv(g.p).d])
|
||||||
|
return WreathProductElem(g.n*w, g.p*h.p, false)
|
||||||
###############################################################################
|
end
|
||||||
#
|
|
||||||
# Inversion
|
|
||||||
#
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
doc"""
|
doc"""
|
||||||
inv(g::WreathProductElem)
|
inv(g::WreathProductElem)
|
||||||
> Returns the inverse of element of a wreath product, according to the formula
|
> Returns the inverse of element of a wreath product, according to the formula
|
||||||
> g^-1 = (g.n, g.p)^-1 = (g.p^-1(g.n^-1), g.p^-1).
|
> `g^-1 = (g.n, g.p)^-1 = (g.p^-1(g.n^-1), g.p^-1)`.
|
||||||
"""
|
"""
|
||||||
function inv(g::WreathProductElem)
|
function inv(g::WreathProductElem)
|
||||||
G = parent(g)
|
w = DirectProductGroupElem(inv(g.n).elts[g.p.d])
|
||||||
w = G.N(inv(g.n).elts[g.p.d])
|
return WreathProductElem(w, inv(g.p), false)
|
||||||
return G(w, inv(g.p))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@ -218,7 +199,7 @@ matrix_repr(g::WreathProductElem) = Any[matrix_repr(g.p) g.n]
|
|||||||
|
|
||||||
function elements(G::WreathProduct)
|
function elements(G::WreathProduct)
|
||||||
iter = Base.product(collect(elements(G.N)), collect(elements(G.P)))
|
iter = Base.product(collect(elements(G.N)), collect(elements(G.P)))
|
||||||
return (G(n)*G(p) for (n,p) in iter)
|
return (WreathProductElem(n, p, false) for (n,p) in iter)
|
||||||
end
|
end
|
||||||
|
|
||||||
order(G::WreathProduct) = order(G.P)*order(G.N)
|
order(G::WreathProduct) = order(G.P)*order(G.N)
|
||||||
|
83
test/DirectProd-tests.jl
Normal file
83
test/DirectProd-tests.jl
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
@testset "DirectProducts" begin
|
||||||
|
using Nemo
|
||||||
|
|
||||||
|
G = PermutationGroup(3)
|
||||||
|
g = G([2,3,1])
|
||||||
|
F, a = FiniteField(2,3,"a")
|
||||||
|
|
||||||
|
@testset "Constructors" begin
|
||||||
|
@test isa(Groups.DirectProductGroup(G,2), Nemo.Group)
|
||||||
|
@test isa(G×G, Nemo.Group)
|
||||||
|
@test isa(Groups.DirectProductGroup(G,2), Groups.DirectProductGroup{Nemo.PermGroup})
|
||||||
|
|
||||||
|
GG = Groups.DirectProductGroup(G,2)
|
||||||
|
|
||||||
|
@test GG == Groups.DirectProductGroup(G,2)
|
||||||
|
|
||||||
|
@test Groups.DirectProductGroupElem([G(), G()]) == GG()
|
||||||
|
@test GG(G(), G()) == GG()
|
||||||
|
|
||||||
|
@test isa(GG([g, g^2]), GroupElem)
|
||||||
|
@test isa(GG([g, g^2]), Groups.DirectProductGroupElem{Nemo.perm})
|
||||||
|
|
||||||
|
h = GG([g,g^2])
|
||||||
|
|
||||||
|
@test h == GG(h)
|
||||||
|
|
||||||
|
@test isa(GG(g, g^2), GroupElem)
|
||||||
|
@test isa(GG(g, g^2), Groups.DirectProductGroupElem)
|
||||||
|
|
||||||
|
@test_throws String GG(g,g,g)
|
||||||
|
@test GG(g,g^2) == h
|
||||||
|
|
||||||
|
@test size(h) == (2,)
|
||||||
|
@test h[1] == g
|
||||||
|
@test h[2] == g^2
|
||||||
|
h[2] = G()
|
||||||
|
@test h == GG(g, G())
|
||||||
|
end
|
||||||
|
|
||||||
|
GG = Groups.DirectProductGroup(G,2)
|
||||||
|
FF = Groups.DirectProductGroup(F,2)
|
||||||
|
|
||||||
|
@testset "Types" begin
|
||||||
|
@test elem_type(GG) == Groups.DirectProductGroupElem{elem_type(G)}
|
||||||
|
@test elem_type(FF) == Groups.DirectProductGroupElem{elem_type(F)}
|
||||||
|
@test parent_type(typeof(GG(g,g^2))) == Groups.DirectProductGroup{typeof(G)}
|
||||||
|
@test parent_type(typeof(FF(a,a^2))) == Groups.DirectProductGroup{typeof(F)}
|
||||||
|
|
||||||
|
@test isa(FF([0,1]), GroupElem)
|
||||||
|
@test isa(FF([0,1]), Groups.DirectProductGroupElem)
|
||||||
|
@test isa(FF([0,1]), Groups.DirectProductGroupElem{elem_type(F)})
|
||||||
|
@test_throws MethodError FF(1,0)
|
||||||
|
end
|
||||||
|
|
||||||
|
@testset "Group arithmetic" begin
|
||||||
|
g = G([2,3,1])
|
||||||
|
h = GG([g,g^2])
|
||||||
|
|
||||||
|
@test h^2 == GG(g^2,g)
|
||||||
|
@test h^6 == GG()
|
||||||
|
|
||||||
|
@test h*h == h^2
|
||||||
|
|
||||||
|
@test h*inv(h) == GG()
|
||||||
|
|
||||||
|
@test FF([0,a])*FF([a,1]) == FF(a,1+a)
|
||||||
|
x, y = FF([1,a]), FF([a^2,1])
|
||||||
|
@test x*y == FF([a^2+1, a+1])
|
||||||
|
@test inv(x) == FF([1,a])
|
||||||
|
end
|
||||||
|
|
||||||
|
@testset "Misc" begin
|
||||||
|
@test order(GG) == 36
|
||||||
|
@test order(FF) == 64
|
||||||
|
|
||||||
|
@test isa([elements(GG)...], Vector{Groups.DirectProductGroupElem{elem_type(G)}})
|
||||||
|
elts = [elements(GG)...]
|
||||||
|
|
||||||
|
@test length(elts) == 36
|
||||||
|
@test all([g*inv(g) for g in elts] .== GG())
|
||||||
|
@test all(inv(g*h) == inv(h)*inv(g) for g in elts for h in elts)
|
||||||
|
end
|
||||||
|
end
|
@ -1,7 +1,9 @@
|
|||||||
|
|
||||||
@testset "Groups.FreeSymbols" begin
|
@testset "Groups.FreeSymbols" begin
|
||||||
s = Groups.FreeSymbol("s")
|
s = Groups.FreeSymbol("s")
|
||||||
t = Groups.FreeSymbol("t")
|
t = Groups.FreeSymbol("t")
|
||||||
@testset "defines" begin
|
|
||||||
|
@testset "constructors" begin
|
||||||
@test isa(Groups.FreeSymbol("aaaaaaaaaaaaaaaa"), Groups.GSymbol)
|
@test isa(Groups.FreeSymbol("aaaaaaaaaaaaaaaa"), Groups.GSymbol)
|
||||||
@test Groups.FreeSymbol("abc").pow == 1
|
@test Groups.FreeSymbol("abc").pow == 1
|
||||||
@test isa(s, Groups.FreeSymbol)
|
@test isa(s, Groups.FreeSymbol)
|
||||||
@ -23,10 +25,10 @@
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@testset "FreeGroupElems" begin
|
@testset "FreeGroupSymbols manipulation" begin
|
||||||
s = Groups.FreeSymbol("s")
|
s = Groups.FreeSymbol("s")
|
||||||
t = Groups.FreeSymbol("t", -2)
|
t = Groups.FreeSymbol("t", -2)
|
||||||
@testset "defines" begin
|
|
||||||
@test isa(Groups.GWord(s), Groups.GWord)
|
@test isa(Groups.GWord(s), Groups.GWord)
|
||||||
@test isa(Groups.GWord(s), FreeGroupElem)
|
@test isa(Groups.GWord(s), FreeGroupElem)
|
||||||
@test isa(FreeGroupElem(s), Groups.GWord)
|
@test isa(FreeGroupElem(s), Groups.GWord)
|
||||||
@ -35,18 +37,7 @@ end
|
|||||||
@test isa(Vector{FreeGroupElem}([s,t]), Vector{FreeGroupElem})
|
@test isa(Vector{FreeGroupElem}([s,t]), Vector{FreeGroupElem})
|
||||||
@test length(FreeGroupElem(s)) == 1
|
@test length(FreeGroupElem(s)) == 1
|
||||||
@test length(FreeGroupElem(t)) == 2
|
@test length(FreeGroupElem(t)) == 2
|
||||||
end
|
|
||||||
|
|
||||||
@testset "eltary functions" begin
|
|
||||||
G = FreeGroup(["s", "t"])
|
|
||||||
s = G(s)
|
|
||||||
t = G(t)
|
|
||||||
@test Vector{Groups.GWord}([s,t]) == [Groups.GWord(s), Groups.GWord(t)]
|
|
||||||
|
|
||||||
@test (s*s).symbols == (s^2).symbols
|
|
||||||
|
|
||||||
@test hash([t^1,s^1]) == hash([t^2*inv(t),s*inv(s)*s])
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@testset "FreeGroup" begin
|
@testset "FreeGroup" begin
|
||||||
@ -64,6 +55,11 @@ end
|
|||||||
s, t = Nemo.gens(G)
|
s, t = Nemo.gens(G)
|
||||||
|
|
||||||
@testset "internal arithmetic" begin
|
@testset "internal arithmetic" begin
|
||||||
|
|
||||||
|
@test Vector{Groups.GWord}([s,t]) == [Groups.GWord(s), Groups.GWord(t)]
|
||||||
|
@test (s*s).symbols == (s^2).symbols
|
||||||
|
@test hash([t^1,s^1]) == hash([t^2*inv(t),s*inv(s)*s])
|
||||||
|
|
||||||
t_symb = Groups.FreeSymbol("t")
|
t_symb = Groups.FreeSymbol("t")
|
||||||
tt = deepcopy(t)
|
tt = deepcopy(t)
|
||||||
@test string(Groups.r_multiply!(tt,[inv(t_symb)]; reduced=true)) ==
|
@test string(Groups.r_multiply!(tt,[inv(t_symb)]; reduced=true)) ==
|
||||||
@ -96,7 +92,7 @@ end
|
|||||||
@test Groups.reduce!(w).symbols ==Vector{Groups.FreeSymbol}([])
|
@test Groups.reduce!(w).symbols ==Vector{Groups.FreeSymbol}([])
|
||||||
end
|
end
|
||||||
|
|
||||||
@testset "binary/inv operations" begin
|
@testset "Group operations" begin
|
||||||
@test parent(s) == G
|
@test parent(s) == G
|
||||||
@test parent(s) === parent(deepcopy(s))
|
@test parent(s) === parent(deepcopy(s))
|
||||||
@test isa(s*t, FreeGroupElem)
|
@test isa(s*t, FreeGroupElem)
|
||||||
|
85
test/WreathProd-tests.jl
Normal file
85
test/WreathProd-tests.jl
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
@testset "WreathProducts" begin
|
||||||
|
S_3 = PermutationGroup(3)
|
||||||
|
F, a = FiniteField(2,3,"a")
|
||||||
|
b = S_3([2,3,1])
|
||||||
|
|
||||||
|
@testset "Constructors" begin
|
||||||
|
@test isa(Groups.WreathProduct(F, S_3), Nemo.Group)
|
||||||
|
@test isa(Groups.WreathProduct(F, S_3), Groups.WreathProduct)
|
||||||
|
@test isa(Groups.WreathProduct(F, S_3), Groups.WreathProduct{Nemo.FqNmodFiniteField})
|
||||||
|
|
||||||
|
aa = Groups.DirectProductGroupElem([a^0 ,a, a^2])
|
||||||
|
|
||||||
|
@test isa(Groups.WreathProductElem(aa, b), Nemo.GroupElem)
|
||||||
|
@test isa(Groups.WreathProductElem(aa, b), Groups.WreathProductElem)
|
||||||
|
@test isa(Groups.WreathProductElem(aa, b), Groups.WreathProductElem{typeof(a)})
|
||||||
|
|
||||||
|
B3 = Groups.WreathProduct(F, S_3)
|
||||||
|
|
||||||
|
@test B3.N == Groups.DirectProductGroup(F, 3)
|
||||||
|
@test B3.P == S_3
|
||||||
|
|
||||||
|
@test B3(aa, b) == Groups.WreathProductElem(aa, b)
|
||||||
|
@test B3(b) == Groups.WreathProductElem(B3.N(), b)
|
||||||
|
@test B3(aa) == Groups.WreathProductElem(aa, S_3())
|
||||||
|
|
||||||
|
g = B3(aa, b)
|
||||||
|
|
||||||
|
@test g.p == b
|
||||||
|
@test g.n == aa
|
||||||
|
h = deepcopy(g)
|
||||||
|
|
||||||
|
@test hash(g) == hash(h)
|
||||||
|
|
||||||
|
g.n[1] = a
|
||||||
|
|
||||||
|
@test g.n[1] == a
|
||||||
|
@test g != h
|
||||||
|
|
||||||
|
@test hash(g) != hash(h)
|
||||||
|
end
|
||||||
|
|
||||||
|
@testset "Types" begin
|
||||||
|
B3 = Groups.WreathProduct(F, S_3)
|
||||||
|
|
||||||
|
@test elem_type(B3) == Groups.WreathProductElem{elem_type(F)}
|
||||||
|
|
||||||
|
@test parent_type(typeof(B3())) == Groups.WreathProduct{parent_type(typeof(B3.N.group()))}
|
||||||
|
|
||||||
|
@test parent(B3()) == Groups.WreathProduct(F,S_3)
|
||||||
|
@test parent(B3()) == B3
|
||||||
|
end
|
||||||
|
|
||||||
|
@testset "Group arithmetic" begin
|
||||||
|
B3 = Groups.WreathProduct(F, S_3)
|
||||||
|
|
||||||
|
x = B3(B3.N([1,0,0]), B3.P([2,3,1]))
|
||||||
|
y = B3(B3.N([0,1,1]), B3.P([2,1,3]))
|
||||||
|
|
||||||
|
@test x*y == B3(B3.N([0,0,1]), B3.P([3,2,1]))
|
||||||
|
@test y*x == B3(B3.N([0,0,1]), B3.P([1,3,2]))
|
||||||
|
|
||||||
|
@test inv(x) == B3(B3.N([0,0,1]), B3.P([3,1,2]))
|
||||||
|
@test inv(y) == B3(B3.N([1,0,1]), B3.P([2,1,3]))
|
||||||
|
|
||||||
|
@test inv(x)*y == B3(B3.N([1,1,1]), B3.P([1,3,2]))
|
||||||
|
@test y*inv(x) == B3(B3.N([0,1,0]), B3.P([3,2,1]))
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
@testset "Misc" begin
|
||||||
|
B3 = Groups.WreathProduct(FiniteField(2,1,"a")[1], S_3)
|
||||||
|
@test order(B3) == 48
|
||||||
|
|
||||||
|
Wr = WreathProduct(PermutationGroup(2),S_3)
|
||||||
|
|
||||||
|
@test isa([elements(Wr)...], Vector{Groups.WreathProductElem{Nemo.perm}})
|
||||||
|
|
||||||
|
elts = [elements(Wr)...]
|
||||||
|
|
||||||
|
@test length(elts) == order(Wr)
|
||||||
|
@test all([g*inv(g) for g in elts] .== Wr())
|
||||||
|
@test all(inv(g*h) == inv(h)*inv(g) for g in elts for h in elts)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
@ -6,4 +6,6 @@ using Base.Test
|
|||||||
@testset "Groups" begin
|
@testset "Groups" begin
|
||||||
include("FreeGroup-tests.jl")
|
include("FreeGroup-tests.jl")
|
||||||
include("AutGroup-tests.jl")
|
include("AutGroup-tests.jl")
|
||||||
|
include("DirectProd-tests.jl")
|
||||||
|
include("WreathProd-tests.jl")
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user