From 6273f2112af5e10deb8422dc6b40b8a0387270a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Wed, 21 Aug 2024 13:38:02 +0200 Subject: [PATCH 1/4] Fix value_type and key_type for Tuple --- src/coefficients.jl | 3 +-- src/types.jl | 5 ++++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/coefficients.jl b/src/coefficients.jl index 9330350..a2b0d6c 100644 --- a/src/coefficients.jl +++ b/src/coefficients.jl @@ -33,6 +33,7 @@ key_type(b) = keytype(b) # back to `keytype{::Type{<:AbstractArray})` which returns `Int`. key_type(::Type{SparseArrays.SparseVector{V,K}}) where {V,K} = K key_type(v::SparseArrays.SparseVector) = key_type(typeof(v)) +key_type(::Tuple) = Int Base.iszero(ac::AbstractCoefficients) = isempty(keys(ac)) @@ -260,5 +261,3 @@ function MA.operate_to!( end return res end - - diff --git a/src/types.jl b/src/types.jl index e3bd5bf..7ec2dce 100644 --- a/src/types.jl +++ b/src/types.jl @@ -51,9 +51,12 @@ function MA.promote_operation(::typeof(basis), ::Type{<:AlgebraElement{A}}) wher end basis(a::AlgebraElement) = basis(parent(a)) +value_type(coeffs) = valtype(coeffs) +value_type(::NTuple{N,T}) where {N,T} = T + function AlgebraElement(coeffs, A::AbstractStarAlgebra) _sanity_checks(coeffs, A) - return AlgebraElement{typeof(A),valtype(coeffs),typeof(coeffs)}(coeffs, A) + return AlgebraElement{typeof(A),value_type(coeffs),typeof(coeffs)}(coeffs, A) end function AlgebraElement( From 800b5047ebabe1dca81bf51e2fec1db4598c1b79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Thu, 22 Aug 2024 17:27:10 +0200 Subject: [PATCH 2/4] Add tests --- src/bases.jl | 4 ++-- src/coefficients.jl | 19 +++++++++++++------ src/diracs_augmented.jl | 2 +- src/show.jl | 2 +- src/sparse_coeffs.jl | 8 ++++---- src/types.jl | 9 +++------ test/basic.jl | 13 +++++++++++++ test/runtests.jl | 1 + 8 files changed, 38 insertions(+), 20 deletions(-) create mode 100644 test/basic.jl diff --git a/src/bases.jl b/src/bases.jl index 97d9ad5..0e355a2 100644 --- a/src/bases.jl +++ b/src/bases.jl @@ -65,7 +65,7 @@ Translate coefficients `cfs` in `source::AbstractBasis` to basis function coeffs(cfs, source::AbstractBasis, target::AbstractBasis) source === target && return cfs source == target && return cfs - res = zero_coeffs(valtype(cfs), target) + res = zero_coeffs(value_type(cfs), target) return coeffs!(res, cfs, source, target) end @@ -86,7 +86,7 @@ Return `A' * cfs` where `A` is the linear map applied by function adjoint_coeffs(cfs, source::AbstractBasis, target::AbstractBasis) source === target && return cfs source == target && return cfs - res = zero_coeffs(valtype(cfs), source) + res = zero_coeffs(value_type(cfs), source) return adjoint_coeffs!(res, cfs, source, target) end diff --git a/src/coefficients.jl b/src/coefficients.jl index a2b0d6c..54bcf21 100644 --- a/src/coefficients.jl +++ b/src/coefficients.jl @@ -24,9 +24,9 @@ provided based on random indexing. Additionally one needs to provide: abstract type AbstractCoefficients{K,V} end key_type(::Type{<:AbstractCoefficients{K}}) where {K} = K -Base.valtype(::Type{<:AbstractCoefficients{K,V}}) where {K,V} = V +value_type(::Type{<:AbstractCoefficients{K,V}}) where {K,V} = V key_type(b::AbstractCoefficients) = key_type(typeof(b)) -Base.valtype(b::AbstractCoefficients) = valtype(typeof(b)) +value_type(b::AbstractCoefficients) = value_type(typeof(b)) key_type(b) = keytype(b) # `keytype(::Type{SparseVector{V,K}})` is not defined so it falls @@ -35,9 +35,16 @@ key_type(::Type{SparseArrays.SparseVector{V,K}}) where {V,K} = K key_type(v::SparseArrays.SparseVector) = key_type(typeof(v)) key_type(::Tuple) = Int +value_type(coeffs) = valtype(coeffs) +# `valtype` is not defined for `Tuple` so we need to define +# our own function `value_type` as defining `valtype` for +# tuples would be type piracy +value_type(::Type{NTuple{N,T}}) where {N,T} = T +value_type(::NTuple{N,T}) where {N,T} = T + Base.iszero(ac::AbstractCoefficients) = isempty(keys(ac)) -Base.similar(ac::AbstractCoefficients) = similar(ac, valtype(ac)) +Base.similar(ac::AbstractCoefficients) = similar(ac, value_type(ac)) similar_type(::Type{<:Vector}, ::Type{T}) where {T} = Vector{T} similar_type(::Type{<:SparseArrays.SparseVector{C,I}}, ::Type{T}) where {C,I,T} = SparseArrays.SparseVector{T,I} @@ -97,7 +104,7 @@ end function LinearAlgebra.dot(ac::AbstractCoefficients, bc::AbstractCoefficients) if isempty(values(ac)) || isempty(values(bc)) - return zero(MA.promote_sum_mul(valtype(ac), valtype(bc))) + return zero(MA.promote_sum_mul(value_type(ac), value_type(bc))) else return sum(c * star(bc[i]) for (i, c) in nonzero_pairs(ac)) end @@ -106,7 +113,7 @@ end function LinearAlgebra.dot(w::AbstractVector, ac::AbstractCoefficients) @assert key_type(ac) <: Integer if isempty(values(ac)) - return zero(MA.promote_sum_mul(eltype(w), valtype(ac))) + return zero(MA.promote_sum_mul(eltype(w), value_type(ac))) else return sum(w[i] * star(v) for (i, v) in nonzero_pairs(ac)) end @@ -115,7 +122,7 @@ end function LinearAlgebra.dot(ac::AbstractCoefficients, w::AbstractVector) @assert key_type(ac) <: Integer if isempty(values(ac)) - return zero(MA.promote_sum_mul(eltype(w), valtype(ac))) + return zero(MA.promote_sum_mul(eltype(w), value_type(ac))) else return sum(v * star(w[i]) for (i, v) in nonzero_pairs(ac)) end diff --git a/src/diracs_augmented.jl b/src/diracs_augmented.jl index 0fb0f21..890aa13 100644 --- a/src/diracs_augmented.jl +++ b/src/diracs_augmented.jl @@ -2,7 +2,7 @@ aug(cfs::Any) = sum(values(cfs)) aug(a::AlgebraElement) = aug(coeffs(a)) function aug(ac::AbstractCoefficients) - isempty(keys(ac)) && return zero(valtype(ac)) + isempty(keys(ac)) && return zero(value_type(ac)) return sum(c * aug(x) for (x, c) in nonzero_pairs(ac)) end diff --git a/src/show.jl b/src/show.jl index a51b0ef..4ae2d60 100644 --- a/src/show.jl +++ b/src/show.jl @@ -102,7 +102,7 @@ end function _show(io::IO, mime, a::AlgebraElement) A = parent(a) if iszero(a) - T = valtype(coeffs(a)) + T = value_type(coeffs(a)) _coeff_elt_print(io, mime, zero(T), first(basis(A))) else _first = true diff --git a/src/sparse_coeffs.jl b/src/sparse_coeffs.jl index 3e7236f..6e4e0c5 100644 --- a/src/sparse_coeffs.jl +++ b/src/sparse_coeffs.jl @@ -32,7 +32,7 @@ function Base.getindex(sc::SparseCoefficients{K}, key::K) where {K} return zero(v) end else - return zero(valtype(sc)) + return zero(value_type(sc)) end end @@ -112,7 +112,7 @@ function similar_type(::Type{SparseCoefficients{K,V,Vk,Vv}}, ::Type{T}) where {K return SparseCoefficients{K,T,_similar_type(Vk, K),_similar_type(Vv, T)} end -function Base.similar(s::SparseCoefficients, ::Type{T} = valtype(s)) where {T} +function Base.similar(s::SparseCoefficients, ::Type{T} = value_type(s)) where {T} return SparseCoefficients(collect(s.basis_elements), _similar(s.values, T)) end @@ -127,13 +127,13 @@ end ### temporary convenience? how to handle this? function __prealloc(X::SparseCoefficients, a::Number, op) - T = MA.promote_operation(op, valtype(X), typeof(a)) + T = MA.promote_operation(op, value_type(X), typeof(a)) return similar(X, T) end function __prealloc(X::SparseCoefficients, Y::SparseCoefficients, op) # this is not even correct for op = * - T = MA.promote_operation(op, valtype(X), valtype(Y)) + T = MA.promote_operation(op, value_type(X), value_type(Y)) return similar(X, T) end diff --git a/src/types.jl b/src/types.jl index 7ec2dce..313d426 100644 --- a/src/types.jl +++ b/src/types.jl @@ -34,7 +34,7 @@ struct AlgebraElement{A,T,V} <: MA.AbstractMutable end Base.parent(a::AlgebraElement) = a.parent -Base.eltype(::Type{A}) where {A<:AlgebraElement} = valtype(MA.promote_operation(coeffs, A)) +Base.eltype(::Type{A}) where {A<:AlgebraElement} = value_type(MA.promote_operation(coeffs, A)) Base.eltype(a::AlgebraElement) = eltype(typeof(a)) function MA.promote_operation(::typeof(coeffs), ::Type{AlgebraElement{A,T,V}}) where {A,T,V} return V @@ -51,9 +51,6 @@ function MA.promote_operation(::typeof(basis), ::Type{<:AlgebraElement{A}}) wher end basis(a::AlgebraElement) = basis(parent(a)) -value_type(coeffs) = valtype(coeffs) -value_type(::NTuple{N,T}) where {N,T} = T - function AlgebraElement(coeffs, A::AbstractStarAlgebra) _sanity_checks(coeffs, A) return AlgebraElement{typeof(A),value_type(coeffs),typeof(coeffs)}(coeffs, A) @@ -63,7 +60,7 @@ function AlgebraElement( coeffs::SparseCoefficients{T}, A::AbstractStarAlgebra{O,T}, ) where {O,T} - return AlgebraElement{typeof(A),valtype(coeffs),typeof(coeffs)}(coeffs, A) + return AlgebraElement{typeof(A),value_type(coeffs),typeof(coeffs)}(coeffs, A) end ### constructing elements @@ -92,7 +89,7 @@ end Base.zero(a::AlgebraElement) = (b = similar(a); return MA.operate!(zero, b)) Base.one(a::AlgebraElement) = one(eltype(a), parent(a)) -Base.iszero(a::AlgebraElement) = iszero(coeffs(a)) +Base.iszero(a::AlgebraElement) = all(iszero, coeffs(a)) function Base.isone(a::AlgebraElement) c = coeffs(a) diff --git a/test/basic.jl b/test/basic.jl new file mode 100644 index 0000000..95038cc --- /dev/null +++ b/test/basic.jl @@ -0,0 +1,13 @@ +struct DummyBasis{T} <: SA.ExplicitBasis{T,Int} + elements::Vector{T} +end + +Base.length(b::DummyBasis) = length(b.elements) +Base.getindex(b::DummyBasis, i::Int) = b.elements[i] + +@testset "Basic tests" begin + b = DummyBasis(Irrational[π, ℯ]) + a = StarAlgebra(nothing, b) + s(i) = sprint(show, MIME"text/plain"(), i) + @test sprint(show, AlgebraElement([2, -1], a)) == "2·$(s(π)) - 1·$(s(ℯ))" +end diff --git a/test/runtests.jl b/test/runtests.jl index 3d87d80..fa78c78 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -26,6 +26,7 @@ include("test_example_words.jl") include("test_example_acoeffs.jl") @testset "StarAlgebras" begin + include("basic.jl") # proof of concept using PermutationGroups include("perm_grp_algebra.jl") From 335d1fb067a8f659f4226e470cd039923f69edbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Thu, 22 Aug 2024 17:29:02 +0200 Subject: [PATCH 3/4] Add comment --- src/types.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types.jl b/src/types.jl index 313d426..3613881 100644 --- a/src/types.jl +++ b/src/types.jl @@ -89,6 +89,7 @@ end Base.zero(a::AlgebraElement) = (b = similar(a); return MA.operate!(zero, b)) Base.one(a::AlgebraElement) = one(eltype(a), parent(a)) +# `iszero(coeffs(a))` doesn't work if `coeffs(a) isa Tuple` Base.iszero(a::AlgebraElement) = all(iszero, coeffs(a)) function Base.isone(a::AlgebraElement) From 7836f8e1afeca400f45f739453e03f64255dbc85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Fri, 23 Aug 2024 09:34:16 +0200 Subject: [PATCH 4/4] Remove iszero fix --- src/types.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/types.jl b/src/types.jl index 3613881..5204092 100644 --- a/src/types.jl +++ b/src/types.jl @@ -89,8 +89,7 @@ end Base.zero(a::AlgebraElement) = (b = similar(a); return MA.operate!(zero, b)) Base.one(a::AlgebraElement) = one(eltype(a), parent(a)) -# `iszero(coeffs(a))` doesn't work if `coeffs(a) isa Tuple` -Base.iszero(a::AlgebraElement) = all(iszero, coeffs(a)) +Base.iszero(a::AlgebraElement) = iszero(coeffs(a)) function Base.isone(a::AlgebraElement) c = coeffs(a)