digitalmars.D.learn - cloning array
- Sean (38/38) Jun 02 2021 Hello
- Basile.B (15/53) Jun 02 2021 it's rather an unintuitive behavior.
- Basile.B (17/19) Jun 02 2021 On Wednesday, 2 June 2021 at 15:59:38 UTC, Basile.B wrote:
- Gavin Ray (6/10) Jun 02 2021 Would it be worth modifying the docs for `.dup()` so that this
- Basile.B (4/14) Jun 02 2021 Me too actually. the reason why this did not work as expected was
- Sean (8/9) Jun 02 2021 Okey, so I have to copy every (N-1) dimensional element - one
- Steven Schveighoffer (17/20) Jun 02 2021 Yes. `dup` is a shallow copy.
- Sean (3/4) Jun 02 2021 My current solution, if anyone wonders :
- cc (19/24) Jun 03 2021 You may find the `hasIndirections` template from std.traits
- Alexandru Ermicioi (18/19) Jun 03 2021 You can implement deep copy using template recursion:
- Alain De Vos (17/17) Jun 03 2021 ```
Hello I have seen this : https://forum.dlang.org/thread/1473526717.1917.20.camel winder.org.uk Now, please consider this code: import std.stdio; import std.math; import std.stdio; import std.conv; import std.format; import std.math; import std.algorithm; import std.net.curl; import std.json; import std.path; import std.array; import std.net.curl; import core.stdc.stdlib; import std.datetime; import std.file; void main() { auto a = new double[][] (0,0); a ~= [ 1.0, 2.45]; a ~= [ 4.9 ,28, 9]; auto b = a.dup; a[1] = remove(a[1],1); writeln(b); } I compile with dmd version : DMD64 D Compiler v2.096.1 Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved written by Walter Bright Output : [[1, 2.45], [4.9, 9, 9]] What I would expect : [[1, 2.45], [4.9, 28, 9]], because i am copying the array `a` to a different place - at `b`. Is this normal behavior of dup? if so, how can I get the behavior i am searching for? Thank you.
Jun 02 2021
On Wednesday, 2 June 2021 at 15:32:38 UTC, Sean wrote:Hello I have seen this : https://forum.dlang.org/thread/1473526717.1917.20.camel winder.org.uk Now, please consider this code: import std.stdio; import std.math; import std.stdio; import std.conv; import std.format; import std.math; import std.algorithm; import std.net.curl; import std.json; import std.path; import std.array; import std.net.curl; import core.stdc.stdlib; import std.datetime; import std.file; void main() { auto a = new double[][] (0,0); a ~= [ 1.0, 2.45]; a ~= [ 4.9 ,28, 9]; auto b = a.dup; a[1] = remove(a[1],1); writeln(b); } I compile with dmd version : DMD64 D Compiler v2.096.1 Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved written by Walter Bright Output : [[1, 2.45], [4.9, 9, 9]] What I would expect : [[1, 2.45], [4.9, 28, 9]], because i am copying the array `a` to a different place - at `b`. Is this normal behavior of dup? if so, how can I get the behavior i am searching for? Thank you.it's rather an unintuitive behavior. `.dup` is not a deep copy: --- import std; void main() { auto a = new double[][] (0,0); a ~= [ 1.0, 2.45]; a ~= [ 4.9 ,28, 9]; auto b = [a[0].dup, a[1].dup]; a[1] = remove(a[1],1); writeln(b); } --- works as you expect
Jun 02 2021
On Wednesday, 2 June 2021 at 15:59:38 UTC, Basile.B wrote:On Wednesday, 2 June 2021 at 15:32:38 UTC, Sean wrote: works as you expectOn Wednesday, 2 June 2021 at 15:59:38 UTC, Basile.B wrote: ```d import std; void main() { auto a = new double[][] (0,0); a ~= [ 1.0, 2.45]; a ~= [ 4.9 ,28, 9]; auto b = [a[0].dup, a[1].dup]; a[1] = remove(a[1],1); writeln(b); } ``` works a expected. The reason why is that your array elements are fat pointers, so when you dup a, you dup some fats pointer, so you got the same elements as "a" but accessible from another chunck of memory.
Jun 02 2021
On Wednesday, 2 June 2021 at 16:07:35 UTC, Basile.B wrote:works a expected. The reason why is that your array elements are fat pointers, so when you dup a, you dup some fats pointer, so you got the same elements as "a" but accessible from another chunck of memory.Would it be worth modifying the docs for `.dup()` so that this behavior is clear? I would have been confused by this as well. It's probably a no-brainer if you understand general memory principles but not everyone does.
Jun 02 2021
On Wednesday, 2 June 2021 at 16:50:16 UTC, Gavin Ray wrote:On Wednesday, 2 June 2021 at 16:07:35 UTC, Basile.B wrote:yes, I think so, it's worth a dlang.org change.works a expected. The reason why is that your array elements are fat pointers, so when you dup a, you dup some fats pointer, so you got the same elements as "a" but accessible from another chunck of memory.Would it be worth modifying the docs for `.dup()` so that this behavior is clear?I would have been confused by this as well.Me too actually. the reason why this did not work as expected was not immediate.It's probably a no-brainer if you understand general memory principles but not everyone does.
Jun 02 2021
On Wednesday, 2 June 2021 at 15:59:38 UTC, Basile.B wrote:works as you expectOkey, so I have to copy every (N-1) dimensional element - one after one - if the array is N dimensional, with N > 1, and repeat it for every element if they themselves are arrays with dimension M > 1 ? This becomes very difficult if we have large tensors, 16 - 85 dimensions ( I am doing AI with d ) and eash element itself is a dynamic array.
Jun 02 2021
On Wednesday, 2 June 2021 at 16:08:14 UTC, Sean wrote:On Wednesday, 2 June 2021 at 15:59:38 UTC, Basile.B wrote:you should use library types for this kind of operations, for example they can provide virtually N dim arrays that are actually flattened. Maybe Mir would help.works as you expectOkey, so I have to copy every (N-1) dimensional element - one after one - if the array is N dimensional, with N > 1, and repeat it for every element if they themselves are arrays with dimension M > 1 ? This becomes very difficult if we have large tensors, 16 - 85 dimensions ( I am doing AI with d ) and eash element itself is a dynamic array.
Jun 02 2021
On Wednesday, 2 June 2021 at 16:18:03 UTC, Basile.B wrote:Maybe Mir would help.Tried. However, I am more of a mathematician, than a software developer. So writing my own code was easier than to follow through the design philosophy and internalize the idioms and styles of Mir. When this project is done, I will study Mir more in detail
Jun 02 2021
On 6/2/21 11:32 AM, Sean wrote:Is this normal behavior of dup? if so, how can I get the behavior i am searching for? Thank you.Yes. `dup` is a shallow copy. To get the behavior you want: ```d auto deepdup(T)(T[] arr) { import std.algorithm, std.array; static if(is(T == U[], U)) return arr.map!(x => .deepdup(x)).array; else return arr.dup; } // use like arr.deepdup where you would normally put arr.dup ``` Note that this is going to be pretty inefficient allocation-wise, but will work with minimal code. -Steve
Jun 02 2021
On Wednesday, 2 June 2021 at 15:32:38 UTC, Sean wrote:if so, how can I get the behavior i am searching for? Thank you.My current solution, if anyone wonders : https://github.com/patefacio/d-help/blob/master/d-help/opmix/dup.d
Jun 02 2021
On Wednesday, 2 June 2021 at 17:50:13 UTC, Sean wrote:On Wednesday, 2 June 2021 at 15:32:38 UTC, Sean wrote:You may find the `hasIndirections` template from std.traits useful. ```d import std.traits : hasIndirections, ValueType; import std.range.primitives : ElementType; int[] a; int[][] b; int[string] x; int[][string] y; struct S { int s; } struct T { int[] t; } assert(!hasIndirections!( ElementType!(typeof(a)) )); assert( hasIndirections!( ElementType!(typeof(b)) )); assert(!hasIndirections!( ValueType!(typeof(x)) )); assert( hasIndirections!( ValueType!(typeof(y)) )); assert(!hasIndirections!S); assert( hasIndirections!T); ```if so, how can I get the behavior i am searching for? Thank you.My current solution, if anyone wonders : https://github.com/patefacio/d-help/blob/master/d-help/opmix/dup.d
Jun 03 2021
On Wednesday, 2 June 2021 at 15:32:38 UTC, Sean wrote:...You can implement deep copy using template recursion: import std; T[] rdup(T : U[], U)(T[] duped) { return duped.map!(arr => arr.rdup).array; } T[] rdup(T)(T[] duped) { return duped.dup; } void main() { int[][][] dupeable = [[[1], [2]], [[3]]]; auto duped = dupeable.rdup; duped[0][0][0] = 9; writeln("Hello D-eep copy of ", dupeable, " to ", duped); } Best regards, Alexandru.
Jun 03 2021
``` import std.stdio; void main(){ auto a=new int[][] (0,0); a~=[1,2]; a~=[3,4]; auto b= a.dup; a[0]=[5,6]; a[1][1]=7; writeln(b); } ``` Program above outputs [[1, 2], [3, 7]] Which means a[1][1] and b[1][1] point to the same memory location. But a[0] occupies a different memory location as b[0]. It is a shallow copy and is the expected behaviour. Maybe there is need for a library function dupdeep ?
Jun 03 2021