## digitalmars.D.learn - Multidimensional slice

• Rafael (28/28) Dec 19 2012 Hi, all!
• Nekroze (5/9) Dec 19 2012 Warning the following is my total noob opinion.
• Rafael (5/14) Dec 19 2012 Yes, this is the first solution, that come to mind. But there are
• Rafael (5/21) Dec 19 2012 Not uniform syntax in this case is the one simple thing:
• Nekroze (10/32) Dec 19 2012 Sorry it may be my lack of knowledge or something but no one else
• Rafael (14/48) Dec 19 2012 Ok.
• Nekroze (6/18) Dec 19 2012 Well if you are looking at operator overloading you can overload
• Rafael (6/25) Dec 19 2012 ...and we return to my initial question :)
• Nekroze (11/37) Dec 19 2012 Instead of defining a struct for that why not allow index to take
• Rafael (4/43) Dec 19 2012 Yes, it is good solution, thank you! But anyway it means not so
• Nekroze (3/6) Dec 19 2012 Awesome, glad i could help even with my limited knowledge, good
• Rafael (3/10) Dec 19 2012 Excuse me my english once more. When a said "killjoy", I means
• John Chapman (2/2) Dec 19 2012 opIndex/opIndexAssign take multiple indices.
• Rafael (3/5) Dec 19 2012 Yes, but slices - not, and my initial question was about it.
• Nekroze (4/6) Dec 19 2012 Yes however i believe the OP also wants to provide multiple
• =?UTF-8?B?QWxpIMOHZWhyZWxp?= (6/11) Dec 19 2012 I don't know whether all of those are covered but what you need is
```Hi, all!
In advance, excuse me for my terrible english.

I try to learn the D language. One of the areas of my work is
numerical calculations, and there are lot of linear algebra
objects and operations. For beginning I started with
implementation of matrix calculations. Note, that I am doing this
is only in order to learn a language.
So, I try to implement operations with density and sparse
matrixes with uniform interface. And was confused with slice
operations. For example:

uint rows = 100, cols = 100;
auto A = new MatrixDensity!double(rows, cols);
auto S = new MatrixSparse!double(rows, cols);
auto x = new VectorColumn!double(rows);
auto y = new VectorRow!double(cols);

//and now it possible to implement:
auto a_ij = A[i, j]; //opIndex(uint row, uint col)
S[i, j] = a_ij; //opIndexAssign(T value, uint row, uint col)
y = S[i]; //opIndex(uint row)
A[i] = y; //opIndexAssign(VectorRow!T value, uint row)

//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.e. I want to implement multimentional slices to realize simple,
generalized and "human readable" syntax for matrix and vectors
operations (like a Matlab syntax for example). Or may be I use
not right way for realization?
```
Dec 19 2012
"Nekroze" <nekroze eturnilnetwork.com> writes:
```On Wednesday, 19 December 2012 at 09:58:37 UTC, Rafael wrote:
//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

Warning the following is my total noob opinion.

Instead of using [0..\$,2] for example, try [0..\$][2] and see how
that works out. D doesn't use multiple indexes in the same []
section as far as i know so give that a go.
```
Dec 19 2012
```On Wednesday, 19 December 2012 at 10:17:28 UTC, Nekroze wrote:
On Wednesday, 19 December 2012 at 09:58:37 UTC, Rafael wrote:
//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

Warning the following is my total noob opinion.

Instead of using [0..\$,2] for example, try [0..\$][2] and see
how that works out. D doesn't use multiple indexes in the same
[] section as far as i know so give that a go.

Yes, this is the first solution, that come to mind. But there are
some problems in that way. Firs of them (but not main) - not
uniform syntax. The more important: which should result operation
Matrix[0..\$] in that case?
```
Dec 19 2012
```On Wednesday, 19 December 2012 at 10:25:23 UTC, Rafael wrote:
On Wednesday, 19 December 2012 at 10:17:28 UTC, Nekroze wrote:
On Wednesday, 19 December 2012 at 09:58:37 UTC, Rafael wrote:
//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

Warning the following is my total noob opinion.

Instead of using [0..\$,2] for example, try [0..\$][2] and see
how that works out. D doesn't use multiple indexes in the same
[] section as far as i know so give that a go.

Yes, this is the first solution, that come to mind. But there
are some problems in that way. Firs of them (but not main) -
not uniform syntax. The more important: which should result
operation Matrix[0..\$] in that case?

Not uniform syntax in this case is the one simple thing:
A[i, j]; // get the a_ij
A[i][j]; // get the a_ij

but I like a first variant!
```
Dec 19 2012
"Nekroze" <nekroze eturnilnetwork.com> writes:
```On Wednesday, 19 December 2012 at 10:33:38 UTC, Rafael wrote:
On Wednesday, 19 December 2012 at 10:25:23 UTC, Rafael wrote:
On Wednesday, 19 December 2012 at 10:17:28 UTC, Nekroze wrote:
On Wednesday, 19 December 2012 at 09:58:37 UTC, Rafael wrote:
//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

Warning the following is my total noob opinion.

Instead of using [0..\$,2] for example, try [0..\$][2] and see
how that works out. D doesn't use multiple indexes in the
same [] section as far as i know so give that a go.

Yes, this is the first solution, that come to mind. But there
are some problems in that way. Firs of them (but not main) -
not uniform syntax. The more important: which should result
operation Matrix[0..\$] in that case?

Not uniform syntax in this case is the one simple thing:
A[i, j]; // get the a_ij
A[i][j]; // get the a_ij

but I like a first variant!

Sorry it may be my lack of knowledge or something but no one else
seems to be responding so i will keep trying to help as best i
can.

What do you mean by uniform syntax? do you mean you want the
syntax to be the same as in other languages? because as it says
on the dlang page for arrays under rectangular arrays it says
that a[i][j] is just the way that D does it where as in c++ is
a[i, j] but that's just one of the differences between languages
that cant be avoided as far as i know.
```
Dec 19 2012
```On Wednesday, 19 December 2012 at 11:59:24 UTC, Nekroze wrote:
On Wednesday, 19 December 2012 at 10:33:38 UTC, Rafael wrote:
On Wednesday, 19 December 2012 at 10:25:23 UTC, Rafael wrote:
On Wednesday, 19 December 2012 at 10:17:28 UTC, Nekroze wrote:
On Wednesday, 19 December 2012 at 09:58:37 UTC, Rafael wrote:
//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

Warning the following is my total noob opinion.

Instead of using [0..\$,2] for example, try [0..\$][2] and see
how that works out. D doesn't use multiple indexes in the
same [] section as far as i know so give that a go.

Yes, this is the first solution, that come to mind. But there
are some problems in that way. Firs of them (but not main) -
not uniform syntax. The more important: which should result
operation Matrix[0..\$] in that case?

Not uniform syntax in this case is the one simple thing:
A[i, j]; // get the a_ij
A[i][j]; // get the a_ij

but I like a first variant!

Sorry it may be my lack of knowledge or something but no one
else seems to be responding so i will keep trying to help as
best i can.

What do you mean by uniform syntax? do you mean you want the
syntax to be the same as in other languages? because as it says
on the dlang page for arrays under rectangular arrays it says
that a[i][j] is just the way that D does it where as in c++ is
a[i, j] but that's just one of the differences between
languages that cant be avoided as far as i know.

Ok.
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.
```
Dec 19 2012
"Nekroze" <nekroze eturnilnetwork.com> writes:
```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.

opSlice as described here
sure if you can defined multiple slices delimited by commas in
the same [] block but it is worth a try.
```
Dec 19 2012
```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.

not sure if you can defined multiple slices delimited by commas
in the same [] block but it is worth a try.

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];
```
Dec 19 2012
"Nekroze" <nekroze eturnilnetwork.com> writes:
```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.

not sure if you can defined multiple slices delimited by
commas in the same [] block but it is worth a try.

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?
```
Dec 19 2012
```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.

not sure if you can defined multiple slices delimited by
commas in the same [] block but it is worth a try.

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 :)
```
Dec 19 2012
"Nekroze" <nekroze eturnilnetwork.com> writes:
```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.
```
Dec 19 2012
```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 :)
```
Dec 19 2012
"John Chapman" <johnch_atms hotmail.com> writes:
```opIndex/opIndexAssign take multiple indices.
```
Dec 19 2012
```On Wednesday, 19 December 2012 at 13:34:52 UTC, John Chapman
wrote:
opIndex/opIndexAssign take multiple indices.

Yes, but slices - not, and my initial question was about it.
```
Dec 19 2012
"Nekroze" <nekroze eturnilnetwork.com> writes:
```On Wednesday, 19 December 2012 at 13:34:52 UTC, John Chapman
wrote:
opIndex/opIndexAssign take multiple indices.

Yes however i believe the OP also wants to provide multiple
slices as well as multiple indices. Atleast as far as i can tell.
```
Dec 19 2012
=?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
```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
```
Dec 19 2012
=?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
```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
```
Dec 19 2012
"Remi Thebault" <remi.thebault outlook.com> writes:
```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.
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
```
Aug 09 2014
"H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
```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.
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

T

--
Give a man a fish, and he eats once. Teach a man to fish, and he will
sit forever.
```
Aug 09 2014
"Remi Thebault" <remi.thebault outlook.com> writes:
```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