Re: Struct array assignment behaviour using example from Programming in D, chapter 78

2016-03-25 Thread data pulverizer via Digitalmars-d-learn

On Friday, 25 March 2016 at 08:53:20 UTC, Ali Çehreli wrote:

On 03/25/2016 12:00 AM, data pulverizer wrote:
> On Thursday, 24 March 2016 at 18:46:14 UTC, Ali Çehreli wrote:
>> On 03/24/2016 10:24 AM, data pulverizer wrote:
>> > I have been playing with the matrix example given at the
end
>> of chapter
>> > 78 of Ali Çehreli's
>>
>> For reference, it's "Multi-dimensional operator overloading
example"
>> here:
>>
>>   http://ddili.org/ders/d.en/templates_more.html
>>
>> >having problems with overloading the opAssign operator.

> Thank you. Let me try to ask the question again. The problem
I am
> experiencing is to do with opIndexAssign().
>
> I added the following public operators:
>
>  Matrix opAssign(int[][] arr)
>  {
>  writeln(__FUNCTION__);
>  this.rows = arr;
>  return this;
>  }

The problem is due to the aliasing of 'rows' members of Matrix 
objects. subMatrix is supposed to be a reference into some 
elements of an existing Matrix. As soon as we do the above 
assignment, this Matrix (which may be a subMatrix in a specific 
context) breaks lose from its actual Matrix elements.


We need to implement the function above "in place":

Matrix opAssign(int[][] arr)
{
writeln(__FUNCTION__);

if (rows.length < arr.length) {
rows.length = arr.length;
}

foreach (i, row; arr) {
const newLength = row.length;

if (rows[i].length < newLength) {
rows[i].length = newLength;
}
rows[i][0..newLength] = row[];
}

return this;
}

(There must be an existing function that does that.)

>  Matrix opAssign(Matrix mat)
>  {
>  writeln(__FUNCTION__);
>  this.rows = mat.rows;

Same thing applies above: We need to assign to this.rows in 
place (which is easier by taking advantage of the previous 
function):


this = mat.rows;

>  return this;
>  }

No changes needed for the other two functions but I would 
'return this' instead of 'return subMatrix' for them as well.


Ali


That's great! Thank you very much for the fix and extra 
suggestions, and for your patience putting up with my poorly 
formulated question! Looks like I need to go and read all the 
structs and operators chapters thoroughly!


Re: Struct array assignment behaviour using example from Programming in D, chapter 78

2016-03-25 Thread Ali Çehreli via Digitalmars-d-learn

On 03/25/2016 12:00 AM, data pulverizer wrote:
> On Thursday, 24 March 2016 at 18:46:14 UTC, Ali Çehreli wrote:
>> On 03/24/2016 10:24 AM, data pulverizer wrote:
>> > I have been playing with the matrix example given at the end
>> of chapter
>> > 78 of Ali Çehreli's
>>
>> For reference, it's "Multi-dimensional operator overloading example"
>> here:
>>
>>   http://ddili.org/ders/d.en/templates_more.html
>>
>> >having problems with overloading the opAssign operator.

> Thank you. Let me try to ask the question again. The problem I am
> experiencing is to do with opIndexAssign().
>
> I added the following public operators:
>
>  Matrix opAssign(int[][] arr)
>  {
>  writeln(__FUNCTION__);
>  this.rows = arr;
>  return this;
>  }

The problem is due to the aliasing of 'rows' members of Matrix objects. 
subMatrix is supposed to be a reference into some elements of an 
existing Matrix. As soon as we do the above assignment, this Matrix 
(which may be a subMatrix in a specific context) breaks lose from its 
actual Matrix elements.


We need to implement the function above "in place":

Matrix opAssign(int[][] arr)
{
writeln(__FUNCTION__);

if (rows.length < arr.length) {
rows.length = arr.length;
}

foreach (i, row; arr) {
const newLength = row.length;

if (rows[i].length < newLength) {
rows[i].length = newLength;
}
rows[i][0..newLength] = row[];
}

return this;
}

(There must be an existing function that does that.)

>  Matrix opAssign(Matrix mat)
>  {
>  writeln(__FUNCTION__);
>  this.rows = mat.rows;

Same thing applies above: We need to assign to this.rows in place (which 
is easier by taking advantage of the previous function):


this = mat.rows;

>  return this;
>  }

No changes needed for the other two functions but I would 'return this' 
instead of 'return subMatrix' for them as well.


Ali



Re: Struct array assignment behaviour using example from Programming in D, chapter 78

2016-03-25 Thread data pulverizer via Digitalmars-d-learn

On Thursday, 24 March 2016 at 18:46:14 UTC, Ali Çehreli wrote:

On 03/24/2016 10:24 AM, data pulverizer wrote:
> I have been playing with the matrix example given at the end
of chapter
> 78 of Ali Çehreli's

For reference, it's "Multi-dimensional operator overloading 
example" here:


  http://ddili.org/ders/d.en/templates_more.html

>having problems with overloading the opAssign operator.
>
> rows is a private int[][] in a Matrix struct.
>
> I have added the following ...
>
> Matrix opAssign(int[][] arr)
> {
>  this.rows = arr;
>  // rows = arr // does not work either ...
>  return this;
> }
>
> However this does not work (no error occurs, it just doesn't
do
> anything)

How are you testing it? The following worked for me:

1) Added that opAssign() to the struct. (Verified that it gets 
called.)


2) Tested with the following code:

auto m2 = Matrix();
auto rows = [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ];
m2 = rows;

writeln(m2);

(I've tested with a dynamically generated 'rows' as well.)

Ali


Thank you. Let me try to ask the question again. The problem I am 
experiencing is to do with opIndexAssign().


I added the following public operators:

Matrix opAssign(int[][] arr)
{
writeln(__FUNCTION__);
this.rows = arr;
return this;
}

Matrix opAssign(Matrix mat)
{
writeln(__FUNCTION__);
this.rows = mat.rows;
return this;
}

Matrix opIndexAssign(A...)(int[][] arr, A arguments)
if(A.length <= 2){
writeln(__FUNCTION__);
Matrix subMatrix = opIndex(arguments);
		assert(((arr.length == subMatrix.nrow()) & (arr[0].length == 
subMatrix.ncol())),

"Array dimension do not match matrix replacement.\n");
/*foreach(i, row; subMatrix.rows){
row[] = arr[i];
}*/
subMatrix = arr; // Does not work
return subMatrix;
}

Matrix opIndexAssign(A...)(Matrix mat, A arguments)
if(A.length <= 2){
writeln(__FUNCTION__);
Matrix subMatrix = opIndex(arguments);
		assert(((mat.nrow() == subMatrix.nrow()) & (mat.ncol() == 
subMatrix.ncol())),

"Array dimension do not match matrix replacement.\n");
/*foreach(i, row; subMatrix.rows){
row[] = mat.rows[i];
}*/
subMatrix = mat; // Does not work
return subMatrix;
}




void main(){
// Here we test opAssign [][]int
auto a = Matrix();
a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; // this works
writeln(a);
// opIndexAssign int[][]
a[0..2, 0..2] = [[88, 88], [88, 88]]; // this does not work
writeln(a);
auto b = Matrix();
// opAssign Matrix
b = a; // this works
writeln(b);
	b = [[88, 88, 88, 88], [88, 88, 88, 88], [88, 88, 88, 88], [88, 
88, 88, 88]];

// opIndexAssign Matrix
b[0..3, 0..3] = a; // this does not work
writeln(b);
}


If you uncomment the foreach lines, the opIndexAssign() work.



Re: Struct array assignment behaviour using example from Programming in D, chapter 78

2016-03-24 Thread Ali Çehreli via Digitalmars-d-learn

On 03/24/2016 10:24 AM, data pulverizer wrote:
> I have been playing with the matrix example given at the end of chapter
> 78 of Ali Çehreli's

For reference, it's "Multi-dimensional operator overloading example" here:

  http://ddili.org/ders/d.en/templates_more.html

>having problems with overloading the opAssign operator.
>
> rows is a private int[][] in a Matrix struct.
>
> I have added the following ...
>
> Matrix opAssign(int[][] arr)
> {
>  this.rows = arr;
>  // rows = arr // does not work either ...
>  return this;
> }
>
> However this does not work (no error occurs, it just doesn't do
> anything)

How are you testing it? The following worked for me:

1) Added that opAssign() to the struct. (Verified that it gets called.)

2) Tested with the following code:

auto m2 = Matrix();
auto rows = [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ];
m2 = rows;

writeln(m2);

(I've tested with a dynamically generated 'rows' as well.)

Ali



Re: Struct array assignment behaviour using example from Programming in D, chapter 78

2016-03-24 Thread data pulverizer via Digitalmars-d-learn

On Thursday, 24 March 2016 at 17:24:38 UTC, data pulverizer wrote:
I have been playing with the matrix example given at the end of 
chapter 78 of Ali Çehreli's fabulous book and am having 
problems with overloading the opAssign operator.


rows is a private int[][] in a Matrix struct.

I have added the following ...

Matrix opAssign(int[][] arr)
{
this.rows = arr;
// rows = arr // does not work either ...
return this;
}

However this does not work (no error occurs, it just doesn't do 
anything) but this does work ...


Matrix opAssign(int[][] arr)
{
foreach(i, row; rows){
row[] = arr[i];
}
return this;
}

The second is not efficient since it has to loop to assign the 
array. Is there a more efficient way of overwriting the array?


Sorry. Please disregard. I'll drive home and ask this question 
properly!


Struct array assignment behaviour using example from Programming in D, chapter 78

2016-03-24 Thread data pulverizer via Digitalmars-d-learn
I have been playing with the matrix example given at the end of 
chapter 78 of Ali Çehreli's fabulous book and am having problems 
with overloading the opAssign operator.


rows is a private int[][] in a Matrix struct.

I have added the following ...

Matrix opAssign(int[][] arr)
{
this.rows = arr;
// rows = arr // does not work either ...
return this;
}

However this does not work (no error occurs, it just doesn't do 
anything) but this does work ...


Matrix opAssign(int[][] arr)
{
foreach(i, row; rows){
row[] = arr[i];
}
return this;
}

The second is not efficient since it has to loop to assign the 
array. Is there a more efficient way of overwriting the array?