Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected result for inner product using reduce

Tags:

reduce

chapel

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

enter image description here

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...?

like image 925
minibean Avatar asked Nov 24 '25 04:11

minibean


1 Answers

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

like image 101
ben-albrecht Avatar answered Nov 25 '25 17:11

ben-albrecht