From 04e72bf17aa0db7aa06d48efd5921a6c272f8165 Mon Sep 17 00:00:00 2001 From: kalmar Date: Wed, 18 Jan 2017 17:51:58 +0100 Subject: [PATCH] oh boy, we need a lot of work to make unique work... --- FreeGroups.jl | 44 ++++++++++++++++++++++++++++++++++++++++++-- property(T).jl | 12 ++++++------ 2 files changed, 48 insertions(+), 8 deletions(-) diff --git a/FreeGroups.jl b/FreeGroups.jl index 3e71ba7..9c19054 100644 --- a/FreeGroups.jl +++ b/FreeGroups.jl @@ -2,7 +2,7 @@ module FreeGroups export GSymbol, AutSymbol, Word, GWord, FGWord, AutWord, FGAutomorphism -import Base: length, ==, show, convert +import Base: length, ==, hash, show, convert import Base: *, ^, convert import Base: one, inv, reduce, push!, unshift! @@ -73,6 +73,36 @@ end abstract Word +#= +@ScottPJones + +If so, I'd recommend + 1) making GWord a type, not an immutable + 2) add fields + savedhash::UInt and + modified::Bool + 3) make any function that modifies the contents of .symbols set the modified flag, + 4) make the hash function + a) check that flag: + if false, return the savedhash field, + otherwise, call reduce!, + b) clear the modified flag, and + c) calculate a hash value simply by calling hash(symbols) + d) save that back into the savedhash field + + 5) for ==, I don't think you need to do all that checking for length or length == 0, that will already be handled by comparing the symbols vectors (possibly faster) + +function (==){T}(W::GWord{T}, Z::GWord{T}) + W.modified && reduce!(W) # reduce could actually clear the flag and recalculate the hash + Z.modified && reduce!(Z) + W.hash == Z.hash && W.symbols == Z.symbols +end + +hash{T}(W::GWord{T}) = (W.modified && reduce!(W); W.hash) + +(and last lines of reduce! would have W.modified = false ; W.hash = hash(W.symbols)) +=# + immutable GWord{T<:GSymbol} <: Word symbols::Vector{T} end @@ -131,7 +161,17 @@ end reduce(W::GWord) = reduce!(deepcopy(W)) -(==)(W::GWord{FGSymbol}, Z::GWord{FGSymbol}) = reduce!(W).symbols == reduce!(Z).symbols +function (==){T}(W::GWord{T}, Z::GWord{T}) + reduce!(W) + reduce!(Z) + if length(W) != length(Z) + return false + elseif length(W) == 0 + return true + else + return W.symbols == Z.symbols + end +end function show(io::IO, W::GWord) if length(W) == 0 diff --git a/property(T).jl b/property(T).jl index 316a387..91348f3 100644 --- a/property(T).jl +++ b/property(T).jl @@ -2,20 +2,20 @@ using JuMP import Base: rationalize using GroupAlgebras -function products{T<:Real}(S1::Array{Array{T,2},1}, S2::Array{Array{T,2},1}) - result = [0*similar(S1[1])] +function products(S1, S2) + result = Vector{eltype(S1[1]*S2[1])}() for x in S1 for y in S2 push!(result, x*y) end end - return unique(result[2:end]) + return unique(result) end function generate_B₂_and_B₄(identity, S₁) - S₂ = unique(products(S₁, S₁)); - S₃ = unique(products(S₁, S₂)); - S₄ = unique(products(S₂, S₂)); + S₂ = products(S₁, S₁); + S₃ = products(S₁, S₂); + S₄ = products(S₂, S₂); B₂ = unique(vcat([identity],S₁,S₂)); B₄ = unique(vcat(B₂, S₃, S₄));