Basically what I (think) I need is this function:
https://stackoverflow.com/questions/27086195/linear-index-upper-triangular-matrix
Of course I can just implement it, two lines of code. But that seems something that probably is needed quite frequently in matrix computations, so I am surprised I didnβt find it as a Base function.
First I thought that most people would prefer constructing an iterator like (for a 3x3 matrix, for example):
julia> for c in Iterators.filter(c -> c[1] < c[2], CartesianIndices((1:3,1:3)))
@show c
end
c = CartesianIndex(1, 2)
c = CartesianIndex(1, 3)
c = CartesianIndex(2, 3)
That would be fine for my current purposes, except that it does not play well with @threads
:
julia> Threads.@threads for c in Iterators.filter(c -> c[1] < c[2], CartesianIndices((1:3,1:3)))
@show c
end
ERROR: TaskFailedException
Stacktrace:
[1] wait
@ ./task.jl:322 [inlined]
[2] threading_run(func::Function)
@ Base.Threads ./threadingconstructs.jl:34
[3] top-level scope
@ ./threadingconstructs.jl:93
nested task error: MethodError: no method matching length(::Base.Iterators.Filter{var"#19#20", CartesianIndices{2, Tuple{UnitRange{Int64}, UnitRange{Int64}}}})
What I am missing here? Should I just use a custom implementation of the indexing, is there a Base function already for that, or some alternative way to iterate that is accepted by @threads
?