Re: Doubt - Static multidimension arrays

2016-01-21 Thread tsbockman via Digitalmars-d-learn

On Thursday, 21 January 2016 at 01:36:21 UTC, Nemo wrote:
I don't remember where I saw it, but actually, in static 
multi-dimensional arrays, arr[0][1] is next to arr[0][0] in 
memory. You can see it with:


void main () {
  ubyte [7][5] arr;
  import std.stdio : writeln;
  writeln ( & arr[0][0], " ", & arr[0][1], " ", & arr [1][0] );
}


Yes. That's consistent both with what I wrote in the message that 
you quoted, and with how non-static arrays work.


dpaste: http://dpaste.dzfl.pl/5ca02bd98f82


Re: Doubt - Static multidimension arrays

2016-01-20 Thread Nemo via Digitalmars-d-learn

On Tuesday, 19 January 2016 at 20:39:37 UTC, tsbockman wrote:

On Tuesday, 19 January 2016 at 19:14:30 UTC, alb wrote:

   [...]


One other thing you may want to keep in mind when working on 
this kind of thing - when you loop over a multi-dimensional 
array, the order matters.


For large arrays, this:

int[c_max][r_max] arr;

foreach(r; 0 .. r_max)
{
foreach(c; 0 .. c_max)
{
// do something with arr[r][c] here
}
}

Can be *much* faster than this:

int[c_max][r_max] arr;

foreach(c; 0 .. c_max)
{
foreach(r; 0 .. r_max)
{
// do something with arr[r][c] here
}
}

The reason is that the first version access the elements in the 
order that they are actually stored in memory, whereas the 
second forces the CPU to jump between rows for each element.



[...]


You're welcome.

And yes, it can definitely be confusing. I understand why the 
array syntax in D is the way it is, but that still doesn't 
always save me from mixing things up once in a while anyway.


I don't remember where I saw it, but actually, in static 
multi-dimensional arrays, arr[0][1] is next to arr[0][0] in 
memory. You can see it with:


void main () {
  ubyte [7][5] arr;
  import std.stdio : writeln;
  writeln ( & arr[0][0], " ", & arr[0][1], " ", & arr [1][0] );
}


Re: Doubt - Static multidimension arrays

2016-01-19 Thread tsbockman via Digitalmars-d-learn

On Tuesday, 19 January 2016 at 07:46:59 UTC, Mike Parker wrote:
It's not that he's seeing them as special, it's just that 
indexing them in D is different than doing so in C or C++. It 
trips a lot of people up.


No, the difference is actually in C/C++ 's declaration syntax; 
the way that indexing works is exactly the same as in D.


This C++ code (http://codepad.org/XeVSndBP):

#include 
#include 

class Row {
int data[10];
public:
int& operator[](int x) {
return data[x]; }
};

int main(void) {
int arr2d[5][10];
Row arrOfArrs[5];

for(int r = 0; r < 5; ++r)
{
for(int c = 0; c < 10; ++c)
{
arr2d[r][c] = (r * 10) + c;
arrOfArrs[r][c] = (r * 10) + c;
}
}

cout << (arr2d[4][9] == arrOfArrs[4][9]) << endl;
cout << (memcmp(arr2d, arrOfArrs, sizeof(int)*5*10) == 0) << 
endl;


return 0;
}


Does exactly the same thing as this D code 
(http://dpaste.dzfl.pl/1731eb86bc83):


import std.stdio;
import core.stdc.string;

alias Row = int[10];

int main() {
int[10][5] arr2d;
Row[5] arrOfArrs;

for(int r = 0; r < 5; ++r)
{
for(int c = 0; c < 10; ++c)
{
arr2d[r][c] = (r * 10) + c;
arrOfArrs[r][c] = (r * 10) + c;
}
}

writeln(arr2d[4][9] == arrOfArrs[4][9]);
writeln(memcmp(arr2d.ptr, arrOfArrs.ptr, int.sizeof*5*10) == 
0);


return 0;
}

The only relevant difference between the two, is that the order 
of the row and column specification is swapped in *the 
declaration*, not when indexing.


Re: Doubt - Static multidimension arrays

2016-01-19 Thread tsbockman via Digitalmars-d-learn

On Tuesday, 19 January 2016 at 19:14:30 UTC, alb wrote:
So guys: Ali, Mike Parker and tsbockman thanks for all your 
explanation, in fact looking now I and after making some tests 
I really got it.


So:
   int[2]a1; // Array of 2 elements of type int

   int[2][5] a2; // Array of 2 elements of type int divided in 
5 rows


   writeln(a2[0]); // = accessing row 0 = [0,0]
   writeln(a2[4]); // = accessing row 4 = [0,0]


One other thing you may want to keep in mind when working on this 
kind of thing - when you loop over a multi-dimensional array, the 
order matters.


For large arrays, this:

int[c_max][r_max] arr;

foreach(r; 0 .. r_max)
{
foreach(c; 0 .. c_max)
{
// do something with arr[r][c] here
}
}

Can be *much* faster than this:

int[c_max][r_max] arr;

foreach(c; 0 .. c_max)
{
foreach(r; 0 .. r_max)
{
// do something with arr[r][c] here
}
}

The reason is that the first version access the elements in the 
order that they are actually stored in memory, whereas the second 
forces the CPU to jump between rows for each element.


If that in mind, now it all makes sense for me, and of course 
it's consistent as well. Sorry to bother about this, but I 
think this will help other newcomers.


Thanks again for help/tips which helped turn my mindset.

Albert.


You're welcome.

And yes, it can definitely be confusing. I understand why the 
array syntax in D is the way it is, but that still doesn't always 
save me from mixing things up once in a while anyway.


Re: Doubt - Static multidimension arrays

2016-01-19 Thread alb via Digitalmars-d-learn
So guys: Ali, Mike Parker and tsbockman thanks for all your 
explanation, in fact looking now I and after making some tests I 
really got it.


So:
   int[2]a1; // Array of 2 elements of type int

   int[2][5] a2; // Array of 2 elements of type int divided in 5 
rows


   writeln(a2[0]); // = accessing row 0 = [0,0]
   writeln(a2[4]); // = accessing row 4 = [0,0]

If that in mind, now it all makes sense for me, and of course 
it's consistent as well. Sorry to bother about this, but I think 
this will help other newcomers.


Thanks again for help/tips which helped turn my mindset.

Albert.


Re: Doubt - Static multidimension arrays

2016-01-19 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 19 January 2016 at 08:27:56 UTC, tsbockman wrote:

The only relevant difference between the two, is that the order 
of the row and column specification is swapped in *the 
declaration*, not when indexing.


Newcomers to D tend to think in terms of C when they declare 
arrays, so the confusion comes when they find out they have to 
index it in a way that is the reverse of what they expect. Yes, 
it's because the declaration syntax is different, but it's always 
the indexing that trips them up. That's all I meant. It usually 
isn't obvious what the root of the misunderstanding is until 
someone explains it.


Re: Doubt - Static multidimension arrays

2016-01-19 Thread tsbockman via Digitalmars-d-learn

On Tuesday, 19 January 2016 at 13:00:19 UTC, Mike Parker wrote:
Newcomers to D tend to think in terms of C when they declare 
arrays, so the confusion comes when they find out they have to 
index it in a way that is the reverse of what they expect. Yes, 
it's because the declaration syntax is different, but it's 
always the indexing that trips them up. That's all I meant. It 
usually isn't obvious what the root of the misunderstanding is 
until someone explains it.


I guess my problem is that I'm assuming that people who've worked 
with C++ will understand that this: `int arr[5][10]` is *not* an 
"array of arrays"; my point would be clearer if I'd written this:


template class Array {
T data[size];
public:
T& operator[](int x) {
return data[x]; }
};

int arr2d[5][10];
Array< Array< int, 10 >, 5 > arrOfArrs;

Notice that an actual "array of arrays" declaration has the 
dimensions listed in the same order as D. I'd hope that 
expressing it this way would make it obvious to any experienced 
C/C++ programmer why D's declaration syntax is the way that it is.


Anyway, I'll give it a rest now. I thought this way of looking at 
it would make things easier to understand, but I guess not...


Re: Doubt - Static multidimension arrays

2016-01-19 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 19 January 2016 at 14:58:51 UTC, tsbockman wrote:

Anyway, I'll give it a rest now. I thought this way of looking 
at it would make things easier to understand, but I guess not...


In my experience, it's focusing on the types in the D array 
syntax, rather than the actual ordering, that helps people over 
the hump. The rows vs. columns bit is useful to demonstrate the 
difference, but the focus on types clarifies it. That's how I 
approached it in the section on arrays in Learning D.


Re: Doubt - Static multidimension arrays

2016-01-18 Thread albert00 via Digitalmars-d-learn

On Tuesday, 19 January 2016 at 02:54:03 UTC, cym13 wrote:

int[2][5] arr;

?


How is that not rectangular? It's sounds like you're confusing 
it with "square".


Ow my problem is:

int[2][2] arr;  // This works

int[2][5] arr;  // This not working

And I'd like to create the former.




Re: Doubt - Static multidimension arrays

2016-01-18 Thread Ali Çehreli via Digitalmars-d-learn

On 01/18/2016 07:20 PM, albert00 wrote:

> It's strange since I was declaring int[1][2] (1 row / 2 columns) and
> then accessing as:
>
>  arr2[0][0] = 1;
>  arr2[1][0] = 2;
>
> Seems like 2 rows and 1 column. This makes sense?

Yes, it makes sense and its consistent. This is one of many little 
things that D is an improvement over C and C++.


Static array type syntax is always the following:

Type[length]

For example, the following is a row with two columns:

int[2]

When you want a certain number of those, you follow the same array 
definition syntax:


Type[length]

Since each element is int[2] in this case, for 3 rows we get:

int[2][3]

So, in order to get 1 row of 2 columns, you would write

int[2][1]

Accessing elements is consistent as well:

var[index]

So,

arr2[0]

would be the first row, which has two columns; which is further accessed 
by another index:


arr2[0][1]

is first row, second column.

Ali



Doubt - Static multidimension arrays

2016-01-18 Thread albert via Digitalmars-d-learn

Hello,

I was looking over 
http://dlang.org/spec/arrays.html#rectangular-arrays:


And I've found that D multidimensional arrays are Rectangular, so 
it's impossible to create non-rectangular multidimensional static 
array like:


int[2][5] arr;

?


Re: Doubt - Static multidimension arrays

2016-01-18 Thread cym13 via Digitalmars-d-learn

On Tuesday, 19 January 2016 at 02:47:04 UTC, albert wrote:

Hello,

I was looking over 
http://dlang.org/spec/arrays.html#rectangular-arrays:


And I've found that D multidimensional arrays are Rectangular, 
so it's impossible to create non-rectangular multidimensional 
static array like:


int[2][5] arr;

?


How is that not rectangular? It's sounds like you're confusing it 
with "square".


Re: Doubt - Static multidimension arrays

2016-01-18 Thread albert00 via Digitalmars-d-learn
Well maybe it was my fault, but anyway, here's a small example of 
what I was working on:


void main(){
// Array 1  
int[2][2] arr1;

arr1[0][0] = 1;
arr1[0][1] = 2;
arr1[1][0] = 3;
arr1[1][1] = 4;

// Array 2
int[1][2] arr2;

//arr2[0][0] = 1;
//arr2[0][1] = 2; // <- Error

arr2[0][0] = 1;
arr2[1][0] = 2;
}

So for what I can see on Array 2 is the column/row works 
otherwise.


It's strange since I was declaring int[1][2] (1 row / 2 columns) 
and then accessing as:


arr2[0][0] = 1;
arr2[1][0] = 2;

Seems like 2 rows and 1 column. This makes sense?


Re: Doubt - Static multidimension arrays

2016-01-18 Thread tsbockman via Digitalmars-d-learn

On Tuesday, 19 January 2016 at 03:20:30 UTC, albert00 wrote:

[...]


You're not really creating a rectangular array - what you're 
making is an array *of arrays*:


int[10][5] a; // An array of 5 (int[10])

writeln(typeof(a).stringof);  // int[10][5]
writeln(typeof(a[4]).stringof);// int[10]
writeln(typeof(a[4][9]).stringof); // int

The recently accepted `std.experimental.ndslice` module provides 
a real multi-dimensional array interface:

http://dlang.org/phobos-prerelease/std_experimental_ndslice.html


(There might be something else relevant in Phobos as well, with a 
less numerically-oriented focus; I'm not sure.)




Re: Doubt - Static multidimension arrays

2016-01-18 Thread Albert00 via Digitalmars-d-learn

On Tuesday, 19 January 2016 at 05:32:07 UTC, Ali Çehreli wrote:

Ali, look what you said:


For example, the following is a row with two columns:

int[2]


Then you said:


So, in order to get 1 row of 2 columns, you would write

int[2][1]


So the first pair of square-brackets is the column and second is 
the row as you said above, but look what happens when I try to 
access thinking that way:


void main(){
int[2][1] arr; // 2 columns & 1 row as Ali said...

arr[0][0] = 1;
arr[1][0] = 2;
}

ERROR:

/d609/f167.d(14): Error: array index 1 is out of bounds arr[0 .. 
1]
/d609/f167.d(14): Error: array index 1 is out of bounds arr[0 .. 
1]



So now the first pair of brackets in fact is the ROW and the 
second is the COLUMN, because this works:


void main(){
int[2][1] arr; // 2 columns & 1 row

arr[0][0] = 1;
arr[0][1] = 2;
}

Maybe I'm really dumb, but you need to agree that even with your 
good explanation it still doesn't making sense.


Albert.


Re: Doubt - Static multidimension arrays

2016-01-18 Thread tsbockman via Digitalmars-d-learn

On Tuesday, 19 January 2016 at 07:35:34 UTC, tsbockman wrote:

By substitution, we expect `b[0]` to be equal to `(a[4])[9]`.


Apparently I need to get more sleep:

By substitution, we expect `b[9]` to be equal to `(a[4])[9]`.


Re: Doubt - Static multidimension arrays

2016-01-18 Thread Ali Çehreli via Digitalmars-d-learn

On 01/18/2016 11:12 PM, Albert00 wrote:
> On Tuesday, 19 January 2016 at 05:32:07 UTC, Ali Çehreli wrote:
>
> Ali, look what you said:
>
>> For example, the following is a row with two columns:
>>
>> int[2]
>
> Then you said:
>
>> So, in order to get 1 row of 2 columns, you would write
>>
>> int[2][1]

To rephrase myself, that is an array of 1 element, where the element 
type is int[2]. So the only valid index is 0, which gives you an element 
of int[2]. (You can further index into that element of course.)


> So the first pair of square-brackets is the column and second is the row
> as you said above,

I stress the fact that it is always the following syntax:

Type[length]

So, again, if we have an array of 1-element where the elements are of 
type int[2], then it is this (space added for readability):


int[2] [1]

> but look what happens when I try to access thinking
> that way:

I suspect C and C++ way for inside-out (or is it outside-in) syntax is 
affecting your thinking. ;)


> void main(){
>  int[2][1] arr; // 2 columns & 1 row as Ali said...
>
>  arr[0]

That one gives you the first element.

> [0] = 1;

and that one gives you the first element of that first element.

>  arr[1][0] = 2;

Sorry, there is no element-1 for the arr: That has only one element.

> }
>
> ERROR:
>
> /d609/f167.d(14): Error: array index 1 is out of bounds arr[0 .. 1]
> /d609/f167.d(14): Error: array index 1 is out of bounds arr[0 .. 1]
>
>
> So now the first pair of brackets in fact is the ROW and the second is
> the COLUMN, because this works:
>
> void main(){
>  int[2][1] arr; // 2 columns & 1 row

Yes, that's exactly what I said. :)

>  arr[0][0] = 1;
>  arr[0][1] = 2;
> }
>
> Maybe I'm really dumb,

Not at all. I blame C and C++. ;)

> but you need to agree that even with your good explanation it
> still doesn't making sense.

I don't agree: It makes sense and is consistent. :)

> Albert.

Ali



Re: Doubt - Static multidimension arrays

2016-01-18 Thread albert00 via Digitalmars-d-learn

On Tuesday, 19 January 2016 at 04:50:18 UTC, tsbockman wrote:

On Tuesday, 19 January 2016 at 03:20:30 UTC, albert00 wrote:

[...]


... what you're making is an array *of arrays*:


Maybe I was misunderstood, because in fact that is what I was 
making an array of arrays, but my problem in fact was in 
accessing it.


Like I said above:

I was declaring int[1][2] arr:

But to access I need to invert the columns like:

arr2[0][0] = 1;
arr2[1][0] = 2;



int[10][5] a; // An array of 5 (int[10])


Using your example, in my head I'd access the last element as:

a[9][4] but that would give me an error:

Error: array index 9 is out of bounds arr[0 .. 5]

So I need to invert a[4][9].

Again seems a bit strange "FOR ME" since I declare in one way and 
access the other way.


albert.

PS: I'm changing my name because I think there is another user 
with the same name, that Icon is not mine.


Re: Doubt - Static multidimension arrays

2016-01-18 Thread alb via Digitalmars-d-learn

On Tuesday, 19 January 2016 at 07:19:54 UTC, Ali Çehreli wrote:

...


Well anyway thanks for your help. For now I'll just think the 
otherwise. :)


Albert.




Re: Doubt - Static multidimension arrays

2016-01-18 Thread tsbockman via Digitalmars-d-learn

On Tuesday, 19 January 2016 at 07:21:39 UTC, albert00 wrote:
Again seems a bit strange "FOR ME" since I declare in one way 
and access the other way.


albert.


That's because you're stuck in the mindset that 2d arrays are 
somehow *special*. If I do this:


Row[5] a;
const b = a[4];

Of what type do you expect `b` to be? Of type `Row`, yes?

Now let's define `Row`:

alias Row = int[10];
Row[5] a;
const b = a[9];
const int = c = b[4];

Of what type is `b` now? Of course it is still `Row`.

By substitution, we expect `b[0]` to be equal to `(a[9])[4]`.


Re: Doubt - Static multidimension arrays

2016-01-18 Thread tsbockman via Digitalmars-d-learn

On Tuesday, 19 January 2016 at 07:32:22 UTC, tsbockman wrote:

Now let's define `Row`:

alias Row = int[10];
Row[5] a;
const b = a[9];
const int = c = b[4];

Of what type is `b` now? Of course it is still `Row`.

By substitution, we expect `b[0]` to be equal to `(a[9])[4]`.


Sigh. I should proof-read my stuff more carefully:

alias Row = int[10];
Row[5] a;
const Row b = a[4];
const int = c = b[9];

Of what type is `b` now? Of course it is still `Row`.

By substitution, we expect `b[0]` to be equal to `(a[4])[9]`.


Re: Doubt - Static multidimension arrays

2016-01-18 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 19 January 2016 at 07:21:39 UTC, albert00 wrote:

On Tuesday, 19 January 2016 at 04:50:18 UTC, tsbockman wrote:

On Tuesday, 19 January 2016 at 03:20:30 UTC, albert00 wrote:

[...]


... what you're making is an array *of arrays*:


Maybe I was misunderstood, because in fact that is what I was 
making an array of arrays, but my problem in fact was in 
accessing it.


Like I said above:

I was declaring int[1][2] arr:

But to access I need to invert the columns like:

arr2[0][0] = 1;
arr2[1][0] = 2;



int[10][5] a; // An array of 5 (int[10])


Using your example, in my head I'd access the last element as:

a[9][4] but that would give me an error:

Error: array index 9 is out of bounds arr[0 .. 5]

So I need to invert a[4][9].

Again seems a bit strange "FOR ME" since I declare in one way 
and access the other way.


Try not to think in terms of columns and rows. It makes more 
sense to think of it in terms of *types*.


Given the following array declaration, which is an array of int:

int[2] nums;

Then any index into nums (such as nums[0]) is going to return an 
int. The same logic applies given this array declaration, which 
is an array of int[2]:


int[2][5] numArrays;

Then any index into numArrays is going to return int[2] (for 
example, numArrays[0]). In order to access the members of the 
returned array, we need one more index, so that int[0][1] is the 
second element of the first array. In other words, it's shorthand 
for:


int[2] arr = numArrays[0];
int num = arr[1];

Seen in this light, it is entirely consistent and not strange at 
all. It just takes some people a bit of effort to stop thinking 
in terms of C's multidimensional arrays so that it becomes 
second-nature to see it in this light. I was using D for quite 
some time before I finally got used to it.





Re: Doubt - Static multidimension arrays

2016-01-18 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 19 January 2016 at 07:32:22 UTC, tsbockman wrote:


That's because you're stuck in the mindset that 2d arrays are 
somehow *special*. If I do this:




It's not that he's seeing them as special, it's just that 
indexing them in D is different than doing so in C or C++. It 
trips a lot of people up.