www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Squaring Arrays without Overlapping Array Error

reply "jmh530" <john.michael.hall gmail.com> writes:
If I call a function like

int[] square_array(int[] x)
{
	return x[] *= x[];
}

I get an error that there is an overlapping array in a vector 
operation. I guess this makes sense as the lhs and rhs are 
occupying the same memory. Nevertheless, I find it a little 
frustrating.

I tried two alternatives, one just adds a temporary duplicate 
array for the lhs x[] in the above, while the other uses a 
foreach loop. Both get correct results without errors, but also 
have their issues. Duplicating requires memory allocation, which 
makes it slower for small arrays. Foreach (ignoring parallelism 
or SIMD) tends to be slower for larger arrays, I take it due to 
compiler optimizations for vector operations.

Are there any other alternatives here?
Jul 06 2015
next sibling parent reply "tcak" <1ltkrs+3wyh1ow7kzn1k sharklasers.com> writes:
On Tuesday, 7 July 2015 at 05:27:10 UTC, jmh530 wrote:
 If I call a function like

 int[] square_array(int[] x)
 {
 	return x[] *= x[];
 }

 I get an error that there is an overlapping array in a vector 
 operation. I guess this makes sense as the lhs and rhs are 
 occupying the same memory. Nevertheless, I find it a little 
 frustrating.

 I tried two alternatives, one just adds a temporary duplicate 
 array for the lhs x[] in the above, while the other uses a 
 foreach loop. Both get correct results without errors, but also 
 have their issues. Duplicating requires memory allocation, 
 which makes it slower for small arrays. Foreach (ignoring 
 parallelism or SIMD) tends to be slower for larger arrays, I 
 take it due to compiler optimizations for vector operations.

 Are there any other alternatives here?
I have never used arrays in that way before, though I don't get why you are writing return line in that way. Shouldn't it be like `return (x[] * x[]);` ?
Jul 07 2015
next sibling parent "tcak" <1ltkrs+3wyh1ow7kzn1k sharklasers.com> writes:
On Tuesday, 7 July 2015 at 08:06:50 UTC, tcak wrote:
 On Tuesday, 7 July 2015 at 05:27:10 UTC, jmh530 wrote:
 [...]
I have never used arrays in that way before, though I don't get why you are writing return line in that way. Shouldn't it be like `return (x[] * x[]);` ?
But, yes, the result should be stored somewhere still. Since either you, or the compiler would be writing a loop for multiplication already, I would be writing by hand for this operation.
Jul 07 2015
prev sibling parent "jmh530" <john.michael.hall gmail.com> writes:
On Tuesday, 7 July 2015 at 08:06:50 UTC, tcak wrote:
 I have never used arrays in that way before, though I don't get 
 why you are writing return line in that way. Shouldn't it be 
 like `return (x[] * x[]);` ?
There's nothing fundamentally wrong with doing that in the return line. For instance, the one I duplicated the array on looks like int[] square_array_dup(int[] x) { auto y = x.dup; return y[] *= x[]; } To get your way to work requires int[] square_array(int[] x) { int[] y; y.length = x.length; y[] = x[] * x[]; return y; } which can be slower. Anyway, the main reason I used x[] *= x[] was that the original code I had written was not in a function and was just void main() { int len = 10; auto x = len.iota.array; x[] *= x[]; } Obviously, in this case, I can just do a map before putting it into an array, but then I got more interested in squaring arrays.
Jul 07 2015
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 7/7/15 1:27 AM, jmh530 wrote:
 If I call a function like

 int[] square_array(int[] x)
 {
      return x[] *= x[];
 }

 I get an error that there is an overlapping array in a vector operation.
Yeah, this seems like an unnecessary limitation for exact matching. In other words, if your destination array exactly matches one or more of the arguments, it should be fine. Where the overlapping starts causing problems is something like this: x[1..$] *= x[0..$-1]; I would love to see this limitation fixed. -Steve
Jul 07 2015
parent reply "jmh530" <john.michael.hall gmail.com> writes:
On Tuesday, 7 July 2015 at 13:58:17 UTC, Steven Schveighoffer 
wrote:
 Yeah, this seems like an unnecessary limitation for exact 
 matching. In other words, if your destination array exactly 
 matches one or more of the arguments, it should be fine. Where 
 the overlapping starts causing problems is something like this:

 x[1..$] *= x[0..$-1];

 I would love to see this limitation fixed.

 -Steve
Do you think I should file a bug report?
Jul 07 2015
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 7/7/15 12:45 PM, jmh530 wrote:
 On Tuesday, 7 July 2015 at 13:58:17 UTC, Steven Schveighoffer wrote:
 Yeah, this seems like an unnecessary limitation for exact matching. In
 other words, if your destination array exactly matches one or more of
 the arguments, it should be fine. Where the overlapping starts causing
 problems is something like this:

 x[1..$] *= x[0..$-1];

 I would love to see this limitation fixed.
Do you think I should file a bug report?
Sure, file as an enhancement. -Steve
Jul 07 2015
parent "jmh530" <john.michael.hall gmail.com> writes:
On Tuesday, 7 July 2015 at 17:05:21 UTC, Steven Schveighoffer 
wrote:
 Sure, file as an enhancement.

 -Steve
https://issues.dlang.org/show_bug.cgi?id=14783
Jul 07 2015