Acos returns nan with the same value?


#1

Someone help me out here. I feel like I’m losing my mind.

a = RealVector2D.newFrom([3,-2]);
b = RealVector2D.newFrom([3,-2]);
x = (a<|>b)/(a.norm*b.norm); // x = 1.0
acos(1.0); // 0.0
x; // sanity check
acos(x); // going insane?

Is there something weird going on here or am I missing something?


#2

Would be helpful to identify the extension where you got RealVector2D. It is not part of the base class library, and I don’t know where to get it.

hjh


#3

Not sure what that (a<|>b) notation means, but regardless, I imagine x isn’t exactly (floating point) 1, it’s likely a miniscule amount greater than 1. Thus acos() returns NaN. (The domain of valid inputs for acos is [-1, 1].) Just because it prints out “1” when you postln doesn’t meant it is exactly that value (with float types)!

What does x-1.0 return? Or x==1.0? It’s also possible that x is a RealVector2D result and that class has its own overload of acos?

Just a few thoughts to check out…
Glen.


#4

what does x.class gives you ?


#5

It’s from VectorSpace; sorry, spaced on passing that along. Here’s some other code with the functions written out by hand. <|> is the inner product of the two vectors. x.class returns Float

a = [3,-2];
b = [3,-2];
~innerProduct = {|vec1, vec2| (vec1[0] * vec2[0]) + (vec1[1] * vec2[1])}; // define inner product
~norm = {|vec| vec[0].sumsqr(vec[1]).sqrt}; // define norm
x = ~innerProduct.(a,b) / (~norm.(a) * ~norm.(b)); // do it by hand
acos(x); // nan
acos(1.0); // 0.0
x == 1.0; // false   

I think @totalgee is right; x == 1.0 returns false. x-1 returns 2.2204460492503e-16. Is there a way to check when a value not quite 1.0?


#6

I would probably just do acos(x.clip(-1, 1)).

Glen.


#7

There’s also .equalWithPrecision


#8

Thanks all. I’ll likely just clip the input to acos.