11# This file is a part of StarAlgebras.jl. License is MIT: https://github.com/JuliaAlgebra/StarAlgebras.jl/blob/main/LICENSE
22# Copyright (c) 2021-2025: Marek Kaluba, Benoît Legat
33
4- struct SparseCoefficients{K,V,Vk,Vv} <: AbstractCoefficients{K,V}
4+ struct SparseCoefficients{K,V,Vk,Vv,L } <: AbstractCoefficients{K,V}
55 basis_elements:: Vk
66 values:: Vv
7+ isless:: L
78end
89
9- function SparseCoefficients (elts:: Ks , vals:: Vs ) where {Ks,Vs}
10- return SparseCoefficients {eltype(elts),eltype(vals),Ks,Vs} (elts, vals)
10+ function SparseCoefficients (elts:: Ks , vals:: Vs , isless = isless ) where {Ks,Vs}
11+ return SparseCoefficients {eltype(elts),eltype(vals),Ks,Vs,typeof(isless) } (elts, vals, isless )
1112end
1213
1314Base. keys (sc:: SparseCoefficients ) = sc. basis_elements
1415Base. values (sc:: SparseCoefficients ) = sc. values
1516function Base. copy (sc:: SparseCoefficients )
16- return SparseCoefficients (copy (keys (sc)), copy (values (sc)))
17+ return SparseCoefficients (copy (keys (sc)), copy (values (sc)), sc . isless )
1718end
1819
19- function _search (keys:: Tuple , key)
20+ function _search (keys:: Tuple , key; lt )
2021 # `searchsortedfirst` is not defined for `Tuple`
2122 return findfirst (isequal (key), keys)
2223end
2324
24- function _search (keys, key:: K ) where {K}
25- return searchsortedfirst (keys, key; lt = comparable (K) )
25+ function _search (keys, key:: K ; lt ) where {K}
26+ return searchsortedfirst (keys, key; lt)
2627end
2728
2829function Base. getindex (sc:: SparseCoefficients{K} , key:: K ) where {K}
29- k = _search (sc. basis_elements, key)
30+ k = _search (sc. basis_elements, key; lt = sc . isless )
3031 if k in eachindex (sc. basis_elements)
3132 v = sc. values[k]
3233 if sc. basis_elements[k] == key
@@ -40,7 +41,7 @@ function Base.getindex(sc::SparseCoefficients{K}, key::K) where {K}
4041end
4142
4243function Base. setindex! (sc:: SparseCoefficients{K} , val, key:: K ) where {K}
43- k = searchsortedfirst (sc. basis_elements, key; lt = comparable (K) )
44+ k = searchsortedfirst (sc. basis_elements, key; lt = sc . isless )
4445 if k in eachindex (sc. basis_elements) && sc. basis_elements[k] == key
4546 sc. values[k] = val
4647 else
@@ -100,7 +101,7 @@ _first_sparse_coeffs(c::SparseCoefficients, args...) = c
100101_first_sparse_coeffs (_, args... ) = _first_sparse_coeffs (args... )
101102
102103function Base. zero (sc:: SparseCoefficients )
103- return SparseCoefficients (empty (keys (sc)), empty (values (sc)))
104+ return SparseCoefficients (empty (keys (sc)), empty (values (sc)), sc . isless )
104105end
105106
106107_similar (x:: Tuple ) = _similar (x, typeof (x[1 ]))
@@ -111,16 +112,16 @@ _similar(x, ::Type{T}) where {T} = similar(x, T)
111112_similar_type (:: Type{<:Tuple} , :: Type{T} ) where {T} = Vector{T}
112113_similar_type (:: Type{V} , :: Type{T} ) where {V,T} = similar_type (V, T)
113114
114- function similar_type (:: Type{SparseCoefficients{K,V,Vk,Vv}} , :: Type{T} ) where {K,V,Vk,Vv,T}
115- return SparseCoefficients{K,T,_similar_type (Vk, K),_similar_type (Vv, T)}
115+ function similar_type (:: Type{SparseCoefficients{K,V,Vk,Vv,L }} , :: Type{T} ) where {K,V,Vk,Vv,T,L }
116+ return SparseCoefficients{K,T,_similar_type (Vk, K),_similar_type (Vv, T),L }
116117end
117118
118119function Base. similar (s:: SparseCoefficients , :: Type{T} = value_type (s)) where {T}
119- return SparseCoefficients (collect (s. basis_elements), _similar (s. values, T))
120+ return SparseCoefficients (collect (s. basis_elements), _similar (s. values, T), s . isless )
120121end
121122
122123function map_keys (f:: Function , s:: SparseCoefficients )
123- return SparseCoefficients (map (f, s. basis_elements), s. values)
124+ return SparseCoefficients (map (f, s. basis_elements), s. values, s . isless )
124125end
125126
126127function MA. mutability (
@@ -144,29 +145,24 @@ function __prealloc(X::SparseCoefficients, Y::SparseCoefficients, op)
144145 return similar (X, T)
145146end
146147
147- comparable (:: Type ) = isless
148- function MA. operate! (:: typeof (canonical), res:: SparseCoefficients )
149- return MA. operate! (canonical, res, comparable (key_type (res)))
150- end
151-
152148function unsafe_push! (res:: SparseCoefficients , key, value)
153149 push! (res. basis_elements, key)
154150 push! (res. values, value)
155151 return res
156152end
157153
158- # `::C ` is needed to force Julia specialize on the function type
154+ # `{...,L} ` is needed to force Julia specialize on the function type
159155# Otherwise, we get one allocation when we call `issorted`
160156# See https://docs.julialang.org/en/v1/manual/performance-tips/#Be-aware-of-when-Julia-avoids-specializing
161- function MA. operate! (:: typeof (canonical), res:: SparseCoefficients , cmp :: C ) where {C }
162- sorted = issorted (res. basis_elements; lt = cmp )
157+ function MA. operate! (:: typeof (canonical), res:: SparseCoefficients{K,V,Vk,Vv,L} ) where {K,V,Vk,Vv,L }
158+ sorted = issorted (res. basis_elements; lt = res . isless )
163159 distinct = allunique (res. basis_elements)
164160 if sorted && distinct && ! any (iszero, res. values)
165161 return res
166162 end
167163
168164 if ! sorted
169- p = sortperm (res. basis_elements; lt = cmp )
165+ p = sortperm (res. basis_elements; lt = res . isless )
170166 permute! (res. basis_elements, p)
171167 permute! (res. values, p)
172168 end
0 commit comments