Complex result for Real vectors in VectorAngle

I believe this is one of the many manifestations of machine precision arithmetic in Mathematica, and it appears because VectorAngle also works with complex values. If you use the arbitrary precision engine, these cancellation errors should not occur:

 VectorAngle[{-2.7432`12, 0, 0}, {2.7432`12, 0, 0}]
3.14159

Note the `12 on the numbers; this sets a precision of 12 digits. Perhaps more applicable to your situation, you can use SetPrecision (or SetAccuracy) on existing data to convert it to arbitrary precision:

in = {{-2.7432000000000016`, 0.`, 0.`}, {2.743199999999973`, 0.`, 0.`}};

VectorAngle @@ SetPrecision[in, 12]
3.14159

Likewise, using exact arithmetic will avoid this problem as you already note:

VectorAngle @@ Rationalize[in]
π

Please see the second part of this answer for an introduction to machine and arbitrary precision in Mathematica in my own words:

  • Funny behaviour when plotting a polynomial of high degree and large coefficients

Recommended reading:

  • Annoying display truncation of numerical results

  • Confused by (apparent) inconsistent precision

  • Converting to machine precision


Just found this. This is probably a good opportunity to demonstrate the importance of using a numerically stable formula.

I will use a simpler example:

p1 = {2.7432, 0., 0.}; p2 = {-2.743199, 0., 0.};

VectorAngle[] surprisingly returns a complex result:

VectorAngle[p1, p2]
   3.141592653589793 - 2.1073424338879928*^-8*I

but using the explicit classical formula seems okay:

ArcCos[Normalize[p1].Normalize[Conjugate[p2]]]
   3.141592653589793

Now, consider this example:

p1 = {2.7432000016, 0., 0.}; p2 = {-2.743199992, 0., 0.};

VectorAngle[] does fine:

VectorAngle[p1, p2]
   3.141592653589793

but the explicit formula becomes inaccurate:

ArcCos[Normalize[p1].Normalize[Conjugate[p2]]]
   3.141592638688632

Tricky. Both can be inaccurate for nearly antipodal vectors. What to do?

Fortunately, Velvel Kahan has us covered with a much more numerically reliable formula:

vecang[v1_?VectorQ, v2_?VectorQ] := Module[{n1 = Norm[v1], n2 = Norm[v2]},
       2 ArcTan[Norm[v1 n2 + n1 v2], Norm[v1 n2 - n1 v2]]]

which is accurate in both of the cases I gave:

vecang @@@ {{{2.7432, 0., 0.}, {-2.743199, 0., 0.}},
            {{2.7432000016, 0., 0.}, {-2.743199992, 0., 0.}}}
   {3.141592653589793, 3.141592653589793}

Addendum

VectorAngle[] now gives accurate results as of version 11.2:

VectorAngle @@@ {{{2.7432, 0., 0.}, {-2.743199, 0., 0.}},
                 {{2.7432000016, 0., 0.}, {-2.743199992, 0., 0.}}} // InputForm
   {3.141592653589793, 3.141592653589793}

I think this is a bug.

You get the correct result from

vectorAngle[vec1_, vec2_] :=
 ArcCos[vec1.vec2/(Norm[vec1] Norm[vec2])]

vectorAngle[{-2.7432000000000016`, 0.`, 
  0.`}, {2.743199999999973`, 0.`, 0.`}]

(* ==> 3.14159 *)

This function is just a manual implementation of the definition as stated in the documentation of VectorAngle. Therefore, the current built-in VectorAngle does not appear to be implemented as described in the documentation.