使用 reduce 的内积出现意外结果

Unexpected result for inner product using reduce

在此代码中,我通过通常的 inner-product 关系计算两个向量(xvecyvec)之间的角度:

var ang = 30.0 * (pi / 180.0);

var xvec = [3.0, 0.0],
    yvec = [cos(ang), sin(ang)] * 10.0;

var norm1sq = (+ reduce xvec**2),
    norm2sq = (+ reduce yvec**2),
    prod    = (+ reduce xvec * yvec);

var ang_out = acos(prod / sqrt(norm1sq * norm2sq));

writeln("ang_out (in degrees) = ", ang_out * (180.0 / pi));

我的预期结果是 ang_out = 30 度,但实际上我得到了这个输出(使用 chapel-1.20.0):

ang_out (in degrees) = 30.0 60.0

所以我想知道这个“60 度”是从哪里来的...?

下行中的 + reduce 优先于 *,因此我们最终对 xvec 进行归约,然后是 yvec 的提升乘法,使 prod 成为实数元组:

// same as: (+ reduce xvec) * yvec;
prod    = (+ reduce xvec * yvec); 

要修复,请使用括号:

prod    = (+ reduce (xvec * yvec));

或者,使用 LinearAlgebra 点积模块:

use LinearAlgebra;

...

prod    = xvec.dot(yvec);

参见规范中的优先级 table(操作顺序):precedence-and-associativity

如果有兴趣为对话做出贡献,则存在关于针对这种情况更改优先顺序的问题:chapel-lang/chapel#11463