Skip to main content
Commonmark migration
Source Link

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

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}

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}

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}
added 284 characters in body
Source Link

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}

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}

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}
Source Link

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}