December 19, 2012 Re: Multidimensional slice | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nekroze | On Wednesday, 19 December 2012 at 13:28:24 UTC, Nekroze wrote:
> On Wednesday, 19 December 2012 at 12:27:32 UTC, Rafael wrote:
>> 1) It is possible to implement multiindex access using opIndex* methods, moreover this is the simplest way to multiindex access realization. So, we have [i, j, k] notation. Next step after it - slices implementation and it looks logical to save the same notation for it: [i1..i2, j1..j2, k]. But it impossible, if I understand correctly.
>>
>> 2) On the other hand. Syntax via [i][j] leads to some overhead: first index access [i] must return some light accessor object (like range (or iterator)) which supports the index access operation. But using this approach it is possible to implement multidimensional slices. And this means, that opIndex* methods with multiindex are not needed.
>
> Well if you are looking at operator overloading you can overload opSlice as described here http://dlang.org/operatoroverloading.html#Slice however i am not sure if you can defined multiple slices delimited by commas in the same [] block but it is worth a try.
...and we return to my initial question :)
The answer is: no, D is not support multidimension slices. Possible way to solve it is to define some auxiliary structure Slice, and use multiindex by following way:
S [ Slice(0, $), 2] = A [ Slice(0, $), 2];
|
December 19, 2012 Re: Multidimensional slice | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rafael | On Wednesday, 19 December 2012 at 14:08:25 UTC, Rafael wrote:
> On Wednesday, 19 December 2012 at 13:28:24 UTC, Nekroze wrote:
>> On Wednesday, 19 December 2012 at 12:27:32 UTC, Rafael wrote:
>>> 1) It is possible to implement multiindex access using opIndex* methods, moreover this is the simplest way to multiindex access realization. So, we have [i, j, k] notation. Next step after it - slices implementation and it looks logical to save the same notation for it: [i1..i2, j1..j2, k]. But it impossible, if I understand correctly.
>>>
>>> 2) On the other hand. Syntax via [i][j] leads to some overhead: first index access [i] must return some light accessor object (like range (or iterator)) which supports the index access operation. But using this approach it is possible to implement multidimensional slices. And this means, that opIndex* methods with multiindex are not needed.
>>
>> Well if you are looking at operator overloading you can overload opSlice as described here http://dlang.org/operatoroverloading.html#Slice however i am not sure if you can defined multiple slices delimited by commas in the same [] block but it is worth a try.
>
> ...and we return to my initial question :)
> The answer is: no, D is not support multidimension slices. Possible way to solve it is to define some auxiliary structure Slice, and use multiindex by following way:
> S [ Slice(0, $), 2] = A [ Slice(0, $), 2];
Instead of defining a struct for that why not allow index to take a uint array defining the lower and upper bounds of the slice. You may have to make the opSlice or opIndex a template however but I believe you should be able to take a uint[2] as an argument.
Atleast this way you dont have to add more structs to the mix and you can just do:
S[[0, S.length], 2] = A [[0, A.length], 2];
or some such, there may be a way of preserving the $ symbol but you would have to deal with that anyway if you made it an argument to a struct. perhaps a string mixin?
|
December 19, 2012 Re: Multidimensional slice | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nekroze | On Wednesday, 19 December 2012 at 15:19:01 UTC, Nekroze wrote:
> On Wednesday, 19 December 2012 at 14:08:25 UTC, Rafael wrote:
>> On Wednesday, 19 December 2012 at 13:28:24 UTC, Nekroze wrote:
>>> On Wednesday, 19 December 2012 at 12:27:32 UTC, Rafael wrote:
>>>> 1) It is possible to implement multiindex access using opIndex* methods, moreover this is the simplest way to multiindex access realization. So, we have [i, j, k] notation. Next step after it - slices implementation and it looks logical to save the same notation for it: [i1..i2, j1..j2, k]. But it impossible, if I understand correctly.
>>>>
>>>> 2) On the other hand. Syntax via [i][j] leads to some overhead: first index access [i] must return some light accessor object (like range (or iterator)) which supports the index access operation. But using this approach it is possible to implement multidimensional slices. And this means, that opIndex* methods with multiindex are not needed.
>>>
>>> Well if you are looking at operator overloading you can overload opSlice as described here http://dlang.org/operatoroverloading.html#Slice however i am not sure if you can defined multiple slices delimited by commas in the same [] block but it is worth a try.
>>
>> ...and we return to my initial question :)
>> The answer is: no, D is not support multidimension slices. Possible way to solve it is to define some auxiliary structure Slice, and use multiindex by following way:
>> S [ Slice(0, $), 2] = A [ Slice(0, $), 2];
>
> Instead of defining a struct for that why not allow index to take a uint array defining the lower and upper bounds of the slice. You may have to make the opSlice or opIndex a template however but I believe you should be able to take a uint[2] as an argument.
>
> Atleast this way you dont have to add more structs to the mix and you can just do:
> S[[0, S.length], 2] = A [[0, A.length], 2];
> or some such, there may be a way of preserving the $ symbol but you would have to deal with that anyway if you made it an argument to a struct. perhaps a string mixin?
Yes, it is good solution, thank you! But anyway it means not so nice and laconic syntax..
P.S. yes, I am killjoy :)
|
December 19, 2012 Re: Multidimensional slice | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rafael | On Wednesday, 19 December 2012 at 16:19:28 UTC, Rafael wrote:
> Yes, it is good solution, thank you! But anyway it means not so nice and laconic syntax..
>
> P.S. yes, I am killjoy :)
Awesome, glad i could help even with my limited knowledge, good luck, don't understand the PS.
|
December 19, 2012 Re: Multidimensional slice | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nekroze | On Wednesday, 19 December 2012 at 16:50:05 UTC, Nekroze wrote:
> On Wednesday, 19 December 2012 at 16:19:28 UTC, Rafael wrote:
>> Yes, it is good solution, thank you! But anyway it means not so nice and laconic syntax..
>>
>> P.S. yes, I am killjoy :)
>
> Awesome, glad i could help even with my limited knowledge, good luck, don't understand the PS.
Excuse me my english once more. When a said "killjoy", I means bore man :)
|
December 19, 2012 Re: Multidimensional slice | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rafael | On 12/19/2012 01:58 AM, Rafael wrote: > my ... english. Thank you. Your English is very well. > //Then I want to do something like > x = S[0..$, 1]; //get column > S[0..$, 2] = A[0..$, 2]; //get and set column > auto B = A[0..10, 0..10]; //get submatrix block of matrix A I don't know whether all of those are covered but what you need is opDollar, which is already implemented on git master: http://d.puremagic.com/issues/show_bug.cgi?id=3474 Ali |
December 19, 2012 Re: Multidimensional slice | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 12/19/2012 11:35 AM, Ali Çehreli wrote: > On 12/19/2012 01:58 AM, Rafael wrote: > > > my ... english. > > Thank you. Your English is very well. Rather, "Your English is very good." > > //Then I want to do something like > > x = S[0..$, 1]; //get column > > S[0..$, 2] = A[0..$, 2]; //get and set column > > auto B = A[0..10, 0..10]; //get submatrix block of matrix A > > I don't know whether all of those are covered but what you need is > opDollar, which is already implemented on git master: > > http://d.puremagic.com/issues/show_bug.cgi?id=3474 > > Ali Looks like I misunderstood the question. I don't think there is support for number ranges when indexing. Anyway, here is my initial experiment with opDollar(): import std.stdio; struct S { enum width = 3; enum height = 5; int[width][height] numbers; size_t opDollar(size_t dim)() const { static if (dim == 0) { return height; } else static if (dim == 1) { return width; } else { static assert(false); } } int opIndex(size_t h, size_t w) { return numbers[h][w]; } int opIndexAssign(int value, size_t h, size_t w) { return numbers[h][w] = value; } } void main() { auto s = S(); s[$-1, $-1] = 42; assert(s[$-1, $-1] == 42); writeln(s); } Why is opDollar() not documented? Ali |
August 09, 2014 Re: Multidimensional slice | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | Hello D-community Sorry to dig an old post, but I have the exact same need. I have C++ background and I started to use D a few days ago only (a pity I didn't start sooner!) My needs are mostly around numerical calculations. I have a safe and efficient matrix type in C++ that I am porting to D. Implementation is really easier, no doubt. I have coded slicing following this page http://dlang.org/operatoroverloading.html#Slice but the code doesn't compile. here is a reduced and simplified code: struct slice { uint start; uint size; } struct Example { int[] array; uint rows; uint cols; uint start; uint stride; this(int[] array, uint rows, uint cols, uint start=0, uint stride=uint.max) { this.array = array; this.rows = rows; this.cols = cols; this.start = start; this.stride = stride == uint.max ? cols : stride; } uint opDollar(uint dim)() { static assert(dim <= 1); static if (dim == 0) return rows; else return cols; } slice opSlice(uint from, uint to) { return slice(from, to-from); } int opIndex(uint r, uint c) { return array[start + r*stride + c]; } // int[] opIndex(slice rs, uint c) { // // ... // } // int[] opIndex(uint r, slice cs) { // // ... // } Example opIndex(slice rs, slice cs) { uint r = rs.size; uint c = cs.size; uint s = start + rs.start*stride + cs.start; return Example(array, r, c, s, stride); } } int main() { auto m = Example([ 11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34, 41, 42, 43, 44, 51, 52, 53, 54 ], 5, 4); assert (m[3, 2] == 43); auto m2 = m[slice(2, 3), slice(2, 2)]; // <- this is the construct I use in C++ assert (m2[1, 0] == 43); assert (m2.rows == 3 && m2.cols == 2); // m3 should refer to the same slice as m2 auto m3 = m[2..5, 2..4]; // <- compiler syntax error is here assert (m3[1, 0] == 43); assert (m3.rows == 3 && m3.cols == 2); return 0; } the compiler kicks me out with a syntax error: Error: found ',' when expecting ']' Error: semicolon expected following auto declaration, not '2' Error: found '..' when expecting ';' following statement Error: found ']' when expecting ';' following statement Have I done something wrong? Or may be has the documentation been quicker than the compiler implementation? Or a compiler bug? thanks Rémi |
August 09, 2014 Re: Multidimensional slice | ||||
---|---|---|---|---|
| ||||
Posted in reply to Remi Thebault | On Sat, Aug 09, 2014 at 08:43:32PM +0000, Remi Thebault via Digitalmars-d-learn wrote: > Hello D-community > > Sorry to dig an old post, but I have the exact same need. > I have C++ background and I started to use D a few days ago only > (a pity I didn't start sooner!) > > My needs are mostly around numerical calculations. I have a safe and efficient matrix type in C++ that I am porting to D. > > Implementation is really easier, no doubt. > I have coded slicing following this page > http://dlang.org/operatoroverloading.html#Slice > but the code doesn't compile. [...] > slice opSlice(uint from, uint to) > { > return slice(from, to-from); > } You need opSlice to take a compile-time integer argument to determine which dimension you're slicing. Something like this: slice opSlice(size_t dim)(uint from, uint to) { // In this case it's not necessary to actually use dim, but // the lowering does translate to opSlice!0(...). Defining // opSlice without dim will only work for 1D arrays. return slice(from, to-from); } [...] > // m3 should refer to the same slice as m2 > auto m3 = m[2..5, 2..4]; // <- compiler syntax error is here [...] I think you need 2.066 or later to get this to work. After adding (size_t dim) to opSlice, your code compiles fine with git HEAD. T -- Give a man a fish, and he eats once. Teach a man to fish, and he will sit forever. |
August 10, 2014 Re: Multidimensional slice | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Saturday, 9 August 2014 at 21:03:45 UTC, H. S. Teoh via Digitalmars-d-learn wrote:
>
> I think you need 2.066 or later to get this to work. After adding
> (size_t dim) to opSlice, your code compiles fine with git HEAD.
Hi
Thanks for the quick reply.
Indeed I can get it to work with 2.066
Remi
|
Copyright © 1999-2021 by the D Language Foundation