From 3b9e405565aeb2982625449d6dd77254799dfefd Mon Sep 17 00:00:00 2001 From: kalmar Date: Mon, 10 Jul 2017 19:25:52 +0200 Subject: [PATCH 01/50] 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 02/50] 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 03/50] 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 04/50] 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 27e0b03b3c8cfb205c170689b20c6b0f37295196 Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 11 Jul 2017 15:58:02 +0200 Subject: [PATCH 05/50] 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 06/50] 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 07/50] 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 08/50] 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 09/50] 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 10/50] 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 11/50] 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 12/50] 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 13/50] 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 14/50] 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 15/50] 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 16/50] 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 4e213c691df9f803dc365e80079ea274121967b5 Mon Sep 17 00:00:00 2001 From: kalmar Date: Tue, 11 Jul 2017 22:37:53 +0200 Subject: [PATCH 17/50] 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 18/50] 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 19/50] 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 20/50] 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 fc3cbeb14c28d77d0dfc0a7fa0830ba2e20c3a1a Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 12 Jul 2017 20:54:20 +0200 Subject: [PATCH 21/50] 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 22/50] 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 23/50] 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 24/50] 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 25/50] 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 26/50] 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 27/50] 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 28/50] 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 29/50] 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 30/50] 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 31/50] 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 32/50] 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 33/50] 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 34/50] 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 35/50] 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 36/50] 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 37/50] 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 38/50] 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 39/50] 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 40/50] 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 41/50] 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 42/50] 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 43/50] 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 44/50] 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 45/50] 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 46/50] 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 47/50] 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 48/50] 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 49/50] 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 50/50] 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 ############################################################################### #