Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
May 09, 2016 foreach(i,ref val; ndim_arr)?? | ||||
---|---|---|---|---|
| ||||
I noticed some discussion of Cartesian indexes in Julia, where the index is a tuple, along with some discussion of optimizing the index created for cache efficiency. I could find foreach(ref val, m.byElement()), but didn't find an example that returned a tuple index. Is that supported? http://julialang.org/blog/2016/02/iteration http://julialang.org/blog/2016/03/arrays-iteration |
May 10, 2016 Re: foreach(i,ref val; ndim_arr)?? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jay Norwood | On Monday, 9 May 2016 at 18:50:32 UTC, Jay Norwood wrote: > I noticed some discussion of Cartesian indexes in Julia, where the index is a tuple, along with some discussion of optimizing the index created for cache efficiency. I could find foreach(ref val, m.byElement()), but didn't find an example that returned a tuple index. Is that supported? > > http://julialang.org/blog/2016/02/iteration > > http://julialang.org/blog/2016/03/arrays-iteration I guess you are talking about ndslice (http://dlang.org/phobos/std_experimental_ndslice). There are various functions that can take static arrays, as well as tuples as parameters that are both cache-efficient. For example: http://dlang.org/phobos-prerelease/std_experimental_ndslice_slice.html#.makeSlice and http://dlang.org/phobos-prerelease/std_experimental_ndslice_slice.html#.Slice.opIndex I also found the need for a byElement function that also provides the index. I guess it is a good idea for a pull request. In the mean time, you can use the following: auto indexed_range = lockstep( ndslice.byElement, ndslice.shape.indexSlice ); foreach (ref elem; indexes; indexed_range) writefln("Element at %s = %s", indexes, elem); |
May 10, 2016 Re: foreach(i,ref val; ndim_arr)?? | ||||
---|---|---|---|---|
| ||||
Posted in reply to ZombineDev | Am 10.05.2016 um 12:21 schrieb ZombineDev:
> auto indexed_range = lockstep(
Tiny nitpick: lockstep doesn't return a range. It uses opApply to support foreach.
|
May 10, 2016 Re: foreach(i,ref val; ndim_arr)?? | ||||
---|---|---|---|---|
| ||||
Posted in reply to ag0aep6g | On Tuesday, 10 May 2016 at 13:52:27 UTC, ag0aep6g wrote:
> Am 10.05.2016 um 12:21 schrieb ZombineDev:
>> auto indexed_range = lockstep(
>
> Tiny nitpick: lockstep doesn't return a range. It uses opApply to support foreach.
Yes I know and I chose it in purpose, because it allows ref access to individual elements (zip returns a tuple which doesn't provide ref access). Otherwise my translation of OP wouldn't be accurate.
|
May 10, 2016 Re: foreach(i,ref val; ndim_arr)?? | ||||
---|---|---|---|---|
| ||||
Posted in reply to ZombineDev | On Tuesday, 10 May 2016 at 10:21:30 UTC, ZombineDev wrote: > On Monday, 9 May 2016 at 18:50:32 UTC, Jay Norwood wrote: >> I noticed some discussion of Cartesian indexes in Julia, where the index is a tuple, along with some discussion of optimizing the index created for cache efficiency. I could find foreach(ref val, m.byElement()), but didn't find an example that returned a tuple index. Is that supported? >> >> http://julialang.org/blog/2016/02/iteration >> >> http://julialang.org/blog/2016/03/arrays-iteration > > I guess you are talking about ndslice (http://dlang.org/phobos/std_experimental_ndslice). > > There are various functions that can take static arrays, as well as tuples as parameters that are both cache-efficient. For example: > > http://dlang.org/phobos-prerelease/std_experimental_ndslice_slice.html#.makeSlice and > > http://dlang.org/phobos-prerelease/std_experimental_ndslice_slice.html#.Slice.opIndex > > I also found the need for a byElement function that also provides the index. I guess it is a good idea for a pull request. > In the mean time, you can use the following: > > auto indexed_range = lockstep( > ndslice.byElement, > ndslice.shape.indexSlice > ); > > foreach (ref elem; indexes; indexed_range) > writefln("Element at %s = %s", indexes, elem); Oops, this is not entirely correct. Sorry, I was on the phone and I couldn't verify it. Here's a working example: (You can try it at: https://dpaste.dzfl.pl/c0327f067fca) import std.array : array; import std.experimental.ndslice : byElement, indexSlice, sliced; import std.range : iota, lockstep, zip; import std.stdio : writefln; void main() { // needs .array for ref (lvalue) access // (iota offers only rvalues) auto slice = iota(2 * 3 * 4).array.sliced(2, 3, 4); auto indexed_range = lockstep( slice.shape.indexSlice.byElement(), slice.byElement() ); writefln("%s", slice); foreach (idx, ref elem; indexed_range) writefln("Element at %s = %s", idx, ++elem); } [[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]], [[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]]] Element at [0, 0, 0] = 1 Element at [0, 0, 1] = 2 Element at [0, 0, 2] = 3 Element at [0, 0, 3] = 4 Element at [0, 1, 0] = 5 Element at [0, 1, 1] = 6 Element at [0, 1, 2] = 7 Element at [0, 1, 3] = 8 Element at [0, 2, 0] = 9 Element at [0, 2, 1] = 10 Element at [0, 2, 2] = 11 Element at [0, 2, 3] = 12 Element at [1, 0, 0] = 13 Element at [1, 0, 1] = 14 Element at [1, 0, 2] = 15 Element at [1, 0, 3] = 16 Element at [1, 1, 0] = 17 Element at [1, 1, 1] = 18 Element at [1, 1, 2] = 19 Element at [1, 1, 3] = 20 Element at [1, 2, 0] = 21 Element at [1, 2, 1] = 22 Element at [1, 2, 2] = 23 Element at [1, 2, 3] = 24 |
May 10, 2016 Re: foreach(i,ref val; ndim_arr)?? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jay Norwood | On Monday, 9 May 2016 at 18:50:32 UTC, Jay Norwood wrote: > I noticed some discussion of Cartesian indexes in Julia, where the index is a tuple, along with some discussion of optimizing the index created for cache efficiency. I could find foreach(ref val, m.byElement()), but didn't find an example that returned a tuple index. Is that supported? > > http://julialang.org/blog/2016/02/iteration > > http://julialang.org/blog/2016/03/arrays-iteration This example is form documentation: http://dlang.org/phobos/std_experimental_ndslice_selection.html#.byElement import std.experimental.ndslice.slice; auto slice = new long[20].sliced(5, 4); for(auto elems = slice.byElement; !elems.empty; elems.popFront) { size_t[2] index = elems.index; elems.front = index[0] * 10 + index[1] * 3; } assert(slice == [[ 0, 3, 6, 9], [10, 13, 16, 19], [20, 23, 26, 29], [30, 33, 36, 39], [40, 43, 46, 49]]); ndslice does not have opApply, because it overrides range primitives. Iteration with byElement may be a little bit slower then iteration with common foreach loops. A method, say, `forElement` for `foreach` loops may be added, thought. Best regards, llya |
May 10, 2016 Re: foreach(i,ref val; ndim_arr)?? | ||||
---|---|---|---|---|
| ||||
Posted in reply to ZombineDev | On Tuesday, 10 May 2016 at 15:18:50 UTC, ZombineDev wrote:
> On Tuesday, 10 May 2016 at 10:21:30 UTC, ZombineDev wrote:
>
> (You can try it at: https://dpaste.dzfl.pl/c0327f067fca)
>
> import std.array : array;
> import std.experimental.ndslice : byElement, indexSlice, sliced;
> import std.range : iota, lockstep, zip;
> import std.stdio : writefln;
>
> void main()
> {
> // needs .array for ref (lvalue) access
> // (iota offers only rvalues)
> auto slice = iota(2 * 3 * 4).array.sliced(2, 3, 4);
>
> auto indexed_range = lockstep(
> slice.shape.indexSlice.byElement(),
> slice.byElement()
> );
>
> writefln("%s", slice);
>
> foreach (idx, ref elem; indexed_range)
> writefln("Element at %s = %s", idx, ++elem);
> }
>
The code above is slow because it calculates index using multiple assembler ops.
Following would be faster:
for(auto elems = slice.byElement; !elems.empty; elems.popFront)
{
size_t[2] index = elems.index;
elems.front = index[0] * 10 + index[1] * 3;
}
For really fast code just use multiple foreach loops:
foreach(i; matrix.length)
{
auto row = matrix[i]; // optional
foreach(j; matrix.length!1)
{
...
}
}
|
Copyright © 1999-2021 by the D Language Foundation