Sparse matrix product causes unnecessary casting to "Any" thereby causing issues?

Hi all,

I have a large sparse matrix A ( its size is (2823,2823 ) its type is SparceMatrixCSC{ Integer, Int64} ) with 0/1 values only.
I want to get a sparse matrix B = A^2, and get the largest value in this matrix.
For reasons beyond my understanding it looks like matrix B suddenly gets a type β€œAny” making it impossible to cast B back to an Array and/or get it min/max values.

see also screenshot below with minimum example and error message

I get the same errors for

Array( pairwiseComp) 
minimum( pairwiseComp[ :, : ] )

Can someone either show me what I do wrong or give me a work around?

Do you really want the abstract type Integer as the element type, or can you use Int instead?

That’s the type Julia gave to this marix A/compMatrix.
(I first initialized a 2-Dim array with only 0/1 values, then converted it to sparse).

I don’t really care about Integer or Int. I just want to be able to get matrix B = A^2 and get its max/min.
I’m just surprised to see B gets type Any, instead of Integer ( like A has ); and that throwing errors.

Can you share the code you used to make A?

julia> using SparseArrays                                                             
                                                                                      
julia> a = sprand(Int, 7, 7, 0.5)                                                   
7Γ—7 SparseMatrixCSC{Int64, Int64} with 25 stored entries:                           
                   β‹…                    β‹…  …                     β‹…                  
 2818502083055319317  4767726624010214836                        β‹…                  
                   β‹…                    β‹…      6887863942578783783                  
  809827778114231296  8685491858074137979      2448067753728538581                  
                   β‹…                    β‹…                        β‹…                  
                   β‹…  8945844710485273438  …  -1574207559067161462                  
 8530774627037061445  6557253109629682135      4738318991760729793                  
                                                                                    
julia> a.nzval[findall(x -> x != 0, a.nzval)] .= 1                                  
25-element view(::Vector{Int64}, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10  …  16, 17, 18, 19, 
20, 21, 22, 23, 24, 25]) with eltype Int64:                                         
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
 1                                                                                  
                                                                                    
julia> a                                                                            
7Γ—7 SparseMatrixCSC{Int64, Int64} with 25 stored entries:                           
 β‹…  β‹…  1  1  1  1  β‹…                                                                
 1  1  1  β‹…  β‹…  β‹…  β‹…                                                                
 β‹…  β‹…  β‹…  1  1  1  1                                                                
 1  1  1  1  β‹…  β‹…  1                                                                
 β‹…  β‹…  1  β‹…  β‹…  β‹…  β‹…                                                                
 β‹…  1  β‹…  β‹…  1  β‹…  1                                                                
 1  1  β‹…  1  1  β‹…  1                                                                
                                                                                    
julia> a*a                                                                          
7Γ—7 SparseMatrixCSC{Int64, Int64} with 44 stored entries:                           
 1  2  2  2  2  1  3                                                                
 1  1  2  2  2  2  1                                                                
 2  3  2  2  2  β‹…  3                                                                
 3  3  3  4  3  2  3                                                                
 β‹…  β‹…  β‹…  1  1  1  1                                                                
 2  2  2  1  1  β‹…  1                                                                
 3  3  4  3  2  1  2                                                                
                                                                                    
julia> 

It’s based on data, but the following code results in the exact same issues

using SparseArrays

A = zeros( Integer, 2400, 2400 )
for i in 1:2400
    if rand(1:4) == 1
        for j in i+1:2400
            if rand(1:15) == 1
                A[i,j] = 1
                A[j,i] = 1
            end
        end
    end
end

sum( A)
A = sparse( A )
B = A^2

println( "some stats A: size ", size(A), " min value ", minimum( A ), " max value ", maximum( A ) )
println( "some stats B: size ", size(B), " min value ", minimum( B ), " max value ", maximum( B ) )

I’m not sure how or what this answers?

Do you have a reason for using Integer (an abstract type) here? If you use a concrete type like Int (or BigInt if you need the ability to store arbitrarily large numbers), it will not widen the element type to Any when multiplying.

4 Likes

As I pointed out, creating the matrix a from Int (concrete type) leads to stable calculation.

Ah, my apologies; I wasn’t aware there was a significant difference between Int and Integer.

Indeed the usage of Int solves my problem. Thank you.

1 Like

Why is the element type being widened at all? Why doesn’t it stay Integer?

2 Likes

I think some of the sparse array code unfortunately relies on inference to compute some things such as the output element type and if the type is abstract, that might widen.

2 Likes