Symmetric matrix is not symmetric

I’m trying to do a hierarchical clustering of a matrix, and I’m running into a weird problem. Using Distances.jl, I’m doing dm = pairwise(Jaccard(), my_matrix), and then hclust(dm) from Clustering.jl. But I’m getting

julia> rowclust = hclust(rowdm)
ERROR: ArgumentError: Distance matrix should be symmetric.

When I use issymetric from LinearAlgebra, sure enough

julia> issymmetric(rowdm)
false

But I’m pretty sure pairwise from Distances should always return a symmetric matrix when the distance function is metric (which Jaccard is), and when I looked for which element is mismatched

julia> for i in 1:size(rowdm, 1), j in 1:size(rowdm, 2)
           j<i && continue
           if rowdm[i,j] !== rowdm[j, i]
               @info "mismatch!" i, j, rowdm[i,j], rowdm[j,i]
           end
       end

julia>

They all seem to be correct. Am I misunderstanding what a symmetric matrix is? And how this function of Distances.jl works? For what it’s worth, I’m trying to cluster along both columns and rows of my matrix, and the former works as expected. I also haven’t been able to come up with a MWE that throws the same error.

EDIT: Euclidean() distance for the rows seems to work :thinking:

1 Like

What’s the type of rowdm?

Also, what do you get if you do rowdm - transpose(rowdm) and rowdm - adjoint(rowdm)?

1 Like
julia> eltype(rowdm)
Float64

julia> typeof(rowdm)
Matrix{Float64} (alias for Array{Float64, 2})

julia> rowdm - adjoint(rowdm)
1092×1092 Matrix{Float64}:
#...

julia> all(==(0), rowdm - adjoint(rowdm))
false

julia> rowdm - adjoint(rowdm)
1092×1092 Matrix{Float64}:
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  …  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0     0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0     0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0

julia> rowdm[findall(!=(0), rowdm - adjoint(rowdm))]
3540-element Vector{Float64}:
 NaN
 NaN
 NaN
 NaN
 NaN
 NaN
#...

Looks like a bunch of NaNs :exploding_head:

julia> count(isnan, rowdm)
3540

Didn’t know that was possible with Jaccard… Oh well, replacing those fixes things, thanks!

2 Likes