Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
March 24, 2016 Struct array assignment behaviour using example from Programming in D, chapter 78 | ||||
---|---|---|---|---|
| ||||
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? |
March 24, 2016 Re: Struct array assignment behaviour using example from Programming in D, chapter 78 | ||||
---|---|---|---|---|
| ||||
Posted in reply to data pulverizer | 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!
|
March 24, 2016 Re: Struct array assignment behaviour using example from Programming in D, chapter 78 | ||||
---|---|---|---|---|
| ||||
Posted in reply to data pulverizer | 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 |
March 25, 2016 Re: Struct array assignment behaviour using example from Programming in D, chapter 78 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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.
|
March 25, 2016 Re: Struct array assignment behaviour using example from Programming in D, chapter 78 | ||||
---|---|---|---|---|
| ||||
Posted in reply to data pulverizer | 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 |
March 25, 2016 Re: Struct array assignment behaviour using example from Programming in D, chapter 78 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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!
|
Copyright © 1999-2021 by the D Language Foundation