digitalmars.D.learn - Struct array assignment behaviour using example from Programming in D,
- data pulverizer (22/22) Mar 24 2016 I have been playing with the matrix example given at the end of
- data pulverizer (3/25) Mar 24 2016 Sorry. Please disregard. I'll drive home and ask this question
- =?UTF-8?Q?Ali_=c3=87ehreli?= (12/25) Mar 24 2016 For reference, it's "Multi-dimensional operator overloading example" her...
- data pulverizer (61/94) Mar 25 2016 Thank you. Let me try to ask the question again. The problem I am
- =?UTF-8?Q?Ali_=c3=87ehreli?= (29/56) Mar 25 2016 The problem is due to the aliasing of 'rows' members of Matrix objects.
- data pulverizer (5/67) Mar 25 2016 That's great! Thank you very much for the fix and extra
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?
Mar 24 2016
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!
Mar 24 2016
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'sFor reference, it's "Multi-dimensional operator overloading example" here: http://ddili.org/ders/d.en/templates_more.htmlhaving 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
Mar 24 2016
On Thursday, 24 March 2016 at 18:46:14 UTC, Ali Çehreli wrote:On 03/24/2016 10:24 AM, data pulverizer wrote: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.I have been playing with the matrix example given at the endof chapter78 of Ali Çehreli'sFor reference, it's "Multi-dimensional operator overloading example" here: http://ddili.org/ders/d.en/templates_more.htmlhaving 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'tdoanything)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
Mar 25 2016
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 endof chapter78 of Ali Çehreli'sFor reference, it's "Multi-dimensional operator overloading example" here: http://ddili.org/ders/d.en/templates_more.htmlhaving 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
Mar 25 2016
On Friday, 25 March 2016 at 08:53:20 UTC, Ali Çehreli wrote:On 03/25/2016 12:00 AM, data pulverizer wrote: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!On Thursday, 24 March 2016 at 18:46:14 UTC, Ali Çehreli wrote:endOn 03/24/2016 10:24 AM, data pulverizer wrote:I have been playing with the matrix example given at theexample"of chapter78 of Ali Çehreli'sFor reference, it's "Multi-dimensional operator overloadinghere: http://ddili.org/ders/d.en/templates_more.htmlhaving problems with overloading the opAssign operator.Thank you. Let me try to ask the question again. The problemI amexperiencing 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
Mar 25 2016