www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Vector operations doesn't convert to a common type?

reply simendsjo <simen.endsjo pandavre.com> writes:
     int[3]   a = [1,2,4];
     float[3] b = [1,2,4];
     float[3] c;
     // Why doesn't this work?
     c = a[] + b[]; // Error: incompatible types for ((a[]) + (b[])): 
'int[]' and 'float[]'
     // When this works?
     c[0] = a[0] + b[0];
     c[1] = a[1] + b[1];
     c[2] = a[2] + b[2];
     assert(c == [2,4,8]);
Apr 16 2011
next sibling parent simendsjo <simen.endsjo pandavre.com> writes:
On 16.04.2011 12:12, simendsjo wrote:
 int[3] a = [1,2,4];
 float[3] b = [1,2,4];
 float[3] c;
 // Why doesn't this work?
 c = a[] + b[]; // Error: incompatible types for ((a[]) + (b[])): 'int[]'
 and 'float[]'
 // When this works?
 c[0] = a[0] + b[0];
 c[1] = a[1] + b[1];
 c[2] = a[2] + b[2];
 assert(c == [2,4,8]);

I tried using a template mixin to avoid having to type this all over, but I cannot get it to work.. I think I have something wrong with my alias usage, but that's just speculating :) mixin template ArrayVectorOp(string op, alias dest, alias a, alias b, int I) if(dest.length == a.length && dest.length == b.length && I >= 1 && I <= dest.length) { // dest[I-1] = a[I-1] op b[I-1] mixin(dest.stringof~"["~(I-1).stringof~"]" " = " ~a.stringof~"["~(I-1).stringof~"]" ~op ~b.stringof~"["~(I-1).stringof~"];"); static if(I > 1) mixin ArrayVectorOp!(op, dest, a, b, I-1); } void main() { int[3] a = [1, 2, 3]; float[3] b = [2.1, 3.2, 4.3]; float[3] c; mixin ArrayVectorOp!("+", c, a, b, a.length); assert(c == [3.1, 5.2, 7.3]); } Gives the following output: t.d(4): no identifier for declarator c[3 - 1] t.d(4): Error: c is used as a type t.d(4): Error: cannot implicitly convert expression (cast(float)a[2u] + b[2u]) o f type float to const(_error_[]) t.d(4): no identifier for declarator c[2 - 1] t.d(4): Error: c is used as a type t.d(4): Error: cannot implicitly convert expression (cast(float)a[1u] + b[1u]) o f type float to const(_error_[]) t.d(4): no identifier for declarator c[1 - 1] t.d(4): Error: c is used as a type t.d(4): Error: cannot implicitly convert expression (cast(float)a[0u] + b[0u]) o f type float to const(_error_[]) t.d(11): Error: mixin t.main.ArrayVectorOp!("+",c,a,b,3u).ArrayVectorOp!(op,c,a, b,2).ArrayVectorOp!(op,c,a,b,1) error instantiating t.d(11): Error: mixin t.main.ArrayVectorOp!("+",c,a,b,3u).ArrayVectorOp!(op,c,a, b,2) error instantiating t.d(18): Error: mixin t.main.ArrayVectorOp!("+",c,a,b,3u) error instantiating
Apr 16 2011
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
simendsjo:

      int[3]   a = [1,2,4];
      float[3] b = [1,2,4];
      float[3] c;
      // Why doesn't this work?
      c = a[] + b[]; // Error: incompatible types for ((a[]) + (b[])): 
 'int[]' and 'float[]'

      // When this works?
      c[0] = a[0] + b[0];
      c[1] = a[1] + b[1];
      c[2] = a[2] + b[2];
      assert(c == [2,4,8]);

Vector ops are often implemented in assembly, and despite they are less flexible, they sometimes lead to more efficiency (if the arrays are large). The second example uses normal D code, that's much more flexible. Bye, bearophile
Apr 16 2011
prev sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Sat, Apr 16, 2011 at 13:37, simendsjo <simen.endsjo pandavre.com> wrote:
 I tried using a template mixin to avoid having to type this all over, but I
 cannot get it to work.. I think I have something wrong with my alias usage,
 but that's just speculating :)

Try this: auto arrayOp(string op, A, B, int N, int n = 0)(A[N] a, B[N] b) { static if (n < N - 1) mixin("return [a[n] " ~ op ~ " b[n]] ~ arrayOp!(op,A,B,N,n+1)(a, b);"); else mixin("return [a[n] " ~ op ~ " b[n]];"); } void main() { int[3] a = [1,2,4]; float[3] b = [1,2,4]; auto c = arrayOp!"+"(a,b); writeln(c); } I had to resort to the N/n kludge, because of A[N] <-> A[] incompatibilities. Note that this could easily be extend to accept any string function (ala std.algorithm) and any number of arrays. Philippe
Apr 17 2011