Methods for vectors of sparse vs dense matrices

I’m writing a function which should have two methods, one for vectors of sparse matrices (SparseMatrixCSC) and one for vectors of dense matrices.

I don’t want to pre/dicate about the nature of those matrices beyond the point of distinguishing between sparse and dense. So far, my definition look like:

function f(Tₜ::T) where T <: Vector{SparseMatrixCSC{Float64, Int64}}.

and

function f(Tₜ::T) where T <: Vector{Matrix{Float64}}.

yet I want to get rid of that {Float64} specification.

How would I do it?

Eventually, I would like to write the method so that it would apply to any SparseMatrixCSC or to any Matrix (but distinguishing them).

Does it work if you just remove the element type? Like

Vector{Matrix}

or

Vector{<:Matrix}
1 Like

I would do something more abstract, like:

f(Tₜ::AbstractVector{<:AbstractSparseMatrix}) = ...
f(Tₜ::AbstractVector{<:AbstractMatrix}) = ...
5 Likes

The first does not work (that was my initial guess), but the second does!

I didn’t know you could use a nested inherit type in that way, nice!

1 Like

Thanks! This is perfect :slight_smile:

function f(v::T) where T <: Vector{Matrix{N}} where N   v[1]; end                            
f (generic function with 1 method)                                                                  
                                                                                                    
julia> v1 = [rand(2,3)]
1-element Vector{Matrix{Float64}}:                                                                  
 [0.6498353443464961 0.8556641584648517 0.05535954378049679; 0.39224917246518864 0.35720373820135043 0.23334843425685636]                                                                               
                                                                                                    
julia> f(v1)
2×3 Matrix{Float64}:                                                                                
 0.649835  0.855664  0.0553595                                                                      
 0.392249  0.357204  0.233348                                                                       
                                                                                                    
julia> 

Will that do?

I like @stevengj’s answer and I think it could still be made slightly shorter.

f(Tₜ::Vector{<:AbstractSparseMatrix}) = ...
f(Tₜ::Vector{<:AbstractMatrix}) = ...

That’s less generic. Your way only allows the outer container to be Julia’s built-in Vector type, as opposed to some other AbstractVector container (e.g. an OffsetArray, an AxisArrays, etcetera).

3 Likes