Re: Struct array assignment behaviour using example from Programming in D, chapter 78
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
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
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
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
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
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?