NaN issue and if statement
Show older comments
I'm having trouble with my code when I add an if condition to check if B_body(3) is less than 1e-5.
Without the if condition, everything works fine.
But when I add the if condition, I get a warning and B_body(3) values become NaN.
I've tried several solutions, but nothing works.
Any ideas on how to fix this?
epsilon=1e-5;
if abs(B_body(3))<epsilon
T_rw=[0;0;0];
else
T_rw = [0; 0; 1] * (B_body' * T_commanded) / (B_body(3));
end
11 Comments
We don't have enough code to know what happens next, but almost certainly what then occurs after the T_rw vector is set to identically zero is that B_body(3) also becomes identically zero and then the first step after that you end up with a case of
0/0
which is where the NaN comes from. Beyond that, all hope is lost.
You'll need some other special casing to deal with whatever is supposed to happend afterwards, but the model as written doesn't handle the case when whatever T_rw represents becomes identically zero.
Steven Lord
on 7 Aug 2024
But when I add the if condition, I get a warning
What is the full and exact text of the warning message? Please show us all the text displayed in orange in the Command Window. The exact text may be useful and/or necessary to determine what's going on and how to avoid the warning.
Rik
on 7 Aug 2024
If you put your code in your question or a comment, you can run it. That way you can confirm we will see the same error as you.
Sahas
on 8 Aug 2024
As others rightly mentioned, looks like the issue might be arising from the division by B_body(3) when it is very close to zero which leads to division by zero which in turn might be the reason for NaNs.
To avoid this, you can add a small value (like delta) to the denominator to prevent division by zero. You can try this out:
epsilon = 1e-5;
delta = 1e-6;
if abs(B_body(3)) < epsilon
T_rw = [0; 0; 0];
else
T_rw = [0; 0; 1] * (B_body' * T_commanded) / (B_body(3) + delta);
end
This approach slightly modifies the calculation, so make sure it still meets your requirements. If precision is crucial, you might need to handle the code more carefully.
I hope this is beneficial to you. If you need further assistance, please feel free to reach out.
"when it is very close to zero which leads to division by zero which in turn might be the reason for NaN"
Dividing zero by zero leads to NaN. Even dividing zero by the nearest value closest to zero (i.e. the smallest subnormal) does not produce NaN:
0/eps(0)
0/0
Being "very close to zero" is not sufficient.
Sahas
on 8 Aug 2024
And, just for good measure, anything nonzero divided by 0 produces a signed Inf, not NaN.
eps(0)/0
realmax/0
ADDENDUM:
(1)/(-0)
(-1/0)
(-1)/(-0)
NOTA BENE: the sign is based on the sign of the quotient; the (-0) in the denominator is also significant. This can be helpful in some branch analyses...
And, just for good measure, anything nonzero divided by 0 produces Inf, not NaN
To be technically correct it produces an infinite value, not necessarily positive Inf.
y = (-1)/0
There are three non-finite values in MATLAB: Inf, -Inf, and NaN. Those are the values for which the built-in isfinite function will return false, but only the first two will have isinf return true.
x = [1; Inf; -Inf; NaN; 5];
fin = isfinite(x);
infinite = isinf(x);
results = table(x, fin, infinite, VariableNames = ["value", "is finite", "is infinite"])
dpb
on 8 Aug 2024
OK, Steven, you're correct...I didn't mean to imply all would return +Inf...I added the (I thought implied) "signed".... :)
Alexandra
on 9 Aug 2024
You don't neceessarily have to divide by zero to get an infinite value, either...anything that would produce a result greater than the magnitude of realmax or less than realmin will do...division, multiplication or a function like an exponential with positive magnitude...
exp(709)
exp(710)
Answers (0)
Categories
Find more on Data Type Identification 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!