How do I use isassigned with a Matrix?

isassigned is confusing me a bit.

For simple arrays, it works as I would expect:

julia> b = [1,2,3]
3-element Vector{Int64}:
 1
 2
 3

julia> isassigned(b, 3)
true

julia> isassigned(b, 4)  # out of bounds, should return false
false

For matrixes, I don’t quite understand what’s going on:

julia> a = zeros(161, 517)
161×517 Matrix{Float64}:
...

julia> isassigned(a, 500, 514)  # out of bounds, should return false...?
true

Can someone educate me?

It looks like this is a bug julia#47942 in the isassigned code. What it does is to convert 500, 514 to a (zero-based) linear index and check that this is < length(a), which succeeds here because 500-1 + (514-1) * size(a, 1) < length(a).

This check ensures that the linear index is in-bounds (so it prevents jl_array_isassigned from crashing) but it is not a sufficient check of the multidimensional indices.

Maybe @tim.holy can comment further, because the code originated in julia#11167 way back in 2015 (for Julia 0.4).

That being said, if you just want a bounds check (which is all isassigned can do for Matrix{Float64}), you can call checkindex or checkbounds:

julia> checkindex(Bool, axes(a,1), 500) && checkindex(Bool, axes(a,2), 514)
false

julia> checkbounds(a, 500, 514)
ERROR: BoundsError: attempt to access 161×517 Matrix{Float64} at index [500, 514]
3 Likes

Thanks a ton, I missed those check functions. This does exactly what I want.

julia> checkbounds(Bool, a, 161, 517)
true

julia> checkbounds(Bool, a, 162, 517)
false

Of course now I see there is a great page in the docs on this: Bounds checking · The Julia Language

I think I merely happened to stumble on isassigned first. The docs for it say it will return false if an index is out of bounds, and it seems to be the most commonly suggested method out there when I google around. So I assumed it was the idiomatic way of doing it. Would be surprising if it has a longstanding issue that nobody hit before me, but I’m sure crazier things have happened.

3 Likes