代码之家  ›  专栏  ›  技术社区  ›  Brian Dolan

Chapel中的用户定义函数有奇怪的行为。输入vs。埃尔特型

  •  2
  • Brian Dolan  · 技术社区  · 6 年前

    我想写一个连接函数,所以我想出了

    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
    

    这有点神秘。

    1 回复  |  直到 6 年前
        1
  •  2
  •   user3666197    6 年前

    看起来你的代码有点混乱 .type .eltType .给定一个数组变量,如 var A: [1..3] real; , A.type 实际上 [1..3] real 虽然 A.eltType 只是 real .所以当你宣布:

    var v:[1..d] x.type;
    

    而不是得到 真实的 值,实际上是在声明一个数组,其元素本身就是数组 真实的 价值观

    然后,由于Chapel支持从标量到数组的升级赋值(例如。, A = 0.0 这是一个简单的方法来消除我的 A 将元素从原始数组复制到 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 )