Sorry for the bad formatting (getting tangled with the editor). Additional useful code to supplement the previous note:
function dropdim(A,i) v = collect(size(A)) splice!(A,i) return tuple(v...) end # now something like this works: # which gives the sum of the two edge planes of array A3 as a matrix reshape(map(x->A3[x[1]]+A3[x[2]],mapedges(A3,3)),dropdim(A3,3)) On Thursday, March 24, 2016 at 3:21:02 AM UTC+2, Dan wrote: > > # something along these lines: > > topleft(A,d) = tuple(ones(Int,ndims(A))...) > bottomleft(A,d) = tuple([i==d ? 1 : e for (i,e) in enumerate(size(A))]...) > > topright(A,d) = tuple([i==d ? e : 1 for (i,e) in enumerate(size(A))]...) > bottomright(A,d) = size(A) > mapedges(A,d) = zip( > CartesianRange{CartesianIndex{ndims(A)}}( > CartesianIndex{ndims(A)}(topleft(A,d)...), > CartesianIndex{ndims(A)}(bottomleft(A,d)...)), > CartesianRange{CartesianIndex{ndims(A)}}( > CartesianIndex{ndims(A)}(topright(A,d)...), > CartesianIndex{ndims(A)}(bottomright(A,d)...) > )) > > A3 = rand(10,15,8) > > julia> mapedges(A3,1) |> length > 120 > > julia> mapedges(A3,2) |> length > 80 > > julia> mapedges(A3,3) |> length > 150 > > > On Thursday, March 24, 2016 at 2:53:48 AM UTC+2, Tomas Lycken wrote: >> >> …but not really. Reading the docstring more carefully: >> >> Transform the given dimensions of array A using function f. f is called >> on each slice of A of the form A[…,:,…,:,…]. dims is an integer vector >> specifying where the colons go in this expression. The results are >> concatenated along the remaining dimensions. For example, if dims is [1,2] >> and A is 4-dimensional, f is called on A[:,:,i,j] for all i and j. >> >> What I want to do, is rather call f on A[:,:,1,:] and A[:,:,end,:], but >> nothing in between 1 and end for that dimension. mapslices still >> eventually visit the entire array (either by slicing, or by iteration), but >> I only want to visit the “edges”. I might be missing something, though. >> >> // T >> >> On Thursday, March 24, 2016 at 1:48:36 AM UTC+1, Tomas Lycken wrote: >> >> Yes, probably - thanks for the tip! I'll see if I can cook something up... >>> >>> On Thursday, March 24, 2016 at 1:45:32 AM UTC+1, Benjamin Deonovic wrote: >>>> >>>> Can mapslices help here? >>>> >>>> >>>> On Wednesday, March 23, 2016 at 6:59:59 PM UTC-5, Tomas Lycken wrote: >>>>> >>>>> Is there an effective pattern to iterate over the “endpoints” of an >>>>> array along a given dimension? >>>>> >>>>> What I eventually want to accomplish is to apply a function (in this >>>>> case an equality test) to the two end points along a particular dimension >>>>> of an array. I think the pattern is easiest explained by considering 1D, >>>>> 2D >>>>> and 3D: >>>>> >>>>> # assume the existence of some scalar-valued function f(x,y) >>>>> >>>>> A1 = rand(10) >>>>> f(A1[1], A1[end]) # d == 1 (the only possible value) -> one evaluation >>>>> >>>>> A2 = rand(10, 15) >>>>> map(f, A2[1,:], A2[end,:]) # d == 1 -> 15 evaluations >>>>> map(f, A2[:,1], A2[:,end]) # d == 2 -> 10 evaluations >>>>> >>>>> A3 = rand(10, 15, 8) >>>>> map(f, A3[1,:,:], A3[end,:,:]) # d == 1 -> 15x8 evaluations >>>>> map(f, A3[:,1,:], A3[:,end,:]) # d == 2 -> 10x8 evaluations >>>>> map(f, A3[:,:,1], A3[:,:,end]) # d == 3 -> 10x15 evaluations >>>>> >>>>> I just want to consider one dimension at a time, so given A and d, >>>>> and in this specific use case I don’t need to collect the results, so a >>>>> for-loop without an allocated place for the answer instead of a map >>>>> is just fine (probably preferrable, but it’s easier to go in that >>>>> direction >>>>> than in the other). What I’m struggling with, is how to generally >>>>> formulate >>>>> the indexing expressions (like [<d-1 instances of :>, 1, <size(A,d)-d >>>>> instances of :>], but not in pseudo-code…). I assume this can be done >>>>> somehow using CartesianIndexes and/or CartesianRanges, but I can’t >>>>> get my mind around to how. Any help is much appreciated. >>>>> >>>>> // T >>>>> >>>>> >>>> >> >