[julia-users] Re: How do I, as efficiently as possible, iterate over the first and last elements along a given dimension of an array?
Fantastic, thank you! Except for what I assume is a typo in `dropdim` (we want `splice!(v,i)`), this does exactly what I want. // T On Thursday, March 24, 2016 at 2:37:12 AM UTC+1, Dan wrote: > > 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 [, 1, >> ], 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 >> >> > >>> >>
[julia-users] Re: How do I, as efficiently as possible, iterate over the first and last elements along a given dimension of an array?
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 [, 1, 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 > > >> >
[julia-users] Re: How do I, as efficiently as possible, iterate over the first and last elements along a given dimension of an array?
# 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 [, 1, >>> 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 >>> >
[julia-users] Re: How do I, as efficiently as possible, iterate over the first and last elements along a given dimension of an array?
…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 [, 1, >> 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 >>> >>> >>
[julia-users] Re: How do I, as efficiently as possible, iterate over the first and last elements along a given dimension of an array?
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 [, 1, > 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 >> >> >
[julia-users] Re: How do I, as efficiently as possible, iterate over the first and last elements along a given dimension of an array?
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 [, 1, 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 > >