我想写一个连接函数,所以我想出了
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;
}
但它有一个非常奇怪的输出
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);
可生产
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
这有点神秘。
答案 0 :(得分:2)
看起来您的代码混淆了.type
和.eltType
。给定像var A: [1..3] real;
这样的数组变量,A.type
实际上是[1..3] real
,而A.eltType
只是real
。所以当你宣布:
var v:[1..d] x.type;
而不是获取您想要的real
值数组,而不是实际声明一个数组,其元素本身就是real
值的数组。
然后,由于Chapel支持从标量到数组的提升赋值(例如,A = 0.0
将一个简单的方法将上面的A
数组清零),当你复制元素时原始数组到v
,v
的每个数组元素都将值存储在每个位置,导致值的三次重复。
将v
的声明更改为:
var v:[1..d] x.eltType;
应该给你你想要的东西。 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 )