-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support indexing A[I1, i, I2] for CartesianIndexes I1, I2 #10814
Conversation
This is useful for algorithms that perform a calculation along a particular dimension.
Very clever. I wasn't sure there was a use case for having multiple cartesian indices… but this is a great example. This seems reasonable until we can define dispatch for the fully generic version without worry. |
One option would be to define the general version on a different function, somewhat in the spirit of #10525. It'd be a whole lot less code that way, and the general version is very straightforward. |
You mean, a function named something different from Also, I should confess that the particular examples I showed could have been written even more simply as @andreasnoack, ready to write all those |
Is it possible to write the general version as a different function, and have special cases call the other-named generic version? (That might be what @mbauman was referring to...?) |
Yup, exactly. It's not a big deal, though, and hopefully these definitions don't last long. |
Sure, I'll implement it that way. |
I already have some of this written in the context of #10525. I've not pushed it yet (or really tested it thoroughly). function _expand_cartesian_indices(idx_types, I)
idxs = Expr[]
for i=1:length(idx_types)
if idx_types[i] <: CartesianIndex
append!(idxs, Expr[:($I[$i][$d]) for d in 1:length(idx_types[i])])
else
push!(idxs, :($I[$i]))
end
end
idxs
end
stagedfunction _getindex{T,N}(l::LinearIndexing, A::AbstractArray{T,N}, I::Union(Real,AbstractArray,Colon,CartesianIndex))
idxs = _expand_cartesian_indices(I, :I)
if (l <: LinearSlow && length(idxs) == N) || (l <: LinearFast && length(idxs) == 1)
:($(Expr(:meta, :inline)); getindex(A, $(idxs...))
else
:($(Expr(:meta, :inline)); _getindex(l, A, $(idxs...))
end
end |
Ah, I should have looked here again before writing it. But thanks for the head start! If you prefer your longer name, I can change it. |
Nah, your spelling is just fine. 👍 |
Looks great to me! I certainly have use cases for multiplying a higher rank tensor with a matrix along a specific dimension, so this will certainly be very useful for implementing this. But it sounds like your FilterMD might be offering this functionality. |
Wow. Just wow. This, along with #10525, will go a very long way to making my life a lot easier when working on Interpolations.jl. I don't have much else to chip in (this is a little above my competence level, and a lot above my time allowance...) but I'm cheering loudly from the sidelines! + 💯 ! |
Support indexing A[I1, i, I2] for CartesianIndexes I1, I2
This is useful for writing algorithms that perform a calculation along a particular dimension. Not only are the resulting algorithms much prettier, but it's easy to make them cache-friendly even when the calculation is not along dimension 1. This is in contrast with
mapslices
, for example, which slices out 1-dimensional vectors before performing the algorithm, and hence is not cache-friendly.It's worth acknowledging that this is another step along the slow march towards support for general
getindex(A, indexes::Union(Integer, CartesianIndex)...)
. But currently we can't add that without causing massive ambiguity warnings in packages, so until #10525 gets merged I think we'd better stick with special cases.Demo script:
Results:
In addition to the usual "array & indexing ninjas" (@Jutho, @mbauman, @carlobaldassi, @JeffBezanson), CCing @tlycken (this will be useful for
interp_invert!
style operations).