Imaginary output from arccosine function when the input is close to -1

70 views (last 30 days)
I am running a shell buckling simulation, where, I need to find the angle between two vectors. The first vector, m, is [0.000128276283345364, -0.000167881251734009, 7.36224543533651e-06], whereas, the second vector, n, is [-0.000128255846266013, 0.000167854504759308, -7.36107040874295e-06]. To find the angle between these vectors, I am using the following command:
m = [0.000128276283345364, -0.000167881251734009, 7.36224543533651e-06]
n = [-0.000128255846266013, 0.000167854504759308, -7.36107040874295e-06]
m_Mag = sqrt(m(1)^2 + m(2)^2 + m(3)^2);
n_Mag = sqrt(n(1)^2 + n(2)^2 + n(3)^2);
Numerator = ( m(1) * n(1) + m(2) * n(2) + m(3) * n(3) );
Denominator = m_Mag * n_Mag;
Ratio = Numerator / Denominator
theta = acos(Ratio)
The angle should be 180 degrees or pi radians, but Matlab version 2022b is giving a complex number as an output. Is there a workaround this error?
  7 Comments
Ali
Ali about 2 hours ago
@Chuguang Pan I have uploaded the vectors m and n generated by the function in a previous comment. Can you please use them in your calculations? I think if you use these vectors, you will get Ratio = -1 and theta = 3.14159265358979 - 2.1073424255447e-08i.
Chuguang Pan
Chuguang Pan about 2 hours ago
@Ali. I have used the vectors included in your NormalVectors.mat file, and calculated the theta as shown in the answer utilizing dot and vecnorm functions in R2024b.

Sign in to comment.

Accepted Answer

Chuguang Pan
Chuguang Pan about 10 hours ago
Edited: Torsten about 5 hours ago
@Ali. After loading the m and n vectors from your attached NormalVectors.mat file. I find that the calculation result of theta is correct in R2024b. The codes are listed as follows, you can try this in your R2022b.
load NormalVectors.mat m n
Numerator = dot(m,n); % inner product of m and n
Denominator = vecnorm(m)*vecnorm(n);
theta = acos(Numerator/Denominator)
theta = 3.1416
  5 Comments
Ali
Ali about 2 hours ago
@Chuguang Pan Your proposed solution based on first normalizing the vectors and then evaluating the angle between the vectors works perfectly. Thank you so much for your help.
Paul
Paul 10 minutes ago
The proposed solution is not guaranteed to work.
rng(101);
v1 = randn(1,3);
v1 = v1/norm(v1); % normalized before taking the dot product.
v2 = -v1;
By construction, the dot product of v2 and v1 should be exactly -1.
format long e
d = dot(v2,v1)
d =
-1.000000000000000e+00
Even though the dot product looks like -1, the display showing zeros past the decimal point indicates the numerical result is not what it seems. In fact
d < -1
ans = logical
1
and
acos(d)
ans =
3.141592653589793e+00 - 2.107342425544702e-08i
We can see that d differs from -1 in the least significant bit
format hex
[d,-1]
ans = 1×2
bff0000000000001 bff0000000000000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
The example above uses norm despite the objection in this comment, which I don't understand.

Sign in to comment.

More Answers (0)

Categories

Find more on Problem-Based Optimization Setup in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!