I get complex numbers while using "acosd" function
19 views (last 30 days)
Show older comments
Hello everyone,
I would get complexe number when I use acosd function to caclulate cosine inverse of a value, which I am pressty sure is in the range of [-1,1]. Look at the example below. Can anyone let me know where the problem is?
GRD_u=[-0.6372,1.7170];
A_s_uniqe=[0.3479,-0.9375];
y=acosd(dot(GRD_u,A_s_uniqe)/sqrt(sum(GRD_u.^2))/sqrt(sum(A_s_uniqe.^2)))
0 Comments
Accepted Answer
VBBV
on 26 Jun 2023
Edited: VBBV
on 26 Jun 2023
Probably you might have evaluated the equation using incorrect parenthesis enclosing only the dot product for acosd function and dividing the rest of terms in sqrt function as shown below
GRD_u=[-0.6372,1.7170];
A_s_uniqe=[0.3479,-0.9375];
% the dot product is out of range [-1 1]
dot(GRD_u,A_s_uniqe)
% you might have used incorrect parenthesis while evaluating equation
%------------------------->>>
y=acosd(dot(GRD_u,A_s_uniqe))/sqrt(sum(GRD_u.^2))/sqrt(sum(A_s_uniqe.^2))
y=acosd(dot(GRD_u,A_s_uniqe)/sqrt(sum(GRD_u.^2))/sqrt(sum(A_s_uniqe.^2)))
Otherwise, it seems to return real value
0 Comments
More Answers (2)
Mrinal Anand
on 25 Jun 2023
You are getting a complex number because the acosd() function is only defined for values in the range of [-1, 1]. If the function argument is outside this range, it will return a complex number.
In your code, the argument passed to acosd() is calculated as the dot product of GRD_u and A_s_uniqe divided by the product of their magnitudes. If the magnitude of either GRD_u or A_s_uniqe is less than the dot product of the two vectors, then the argument passed to acosd() will be greater than 1, which is outside the defined range.
1 Comment
VBBV
on 26 Jun 2023
@Mrinal Anand, The magnitude of both GRD_u or A_s_uniqe vectors are not less than dot product but its the usage of incorrect parenthesis in equation that would result in complex valued number
GRD_u=[-0.6372,1.7170];
A_s_uniqe=[0.3479,-0.9375];
% dot product
dot(GRD_u,A_s_uniqe)
% Magnitude if both vectors
Mag1 = sqrt(GRD_u(1)^2 + GRD_u(2)^2)
Mag2 = sqrt(A_s_uniqe(1)^2 + A_s_uniqe(2)^2)
dpb
on 25 Jun 2023
Edited: dpb
on 25 Jun 2023
GRD_u=[-0.6372,1.7170];
A_s_uniqe=[0.3479,-0.9375];
y=acosd(dot(GRD_u,A_s_uniqe)/sqrt(sum(GRD_u.^2))/sqrt(sum(A_s_uniqe.^2)))
format longE
arg=dot(GRD_u,A_s_uniqe)/sqrt(sum(GRD_u.^2))/sqrt(sum(A_s_uniqe.^2))
The particular set of values does't cause the problem, but argument is pretty close to -1; it's possible rounding error in floating point numbers could cause a calculation to be just on the other side for a given case.
I'm also guessing that the numbers above are rounded manual inputs from a set of calculations and that for the actual computed values, the above issue occurred -- but the lack of precision with only four decimal places changes the results.
Would have to post the exact values/code that created the problem, but I'll bet if you put the calc in a try...catch block and verify the actual value when it errors or assert() that the abs(value) is <=1 before the call you'll find it's close, but on the wrong side of the tracks.
1 Comment
dpb
on 25 Jun 2023
Edited: dpb
on 25 Jun 2023
The solution will be to use acosd(sign(x)*min(abs(x),1)) in order to bound the calculation to be within [-1,1].
You probably also want to wrap that inside a test to confirm that it is only a rounding isse and not that the code has gone completely off the rails so that you're not just silently passing through nonsensical results.
See Also
Categories
Find more on Environment and Clutter 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!