Azzera filtri
Azzera filtri

I get complex numbers while using "acosd" function

8 visualizzazioni (ultimi 30 giorni)
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)))

Risposta accettata

VBBV
VBBV il 26 Giu 2023
Modificato: VBBV il 26 Giu 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)
ans = -1.8314
% 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 = 98.2871 -37.9687i
y=acosd(dot(GRD_u,A_s_uniqe)/sqrt(sum(GRD_u.^2))/sqrt(sum(A_s_uniqe.^2)))
y = 179.9990
Otherwise, it seems to return real value

Più risposte (2)

Mrinal Anand
Mrinal Anand il 25 Giu 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 Commento
VBBV
VBBV il 26 Giu 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)
ans = -1.8314
% Magnitude if both vectors
Mag1 = sqrt(GRD_u(1)^2 + GRD_u(2)^2)
Mag1 = 1.8314
Mag2 = sqrt(A_s_uniqe(1)^2 + A_s_uniqe(2)^2)
Mag2 = 1.0000

Accedi per commentare.


dpb
dpb il 25 Giu 2023
Modificato: dpb il 25 Giu 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)))
y = 179.9990
format longE
arg=dot(GRD_u,A_s_uniqe)/sqrt(sum(GRD_u.^2))/sqrt(sum(A_s_uniqe.^2))
arg =
-9.999999998594938e-01
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 Commento
dpb
dpb il 25 Giu 2023
Modificato: dpb il 25 Giu 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.

Accedi per commentare.

Categorie

Scopri di più su Environment and Clutter in Help Center e File Exchange

Tag

Community Treasure Hunt

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

Start Hunting!

Translated by