Reputation: 3136
I wanted to write a concatenation function, so I came up with
proc concat(x:[], y:[]) {
const d:int = x.size + y.size;
var v:[1..d] x.type;
writeln("\n d: ", d);
writeln("\n x.domain: ", x.domain);
writeln("\n y.domain: ", y.domain);
var k = 1;
for i in x.domain {
v[k] = x[i];
writeln("i: ", i, " k: ", k, " x[i]: ", x[i], " v[k]: ", v[k]);
k += 1;
}
for i in y.domain {
v[k] = y[i];
writeln("i: ", i, " k: ", k, " y[i]: ", y[i], " v[k]: ", v[k]);
k += 1;
}
writeln("\n v: ", v);
return v;
}
But it has a very odd output
var x: [1..3] real = [1.1, 2.2, 3.3],
y: [9..11] real = [9.9, 10.10, 11.11];
var z = concat(x,y);
writeln(z);
Produces
d: 6
x.domain: {1..3}
y.domain: {9..11}
i: 1 k: 1 x[i]: 1.1 v[k]: 1.1 1.1 1.1
i: 2 k: 2 x[i]: 2.2 v[k]: 2.2 2.2 2.2
i: 3 k: 3 x[i]: 3.3 v[k]: 3.3 3.3 3.3
i: 9 k: 4 y[i]: 9.9 v[k]: 9.9 9.9 9.9
i: 10 k: 5 y[i]: 10.1 v[k]: 10.1 10.1 10.1
i: 11 k: 6 y[i]: 11.11 v[k]: 11.11 11.11 11.11
v: 1.1 1.1 1.1 2.2 2.2 2.2 3.3 3.3 3.3 9.9 9.9 9.9 10.1 10.1 10.1 11.11 11.11 11.11
1.1 1.1 1.1 2.2 2.2 2.2 3.3 3.3 3.3 9.9 9.9 9.9 10.1 10.1 10.1 11.11 11.11 11.11
This is kind of mystifying.
Upvotes: 2
Views: 70
Reputation: 4043
It looks as though your code has confused .type
and .eltType
. Given an array variable like var A: [1..3] real;
, A.type
is effectively [1..3] real
while A.eltType
is simply real
. So when you declarde:
var v:[1..d] x.type;
rather than getting the array of real
values that you intended, you're actually declaring an array whose elements are themselves arrays of real
values.
Then, since Chapel supports promoted assignment from a scalar to an array (e.g., A = 0.0
would be an easy way to zero out my A
array above), when you're copying elements from your original arrays to v
, each array element of v
is storing the value in each of its positions, resulting in the triplication of the values.
Changing the declaration of v
to:
var v:[1..d] x.eltType;
should give you what you want. Here's the corrected version online.
var x: [1.. 3] real = [1.1, 2.2, 3.3],
y: [9..11] real = [9.9, 10.10, 11.11];
var z = concat( x, y );
writeln( z );
proc concat( x:[], y:[] ) {
const d:int = x.size + y.size;
// var v:[1..d] x.type; // ------------------------------------ FAIL
/* d: 6
x.domain: {1..3}
y.domain: {9..11}
i: 1, k: 1, x[i]: 1.10, v[k]: 1.1 1.1 1.1
i: 2, k: 2, x[i]: 2.20, v[k]: 2.2 2.2 2.2
i: 3, k: 3, x[i]: 3.30, v[k]: 3.3 3.3 3.3
i: 9, k: 4, y[i]: 9.90, v[k]: 9.9 9.9 9.9
i: 10, k: 5, y[i]: 10.10, v[k]: 10.1 10.1 10.1
i: 11, k: 6, y[i]: 11.11, v[k]: 11.11 11.11 11.11
v:
1.1 1.1 1.1 2.2 2.2 2.2 3.3 3.3 3.3 9.9 9.9 9.9 10.1 10.1 10.1 11.11 11.11 11.11
1.1 1.1 1.1 2.2 2.2 2.2 3.3 3.3 3.3 9.9 9.9 9.9 10.1 10.1 10.1 11.11 11.11 11.11
*/
var v:[1..d] x.eltType; // ------------------------------------ PASS
/* d: 6
x.domain: {1..3}
y.domain: {9..11}
i: 1, k: 1, x[i]: 1.10, v[k]: 1.1
i: 2, k: 2, x[i]: 2.20, v[k]: 2.2
i: 3, k: 3, x[i]: 3.30, v[k]: 3.3
i: 9, k: 4, y[i]: 9.90, v[k]: 9.9
i: 10, k: 5, y[i]: 10.10, v[k]: 10.1
i: 11, k: 6, y[i]: 11.11, v[k]: 11.11
v:
1.1 2.2 3.3 9.9 10.1 11.11
1.1 2.2 3.3 9.9 10.1 11.11
*/
writeln( "\n d: ", d );
writeln( "x.domain: ", x.domain );
writeln( "y.domain: ", y.domain );
var k = 1;
for i in x.domain {
v[k] = x[i];
// writeln("i: ", i, " k: ", k, " x[i]: ", x[i], " v[k]: ", v[k]);
writef( "i: %{###},", i ); writef( " k: %{###},", k ); writef( " x[i]: %{####.##},", x[i] ); writeln( " v[k]: ", v[k] );
k += 1;
}
for i in y.domain {
v[k] = y[i];
// writeln("i: ", i, " k: ", k, " y[i]: ", y[i], " v[k]: ", v[k]);
writef( "i: %{###},", i ); writef( " k: %{###},", k ); writef( " y[i]: %{####.##},", y[i] ); writeln( " v[k]: ", v[k] );
k += 1;
}
writeln( "\nv:\n", v );
return v;
}
( and both alternatives, side by side, left for any further experimentations )
Upvotes: 2