From e4ed91b47325e62f5f175fac83215d4db5323042 Mon Sep 17 00:00:00 2001 From: kalmar Date: Thu, 6 Jul 2017 17:30:19 +0200 Subject: [PATCH 01/79] rename generators(G::Group) -> gens(G::Group) --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index d1f5768..b40cf0b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -37,7 +37,7 @@ using Nemo @testset "GroupRing constructors FreeGroup" begin using Groups F = FreeGroup(3) - S = generators(F) + S = gens(F) append!(S, [inv(s) for s in S]) S = unique(S) From 5fb131c39009003acdccc755cb62fa968cb5a93f Mon Sep 17 00:00:00 2001 From: kalmar Date: Sun, 9 Jul 2017 14:56:11 +0200 Subject: [PATCH 02/79] add mul! and addeq! for MatrixSpace construction --- src/GroupRings.jl | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 9bcf7ce..30cb020 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -1,7 +1,7 @@ module GroupRings using Nemo -import Nemo: Group, GroupElem, Ring, RingElem, parent, elem_type, parent_type +import Nemo: Group, GroupElem, Ring, RingElem, parent, elem_type, parent_type, mul!, addeq! import Base: convert, show, hash, ==, +, -, *, //, /, length, norm, rationalize, deepcopy_internal, getindex, setindex!, eltype, one, zero @@ -281,6 +281,13 @@ end # ############################################################################### +function addeq!{T}(X::GroupRingElem{T}, Y::GroupRingElem{T}) + parent(X) == parent(Y) || throw(ArgumentError( + "Elements don't seem to belong to the same Group Ring!")) + X.coeffs .+= Y.coeffs + return X +end + function add{T<:Number}(X::GroupRingElem{T}, Y::GroupRingElem{T}) parent(X) == parent(Y) || throw(ArgumentError( "Elements don't seem to belong to the same Group Ring!")) @@ -298,7 +305,7 @@ end (+)(X::GroupRingElem, Y::GroupRingElem) = add(X,Y) (-)(X::GroupRingElem, Y::GroupRingElem) = add(X,-Y) -function mul!{T<:Number}(X::AbstractVector{T}, Y::AbstractVector{T}, +function mul!{T}(X::AbstractVector{T}, Y::AbstractVector{T}, pm::Array{Int,2}, result::AbstractVector{T}) for (j,y) in enumerate(Y) if y != zero(eltype(Y)) @@ -312,6 +319,11 @@ function mul!{T<:Number}(X::AbstractVector{T}, Y::AbstractVector{T}, end end +function mul!(result::GroupRingElem, X::GroupRingElem, Y::GroupRingElem) + mul!(X.coeffs, Y.coeffs, parent(X).pm, result.coeffs) + return result +end + function mul{T<:Number}(X::AbstractVector{T}, Y::AbstractVector{T}, pm::Array{Int,2}) result = zeros(X) @@ -321,8 +333,8 @@ end function mul(X::AbstractVector, Y::AbstractVector, pm::Array{Int,2}) T = promote_type(eltype(X), eltype(Y)) - result = zeros(T, deepcopy(X)) - mul!(X, Y, pm, result) + result = zeros(T, X) + mul!(Vector{T}(X), Vector{T}(Y), pm, result) return result end From 56a0964f309244faaec073558092f0834ca71a3d Mon Sep 17 00:00:00 2001 From: kalmar Date: Mon, 10 Jul 2017 19:21:38 +0200 Subject: [PATCH 03/79] better printing --- src/GroupRings.jl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 30cb020..20703e7 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -197,7 +197,7 @@ zero(RG::GroupRing) = RG() ############################################################################### function show(io::IO, A::GroupRing) - print(io, "Group Ring of [$(A.group)]") + print(io, "Group Ring of $(A.group)") end function show(io::IO, X::GroupRingElem) @@ -208,10 +208,14 @@ function show(io::IO, X::GroupRingElem) elseif isdefined(RG, :basis) non_zeros = ((X.coeffs[i], RG.basis[i]) for i in findn(X.coeffs)) elts = ("$(sign(c)> 0? " + ": " - ")$(abs(c))*$g" for (c,g) in non_zeros) - join(io, elts, "") + str = join(elts, "") + if sign(first(non_zeros)[1]) > 0 + str = str[4:end] + end + print(io, str) else warn("Basis of the parent Group is not defined, showing coeffs") - print(io, X.coeffs) + show(io, MIME("text/plain"), X.coeffs) end end From 3b9e405565aeb2982625449d6dd77254799dfefd Mon Sep 17 00:00:00 2001 From: kalmar Date: Mon, 10 Jul 2017 19:25:52 +0200 Subject: [PATCH 04/79] use a single zero object to compare --- src/GroupRings.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 20703e7..51f29f6 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -311,10 +311,11 @@ end function mul!{T}(X::AbstractVector{T}, Y::AbstractVector{T}, pm::Array{Int,2}, result::AbstractVector{T}) + z = zero(T) for (j,y) in enumerate(Y) - if y != zero(eltype(Y)) + if y != z for (i, index) in enumerate(pm[:,j]) - if X[i] != zero(eltype(X)) + if X[i] != z index == 0 && throw(ArgumentError("The product don't seem to belong to the span of basis!")) result[index] += X[i]*y end From 8463b928cbe4c24dabd9c87617ba2acebb091ccb Mon Sep 17 00:00:00 2001 From: kalmar Date: Mon, 10 Jul 2017 19:26:44 +0200 Subject: [PATCH 05/79] add RG(i::Int) = i*(id) function --- src/GroupRings.jl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 51f29f6..f5e326a 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -113,6 +113,11 @@ end # ############################################################################### +zero(RG::GroupRing, T::Type=Int) = RG(T) +one(RG::GroupRing, T::Type=Int) = RG(RG.group(), T) + +(RG::GroupRing)(i::Int, T::Type=Int) = i*one(RG, T) + function (RG::GroupRing)(T::Type=Int) isdefined(RG, :basis) || throw("Complete the definition of GroupRing first") return GroupRingElem(spzeros(T,length(RG.basis)), RG) @@ -187,9 +192,6 @@ end eltype(X::GroupRingElem) = eltype(X.coeffs) -one(RG::GroupRing) = RG(RG.group()) -zero(RG::GroupRing) = RG() - ############################################################################### # # String I/O From dd518574ff7679886c1064dd673d864cbf6c6a88 Mon Sep 17 00:00:00 2001 From: kalmar Date: Mon, 10 Jul 2017 19:27:28 +0200 Subject: [PATCH 06/79] fix: zero result coeffs before jumping into loopy mul! --- src/GroupRings.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index f5e326a..aa41ecb 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -327,6 +327,7 @@ function mul!{T}(X::AbstractVector{T}, Y::AbstractVector{T}, end function mul!(result::GroupRingElem, X::GroupRingElem, Y::GroupRingElem) + result.coeffs *= 0 mul!(X.coeffs, Y.coeffs, parent(X).pm, result.coeffs) return result end From 688dfa50625d1f30729a3ab3fd2ba0d5cb9a6b13 Mon Sep 17 00:00:00 2001 From: kalmar Date: Mon, 10 Jul 2017 19:28:19 +0200 Subject: [PATCH 07/79] result is the firs argument of mul! --- src/GroupRings.jl | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index aa41ecb..caede0c 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -311,8 +311,7 @@ end (+)(X::GroupRingElem, Y::GroupRingElem) = add(X,Y) (-)(X::GroupRingElem, Y::GroupRingElem) = add(X,-Y) -function mul!{T}(X::AbstractVector{T}, Y::AbstractVector{T}, - pm::Array{Int,2}, result::AbstractVector{T}) +function mul!{T}(result::AbstractVector{T}, X::AbstractVector{T}, Y::AbstractVector{T}, pm::Array{Int,2}) z = zero(T) for (j,y) in enumerate(Y) if y != z @@ -328,21 +327,21 @@ end function mul!(result::GroupRingElem, X::GroupRingElem, Y::GroupRingElem) result.coeffs *= 0 - mul!(X.coeffs, Y.coeffs, parent(X).pm, result.coeffs) + mul!(result.coeffs, X.coeffs, Y.coeffs, parent(X).pm) return result end function mul{T<:Number}(X::AbstractVector{T}, Y::AbstractVector{T}, pm::Array{Int,2}) result = zeros(X) - mul!(X,Y,pm,result) + mul!(result, X, Y, pm) return result end function mul(X::AbstractVector, Y::AbstractVector, pm::Array{Int,2}) T = promote_type(eltype(X), eltype(Y)) result = zeros(T, X) - mul!(Vector{T}(X), Vector{T}(Y), pm, result) + mul!(result, Vector{T}(X), Vector{T}(Y), pm) return result end From 63b4a0594f907a03fa9074c858d8ccd09c9e6b64 Mon Sep 17 00:00:00 2001 From: kalmar Date: Mon, 10 Jul 2017 19:29:53 +0200 Subject: [PATCH 08/79] Revert "add mul! and addeq! for MatrixSpace construction" This reverts commit 5fb131c39009003acdccc755cb62fa968cb5a93f. --- src/GroupRings.jl | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 20703e7..c5573f2 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -1,7 +1,7 @@ module GroupRings using Nemo -import Nemo: Group, GroupElem, Ring, RingElem, parent, elem_type, parent_type, mul!, addeq! +import Nemo: Group, GroupElem, Ring, RingElem, parent, elem_type, parent_type import Base: convert, show, hash, ==, +, -, *, //, /, length, norm, rationalize, deepcopy_internal, getindex, setindex!, eltype, one, zero @@ -285,13 +285,6 @@ end # ############################################################################### -function addeq!{T}(X::GroupRingElem{T}, Y::GroupRingElem{T}) - parent(X) == parent(Y) || throw(ArgumentError( - "Elements don't seem to belong to the same Group Ring!")) - X.coeffs .+= Y.coeffs - return X -end - function add{T<:Number}(X::GroupRingElem{T}, Y::GroupRingElem{T}) parent(X) == parent(Y) || throw(ArgumentError( "Elements don't seem to belong to the same Group Ring!")) @@ -309,7 +302,7 @@ end (+)(X::GroupRingElem, Y::GroupRingElem) = add(X,Y) (-)(X::GroupRingElem, Y::GroupRingElem) = add(X,-Y) -function mul!{T}(X::AbstractVector{T}, Y::AbstractVector{T}, +function mul!{T<:Number}(X::AbstractVector{T}, Y::AbstractVector{T}, pm::Array{Int,2}, result::AbstractVector{T}) for (j,y) in enumerate(Y) if y != zero(eltype(Y)) @@ -323,11 +316,6 @@ function mul!{T}(X::AbstractVector{T}, Y::AbstractVector{T}, end end -function mul!(result::GroupRingElem, X::GroupRingElem, Y::GroupRingElem) - mul!(X.coeffs, Y.coeffs, parent(X).pm, result.coeffs) - return result -end - function mul{T<:Number}(X::AbstractVector{T}, Y::AbstractVector{T}, pm::Array{Int,2}) result = zeros(X) @@ -337,8 +325,8 @@ end function mul(X::AbstractVector, Y::AbstractVector, pm::Array{Int,2}) T = promote_type(eltype(X), eltype(Y)) - result = zeros(T, X) - mul!(Vector{T}(X), Vector{T}(Y), pm, result) + result = zeros(T, deepcopy(X)) + mul!(X, Y, pm, result) return result end From 27e0b03b3c8cfb205c170689b20c6b0f37295196 Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 11 Jul 2017 15:58:02 +0200 Subject: [PATCH 09/79] move type-related functions to one location --- src/GroupRings.jl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index caede0c..5686c9e 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -65,8 +65,16 @@ elem_type(::GroupRing) = GroupRingElem parent_type(::GroupRingElem) = GroupRing parent_type(::Type{GroupRingElem}) = GroupRing +eltype(X::GroupRingElem) = eltype(X.coeffs) + parent{T}(g::GroupRingElem{T}) = g.parent +Base.promote_rule{T<:Number,S<:Number}(::Type{GroupRingElem{T}}, ::Type{GroupRingElem{S}}) = GroupRingElem{promote_type(T,S)} + +function convert{T<:Number}(::Type{T}, X::GroupRingElem) + return GroupRingElem(convert(AbstractVector{T}, X.coeffs), parent(X)) +end + ############################################################################### # # GroupRing / GroupRingElem constructors @@ -77,10 +85,6 @@ function GroupRingElem{T<:Number}(c::AbstractVector{T}, RG::GroupRing) return GroupRingElem{T}(c, RG) end -function convert{T<:Number}(::Type{T}, X::GroupRingElem) - return GroupRingElem(convert(AbstractVector{T}, X.coeffs), parent(X)) -end - function GroupRing(G::Group, pm::Array{Int,2}) size(pm,1) == size(pm,2) || throw("pm must be square, got $(size(pm))") RG = GroupRing(G, initialise=false) From e92a5d72e828ebf2b0a9d63e8914fdde8e9ab8d5 Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 11 Jul 2017 15:58:45 +0200 Subject: [PATCH 10/79] add divexact function --- src/GroupRings.jl | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 5686c9e..d5059c8 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -1,7 +1,7 @@ module GroupRings using Nemo -import Nemo: Group, GroupElem, Ring, RingElem, parent, elem_type, parent_type, mul!, addeq! +import Nemo: Group, GroupElem, Ring, RingElem, parent, elem_type, parent_type, mul!, addeq!, divexact import Base: convert, show, hash, ==, +, -, *, //, /, length, norm, rationalize, deepcopy_internal, getindex, setindex!, eltype, one, zero @@ -368,6 +368,16 @@ function *{T<:Number, S<:Number}(X::GroupRingElem{T}, Y::GroupRingElem{S}) return GroupRingElem(result, RG) end +function divexact{T}(X::GroupRingElem{T}, Y::GroupRingElem{T}) + if length(Y) != 1 + throw("Can not divide by a non-primitive element $(Y)!") + else + idx = findfirst(Y) + c = Y[idx] + g = parent(Y).basis[idx] + return X*1//c*parent(Y)(inv(g)) + end +end ############################################################################### # # *-involution From 8d22162504ecd1b2bdd439007f8751f25799cd2f Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 11 Jul 2017 15:59:15 +0200 Subject: [PATCH 11/79] implement Array protocol for GroupRingElem --- src/GroupRings.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index d5059c8..312a385 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -160,7 +160,7 @@ end ############################################################################### # -# Basic manipulation +# Basic manipulation && Array protocol # ############################################################################### @@ -194,7 +194,8 @@ function setindex!(X::GroupRingElem, value, g::GroupElem) end end -eltype(X::GroupRingElem) = eltype(X.coeffs) +Base.size(X::GroupRingElem) = size(X.coeffs) +Base.linearindexing{T<:GroupRingElem}(::Type{T}) = Base.LinearFast() ############################################################################### # From ed023be1fd7db5e6fb5e5f64e818e104478f830e Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 11 Jul 2017 16:00:50 +0200 Subject: [PATCH 12/79] zero the array where product of X and Y is stored --- src/GroupRings.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 312a385..318870f 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -318,6 +318,7 @@ end function mul!{T}(result::AbstractVector{T}, X::AbstractVector{T}, Y::AbstractVector{T}, pm::Array{Int,2}) z = zero(T) + result .= z for (j,y) in enumerate(Y) if y != z for (i, index) in enumerate(pm[:,j]) From 5a3e2761a45b5be3eeac432640e2679faf9904df Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 11 Jul 2017 16:01:42 +0200 Subject: [PATCH 13/79] change throw message --- src/GroupRings.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 318870f..4d23d13 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -323,7 +323,7 @@ function mul!{T}(result::AbstractVector{T}, X::AbstractVector{T}, Y::AbstractVec if y != z for (i, index) in enumerate(pm[:,j]) if X[i] != z - index == 0 && throw(ArgumentError("The product don't seem to belong to the span of basis!")) + index == 0 && throw(ArgumentError("The product don't seem to be supported on basis!")) result[index] += X[i]*y end end From b80db5274270dba4b6f92666528fee497c4f76bb Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 11 Jul 2017 16:02:43 +0200 Subject: [PATCH 14/79] deepcopy result if result === X to prevent X from zeroing --- src/GroupRings.jl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 4d23d13..714b330 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -331,8 +331,11 @@ function mul!{T}(result::AbstractVector{T}, X::AbstractVector{T}, Y::AbstractVec end end -function mul!(result::GroupRingElem, X::GroupRingElem, Y::GroupRingElem) - result.coeffs *= 0 +function mul!{T}(result::GroupRingElem{T}, X::GroupRingElem{T}, Y::GroupRingElem{T}) + # @show result === X + if result === X + result = deepcopy(result) + end mul!(result.coeffs, X.coeffs, Y.coeffs, parent(X).pm) return result end From 51c638fd65453dc1b73ce2b04b432bf7bfbb433c Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 11 Jul 2017 16:16:41 +0200 Subject: [PATCH 15/79] mul! function for GroupRingElems (different coeffs) --- src/GroupRings.jl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 714b330..5d62b8f 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -340,6 +340,15 @@ function mul!{T}(result::GroupRingElem{T}, X::GroupRingElem{T}, Y::GroupRingElem return result end +function mul!(result::GroupRingElem, X::GroupRingElem, Y::GroupRingElem) + S, T, U = eltype(result), eltype(X), eltype(U) + TT = promote_type(S, T, U) + warn("Types $S, $T, $U are not the same, promoting the result to $TT") + result = deepcopy(result) + mul!(convert(Array{TT},result.coeffs), convert(Array{TT}, X.coeffs), convert(Array{TT}, Y.coeffs), parent(X).pm) + return result +end + function mul{T<:Number}(X::AbstractVector{T}, Y::AbstractVector{T}, pm::Array{Int,2}) result = zeros(X) From eba594b7a4e1776c2fb781582ae0613f9a989059 Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 11 Jul 2017 16:18:11 +0200 Subject: [PATCH 16/79] sanity test mul!(a,a,b) == a*b --- test/runtests.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/runtests.jl b/test/runtests.jl index b40cf0b..9c78efc 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -112,6 +112,9 @@ using Nemo @test eltype(2.0*a) == typeof(2.0) @test (2.0*a).coeffs == 2.0.*(a.coeffs) + b = RG(1) + GroupRing.star(a) + @test a*b == mul!(a,a,b) + @test isa(a/2, GroupRingElem) @test eltype(a/2) == typeof(1/2) @test (a/2).coeffs == 0.5*(a.coeffs) From ffee54616ab018150d1d3dd62d08571fee91d157 Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 11 Jul 2017 18:28:30 +0200 Subject: [PATCH 17/79] critical fix: if g was not in basis setindex! failed silently --- src/GroupRings.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 5d62b8f..d781f59 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -189,9 +189,8 @@ function setindex!(X::GroupRingElem, value, g::GroupElem) typeof(g) == elem_type(RG.group) || throw("$g is not an element of $(RG.group)") if !(g in keys(RG.basis_dict)) g = (RG.group)(g) - else - X.coeffs[RG.basis_dict[g]] = value end + X.coeffs[RG.basis_dict[g]] = value end Base.size(X::GroupRingElem) = size(X.coeffs) From f852a6ca8ef00099b2664bc7347602159149e4e2 Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 11 Jul 2017 18:43:37 +0200 Subject: [PATCH 18/79] add tests for the silent failure --- test/runtests.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/runtests.jl b/test/runtests.jl index 9c78efc..36d476c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -53,6 +53,12 @@ using Nemo B = GroupRing(F, basis, d, pm) @test A == B + g = B() + s = S[2] + g[s] = 1 + @test g == B(s) + @test g[s^2] == 0 + @test_throws KeyError g[s^10] end @testset "GroupRingElems constructors/basic manipulation" begin From 4cb4d299de63f867c82d78a87d38bb85db8cc35e Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 11 Jul 2017 18:44:08 +0200 Subject: [PATCH 19/79] small tweaks to printing --- src/GroupRings.jl | 4 ++-- test/runtests.jl | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index d781f59..b87b1ae 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -214,9 +214,9 @@ function show(io::IO, X::GroupRingElem) elseif isdefined(RG, :basis) non_zeros = ((X.coeffs[i], RG.basis[i]) for i in findn(X.coeffs)) elts = ("$(sign(c)> 0? " + ": " - ")$(abs(c))*$g" for (c,g) in non_zeros) - str = join(elts, "") + str = join(elts, "")[2:end] if sign(first(non_zeros)[1]) > 0 - str = str[4:end] + str = str[3:end] end print(io, str) else diff --git a/test/runtests.jl b/test/runtests.jl index 36d476c..d2e228d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -83,7 +83,8 @@ using Nemo @test a[5] == 1 @test a[p] == 1 - @test string(a) == " + 1*[2, 3, 1]" + @test string(a) == "1*[2, 3, 1]" + @test string(-a) == "- 1*[2, 3, 1]" @test RG([0,0,0,0,1,0]) == a @@ -95,7 +96,8 @@ using Nemo @test a[1] == 2 @test a[s] == 2 - @test string(a) == " + 2*[1, 2, 3] + 1*[2, 3, 1]" + @test string(a) == "2*[1, 2, 3] + 1*[2, 3, 1]" + @test string(-a) == "- 2*[1, 2, 3] - 1*[2, 3, 1]" @test length(a) == 2 end From 7ce52c69973533c63fd4e1487362a26c389eef79 Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 11 Jul 2017 18:44:34 +0200 Subject: [PATCH 20/79] GroupRing.star -> GroupRings.star --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index d2e228d..f0d870a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -120,7 +120,7 @@ using Nemo @test eltype(2.0*a) == typeof(2.0) @test (2.0*a).coeffs == 2.0.*(a.coeffs) - b = RG(1) + GroupRing.star(a) + b = RG(1) + GroupRings.star(a) @test a*b == mul!(a,a,b) @test isa(a/2, GroupRingElem) From 9f6287382d3bb56cd13894bbdc7b83b2f24b7598 Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 11 Jul 2017 18:44:08 +0200 Subject: [PATCH 21/79] small tweaks to printing --- src/GroupRings.jl | 4 ++-- test/runtests.jl | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index c5573f2..b863695 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -208,9 +208,9 @@ function show(io::IO, X::GroupRingElem) elseif isdefined(RG, :basis) non_zeros = ((X.coeffs[i], RG.basis[i]) for i in findn(X.coeffs)) elts = ("$(sign(c)> 0? " + ": " - ")$(abs(c))*$g" for (c,g) in non_zeros) - str = join(elts, "") + str = join(elts, "")[2:end] if sign(first(non_zeros)[1]) > 0 - str = str[4:end] + str = str[3:end] end print(io, str) else diff --git a/test/runtests.jl b/test/runtests.jl index b40cf0b..924efac 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -77,7 +77,8 @@ using Nemo @test a[5] == 1 @test a[p] == 1 - @test string(a) == " + 1*[2, 3, 1]" + @test string(a) == "1*[2, 3, 1]" + @test string(-a) == "- 1*[2, 3, 1]" @test RG([0,0,0,0,1,0]) == a @@ -89,7 +90,8 @@ using Nemo @test a[1] == 2 @test a[s] == 2 - @test string(a) == " + 2*[1, 2, 3] + 1*[2, 3, 1]" + @test string(a) == "2*[1, 2, 3] + 1*[2, 3, 1]" + @test string(-a) == "- 2*[1, 2, 3] - 1*[2, 3, 1]" @test length(a) == 2 end From 8a3a4c70d62f0dcd7a752300e0b4d20201481d63 Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 11 Jul 2017 18:28:30 +0200 Subject: [PATCH 22/79] critical fix: if g was not in basis setindex! failed silently --- src/GroupRings.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index b863695..2487e3c 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -180,9 +180,8 @@ function setindex!(X::GroupRingElem, value, g::GroupElem) typeof(g) == elem_type(RG.group) || throw("$g is not an element of $(RG.group)") if !(g in keys(RG.basis_dict)) g = (RG.group)(g) - else - X.coeffs[RG.basis_dict[g]] = value end + X.coeffs[RG.basis_dict[g]] = value end eltype(X::GroupRingElem) = eltype(X.coeffs) From 90106359e4535b3ccede768436a9419d0eec9161 Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 11 Jul 2017 18:43:37 +0200 Subject: [PATCH 23/79] add tests for the silent failure --- test/runtests.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/runtests.jl b/test/runtests.jl index 924efac..cf2da17 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -53,6 +53,12 @@ using Nemo B = GroupRing(F, basis, d, pm) @test A == B + g = B() + s = S[2] + g[s] = 1 + @test g == B(s) + @test g[s^2] == 0 + @test_throws KeyError g[s^10] end @testset "GroupRingElems constructors/basic manipulation" begin From 4e213c691df9f803dc365e80079ea274121967b5 Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 11 Jul 2017 22:37:53 +0200 Subject: [PATCH 24/79] throw if dividing by a non-unit --- src/GroupRings.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index b87b1ae..e2aa5ef 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -387,10 +387,12 @@ function divexact{T}(X::GroupRingElem{T}, Y::GroupRingElem{T}) else idx = findfirst(Y) c = Y[idx] + c == 0 || throw("Can not invert") g = parent(Y).basis[idx] return X*1//c*parent(Y)(inv(g)) end end + ############################################################################### # # *-involution From b40b9f94ebfe1753d0eff95da695eb8fb2280609 Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 12 Jul 2017 11:34:43 +0200 Subject: [PATCH 25/79] in mul! promote to the common type only if necessary --- src/GroupRings.jl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index e2aa5ef..494de1d 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -340,11 +340,14 @@ function mul!{T}(result::GroupRingElem{T}, X::GroupRingElem{T}, Y::GroupRingElem end function mul!(result::GroupRingElem, X::GroupRingElem, Y::GroupRingElem) - S, T, U = eltype(result), eltype(X), eltype(U) + S, T, U = eltype(result), eltype(X), eltype(Y) TT = promote_type(S, T, U) - warn("Types $S, $T, $U are not the same, promoting the result to $TT") + if S != TT || T != TT || U != TT + warn("Types $S, $T, $U are not the same, promoting the result to $TT") + result.coeffs = convert(Array{TT},result.coeffs) + end result = deepcopy(result) - mul!(convert(Array{TT},result.coeffs), convert(Array{TT}, X.coeffs), convert(Array{TT}, Y.coeffs), parent(X).pm) + mul!(result.coeffs, convert(Array{TT}, X.coeffs), convert(Array{TT}, Y.coeffs), parent(X).pm) return result end From 6e95eae583c48dac56869eaa98e72f7404aa1198 Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 12 Jul 2017 14:31:51 +0200 Subject: [PATCH 26/79] convert only if type of the product and result disagree --- src/GroupRings.jl | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 494de1d..dad9466 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -315,7 +315,7 @@ end (+)(X::GroupRingElem, Y::GroupRingElem) = add(X,Y) (-)(X::GroupRingElem, Y::GroupRingElem) = add(X,-Y) -function mul!{T}(result::AbstractVector{T}, X::AbstractVector{T}, Y::AbstractVector{T}, pm::Array{Int,2}) +function mul!{T}(result::AbstractVector{T}, X::AbstractVector, Y::AbstractVector, pm::Array{Int,2}) z = zero(T) result .= z for (j,y) in enumerate(Y) @@ -339,15 +339,19 @@ function mul!{T}(result::GroupRingElem{T}, X::GroupRingElem{T}, Y::GroupRingElem return result end -function mul!(result::GroupRingElem, X::GroupRingElem, Y::GroupRingElem) - S, T, U = eltype(result), eltype(X), eltype(Y) - TT = promote_type(S, T, U) - if S != TT || T != TT || U != TT - warn("Types $S, $T, $U are not the same, promoting the result to $TT") - result.coeffs = convert(Array{TT},result.coeffs) +function mul!{T<:Number}(result::GroupRingElem{T}, X::GroupRingElem, Y::GroupRingElem) + if result === X + result = deepcopy(result) end - result = deepcopy(result) - mul!(result.coeffs, convert(Array{TT}, X.coeffs), convert(Array{TT}, Y.coeffs), parent(X).pm) + + TT = typeof(first(a.coeffs)*first(b.coeffs)) + + if TT != T + warn("Type of the result $T does not contain type of the product ($TT), promoting.") + result = convert(TT, result) + end + + mul!(result.coeffs, X.coeffs, Y.coeffs, parent(X).pm) return result end From ee3b4e0761ed74b349482cf31d979a933ee69ae9 Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 12 Jul 2017 20:43:12 +0200 Subject: [PATCH 27/79] allocation-free multiplication! --- src/GroupRings.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index dad9466..029d79a 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -318,12 +318,12 @@ end function mul!{T}(result::AbstractVector{T}, X::AbstractVector, Y::AbstractVector, pm::Array{Int,2}) z = zero(T) result .= z - for (j,y) in enumerate(Y) - if y != z - for (i, index) in enumerate(pm[:,j]) + for j in eachindex(Y) + if Y[j] != z + for i in 1:size(pm,1) if X[i] != z - index == 0 && throw(ArgumentError("The product don't seem to be supported on basis!")) - result[index] += X[i]*y + pm[i,j] == 0 && throw(ArgumentError("The product don't seem to be supported on basis!")) + result[pm[i,j]] += X[i]*Y[j] end end end From 6ac5800379c1084f5f0fa6783010a55b972ca751 Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 12 Jul 2017 20:53:17 +0200 Subject: [PATCH 28/79] allocation-free multiplication! # Conflicts: # src/GroupRings.jl --- src/GroupRings.jl | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 2487e3c..92bdc19 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -301,14 +301,15 @@ end (+)(X::GroupRingElem, Y::GroupRingElem) = add(X,Y) (-)(X::GroupRingElem, Y::GroupRingElem) = add(X,-Y) -function mul!{T<:Number}(X::AbstractVector{T}, Y::AbstractVector{T}, - pm::Array{Int,2}, result::AbstractVector{T}) - for (j,y) in enumerate(Y) - if y != zero(eltype(Y)) - for (i, index) in enumerate(pm[:,j]) - if X[i] != zero(eltype(X)) - index == 0 && throw(ArgumentError("The product don't seem to belong to the span of basis!")) - result[index] += X[i]*y +function mul!{T}(result::AbstractVector{T}, X::AbstractVector, Y::AbstractVector, pm::Array{Int,2}) + z = zero(T) + result .= z + for j in eachindex(Y) + if Y[j] != z + for i in 1:size(pm,1) + if X[i] != z + pm[i,j] == 0 && throw(ArgumentError("The product don't seem to be supported on basis!")) + result[pm[i,j]] += X[i]*Y[j] end end end From fc3cbeb14c28d77d0dfc0a7fa0830ba2e20c3a1a Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 12 Jul 2017 20:54:20 +0200 Subject: [PATCH 29/79] preserve type of coerced element --- src/GroupRings.jl | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 029d79a..066485e 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -151,11 +151,13 @@ function (RG::GroupRing)(X::GroupRingElem) end function (RG::GroupRing)(X::GroupRingElem, emb::Function) - result = RG(eltype(X.coeffs)) - for g in parent(X).basis - result[emb(g)] = X[g] - end - return result + result = RG(eltype(X.coeffs)) + T = typeof(X.coeffs) + result.coeffs = T(result.coeffs) + for g in parent(X).basis + result[emb(g)] = X[g] + end + return result end ############################################################################### From a66d7755aeafe4cbd68f848a591b3f7de3448969 Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 12 Jul 2017 20:56:59 +0200 Subject: [PATCH 30/79] fix copy-paste mistake --- src/GroupRings.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 066485e..5610f3c 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -346,7 +346,7 @@ function mul!{T<:Number}(result::GroupRingElem{T}, X::GroupRingElem, Y::GroupRin result = deepcopy(result) end - TT = typeof(first(a.coeffs)*first(b.coeffs)) + TT = typeof(first(X.coeffs)*first(Y.coeffs)) if TT != T warn("Type of the result $T does not contain type of the product ($TT), promoting.") From 8daa86df3113f33bf774294f3daf7013a98559cd Mon Sep 17 00:00:00 2001 From: kalmar Date: Sun, 16 Jul 2017 21:44:42 +0200 Subject: [PATCH 31/79] try...catch are slow --- src/GroupRings.jl | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 5610f3c..4985965 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -128,11 +128,7 @@ function (RG::GroupRing)(T::Type=Int) end function (RG::GroupRing)(g::GroupElem, T::Type=Int) - g = try - RG.group(g) - catch - throw("Can't coerce $g to the underlying group of $RG") - end + g = RG.group(g) result = RG(T) result[g] = one(T) return result From c1e2d4209adb1319d286bc01eb945056af1745b7 Mon Sep 17 00:00:00 2001 From: kalmar Date: Sun, 16 Jul 2017 21:45:24 +0200 Subject: [PATCH 32/79] to match e.g. sparse and dense zeros... ugly --- src/GroupRings.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 4985965..fdaf728 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -167,7 +167,7 @@ function deepcopy_internal(X::GroupRingElem, dict::ObjectIdDict) end function hash(X::GroupRingElem, h::UInt) - return hash(X.coeffs, hash(parent(X), h)) + return hash(full(X.coeffs), hash(parent(X), hash(GroupRingElem, h))) end function getindex(X::GroupRingElem, n::Int) From 75a83da8cbecc5b45215bf4c90206d3f3badb95d Mon Sep 17 00:00:00 2001 From: kalmar Date: Mon, 17 Jul 2017 09:24:56 +0200 Subject: [PATCH 33/79] Type experiment: parametrise GroupRingElem after types of its parent --- src/GroupRings.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 5610f3c..4654ee5 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -34,9 +34,9 @@ GroupRing{Gr<:Group}(G::Gr;initialise=true) = GroupRing{Gr, elem_type(G)}(G, ini GroupRing{Gr<:Group, T<:GroupElem}(G::Gr, b::Vector{T}, b_d::Dict{T,Int}, pm::Array{Int,2}) = GroupRing{Gr, T}(G, b, b_d, pm) -type GroupRingElem{T<:Number} <: RingElem +type GroupRingElem{T<:Number, Gr<:Group, GrEl<:GroupElem} <: RingElem coeffs::AbstractVector{T} - parent::GroupRing + parent::GroupRing{Gr, GrEl} function GroupRingElem(c::AbstractVector{T}, RG::GroupRing, check=true) if check @@ -81,8 +81,8 @@ end # ############################################################################### -function GroupRingElem{T<:Number}(c::AbstractVector{T}, RG::GroupRing) - return GroupRingElem{T}(c, RG) +function GroupRingElem{T<:Number, Gr<:Group, GrEl<:GroupElem}(c::AbstractVector{T}, RG::GroupRing{Gr, GrEl}) + return GroupRingElem{T, Gr, GrEl}(c, RG) end function GroupRing(G::Group, pm::Array{Int,2}) From 1a77e8a2bcdcceffae276520407f4525902f9a71 Mon Sep 17 00:00:00 2001 From: kalmar Date: Mon, 17 Jul 2017 09:32:38 +0200 Subject: [PATCH 34/79] faster (RG::GroupRing)(i::Int) --- src/GroupRings.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 92011ad..ffe8460 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -120,7 +120,11 @@ end zero(RG::GroupRing, T::Type=Int) = RG(T) one(RG::GroupRing, T::Type=Int) = RG(RG.group(), T) -(RG::GroupRing)(i::Int, T::Type=Int) = i*one(RG, T) +function (RG::GroupRing)(i::Int, T::Type=Int) + elt = RG(T) + elt[RG.group()] = i + return elt +end function (RG::GroupRing)(T::Type=Int) isdefined(RG, :basis) || throw("Complete the definition of GroupRing first") From f939a2ae27f472d628ce3ce317c8f8c60ebd252b Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 19 Jul 2017 13:33:55 +0200 Subject: [PATCH 35/79] Revert "Type experiment: parametrise GroupRingElem after types of its parent" This reverts commit 75a83da8cbecc5b45215bf4c90206d3f3badb95d. --- src/GroupRings.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index ffe8460..41bac97 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -34,9 +34,9 @@ GroupRing{Gr<:Group}(G::Gr;initialise=true) = GroupRing{Gr, elem_type(G)}(G, ini GroupRing{Gr<:Group, T<:GroupElem}(G::Gr, b::Vector{T}, b_d::Dict{T,Int}, pm::Array{Int,2}) = GroupRing{Gr, T}(G, b, b_d, pm) -type GroupRingElem{T<:Number, Gr<:Group, GrEl<:GroupElem} <: RingElem +type GroupRingElem{T<:Number} <: RingElem coeffs::AbstractVector{T} - parent::GroupRing{Gr, GrEl} + parent::GroupRing function GroupRingElem(c::AbstractVector{T}, RG::GroupRing, check=true) if check @@ -81,8 +81,8 @@ end # ############################################################################### -function GroupRingElem{T<:Number, Gr<:Group, GrEl<:GroupElem}(c::AbstractVector{T}, RG::GroupRing{Gr, GrEl}) - return GroupRingElem{T, Gr, GrEl}(c, RG) +function GroupRingElem{T<:Number}(c::AbstractVector{T}, RG::GroupRing) + return GroupRingElem{T}(c, RG) end function GroupRing(G::Group, pm::Array{Int,2}) From 7390f4699e682d76fdc1bc6973fb37d84dbe234a Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 19 Jul 2017 22:15:47 +0200 Subject: [PATCH 36/79] add check::Bool=true to add(::GroupRingElem, ::GroupRingElem) --- src/GroupRings.jl | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 41bac97..585f676 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -300,16 +300,18 @@ function addeq!{T}(X::GroupRingElem{T}, Y::GroupRingElem{T}) return X end -function add{T<:Number}(X::GroupRingElem{T}, Y::GroupRingElem{T}) - parent(X) == parent(Y) || throw(ArgumentError( - "Elements don't seem to belong to the same Group Ring!")) +function add{T<:Number}(X::GroupRingElem{T}, Y::GroupRingElem{T}, check::Bool=true) + if check + parent(X) == parent(Y) || throw("Elements don't seem to belong to the same Group Ring!") + end return GroupRingElem(X.coeffs+Y.coeffs, parent(X)) end function add{T<:Number, S<:Number}(X::GroupRingElem{T}, - Y::GroupRingElem{S}) - parent(X) == parent(Y) || throw(ArgumentError( - "Elements don't seem to belong to the same Group Ring!")) + Y::GroupRingElem{S}, check::Bool=true) + if check + parent(X) == parent(Y) || throw("Elements don't seem to belong to the same Group Ring!") + end warn("Adding elements with different base rings!") return GroupRingElem(+(promote(X.coeffs, Y.coeffs)...), parent(X)) end From 3166c588b1170e9a2d45617ed9588a76fbdc3c68 Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 19 Jul 2017 22:17:06 +0200 Subject: [PATCH 37/79] remove checks from addeq! --- src/GroupRings.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 585f676..8913dd6 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -294,8 +294,6 @@ end ############################################################################### function addeq!{T}(X::GroupRingElem{T}, Y::GroupRingElem{T}) - parent(X) == parent(Y) || throw(ArgumentError( - "Elements don't seem to belong to the same Group Ring!")) X.coeffs .+= Y.coeffs return X end From 4c275460cc339f1eab9958f5fb41be81137c2500 Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 19 Jul 2017 22:19:58 +0200 Subject: [PATCH 38/79] indentation --- src/GroupRings.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 8913dd6..ad7d948 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -317,7 +317,10 @@ end (+)(X::GroupRingElem, Y::GroupRingElem) = add(X,Y) (-)(X::GroupRingElem, Y::GroupRingElem) = add(X,-Y) -function mul!{T}(result::AbstractVector{T}, X::AbstractVector, Y::AbstractVector, pm::Array{Int,2}) +function mul!{T}(result::AbstractVector{T}, + X::AbstractVector, + Y::AbstractVector, + pm::Array{Int,2}) z = zero(T) result .= z for j in eachindex(Y) From 5c2fabfb0827fabfcaa135c6c4a069e14997b475 Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 19 Jul 2017 22:38:17 +0200 Subject: [PATCH 39/79] make another version of mul! for GroupRingElts --- src/GroupRings.jl | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index ad7d948..9bfd581 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -335,12 +335,23 @@ function mul!{T}(result::AbstractVector{T}, end end -function mul!{T}(result::GroupRingElem{T}, X::GroupRingElem{T}, Y::GroupRingElem{T}) - # @show result === X +function mul!{T}(result::GroupRingElem{T}, X::GroupRingElem, Y::GroupRingElem) if result === X result = deepcopy(result) end - mul!(result.coeffs, X.coeffs, Y.coeffs, parent(X).pm) + + z = zero(T) + result.coeffs .= z + + for j in eachindex(Y.coeffs) + if Y.coeffs[j] != z + for i in eachindex(X.coeffs) + if X.coeffs[i] != z + result.coeffs[parent(X).pm[i,j]] += X[i]*Y[j] + end + end + end + end return result end From f586cb51460b6c6eb159b23d7db8a19a16339ce6 Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 19 Jul 2017 22:41:15 +0200 Subject: [PATCH 40/79] remove mul functions: * should call mul! directly --- src/GroupRings.jl | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 9bfd581..a41b9c6 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -385,24 +385,7 @@ function mul(X::AbstractVector, Y::AbstractVector, pm::Array{Int,2}) return result end -function *{T<:Number}(X::GroupRingElem{T}, Y::GroupRingElem{T}) - parent(X) == parent(Y) || throw(ArgumentError( - "Elements don't seem to belong to the same Group Ring!")) - RG = parent(X) - isdefined(RG, :pm) || complete(RG) - result = mul(X.coeffs, Y.coeffs, RG.pm) - return GroupRingElem(result, RG) -end -function *{T<:Number, S<:Number}(X::GroupRingElem{T}, Y::GroupRingElem{S}) - parent(X) == parent(Y) || throw("Elements don't seem to belong to the same - Group Ring!") - warn("Multiplying elements with different base rings!") - RG = parent(X) - isdefined(RG, :pm) || complete(RG) - result = mul(X.coeffs, Y.coeffs, RG.pm) - return GroupRingElem(result, RG) -end function divexact{T}(X::GroupRingElem{T}, Y::GroupRingElem{T}) if length(Y) != 1 From f2ad7c804511bf969a968ce00869461c7387b595 Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 19 Jul 2017 22:43:46 +0200 Subject: [PATCH 41/79] new version of *, with optional check::Bool=true --- src/GroupRings.jl | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index a41b9c6..2c40b1d 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -371,10 +371,15 @@ function mul!{T<:Number}(result::GroupRingElem{T}, X::GroupRingElem, Y::GroupRin return result end -function mul{T<:Number}(X::AbstractVector{T}, Y::AbstractVector{T}, - pm::Array{Int,2}) - result = zeros(X) - mul!(result, X, Y, pm) +function *{T<:Number, S<:Number}(X::GroupRingElem{T}, Y::GroupRingElem{S}, check::Bool=true) + if true + parent(X) == parent(Y) || throw("Elements don't seem to belong to the same Group Ring!") + end + + TT = typeof(first(X.coeffs)*first(Y.coeffs)) + warn("Multiplying elements with different base rings! Promoting the result to $TT.") + + result = mul!(result, X, Y) return result end From 5b128cd146477aeb9762e699e3c9aa7d2a89e8f4 Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 19 Jul 2017 22:48:17 +0200 Subject: [PATCH 42/79] brave new inner constructors for GroupRing --- src/GroupRings.jl | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 2c40b1d..4b3aefe 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -17,17 +17,30 @@ type GroupRing{Gr<:Group, T<:GroupElem} <: Ring basis_dict::Dict{T, Int} pm::Array{Int,2} - function GroupRing(G::Gr; initialise=true) - A = new(G) - if initialise - complete(A) + function GroupRing(G::Group, basis::Vector{T}; init::Bool=false) + RG = new(G, basis, reverse_dict(basis)) + if init + RG.pm = try + create_pm(RG.basis, RG.basis_dict) + catch err + isa(err, KeyError) && throw("Product is not supported on basis") + throw(err) + end + else + RG.pm = zeros(Int, length(basis), length(basis)) end - return A + return RG end function GroupRing(G::Gr, basis::Vector{T}, basis_dict::Dict{T,Int}, pm::Array{Int,2}) return new(G, basis, basis_dict, pm) end + + function GroupRing(G::Gr, pm::Array{Int,2}) + RG = new(G) + RG.pm = pm + return RG + end end GroupRing{Gr<:Group}(G::Gr;initialise=true) = GroupRing{Gr, elem_type(G)}(G, initialise=initialise) From 10ab7838448abd0a2c9af0b6e777ccbfaf9006e6 Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 19 Jul 2017 22:48:59 +0200 Subject: [PATCH 43/79] pairing outer constructors --- src/GroupRings.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 4b3aefe..7cf7fc0 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -43,10 +43,14 @@ type GroupRing{Gr<:Group, T<:GroupElem} <: Ring end end -GroupRing{Gr<:Group}(G::Gr;initialise=true) = GroupRing{Gr, elem_type(G)}(G, initialise=initialise) +GroupRing{Gr<:Group, T<:GroupElem}(G::Gr, basis::Vector{T}; init=false) = + GroupRing{Gr, T}(G, basis, init=init) GroupRing{Gr<:Group, T<:GroupElem}(G::Gr, b::Vector{T}, b_d::Dict{T,Int}, pm::Array{Int,2}) = GroupRing{Gr, T}(G, b, b_d, pm) +GroupRing{Gr<:Group}(G::Gr, pm::Array{Int,2}) = + GroupRing{Gr, elem_type(G)}(G, pm) + type GroupRingElem{T<:Number} <: RingElem coeffs::AbstractVector{T} parent::GroupRing From e8eaabc5d266a0e7218662515f52c8227b528288 Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 19 Jul 2017 22:49:57 +0200 Subject: [PATCH 44/79] minimal constructor for GroupRing with no initialisation --- src/GroupRings.jl | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 7cf7fc0..28e9f13 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -102,22 +102,8 @@ function GroupRingElem{T<:Number}(c::AbstractVector{T}, RG::GroupRing) return GroupRingElem{T}(c, RG) end -function GroupRing(G::Group, pm::Array{Int,2}) - size(pm,1) == size(pm,2) || throw("pm must be square, got $(size(pm))") - RG = GroupRing(G, initialise=false) - RG.pm = pm - return RG -end - -function GroupRing(G::Group, basis::Vector) - basis_dict = reverse_dict(basis) - pm = try - create_pm(basis, basis_dict) - catch err - isa(err, KeyError) && throw("Products are not supported on basis") - throw(err) - end - return GroupRing(G, basis, basis_dict, pm) +function GroupRing(G::Group; init::Bool=false) + return GroupRing(G, collect(elements(G)), init=init) end function GroupRing(G::Group, basis::Vector, pm::Array{Int,2}) From 4707cdf40a018dc2bbc45f05dd190dfbc2cc1819 Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 19 Jul 2017 22:51:56 +0200 Subject: [PATCH 45/79] restrict methods to GroupRings with basis --- src/GroupRings.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 28e9f13..d2d0216 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -130,7 +130,7 @@ function (RG::GroupRing)(i::Int, T::Type=Int) end function (RG::GroupRing)(T::Type=Int) - isdefined(RG, :basis) || throw("Complete the definition of GroupRing first") + isdefined(RG, :basis) || throw("Can not coerce without basis of GroupRing") return GroupRingElem(spzeros(T,length(RG.basis)), RG) end @@ -142,6 +142,7 @@ function (RG::GroupRing)(g::GroupElem, T::Type=Int) end function (RG::GroupRing)(x::AbstractVector) + isdefined(RG, :basis) || throw("Can not coerce without basis of GroupRing") length(x) == length(RG.basis) || throw("Can not coerce to $RG: lengths differ") result = RG(eltype(x)) result.coeffs = x @@ -154,6 +155,7 @@ function (RG::GroupRing)(X::GroupRingElem) end function (RG::GroupRing)(X::GroupRingElem, emb::Function) + isdefined(RG, :basis) || throw("Can not coerce without basis of GroupRing") result = RG(eltype(X.coeffs)) T = typeof(X.coeffs) result.coeffs = T(result.coeffs) @@ -415,7 +417,7 @@ end function star{T}(X::GroupRingElem{T}) RG = parent(X) - isdefined(RG, :basis) || complete(RG) + isdefined(RG, :basis) || throw("*-involution without basis is not possible") result = RG(T) for (i,c) in enumerate(X.coeffs) if c != zero(T) From bd300d83a580865891cfd0c8f364a19ba6aa6d29 Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 19 Jul 2017 22:52:35 +0200 Subject: [PATCH 46/79] compare GroupRing's pms only if basis is not available --- src/GroupRings.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index d2d0216..157374a 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -253,8 +253,8 @@ function (==)(A::GroupRing, B::GroupRing) A.basis == B.basis || return false else warn("Bases of GroupRings are not defined, comparing products mats.") + A.pm == B.pm || return false end - A.pm == B.pm || return false return true end From acb05e7a85faa48d4167b96b324cf70635cb5575 Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 19 Jul 2017 22:53:19 +0200 Subject: [PATCH 47/79] better text of throws --- src/GroupRings.jl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 157374a..a2ac768 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -107,9 +107,8 @@ function GroupRing(G::Group; init::Bool=false) end function GroupRing(G::Group, basis::Vector, pm::Array{Int,2}) - size(pm,1) == size(pm,2) || throw("pm must be of size (n,n), got - $(size(pm))") - eltype(basis) == elem_type(G) || throw("basis must consist of elements of $G") + size(pm,1) == size(pm,2) || throw("pm must be square, got $(size(pm))") + eltype(basis) == elem_type(G) || throw("Basis must consist of elements of $G") basis_dict = reverse_dict(basis) return GroupRing(G, basis, basis_dict, pm) end From 9d5790d6d33302afc76fbe0072d3425155888a3d Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 19 Jul 2017 22:54:18 +0200 Subject: [PATCH 48/79] allow for pm to be slowly filled when computing products --- src/GroupRings.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index a2ac768..a8c1cd9 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -351,6 +351,10 @@ function mul!{T}(result::GroupRingElem{T}, X::GroupRingElem, Y::GroupRingElem) if Y.coeffs[j] != z for i in eachindex(X.coeffs) if X.coeffs[i] != z + if parent(X).pm[i,j] == 0 + g = parent(X).basis[i]*parent(Y).basis[j] + parent(X).pm[i,j] = parent(X).basis_dict[g] + end result.coeffs[parent(X).pm[i,j]] += X[i]*Y[j] end end From 170903b430bbff86899035cb59d6047e4c0a0efd Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 19 Jul 2017 22:55:44 +0200 Subject: [PATCH 49/79] new versions of * : for those with and those without basis --- src/GroupRings.jl | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index a8c1cd9..da11ff8 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -363,19 +363,18 @@ function mul!{T}(result::GroupRingElem{T}, X::GroupRingElem, Y::GroupRingElem) return result end -function mul!{T<:Number}(result::GroupRingElem{T}, X::GroupRingElem, Y::GroupRingElem) - if result === X - result = deepcopy(result) +function *{T<:Number}(X::GroupRingElem{T}, Y::GroupRingElem{T}, check::Bool=true) + if check + parent(X) == parent(Y) || throw("Elements don't seem to belong to the same Group Ring!") end - - TT = typeof(first(X.coeffs)*first(Y.coeffs)) - - if TT != T - warn("Type of the result $T does not contain type of the product ($TT), promoting.") - result = convert(TT, result) + if isdefined(parent(X), :basis) + result = parent(X)(similar(X.coeffs)) + result = mul!(result, X, Y) + else + result = similar(X.coeffs) + result = mul!(result, X.coeffs, Y.coeffs, parent(X).pm) + result = GroupRingElem(result, parent(X)) end - - mul!(result.coeffs, X.coeffs, Y.coeffs, parent(X).pm) return result end @@ -389,12 +388,17 @@ function *{T<:Number, S<:Number}(X::GroupRingElem{T}, Y::GroupRingElem{S}, check result = mul!(result, X, Y) return result -end -function mul(X::AbstractVector, Y::AbstractVector, pm::Array{Int,2}) - T = promote_type(eltype(X), eltype(Y)) - result = zeros(T, X) - mul!(result, Vector{T}(X), Vector{T}(Y), pm) + if isdefined(parent(X), :basis) + result = parent(X)(similar(X.coeffs)) + result = convert(TT, result) + result = mul!(result, X, Y) + else + result = similar(X.coeffs) + result = convert(TT, result) + result = mul!(result, X.coeffs, Y.coeffs, parent(X).pm) + result = GroupRingElem(result, parent(X)) + end return result end From 9470d31e952fffdf7368a3c1516d67fa2ef3fb47 Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 19 Jul 2017 22:56:41 +0200 Subject: [PATCH 50/79] rename A -> RG --- src/GroupRings.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index da11ff8..e199ea2 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -480,12 +480,12 @@ end create_pm{T<:GroupElem}(b::Vector{T}) = create_pm(b, reverse_dict(b)) -function complete(A::GroupRing) - if !isdefined(A, :basis) - A.basis = [elements(A.group)...] +function complete!(RG::GroupRing) + if !isdefined(RG, :basis) + RG.basis = [elements(RG.group)...] end - if !isdefined(A, :basis_dict) - A.basis_dict = reverse_dict(A.basis) + if !isdefined(RG, :basis_dict) + RG.basis_dict = reverse_dict(RG.basis) end if !isdefined(A, :pm) A.pm = try From d80cee5df5c77538406d5d8d1091c5fc17a17242 Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 19 Jul 2017 22:57:59 +0200 Subject: [PATCH 51/79] when completing RG.pm compute only missing products --- src/GroupRings.jl | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index e199ea2..1038bbb 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -487,15 +487,11 @@ function complete!(RG::GroupRing) if !isdefined(RG, :basis_dict) RG.basis_dict = reverse_dict(RG.basis) end - if !isdefined(A, :pm) - A.pm = try - create_pm(A.basis, A.basis_dict) - catch err - isa(err, KeyError) && throw("Product is not supported on basis") - throw(err) - end + for linidx in find(RG.pm .== 0) + i,j = ind2sub(size(RG.pm), linidx) + RG.pm[i,j] = RG.basis_dict[RG.basis[i]*RG.basis[j]] end - return A + return RG end end # of module GroupRings From afac7de06d1af4326e8afe13d2c37dcb4eea9876 Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 19 Jul 2017 23:00:44 +0200 Subject: [PATCH 52/79] doc strings for mul!s --- src/GroupRings.jl | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 1038bbb..bd89396 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -321,6 +321,20 @@ end (+)(X::GroupRingElem, Y::GroupRingElem) = add(X,Y) (-)(X::GroupRingElem, Y::GroupRingElem) = add(X,-Y) +doc""" + mul!{T}(result::AbstractArray{T}, + X::AbstractVector, + Y::AbstractVector, + pm::Array{Int,2}) +> The most specialised multiplication for `X` and `Y` (`coeffs` of +> `GroupRingElems`) using multiplication table `pm`. +> Notes: +> * this method will silently produce false results if `X[k]` is non-zero for +> `k > size(pm,1)`. +> * This method will fail if any zeros (i.e. uninitialised entries) are present +> in `pm`. +> * Use with extreme care! +""" function mul!{T}(result::AbstractVector{T}, X::AbstractVector, Y::AbstractVector, @@ -339,6 +353,17 @@ function mul!{T}(result::AbstractVector{T}, end end +doc""" + mul!{T}(result::GroupRingElem{T}, + X::GroupRingElem, + Y::GroupRingElem) +> In-place multiplication for `GroupRingElem`s `X` and `Y`. +> `mul!` will make use the initialised entries of `pm` attribute of +> `parent(X)::GroupRing` (if available), and will compute and store in `pm` the +> remaining products. +> The method will fail with `KeyError` if product `X*Y` is not supported on +> `parent(X).basis`. +""" function mul!{T}(result::GroupRingElem{T}, X::GroupRingElem, Y::GroupRingElem) if result === X result = deepcopy(result) From 2763a9c9cce27db209875a64cd607fcf8bf4540c Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 19 Jul 2017 23:01:53 +0200 Subject: [PATCH 53/79] test updates for the new constructor of GroupRings --- test/runtests.jl | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index f0d870a..a9c3fe3 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -10,14 +10,16 @@ using Nemo @test isa(GroupRing(G), Nemo.Ring) @test isa(GroupRing(G), GroupRing) - RG = GroupRing(G, initialise=false) - @test isdefined(RG, :pm) == false - @test isdefined(RG, :basis) == false - @test isdefined(RG, :basis_dict) == false - - @test isa(complete(RG), GroupRing) - @test size(RG.pm) == (6,6) + RG = GroupRing(G, init=false) + @test isdefined(RG, :basis) == true @test length(RG.basis) == 6 + @test isdefined(RG, :basis_dict) == true + @test isdefined(RG, :pm) == true + @test RG.pm == zeros(Int, (6,6)) + + @test isa(complete!(RG), GroupRing) + @test all(RG.pm .> 0) + @test RG.pm == GroupRing(G, init=true).pm @test RG.basis_dict == GroupRings.reverse_dict(elements(G)) @@ -63,7 +65,7 @@ using Nemo @testset "GroupRingElems constructors/basic manipulation" begin G = PermutationGroup(3) - RG = GroupRing(G, initialise=true) + RG = GroupRing(G, init=true) a = rand(6) @test isa(GroupRingElem(a, RG), GroupRingElem) @test isa(RG(a), GroupRingElem) From 9a35d1f6ae680cbe189c9addb79a68c8104a45ad Mon Sep 17 00:00:00 2001 From: kalmar Date: Fri, 21 Jul 2017 17:15:38 +0200 Subject: [PATCH 54/79] always return result from mul! --- src/GroupRings.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index bd89396..fe82a9f 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -351,6 +351,7 @@ function mul!{T}(result::AbstractVector{T}, end end end + return result end doc""" From 24312ee9723fc160117558cb9be7b11d6af84b39 Mon Sep 17 00:00:00 2001 From: kalmar Date: Fri, 21 Jul 2017 17:16:38 +0200 Subject: [PATCH 55/79] slowly update RG.pm as multiplication happens --- src/GroupRings.jl | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index fe82a9f..6f2fe0d 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -373,15 +373,17 @@ function mul!{T}(result::GroupRingElem{T}, X::GroupRingElem, Y::GroupRingElem) z = zero(T) result.coeffs .= z - for j in eachindex(Y.coeffs) + RG = parent(X) + + for j::Int in eachindex(Y.coeffs) if Y.coeffs[j] != z - for i in eachindex(X.coeffs) + for i::Int in eachindex(X.coeffs) if X.coeffs[i] != z - if parent(X).pm[i,j] == 0 - g = parent(X).basis[i]*parent(Y).basis[j] - parent(X).pm[i,j] = parent(X).basis_dict[g] + if RG.pm[i,j] == 0 + g::elem_type(parent(X).group) = RG.basis[i]*RG.basis[j] + RG.pm[i,j] = RG.basis_dict[g] end - result.coeffs[parent(X).pm[i,j]] += X[i]*Y[j] + result.coeffs[RG.pm[i,j]] += X[i]*Y[j] end end end From bce92ef27858d4c66105698c2f9c0ace7a317e4e Mon Sep 17 00:00:00 2001 From: kalmar Date: Fri, 21 Jul 2017 17:17:38 +0200 Subject: [PATCH 56/79] change collect(a) -> [a...]: we need vector of elements for GroupRing --- src/GroupRings.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 6f2fe0d..fc44dcf 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -103,7 +103,7 @@ function GroupRingElem{T<:Number}(c::AbstractVector{T}, RG::GroupRing) end function GroupRing(G::Group; init::Bool=false) - return GroupRing(G, collect(elements(G)), init=init) + return GroupRing(G, [elements(G)...], init=init) end function GroupRing(G::Group, basis::Vector, pm::Array{Int,2}) From 13fa9962a950b0497fd5d8c7a3b981c6bbfcbdd2 Mon Sep 17 00:00:00 2001 From: kalmar Date: Fri, 21 Jul 2017 17:33:29 +0200 Subject: [PATCH 57/79] input similar directly into mul! --- src/GroupRings.jl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index fc44dcf..bc826cd 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -399,8 +399,7 @@ function *{T<:Number}(X::GroupRingElem{T}, Y::GroupRingElem{T}, check::Bool=true result = parent(X)(similar(X.coeffs)) result = mul!(result, X, Y) else - result = similar(X.coeffs) - result = mul!(result, X.coeffs, Y.coeffs, parent(X).pm) + result = mul!(similar(X.coeffs), X.coeffs, Y.coeffs, parent(X).pm) result = GroupRingElem(result, parent(X)) end return result @@ -422,8 +421,7 @@ function *{T<:Number, S<:Number}(X::GroupRingElem{T}, Y::GroupRingElem{S}, check result = convert(TT, result) result = mul!(result, X, Y) else - result = similar(X.coeffs) - result = convert(TT, result) + result = convert(TT, similar(X.coeffs)) result = mul!(result, X.coeffs, Y.coeffs, parent(X).pm) result = GroupRingElem(result, parent(X)) end From de72253e905ab1932277fadef918ff9a6928908d Mon Sep 17 00:00:00 2001 From: kalmar Date: Fri, 21 Jul 2017 20:36:48 +0200 Subject: [PATCH 58/79] export complete! and star-involution --- src/GroupRings.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index bc826cd..bf3e173 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -69,7 +69,7 @@ type GroupRingElem{T<:Number} <: RingElem end end -export GroupRing, GroupRingElem, complete, create_pm +export GroupRing, GroupRingElem, complete!, create_pm, star ############################################################################### # From c21f9e043b1cd12da2c221707f41b9c6d4c84034 Mon Sep 17 00:00:00 2001 From: kalmar Date: Mon, 24 Jul 2017 17:27:49 +0200 Subject: [PATCH 59/79] throw if idices of X or Y go beyond size(pm) --- src/GroupRings.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index bf3e173..c0f416c 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -375,10 +375,14 @@ function mul!{T}(result::GroupRingElem{T}, X::GroupRingElem, Y::GroupRingElem) RG = parent(X) + s = size(RG.pm) + for j::Int in eachindex(Y.coeffs) if Y.coeffs[j] != z + j <= s[2] || throw("Element in Y outside of support of RG.pm") for i::Int in eachindex(X.coeffs) if X.coeffs[i] != z + i <= s[1] || throw("Element in X outside of support of RG.pm") if RG.pm[i,j] == 0 g::elem_type(parent(X).group) = RG.basis[i]*RG.basis[j] RG.pm[i,j] = RG.basis_dict[g] From 1862868a357950e86fe93d776aeb35494441e99b Mon Sep 17 00:00:00 2001 From: kalmar Date: Mon, 24 Jul 2017 22:50:52 +0200 Subject: [PATCH 60/79] more verbose throws in divexact --- src/GroupRings.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index bf3e173..45bae20 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -432,11 +432,11 @@ end function divexact{T}(X::GroupRingElem{T}, Y::GroupRingElem{T}) if length(Y) != 1 - throw("Can not divide by a non-primitive element $(Y)!") + throw("Can not divide by a non-primitive element: $(Y)!") else idx = findfirst(Y) c = Y[idx] - c == 0 || throw("Can not invert") + c != 0 || throw("Can not invert: $c not found in $Y") g = parent(Y).basis[idx] return X*1//c*parent(Y)(inv(g)) end From 7188433472292f32034f33ded9532605b2801586 Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 25 Jul 2017 00:01:23 +0200 Subject: [PATCH 61/79] fix: remove remains of the old version --- src/GroupRings.jl | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 45bae20..f2246df 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -413,9 +413,6 @@ function *{T<:Number, S<:Number}(X::GroupRingElem{T}, Y::GroupRingElem{S}, check TT = typeof(first(X.coeffs)*first(Y.coeffs)) warn("Multiplying elements with different base rings! Promoting the result to $TT.") - result = mul!(result, X, Y) - return result - if isdefined(parent(X), :basis) result = parent(X)(similar(X.coeffs)) result = convert(TT, result) From 2c4a7561c42782bbbef77bf5f94838705c1a0455 Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 25 Jul 2017 14:35:09 +0200 Subject: [PATCH 62/79] fix: parent_type, elem_type dispatch after type! --- src/GroupRings.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 2f31bb2..faf2c0d 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -77,9 +77,8 @@ export GroupRing, GroupRingElem, complete!, create_pm, star # ############################################################################### -elem_type(::GroupRing) = GroupRingElem +elem_type(::Type{GroupRing}) = GroupRingElem -parent_type(::GroupRingElem) = GroupRing parent_type(::Type{GroupRingElem}) = GroupRing eltype(X::GroupRingElem) = eltype(X.coeffs) From 75627514fd19b4171e514eb9cf48758734e77c54 Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 25 Jul 2017 14:43:04 +0200 Subject: [PATCH 63/79] replace init kw. by fastm in GroupRing constructor --- src/GroupRings.jl | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index faf2c0d..6de7c14 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -17,18 +17,9 @@ type GroupRing{Gr<:Group, T<:GroupElem} <: Ring basis_dict::Dict{T, Int} pm::Array{Int,2} - function GroupRing(G::Group, basis::Vector{T}; init::Bool=false) + function GroupRing(G::Group, basis::Vector{T}; fastm::Bool=false) RG = new(G, basis, reverse_dict(basis)) - if init - RG.pm = try - create_pm(RG.basis, RG.basis_dict) - catch err - isa(err, KeyError) && throw("Product is not supported on basis") - throw(err) - end - else - RG.pm = zeros(Int, length(basis), length(basis)) - end + fastm && fastm!(RG) return RG end @@ -43,8 +34,8 @@ type GroupRing{Gr<:Group, T<:GroupElem} <: Ring end end -GroupRing{Gr<:Group, T<:GroupElem}(G::Gr, basis::Vector{T}; init=false) = - GroupRing{Gr, T}(G, basis, init=init) +GroupRing{Gr<:Group, T<:GroupElem}(G::Gr, basis::Vector{T}; fastm::Bool=true) = + GroupRing{Gr, T}(G, basis, fastm=fastm) GroupRing{Gr<:Group, T<:GroupElem}(G::Gr, b::Vector{T}, b_d::Dict{T,Int}, pm::Array{Int,2}) = GroupRing{Gr, T}(G, b, b_d, pm) @@ -101,8 +92,8 @@ function GroupRingElem{T<:Number}(c::AbstractVector{T}, RG::GroupRing) return GroupRingElem{T}(c, RG) end -function GroupRing(G::Group; init::Bool=false) - return GroupRing(G, [elements(G)...], init=init) +function GroupRing(G::Group; fastm::Bool=false) + return GroupRing(G, [elements(G)...], fastm=fastm) end function GroupRing(G::Group, basis::Vector, pm::Array{Int,2}) @@ -520,4 +511,20 @@ function complete!(RG::GroupRing) return RG end +function fastm!(RG::GroupRing; fill::Bool=false) + isdefined(RG, :basis) || throw("For baseless Group Rings You need to provide pm.") + isdefined(RG, :pm) && return RG + if fill + RG.pm = try + create_pm(RG.basis, RG.basis_dict) + catch err + isa(err, KeyError) && throw("Product is not supported on basis, $err.") + throw(err) + end + else + RG.pm = zeros(Int, length(RG.basis), length(RG.basis)) + end + return RG +end + end # of module GroupRings From 147cd053e31d3a6256fbae00a0ca96c1d2d7d2ae Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 25 Jul 2017 14:43:37 +0200 Subject: [PATCH 64/79] make complete! use fastm! --- src/GroupRings.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 6de7c14..e26667d 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -501,9 +501,9 @@ function complete!(RG::GroupRing) if !isdefined(RG, :basis) RG.basis = [elements(RG.group)...] end - if !isdefined(RG, :basis_dict) - RG.basis_dict = reverse_dict(RG.basis) - end + + fastm!(RG, fill=true) + for linidx in find(RG.pm .== 0) i,j = ind2sub(size(RG.pm), linidx) RG.pm[i,j] = RG.basis_dict[RG.basis[i]*RG.basis[j]] From 3e7fed4e412771a255f933405882d4066f447614 Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 25 Jul 2017 14:44:37 +0200 Subject: [PATCH 65/79] totally pm-free multiplication! --- src/GroupRings.jl | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index e26667d..3c84fe3 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -365,19 +365,30 @@ function mul!{T}(result::GroupRingElem{T}, X::GroupRingElem, Y::GroupRingElem) RG = parent(X) - s = size(RG.pm) + if isdefined(RG, :pm) + s = size(RG.pm) - for j::Int in eachindex(Y.coeffs) - if Y.coeffs[j] != z - j <= s[2] || throw("Element in Y outside of support of RG.pm") - for i::Int in eachindex(X.coeffs) - if X.coeffs[i] != z - i <= s[1] || throw("Element in X outside of support of RG.pm") - if RG.pm[i,j] == 0 - g::elem_type(parent(X).group) = RG.basis[i]*RG.basis[j] - RG.pm[i,j] = RG.basis_dict[g] + for j::Int in 1:length(Y.coeffs) + if Y.coeffs[j] != z + j <= s[2] || throw("Element in Y outside of support of RG.pm") + for i::Int in 1:length(X.coeffs) + if X.coeffs[i] != z + i <= s[1] || throw("Element in X outside of support of RG.pm") + if RG.pm[i,j] == 0 + RG.pm[i,j] = RG.basis_dict[RG.basis[i]*RG.basis[j]] + end + result.coeffs[RG.pm[i,j]] += X[i]*Y[j] + end + end + end + end + else + for j::Int in 1:length(Y.coeffs) + if Y.coeffs[j] != z + for i::Int in 1:length(X.coeffs) + if X.coeffs[i] != z + result[RG.basis[i]*RG.basis[j]] += X[i]*Y[j] end - result.coeffs[RG.pm[i,j]] += X[i]*Y[j] end end end From b874b2d38f7feebb9c57e4c09595f08f948dbfd3 Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 25 Jul 2017 14:45:35 +0200 Subject: [PATCH 66/79] accommodate for fastm kw --- test/runtests.jl | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index a9c3fe3..1d03978 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -10,16 +10,19 @@ using Nemo @test isa(GroupRing(G), Nemo.Ring) @test isa(GroupRing(G), GroupRing) - RG = GroupRing(G, init=false) + RG = GroupRing(G) @test isdefined(RG, :basis) == true @test length(RG.basis) == 6 @test isdefined(RG, :basis_dict) == true + @test isdefined(RG, :pm) == false + + RG = GroupRing(G, fastm=true) @test isdefined(RG, :pm) == true @test RG.pm == zeros(Int, (6,6)) @test isa(complete!(RG), GroupRing) @test all(RG.pm .> 0) - @test RG.pm == GroupRing(G, init=true).pm + @test RG.pm == GroupRings.fastm!(GroupRing(G, fastm=false), fill=true).pm @test RG.basis_dict == GroupRings.reverse_dict(elements(G)) @@ -65,7 +68,7 @@ using Nemo @testset "GroupRingElems constructors/basic manipulation" begin G = PermutationGroup(3) - RG = GroupRing(G, init=true) + RG = GroupRing(G, fastm=true) a = rand(6) @test isa(GroupRingElem(a, RG), GroupRingElem) @test isa(RG(a), GroupRingElem) @@ -106,7 +109,7 @@ using Nemo @testset "Arithmetic" begin G = PermutationGroup(3) - RG = GroupRing(G) + RG = GroupRing(G, fastm=true) a = RG(ones(Int, order(G))) @testset "scalar operators" begin From 029de0194ef1bbb08ad6b01da6849507b66e522f Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 25 Jul 2017 14:46:18 +0200 Subject: [PATCH 67/79] move mul! to GroupRing multiplication tests --- test/runtests.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 1d03978..a6d517d 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -125,9 +125,6 @@ using Nemo @test eltype(2.0*a) == typeof(2.0) @test (2.0*a).coeffs == 2.0.*(a.coeffs) - b = RG(1) + GroupRings.star(a) - @test a*b == mul!(a,a,b) - @test isa(a/2, GroupRingElem) @test eltype(a/2) == typeof(1/2) @test (a/2).coeffs == 0.5*(a.coeffs) @@ -173,6 +170,9 @@ using Nemo @test GroupRings.augmentation((one(RG)-RG(g))) == 0 end + b = RG(1) + GroupRings.star(a) + @test a*b == mul!(a,a,b) + z = sum((one(RG)-RG(g))*GroupRings.star(one(RG)-RG(g)) for g in elements(G)) @test GroupRings.augmentation(z) == 0 From 0d3dad9c4dbf32a5a4af1744d742dd79839a012d Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 25 Jul 2017 14:47:06 +0200 Subject: [PATCH 68/79] replace for loop of @test's by @test all(...) --- test/runtests.jl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index a6d517d..36869e8 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -73,9 +73,7 @@ using Nemo @test isa(GroupRingElem(a, RG), GroupRingElem) @test isa(RG(a), GroupRingElem) - for g in elements(G) - @test isa(RG(g), GroupRingElem) - end + @test all(isa(RG(g), GroupRingElem) for g in elements(G)) @test_throws String GroupRingElem([1,2,3], RG) @test isa(RG(G([2,3,1])), GroupRingElem) From 39039f9ec17efca5efb66f81c09e08804495a260 Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 25 Jul 2017 14:47:59 +0200 Subject: [PATCH 69/79] no need to parametrize parent by type of coefficients --- src/GroupRings.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 3c84fe3..6a60410 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -74,7 +74,7 @@ parent_type(::Type{GroupRingElem}) = GroupRing eltype(X::GroupRingElem) = eltype(X.coeffs) -parent{T}(g::GroupRingElem{T}) = g.parent +parent(g::GroupRingElem) = g.parent Base.promote_rule{T<:Number,S<:Number}(::Type{GroupRingElem{T}}, ::Type{GroupRingElem{S}}) = GroupRingElem{promote_type(T,S)} From 66711a31811bc568415fd0c7bb268a403c40e6fa Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 25 Jul 2017 14:48:48 +0200 Subject: [PATCH 70/79] cosmetic --- src/GroupRings.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 6a60410..fd7669b 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -99,8 +99,7 @@ end function GroupRing(G::Group, basis::Vector, pm::Array{Int,2}) size(pm,1) == size(pm,2) || throw("pm must be square, got $(size(pm))") eltype(basis) == elem_type(G) || throw("Basis must consist of elements of $G") - basis_dict = reverse_dict(basis) - return GroupRing(G, basis, basis_dict, pm) + return GroupRing(G, basis, reverse_dict(basis), pm) end ############################################################################### From 99196525902f926a12402e249fa101e954abb96a Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 25 Jul 2017 14:49:17 +0200 Subject: [PATCH 71/79] replace eachindex() by 1:length() for now --- src/GroupRings.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index fd7669b..48abe5a 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -330,7 +330,7 @@ function mul!{T}(result::AbstractVector{T}, pm::Array{Int,2}) z = zero(T) result .= z - for j in eachindex(Y) + for j in 1:length(Y) if Y[j] != z for i in 1:size(pm,1) if X[i] != z From ddaef7387259c7d711e2a3e0150516cfb1fa3255 Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 25 Jul 2017 14:49:41 +0200 Subject: [PATCH 72/79] add explicit types for keywords --- src/GroupRings.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 48abe5a..1adf81b 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -490,7 +490,7 @@ function reverse_dict(iter) end function create_pm{T<:GroupElem}(basis::Vector{T}, basis_dict::Dict{T, Int}, - limit=length(basis); twisted=false) + limit::Int=length(basis); twisted::Bool=false) product_matrix = zeros(Int, (limit,limit)) for i in 1:limit x = basis[i] From 9e09317148e70f597b3b5eb1d653306759403962 Mon Sep 17 00:00:00 2001 From: kalmar Date: Thu, 27 Jul 2017 22:08:53 +0200 Subject: [PATCH 73/79] add specialisations for GroupRing over multiplicative Groups of Rings --- src/GroupRings.jl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 1adf81b..d2cf331 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -110,6 +110,7 @@ end zero(RG::GroupRing, T::Type=Int) = RG(T) one(RG::GroupRing, T::Type=Int) = RG(RG.group(), T) +one{R<:Nemo.Ring, S<:Nemo.RingElem}(RG::GroupRing{R,S}) = RG(eye(RG.group())) function (RG::GroupRing)(i::Int, T::Type=Int) elt = RG(T) @@ -117,6 +118,12 @@ function (RG::GroupRing)(i::Int, T::Type=Int) return elt end +function (RG::GroupRing{R,S}){R<:Ring, S}(i::Int, T::Type=Int) + elt = RG(T) + elt[eye(RG.group())] = i + return elt +end + function (RG::GroupRing)(T::Type=Int) isdefined(RG, :basis) || throw("Can not coerce without basis of GroupRing") return GroupRingElem(spzeros(T,length(RG.basis)), RG) From 8d1604863cfc33c9538a18b85496db4d605493ec Mon Sep 17 00:00:00 2001 From: kalmar Date: Thu, 27 Jul 2017 22:09:48 +0200 Subject: [PATCH 74/79] RG(::Vector{GroupElem}) method for constructing GroupRingElems --- src/GroupRings.jl | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index d2cf331..7a4ad4e 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -136,7 +136,7 @@ function (RG::GroupRing)(g::GroupElem, T::Type=Int) return result end -function (RG::GroupRing)(x::AbstractVector) +function (RG::GroupRing){T<:Number}(x::AbstractVector{T}) isdefined(RG, :basis) || throw("Can not coerce without basis of GroupRing") length(x) == length(RG.basis) || throw("Can not coerce to $RG: lengths differ") result = RG(eltype(x)) @@ -144,6 +144,16 @@ function (RG::GroupRing)(x::AbstractVector) return result end +function (RG::GroupRing{Gr,T}){Gr<:Nemo.Group, T<:Nemo.GroupElem}(V::Vector{T}, + S::Type=Rational{Int}; alt=false) + res = RG(S) + for g in V + c = (alt ? sign(g)*one(S) : one(S)) + res[g] += c/length(V) + end + return res +end + function (RG::GroupRing)(X::GroupRingElem) RG == parent(X) || throw("Can not coerce!") return RG(X.coeffs) From afaff8cc41e1458ef41b8fdaf17792f7bc1e7d06 Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 1 Aug 2017 10:31:35 +0200 Subject: [PATCH 75/79] add elem_type(::Type{GroupRing{T,S}}) --- src/GroupRings.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 7a4ad4e..97f08ea 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -68,7 +68,7 @@ export GroupRing, GroupRingElem, complete!, create_pm, star # ############################################################################### -elem_type(::Type{GroupRing}) = GroupRingElem +elem_type{T,S}(::Type{GroupRing{T,S}}) = GroupRingElem parent_type(::Type{GroupRingElem}) = GroupRing From 50629a762c706211212cdade33a29f11f788efdd Mon Sep 17 00:00:00 2001 From: kalmar Date: Fri, 4 Aug 2017 15:55:46 +0200 Subject: [PATCH 76/79] add threading to create_pm --- src/GroupRings.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 97f08ea..6abddd4 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -509,7 +509,7 @@ end function create_pm{T<:GroupElem}(basis::Vector{T}, basis_dict::Dict{T, Int}, limit::Int=length(basis); twisted::Bool=false) product_matrix = zeros(Int, (limit,limit)) - for i in 1:limit + Threads.@threads for i in 1:limit x = basis[i] if twisted x = inv(x) From 7bbfe4408ca3df3b11a06cced6d3b56ae1886953 Mon Sep 17 00:00:00 2001 From: kalmar Date: Fri, 4 Aug 2017 18:25:44 +0200 Subject: [PATCH 77/79] add scalar in-place mul! --- src/GroupRings.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index 6abddd4..a9c4b9f 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -271,6 +271,11 @@ end (-)(X::GroupRingElem) = GroupRingElem(-X.coeffs, parent(X)) +function mul!{T<:Number}(a::T, X::GroupRingElem{T}) + X.coeffs .*= a + return X +end + mul{T<:Number}(a::T, X::GroupRingElem{T}) = GroupRingElem(a*X.coeffs, parent(X)) function mul{T<:Number, S<:Number}(a::T, X::GroupRingElem{S}) From 53c1872d0d47d39be690addf54734577f8ca8d61 Mon Sep 17 00:00:00 2001 From: kalmar Date: Fri, 4 Aug 2017 21:35:29 +0200 Subject: [PATCH 78/79] avoid temporary variable --- src/GroupRings.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index a9c4b9f..e7a01ef 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -520,8 +520,7 @@ function create_pm{T<:GroupElem}(basis::Vector{T}, basis_dict::Dict{T, Int}, x = inv(x) end for j in 1:limit - w = x*(basis[j]) - product_matrix[i,j] = basis_dict[w] + product_matrix[i,j] = basis_dict[x*(basis[j])] end end return product_matrix From 0e8cec9f412711bf54d16d792f0bd443c09abf61 Mon Sep 17 00:00:00 2001 From: kalmarek Date: Sun, 27 Aug 2017 20:38:02 +0200 Subject: [PATCH 79/79] Performance tweaks to mul! --- src/GroupRings.jl | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/GroupRings.jl b/src/GroupRings.jl index e7a01ef..5524863 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -352,9 +352,12 @@ function mul!{T}(result::AbstractVector{T}, pm::Array{Int,2}) z = zero(T) result .= z - for j in 1:length(Y) + lY = length(Y) + s = size(pm,1) + + @inbounds for j in 1:lY if Y[j] != z - for i in 1:size(pm,1) + for i in 1:s if X[i] != z pm[i,j] == 0 && throw(ArgumentError("The product don't seem to be supported on basis!")) result[pm[i,j]] += X[i]*Y[j] @@ -386,15 +389,18 @@ function mul!{T}(result::GroupRingElem{T}, X::GroupRingElem, Y::GroupRingElem) RG = parent(X) + lX = length(X.coeffs) + lY = length(Y.coeffs) + if isdefined(RG, :pm) s = size(RG.pm) + findlast(X.coeffs) <= s[1] || throw("Element in X outside of support of RG.pm") + findlast(Y.coeffs) <= s[2] || throw("Element in Y outside of support of RG.pm") - for j::Int in 1:length(Y.coeffs) + for j in 1:lY if Y.coeffs[j] != z - j <= s[2] || throw("Element in Y outside of support of RG.pm") - for i::Int in 1:length(X.coeffs) + for i in 1:lX if X.coeffs[i] != z - i <= s[1] || throw("Element in X outside of support of RG.pm") if RG.pm[i,j] == 0 RG.pm[i,j] = RG.basis_dict[RG.basis[i]*RG.basis[j]] end @@ -404,9 +410,9 @@ function mul!{T}(result::GroupRingElem{T}, X::GroupRingElem, Y::GroupRingElem) end end else - for j::Int in 1:length(Y.coeffs) + for j::Int in 1:lY if Y.coeffs[j] != z - for i::Int in 1:length(X.coeffs) + for i::Int in 1:lX if X.coeffs[i] != z result[RG.basis[i]*RG.basis[j]] += X[i]*Y[j] end