diff --git a/Manifest.toml b/Manifest.toml new file mode 100644 index 0000000..b36dfdd --- /dev/null +++ b/Manifest.toml @@ -0,0 +1,50 @@ +[[AbstractAlgebra]] +deps = ["InteractiveUtils", "LinearAlgebra", "Markdown", "Random", "SparseArrays", "Test"] +git-tree-sha1 = "9163ee4ff00b442021ffcda1b6c1b43ced6750fb" +repo-rev = "master" +repo-url = "AbstractAlgebra" +uuid = "c3fe647b-3220-5bb0-a1ea-a7954cac585d" +version = "0.1.2+" + +[[Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[Distributed]] +deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[InteractiveUtils]] +deps = ["LinearAlgebra", "Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[LinearAlgebra]] +deps = ["Libdl"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[Random]] +deps = ["Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[Test]] +deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/Project.toml b/Project.toml new file mode 100644 index 0000000..eabe511 --- /dev/null +++ b/Project.toml @@ -0,0 +1,10 @@ +name = "Groups" +uuid = "5d8bd718-bd84-11e8-3b40-ad14f4a32557" +authors = ["Marek Kaluba "] +version = "0.1.0" + +[deps] +AbstractAlgebra = "c3fe647b-3220-5bb0-a1ea-a7954cac585d" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/src/AutGroup.jl b/src/AutGroup.jl index a9c34a8..13c08d6 100644 --- a/src/AutGroup.jl +++ b/src/AutGroup.jl @@ -140,7 +140,7 @@ end function domain(G::AutGroup{N}) where N F = G.objectGroup gg = gens(F) - return ntuple(i->gg[i], Val{N}) + return ntuple(i->gg[i], Val(N)) end ############################################################################### @@ -369,23 +369,23 @@ function reduce!(W::Automorphism) end function linear_repr(A::Automorphism{N}, hom=matrix_repr) where N - return reduce(*, hom(Identity(), N, 1), linear_repr.(A.symbols, N, hom)) + return reduce(*, linear_repr.(A.symbols, N, hom), init=hom(Identity(),N,1)) end linear_repr(a::AutSymbol, n::Int, hom) = hom(a.fn, n, a.pow) function matrix_repr(a::Union{RTransvect, LTransvect}, n::Int, pow) - x = eye(n) + x = Matrix{Int}(I, n, n) x[a.i,a.j] = pow return x end function matrix_repr(a::FlipAut, n::Int, pow) - x = eye(n) + x = Matrix{Int}(I, n, n) x[a.i,a.i] = -1^pow return x end -matrix_repr(a::PermAut, n::Int, pow) = eye(n)[(a.perm^pow).d, :] +matrix_repr(a::PermAut, n::Int, pow) = Matrix{Int}(I, n, n)[(a.perm^pow).d, :] -matrix_repr(a::Identity, n::Int, pow) = eye(n) +matrix_repr(a::Identity, n::Int, pow) = Matrix{Int}(I, n, n) diff --git a/src/DirectProducts.jl b/src/DirectProducts.jl index 97c1273..caaac22 100644 --- a/src/DirectProducts.jl +++ b/src/DirectProducts.jl @@ -83,12 +83,11 @@ elements(G::MltGrp{F}) where F <: AbstractAlgebra.GFField = (G(i*G.obj(1)) for i # ############################################################################### -doc""" +@doc doc""" DirectProductGroup(G::Group, n::Int) <: Group Implements `n`-fold direct product of `G`. The group operation is `*` distributed component-wise, with component-wise identity as neutral element. """ - struct DirectProductGroup{T<:Group} <: Group group::T n::Int @@ -170,7 +169,7 @@ end # ############################################################################### -doc""" +@doc 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 @@ -225,7 +224,7 @@ end # ############################################################################### -doc""" +@doc doc""" ==(g::DirectProductGroup, h::DirectProductGroup) > Checks if two direct product groups are the same. """ @@ -235,7 +234,7 @@ function (==)(G::DirectProductGroup, H::DirectProductGroup) return true end -doc""" +@doc doc""" ==(g::DirectProductGroupElem, h::DirectProductGroupElem) > Checks if two direct product group elements are the same. """ @@ -250,7 +249,7 @@ end # ############################################################################### -doc""" +@doc doc""" *(g::DirectProductGroupElem, h::DirectProductGroupElem) > Return the direct-product group operation of elements, i.e. component-wise > operation as defined by `operations` field of the parent object. @@ -263,7 +262,7 @@ function *(g::DirectProductGroupElem{T}, h::DirectProductGroupElem{T}, check::Bo return DirectProductGroupElem([a*b for (a,b) in zip(g.elts,h.elts)]) end -doc""" +@doc doc""" inv(g::DirectProductGroupElem) > Return the inverse of the given element in the direct product group. """ @@ -310,16 +309,15 @@ Base.done(DPIter::DirectPowerIter, state) = DPIter.totalorder <= state Base.eltype(::Type{DirectPowerIter{Gr, GrEl}}) where {Gr, GrEl} = DirectProductGroupElem{GrEl} -doc""" +@doc doc""" elements(G::DirectProductGroup) > Returns `generator` that produces all elements of group `G` (provided that > `G.group` implements the `elements` method). """ elements(G::DirectProductGroup) = DirectPowerIter(G.group, G.n) -doc""" +@doc doc""" order(G::DirectProductGroup) > Returns the order (number of elements) in the group. - """ order(G::DirectProductGroup) = order(G.group)^G.n diff --git a/src/FPGroups.jl b/src/FPGroups.jl index 789d28e..2f0d8bf 100644 --- a/src/FPGroups.jl +++ b/src/FPGroups.jl @@ -15,7 +15,7 @@ mutable struct FPGroup <: AbstractFPGroup gens::Vector{FPSymbol} rels::Dict{FPGroupElem, FPGroupElem} - function FPGroup{T<:GSymbol}(gens::Vector{T}, rels::Dict{FPGroupElem, FPGroupElem}) + function FPGroup(gens::Vector{T}, rels::Dict{FPGroupElem, FPGroupElem}) where {T<:GSymbol} G = new(gens) G.rels = Dict(G(k) => G(v) for (k,v) in rels) return G diff --git a/src/FreeGroup.jl b/src/FreeGroup.jl index 91b4f87..f53a0fd 100644 --- a/src/FreeGroup.jl +++ b/src/FreeGroup.jl @@ -14,7 +14,7 @@ FreeGroupElem = GroupWord{FreeSymbol} mutable struct FreeGroup <: AbstractFPGroup gens::Vector{FreeSymbol} - function FreeGroup{T<:GSymbol}(gens::Vector{T}) + function FreeGroup(gens::Vector{T}) where {T<:GSymbol} G = new(gens) G.gens = gens return G diff --git a/src/Groups.jl b/src/Groups.jl index ab35255..c70c781 100644 --- a/src/Groups.jl +++ b/src/Groups.jl @@ -7,17 +7,20 @@ import AbstractAlgebra: parent, parent_type, elem_type import AbstractAlgebra: elements, order, gens, matrix_repr import Base: length, ==, hash, show, convert -import Base: inv, reduce, *, ^ +import Base: inv, reduce, *, ^, power_by_squaring import Base: findfirst, findnext import Base: deepcopy_internal +using LinearAlgebra +using Markdown + ############################################################################### # # ParentType / ObjectType definition # ############################################################################### -doc""" +@doc doc""" ::GSymbol > Abstract type which all group symbols of AbstractFPGroups should subtype. Each > concrete subtype should implement fields: @@ -29,7 +32,7 @@ abstract type GSymbol end abstract type GWord{T<:GSymbol} <:GroupElem end -doc""" +@doc doc""" W::GroupWord{T} <: GWord{T<:GSymbol} <:GroupElem > Basic representation of element of a finitely presented group. `W.symbols` > fieldname contains particular group symbols which multiplied constitute a @@ -76,7 +79,7 @@ include("WreathProducts.jl") # ############################################################################### -parent{T<:GSymbol}(w::GWord{T}) = w.parent +parent(w::GWord{T}) where {T<:GSymbol} = w.parent ############################################################################### # @@ -99,7 +102,7 @@ function hash(W::GWord, h::UInt) end # WARNING: Due to specialised (constant) hash function of GWords this one is actually necessary! -function deepcopy_internal(W::T, dict::ObjectIdDict) where {T<:GWord} +function deepcopy_internal(W::T, dict::IdDict) where {T<:GWord} G = parent(W) return G(T(deepcopy(W.symbols))) end @@ -150,7 +153,7 @@ function reduce!(W::GWord) return W end -doc""" +@doc doc""" reduce(W::GWord) > performs reduction/simplification of a group element (word in generators). > The default reduction is the free group reduction, i.e. consists of @@ -161,7 +164,7 @@ doc""" """ reduce(W::GWord) = reduce!(deepcopy(W)) -doc""" +@doc doc""" gens(G::AbstractFPGroups) > returns vector of generators of `G`, as its elements. @@ -174,7 +177,7 @@ gens(G::AbstractFPGroup) = [G(g) for g in G.gens] # ############################################################################### -doc""" +@doc doc""" show(io::IO, W::GWord) > The actual string produced by show depends on the eltype of `W.symbols`. @@ -320,14 +323,14 @@ function findnext(W::GWord, Z::GWord, i::Int) if n == 0 return 0 elseif n == 1 - for idx in i:endof(W.symbols) + for idx in i:lastindex(W.symbols) if issubsymbol(Z.symbols[1], W.symbols[idx]) return idx end end return 0 else - for idx in i:endof(W.symbols) - n + 1 + for idx in i:lastindex(W.symbols) - n + 1 foundfirst = issubsymbol(Z.symbols[1], W.symbols[idx]) lastmatch = issubsymbol(Z.symbols[end], W.symbols[idx+n-1]) if foundfirst && lastmatch @@ -416,7 +419,7 @@ function generate_balls(S::Vector{T}, Id::T=parent(first(S))(); radius=2, op=*) return B, sizes end -function generate_balls{T<:RingElem}(S::Vector{T}, Id::T=one(parent(first(S))); radius=2, op=*) +function generate_balls(S::Vector{T}, Id::T=one(parent(first(S))); radius=2, op=*) where {T<:RingElem} sizes = Int[] B = [Id] for i in 1:radius diff --git a/src/WreathProducts.jl b/src/WreathProducts.jl index 1f80d4d..14647ba 100644 --- a/src/WreathProducts.jl +++ b/src/WreathProducts.jl @@ -6,7 +6,7 @@ export WreathProduct, WreathProductElem # ############################################################################### -doc""" +@doc doc""" WreathProduct(N, P) <: Group > Implements Wreath product of a group `N` by permutation group $P = S_n$, > usually written as $N \wr P$. @@ -91,7 +91,7 @@ function (G::WreathProduct)(g::WreathProductElem) return WreathProductElem(n, p) end -doc""" +@doc doc""" (G::WreathProduct)(n::DirectProductGroupElem, p::Generic.perm) > Creates an element of wreath product `G` by coercing `n` and `p` to `G.N` and > `G.P`, respectively. @@ -100,13 +100,13 @@ doc""" (G::WreathProduct)() = WreathProductElem(G.N(), G.P(), false) -doc""" +@doc doc""" (G::WreathProduct)(p::Generic.perm) > Returns the image of permutation `p` in `G` via embedding `p -> (id,p)`. """ (G::WreathProduct)(p::Generic.perm) = G(G.N(), p) -doc""" +@doc doc""" (G::WreathProduct)(n::DirectProductGroupElem) > Returns the image of `n` in `G` via embedding `n -> (n,())`. This is the > embedding that makes sequence `1 -> N -> G -> P -> 1` exact. @@ -169,7 +169,7 @@ end (p::perm)(n::DirectProductGroupElem) = DirectProductGroupElem(n.elts[p.d]) -doc""" +@doc doc""" *(g::WreathProductElem, h::WreathProductElem) > Return the wreath product group operation of elements, i.e. > @@ -182,7 +182,7 @@ function *(g::WreathProductElem, h::WreathProductElem) return WreathProductElem(g.n*g.p(h.n), g.p*h.p, false) end -doc""" +@doc doc""" inv(g::WreathProductElem) > 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)`. diff --git a/test/AutGroup-tests.jl b/test/AutGroup-tests.jl index 48d9cb8..ed582b9 100644 --- a/test/AutGroup-tests.jl +++ b/test/AutGroup-tests.jl @@ -1,4 +1,5 @@ @testset "Automorphisms" begin + G = PermutationGroup(Int8(4)) @testset "AutSymbol" begin @@ -129,7 +130,7 @@ f = Groups.perm_autsymbol([2,1,4,3]) @test isa(inv(f), Groups.AutSymbol) - @test_throws DomainError f^-1 + @test_throws MethodError f^-1 @test_throws MethodError f*f @test A(f)^-1 == A(inv(f)) @@ -214,10 +215,10 @@ S = unique([gens(G); inv.(gens(G))]) R = 3 - @test Groups.linear_repr(G()) isa Matrix{Float64} - @test Groups.linear_repr(G()) == eye(N) + @test Groups.linear_repr(G()) isa Matrix{Int} + @test Groups.linear_repr(G()) == Matrix{Int}(I, N, N) - M = eye(N) + M = Matrix{Int}(I, N, N) M[1,2] = 1 ϱ₁₂ = G(Groups.rmul_autsymbol(1,2)) λ₁₂ = G(Groups.rmul_autsymbol(1,2)) @@ -230,22 +231,22 @@ @test Groups.linear_repr(ϱ₁₂^-1) == M @test Groups.linear_repr(λ₁₂^-1) == M - @test Groups.linear_repr(ϱ₁₂*λ₁₂^-1) == eye(N) - @test Groups.linear_repr(λ₁₂^-1*ϱ₁₂) == eye(N) + @test Groups.linear_repr(ϱ₁₂*λ₁₂^-1) == Matrix{Int}(I, N, N) + @test Groups.linear_repr(λ₁₂^-1*ϱ₁₂) == Matrix{Int}(I, N, N) - M = eye(N) + M = Matrix{Int}(I, N, N) M[2,2] = -1 ε₂ = G(Groups.flip_autsymbol(2)) @test Groups.linear_repr(ε₂) == M - @test Groups.linear_repr(ε₂^2) == eye(N) + @test Groups.linear_repr(ε₂^2) == Matrix{Int}(I, N, N) M = [0 1 0; 0 0 1; 1 0 0] σ = G(Groups.perm_autsymbol([2,3,1])) @test Groups.linear_repr(σ) == M - @test Groups.linear_repr(σ^3) == eye(3) - @test Groups.linear_repr(σ)^3 ≈ eye(3) + @test Groups.linear_repr(σ^3) == Matrix{Int}(I, 3, 3) + @test Groups.linear_repr(σ)^3 == Matrix{Int}(I, 3, 3) function test_homomorphism(S, r) for elts in Iterators.product([[g for g in S] for _ in 1:r]...) diff --git a/test/runtests.jl b/test/runtests.jl index 30ac4bb..d968c00 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,7 +1,9 @@ -using Base.Test +using Test using AbstractAlgebra using Groups +using LinearAlgebra + @testset "Groups" begin include("FreeGroup-tests.jl") include("AutGroup-tests.jl")