In this code, I am calculating the angle between two vectors (xvec and yvec) by the usual inner-product relation:

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));
My expected result is ang_out = 30 degrees, but in fact I get this output (with chapel-1.20.0):
ang_out (in degrees) = 30.0 60.0
So I am wondering where this "60 degrees" comes from...?
The + reduce in the line below takes precedence over the *, so we end up doing a reduction on xvec followed by a promoted multiplication with yvec, making prod a tuple of reals:
// same as: (+ reduce xvec) * yvec;
prod = (+ reduce xvec * yvec);
To fix, use parentheses:
prod = (+ reduce (xvec * yvec));
Alternatively, use the LinearAlgebra module for the dot product:
use LinearAlgebra;
...
prod = xvec.dot(yvec);
See the precedence table (order of operations) in the spec: precedence-and-associativity
If interested in contributing to the conversation, there is an issue about changing the order of precedence for exactly this situation: chapel-lang/chapel#11463
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With