digitalmars.D - array operations enhancements
- F. Almeida (12/12) Aug 17 2010 It is an excellent feature of D2 that one can do
- Don (8/27) Aug 18 2010 It's not terribly obvious to me that the 'ref' means 'this function can
- ponce (4/4) Aug 19 2010 pure double anyfunc(ref double x) { ... }
- KennyTM~ (17/29) Aug 19 2010 import std.algorithm;
- F. Almeida (16/39) Aug 19 2010 case)?
- Don (10/53) Aug 20 2010 Definitely. I'm just a bit paranoid about what could happen with
It is an excellent feature of D2 that one can do double a[]; double b[]; double c[]; //... c = a[] + 2.0*b[]; But this is still limited, as we cannot include function calls in these operations. What if the compiler was able to introduce them in the assignment loop, provided that the functions pass ref double (in this case)? double anyfun(ref double x) { ... } c = anyfun(a[]) + 2.0*b[];
Aug 17 2010
F. Almeida wrote:It is an excellent feature of D2 that one can do double a[]; double b[]; double c[]; //... c = a[] + 2.0*b[]; But this is still limited, as we cannot include function calls in these operations. What if the compiler was able to introduce them in the assignment loop, provided that the functions pass ref double (in this case)? double anyfun(ref double x) { ... } c = anyfun(a[]) + 2.0*b[];It's not terribly obvious to me that the 'ref' means 'this function can be parallelized'. Also, the function needs to be marked as pure. Otherwise, that's an interesting syntax. I do think we need a solution to this, so it's good to keep thinking about. It may be that, for example: a[] = x * sin(b[])[] + y * cos(b[])[]; will be enough.
Aug 18 2010
pure double anyfunc(ref double x) { ... } pure double anyfunc(double[]) { ... } double[] c = anyfun(a[]) + 2.0*b[]; This proposal could be nice for making array operations more useful, but complicates overloading.
Aug 19 2010
ponce wrote:pure double anyfunc(ref double x) { ... } pure double anyfunc(double[]) { ... } double[] c = anyfun(a[]) + 2.0*b[]; This proposal could be nice for making array operations more useful, but complicates overloading.Related example: double [] c = anyfun(a[]) * b[]; Is this element-wise using the first function, or scalar multiplication using the second? That's why I think appending a [] to the end of every function call would probably be necessary. Changing your second function to: pure double[] anyfunc(double[]) { ... } would have to create an error, because otherwise there is an ambiguity with double[] c = anyfun(a[0..$])[] + b[]; So I don't think the 'ref' is buying us anything at all. We could say that [] after a function call means 'use an array function, if it exists, otherwise synthesize an array operation, if a pure single-element function exists, otherwise generate an error'. And at present, array operations cannot generate temporaries, so an attempt to use the array function from inside an array operation would always be an error.
Aug 19 2010
Don Wrote:ponce wrote:Just report the ambiguity error.pure double anyfunc(ref double x) { ... } pure double anyfunc(double[]) { ... } double[] c = anyfun(a[]) + 2.0*b[]; This proposal could be nice for making array operations more useful, but complicates overloading.Related example: double [] c = anyfun(a[]) * b[]; Is this element-wise using the first function, or scalar multiplication using the second?
Aug 19 2010
On Aug 18, 10 14:41, F. Almeida wrote:It is an excellent feature of D2 that one can do double a[]; double b[]; double c[]; //... c = a[] + 2.0*b[]; But this is still limited, as we cannot include function calls in these operations. What if the compiler was able to introduce them in the assignment loop, provided that the functions pass ref double (in this case)? double anyfun(ref double x) { ... } c = anyfun(a[]) + 2.0*b[];import std.algorithm; import std.stdio; import std.array; auto vectorize(alias f, U)(U a) { return array(map!f(a)); } double square(double x) { return x*x; } void main () { auto a = [1.0, 2.0, 3.0, 4.0]; auto b = [5.0, 6.0, 7.0, 8.0]; auto c = [0.0, 0.0, 0.0, 0.0]; c[] = vectorize!square(a)[] + 2.0 * b[]; writeln(">", c); }
Aug 19 2010
== Quote from KennyTM~ (kennytm gmail.com)'s articleOn Aug 18, 10 14:41, F. Almeida wrote:assignmentWhat if the compiler was able to introduce them in thecase)?loop, provided that the functions pass ref double (in thisThis doesn't help, as vectorize!() is being called to create an array before passing it to the array expression (one additional assignment loop). Additional functions passed through vectorize!() would lead to N+1 loops per operation, with N the number of vectorize!() calls, instead of the intended single loop. What is intended is to pass as many functions as possible, and allow the assignment to occur within a single loop. The best alternative so far is to allow the compiler to take initiative whenever a pure function accepting one argument (value, not ref) of the same type exists. pure double myf(double x) { ... } c[] = myf(a[]) + 2.0*myf(b[]); Is such an optimization possible?double anyfun(ref double x) { ... } c = anyfun(a[]) + 2.0*b[];import std.algorithm; import std.stdio; import std.array; auto vectorize(alias f, U)(U a) { return array(map!f(a)); } double square(double x) { return x*x; } void main () { auto a = [1.0, 2.0, 3.0, 4.0]; auto b = [5.0, 6.0, 7.0, 8.0]; auto c = [0.0, 0.0, 0.0, 0.0]; c[] = vectorize!square(a)[] + 2.0 * b[]; writeln(">", c); }
Aug 19 2010
F. Almeida wrote:== Quote from KennyTM~ (kennytm gmail.com)'s articleDefinitely. I'm just a bit paranoid about what could happen with user-defined types. I would hope, btw, that we could do: Complex!double[] a; double [] r = a[].re; // grab the real part I see abs, sqrt, re, and im as the most important use cases. My feeling is that it might be necessary to restrict this to: c[] = myf(a[])[] + 2.0 * myf(b[])[]; That may be paranoia on my part. I'm not certain thatOn Aug 18, 10 14:41, F. Almeida wrote:assignmentWhat if the compiler was able to introduce them in thecase)?loop, provided that the functions pass ref double (in thisThis doesn't help, as vectorize!() is being called to create an array before passing it to the array expression (one additional assignment loop). Additional functions passed through vectorize!() would lead to N+1 loops per operation, with N the number of vectorize!() calls, instead of the intended single loop. What is intended is to pass as many functions as possible, and allow the assignment to occur within a single loop. The best alternative so far is to allow the compiler to take initiative whenever a pure function accepting one argument (value, not ref) of the same type exists. pure double myf(double x) { ... } c[] = myf(a[]) + 2.0*myf(b[]); Is such an optimization possible?double anyfun(ref double x) { ... } c = anyfun(a[]) + 2.0*b[];import std.algorithm; import std.stdio; import std.array; auto vectorize(alias f, U)(U a) { return array(map!f(a)); } double square(double x) { return x*x; } void main () { auto a = [1.0, 2.0, 3.0, 4.0]; auto b = [5.0, 6.0, 7.0, 8.0]; auto c = [0.0, 0.0, 0.0, 0.0]; c[] = vectorize!square(a)[] + 2.0 * b[]; writeln(">", c); }
Aug 20 2010