diff --git a/src/adjtrans.jl b/src/adjtrans.jl index 72e29bbc..55226f31 100644 --- a/src/adjtrans.jl +++ b/src/adjtrans.jl @@ -92,7 +92,7 @@ function *(op :: AdjointLinearOperator{T,S}, v :: AbstractVector{U}) where {T,S, ishermitian(p) && return p * v if p.ctprod !== nothing increase_nctprod(p) - return p.ctprod(v)::Vector{promote_type(T,U)} + return p.ctprod(v)::typeof(v).name.wrapper{promote_type(T,U), typeof(v).parameters[2]} end tprod = p.tprod increment_tprod = true @@ -109,7 +109,7 @@ function *(op :: AdjointLinearOperator{T,S}, v :: AbstractVector{U}) where {T,S, else increase_nprod(p) end - return conj.(tprod(conj.(v)))::Vector{promote_type(T,U)} + return conj.(tprod(conj.(v)))::typeof(v).name.wrapper{promote_type(T,U), typeof(v).parameters[2]} end function *(op :: TransposeLinearOperator{T,S}, v :: AbstractVector{U}) where {T,S,U} @@ -118,7 +118,7 @@ function *(op :: TransposeLinearOperator{T,S}, v :: AbstractVector{U}) where {T, issymmetric(p) && return p * v if p.tprod !== nothing increase_ntprod(p) - return p.tprod(v)::Vector{promote_type(T,U)} + return p.tprod(v)::typeof(v).name.wrapper{promote_type(T,U), typeof(v).parameters[2]} end increment_ctprod = true ctprod = p.ctprod @@ -135,12 +135,12 @@ function *(op :: TransposeLinearOperator{T,S}, v :: AbstractVector{U}) where {T, else increase_nprod(p) end - return conj.(ctprod(conj.(v)))::Vector{promote_type(T,U)} + return conj.(ctprod(conj.(v)))::typeof(v).name.wrapper{promote_type(T,U), typeof(v).parameters[2]} end function *(op :: ConjugateLinearOperator{T,S}, v :: AbstractVector{U}) where {T,S,U} p = op.parent - return conj.(p * conj.(v))::Vector{promote_type(T,U)} + return conj.(p * conj.(v))::typeof(v).name.wrapper{promote_type(T,U), typeof(v).parameters[2]} end -(op :: AdjointLinearOperator) = adjoint(-op.parent) diff --git a/src/operations.jl b/src/operations.jl index 572e6e93..52578bca 100644 --- a/src/operations.jl +++ b/src/operations.jl @@ -4,7 +4,7 @@ import Base.+, Base.-, Base.*, LinearAlgebra.mul! function *(op :: AbstractLinearOperator{T}, v :: AbstractVector{S}) where {T,S} size(v, 1) == size(op, 2) || throw(LinearOperatorException("shape mismatch")) increase_nprod(op) - op.prod(v)::Vector{promote_type(T,S)} + op.prod(v)::typeof(v).name.wrapper{promote_type(T,S), typeof(v).parameters[2]} end # Unary operations. diff --git a/test/test_linop.jl b/test/test_linop.jl index 3d295dae..a04672c1 100644 --- a/test/test_linop.jl +++ b/test/test_linop.jl @@ -646,6 +646,16 @@ function test_linop() @test norm(Matrix(transpose(M)) - transpose(D)) ≤ sqrt(eps()) * norm(D) @test norm(Matrix(M') - D') ≤ sqrt(eps()) * norm(D) end + + # Issue #139 + @testset ExtendedTestSet "Matrix-vector products with SparseMatrix and SparseVector" begin + A = sprand(10, 10, 0.2) + b = sprand(10, 0.2) + opA = LinearOperator(A) + @test opA * b == A * b + @test transpose(opA) * b == transpose(A) * b + @test adjoint(opA) * b == adjoint(A) * b + end end test_linop()