diff --git a/src/GroupRings.jl b/src/GroupRings.jl index f93fee8..299bc7c 100644 --- a/src/GroupRings.jl +++ b/src/GroupRings.jl @@ -12,74 +12,6 @@ import Base: convert, show, hash, ==, +, -, *, ^, //, /, length, getindex, setin export GroupRing, GroupRingElem, complete!, create_pm, star, aug, supp -############################################################################### -# -# String I/O -# -############################################################################### - -function show(io::IO, A::GroupRing) - print(io, "Group Ring of $(A.group)") -end - -function show(io::IO, X::GroupRingElem) - RG = parent(X) - T = eltype(X.coeffs) - if X.coeffs == zero(X.coeffs) - print(io, "$(zero(T))*$((RG.group)())") - elseif isdefined(RG, :basis) - non_zeros = ((X.coeffs[i], RG.basis[i]) for i in findall(!iszero, X.coeffs)) - elts = String[] - for (c,g) in non_zeros - sgn = (sign(c)>=0 ? " + " : " - ") - if c == T(1) - coeff = "" - else - coeff = "$(abs(c))" - end - push!(elts, sgn*coeff*"$(g)") - end - 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") - show(io, MIME("text/plain"), X.coeffs) - end -end - -############################################################################### -# -# Comparison -# -############################################################################### - -function (==)(X::GroupRingElem, Y::GroupRingElem) - if eltype(X.coeffs) != eltype(Y.coeffs) - @warn("Comparing elements with different coeffs Rings!") - end - suppX = supp(X) - suppX == supp(Y) || return false - - for g in suppX - X[g] == Y[g] || return false - end - - return true -end - -function (==)(A::GroupRing, B::GroupRing) - A.group == B.group || return false - if isdefined(A, :basis) && isdefined(B, :basis) - A.basis == B.basis || return false - elseif isdefined(A, :pm) && isdefined(B, :pm) - A.pm == B.pm || return false - end - return true -end - function reverse_dict(::Type{I}, iter) where I<:Integer length(iter) > typemax(I) && error("Can not produce reverse dict: $(length(iter)) is too large for $T") diff --git a/src/ncring_interface.jl b/src/ncring_interface.jl new file mode 100644 index 0000000..4c3b130 --- /dev/null +++ b/src/ncring_interface.jl @@ -0,0 +1,123 @@ +############################################################################### +# +# NCRing Interface +# +############################################################################### + +AbstractAlgebra.parent_type(::Type{GroupRingElem{T, GR}}) where {T, GR} = GR + +function AbstractAlgebra.elem_type(::Type{<:GroupRing{R,G,El}}) where {R,G,El} + return GroupRingElem{elem_type(R), GroupRing{R,G,El}} +end + +AbstractAlgebra.base_ring(RG::GroupRing) = RG.base_ring + +AbstractAlgebra.parent(X::GroupRingElem) = X.parent + +AbstractAlgebra.isexact_type(::Type{<:GroupRingElem{T}}) where T = isexact_type(T) + +# hash(GroupRingElem) = 0x839279ac6f12f62a +function Base.hash(X::GroupRingElem, h::UInt) + return ⊻(hash(X.coeffs, h), hash(parent(X), h), 0x839279ac6f12f62a) +end + +function Base.deepcopy_internal(X::GroupRingElem, dict::IdDict) + return parent(X)(deepcopy(X.coeffs)) +end + +Base.zero(RG::GroupRing) = RG(0) +Base.one(RG::GroupRing) = RG(1) +Base.iszero(X::GroupRingElem{T}) where T = all(x == zero(T) for x in X.coeffs.nzval) + +function Base.isone(X::GroupRingElem{T}) where T + idx = _identity_idx(parent(X)) + X[idx] == one(T) || return false + all(X[i] == zero(T) for i in eachindex(X.coeffs) if i != idx) || return false + return true +end + +############################################################################### +# +# String I/O +# +############################################################################### + +Base.show(io::IO, RG::GroupRing) = + print(io, "Group ring of $(RG.group) with coefficients in $(base_ring(RG))") + +function Base.show(io::IO, X::GroupRingElem{T}) where T + RG = parent(X) + if iszero(X) + print(io, "$(zero(T))*$(multiplicative_id(RG.group))") + elseif hasbasis(RG) + suppX = supp(X) + elts = String[] + + elts = String[] + sgn = "" + for g in suppX + coeff = X[g] + if X[g] < 0 + sgn = " - " + coeff = -coeff + end + push!(elts, sgn*string(coeff)*string(g)) + sgn = " + " + end + str = join(elts, "") + print(io, str) + else + @warn("Basis of the parent group ring is not defined, showing coeffs") + show(io, MIME("text/plain"), X.coeffs) + end +end + +AbstractAlgebra.needs_parentheses(X::GroupRingElem) = true +AbstractAlgebra.displayed_with_minus_in_front(X::GroupRingElem) = false +AbstractAlgebra.show_minus_one(::Type{<:GroupRingElem}) = true + +############################################################################### +# +# Comparison +# +############################################################################### + +function ==(X::GroupRingElem{T}, Y::GroupRingElem{S}) where {T,S} + if promote_type(T,S) ≠ T || promote_type(T,S) ≠ S + @warn "Comparing elements with incompatible coeffs Rings: $T and $S can be only compared as $(promote_type(T,S))" + end + length(X.coeffs) == length(Y.coeffs) || return false + parent(X).group == parent(Y).group || return false + return all(x == y for (x,y) in zip(X.coeffs, Y.coeffs)) +end + +Base.isequal(X::GroupRingElem, Y::GroupRingElem) = X == Y + +_equalorzero(x,y) = x == y || x == 0 || y == 0 + +function ==(A::GroupRing, B::GroupRing) + A.group == B.group || return false + # base_ring(A) == base_ring(B) || return false + + bases = hasbasis(A) && hasbasis(B) + caches = cachesmultiplication(A) && cachesmultiplication(B) + + if bases && caches + length(A) == length(B) || return false + size(A.pm) == size(B.pm) || return false + all(A.basis[i] == B.basis[i] for i in eachindex(A.basis)) || return false + all(_equalorzero(A.pm[i], B.pm[i]) for i in eachindex(A.pm)) || return false + return true + elseif bases # && !caches + length(A) == length(B) || return false + all(A.basis[i] == B.basis[i] for i in eachindex(A.basis)) || return false + return true + elseif caches # && !bases + size(A.pm) == size(B.pm) || return false + all(A.pm[i] == B.pm[i] for i in eachindex(A.pm)) || return false + return true + else + return false + end +end +