diff --git a/src/Operators/banded/Conversion.jl b/src/Operators/banded/Conversion.jl index 2a4e61e0..dad79956 100644 --- a/src/Operators/banded/Conversion.jl +++ b/src/Operators/banded/Conversion.jl @@ -27,8 +27,10 @@ end domainspace(C::ConcreteConversion)=C.domainspace rangespace(C::ConcreteConversion)=C.rangespace -promotedomainspace(C::Conversion, sp::Space) = Conversion(sp, rangespace(C)) -promoterangespace(C::Conversion, sp::Space) = Conversion(domainspace(C), sp) +promotedomainspace(C::Conversion, sp::Space) = + sp == domainspace(C) ? C : Conversion(sp, rangespace(C)) +promoterangespace(C::Conversion, sp::Space) = + sp == rangespace(C) ? C : Conversion(domainspace(C), sp) function _implementconversionerror(a, b) error("Implement Conversion from ", typeof(a), " to ", typeof(b)) diff --git a/src/Operators/general/algebra.jl b/src/Operators/general/algebra.jl index 258d14c2..586432bd 100644 --- a/src/Operators/general/algebra.jl +++ b/src/Operators/general/algebra.jl @@ -73,10 +73,21 @@ end function promoteplus(opsin, sz=size(first(opsin))) ops = filter(!iszeroop, opsin) ET = promote_eltypeof(opsin) + O = eltype(convert_vector(_convertops(Operator{ET}, ops))) v = promotespaces(ops) - PlusOperator{ET}(convert_vector(v), bandwidthsmax(v), sz, - bandwidthsmax(v, blockbandwidths), bandwidthsmax(v, subblockbandwidths)) + w = convert_vector(v) + # The types of the promoted operators may depend on the values of the spaces. + # We retain the concrete type if the promotion preserves it (e.g. if the spaces agree), + # and store the operators as Operator{ET} otherwise. This limits the result to a small Union + if w isa Vector{O} + _promoteplus(ET, w, v, sz) + else + _promoteplus(ET, strictconvert(Vector{Operator{ET}}, w), v, sz) + end end +# the bandwidths are computed from v, which may be better inferred than ops +_promoteplus(::Type{ET}, ops, v, sz) where {ET} = PlusOperator{ET}(ops, bandwidthsmax(v), sz, + bandwidthsmax(v, blockbandwidths), bandwidthsmax(v, subblockbandwidths)) domain(P::PlusOperator) = commondomain(P.ops)