My code does does not go through the the if section

1 visualización (últimos 30 días)
Behrooz Daneshian
Behrooz Daneshian el 18 de En. de 2023
Comentada: Torsten el 19 de En. de 2023
Hi all,
I am pretty sure that in column 1 of Coefficient matrix (Coefficient(1:26,1)) there is value equal to Alpha(my input parameter). I wondering why my cod does not go through the if section. Can anyone tell me what is going wrong here?
clear
close all
clc
load("Coefficient.mat")
Alpha=0.8;
Mu=9;
Alpha_vector=Coefficient(:,2)+Coefficient(:,3)*Mu+Coefficient(:,4)*(Mu^2)+Coefficient(:,5)*(Mu^3)+Coefficient(:,6)*(Mu^4)...
+Coefficient(:,7)*(Mu^5)+Coefficient(:,8)*(Mu^6);
[wasfound, idx] = ismember(Alpha, Coefficient(1:26,1));
if wasfound
landa = Alpha_vector(idx);
else
do other stuff
end

Respuesta aceptada

John D'Errico
John D'Errico el 18 de En. de 2023
Rule # 1: NEVER test for exact equality of floating point numbers. (At least unless you fully, completely absolutely understand floating point representations.)
Rule # 2: There ain't no rule 2.
Welcome to the wonderful wacky world of floating point arithmetic, where what looks like a number that you know and recognize is not always the case.
Effectively in your code, you are looking for an EXACT match to the number 0.8. You do recognize of course that 0.8 is not reepresentable exactly as a double precision number? This is because MATLAB (as well as almost all other languages) use an IEE floating point representation for doubles, that encodes the numbers in a BINARY form.
For example, what is the EXACT value of 2/3, when represented as a decimal, in a finite number of decimal digits? I am sure you would accept that 0.6666 is not the value, nor is 0.6667. And as many digits as you wish to take, you will ner get an exact match. This is because 2/3 lacks a finite, terminating expansion in a decimal form.
So do you assume that 0.8 has such an expansion in binary? (NO, it does not.) Instead, MATLAB uses the closest approximation it can find using 52 binary bits of precision. It will be close, but not exactly the case. So in fact, 0.8, in binary form is an infinitely repeating binary number of this form:
0.11001100110011001100110011001100110011001100110011001100...
MATLAB actually stores it as effectively this value:
0.11001100110011001100110011001100110011001100110011010
Do you see that MATLAB has been forced to approximate the infintely repeating binary form as a finite form?
What is worse of course is then every computation you do with these approximate values as stored as doubles then can accumulate into larger errors in the least significant bits. (Luckily the law of large numbers tends to work in your favor to cancel any errors out.)
So what can you do? USE A TOLERANCE. ALWAYS. That is, whenever you would be testing for exact equality of two floating point numbers, DON'T. See rule 1.
  4 comentarios
Behrooz Daneshian
Behrooz Daneshian el 19 de En. de 2023
Thank you much. I learned a lot from you.
I made my code more efficient.
clear
close all
clc
load("Coefficient.mat")
Alpha=6;
Mu=.1;
Alpha_vector=Coefficient(:,2)+Coefficient(:,3)*Mu+Coefficient(:,4)*(Mu^2)+Coefficient(:,5)*(Mu^3)+Coefficient(:,6)*(Mu^4)...
+Coefficient(:,7)*(Mu^5)+Coefficient(:,8)*(Mu^6);
Mu_max=[10 10 10 10 10 9 8 sqrt(42) sqrt(30) 5 sqrt(20) sqrt(12) 3 sqrt(6) 2.1040 1.6818 1.4142 0.9487 0.7483 0.6...
0.4472 0.4 0.3464 0.27 0.22 0.1414];
lambda_min=[0.57 0.46 0.4 0.35 0.32 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3];
for k=1:length(Coefficient(:,1))
if ismembertol(Alpha, Coefficient(k,1), 1e-8) && Mu>=Mu_max(k)
lambda=landa_min(k);
elseif ismembertol(Alpha, Coefficient(k,1), 1e-8) && Mu<Mu_max(k)
lambda=Alpha_vector(k);
elseif Alpha>Coefficient(k,1) && Alpha<Coefficient(k+1,1) && Mu>=Mu_max(k)
lambda=landa_min(k);
elseif Alpha>Coefficient(k,1) && Alpha<Coefficient(k+1,1) && Mu<Mu_max(k)
Lambda=interp1([0:0.1:1, 1.2:0.2:2, 2.5:0.5:6, 7, 8], Alpha_vector, Alpha);
end
end
Torsten
Torsten el 19 de En. de 2023
Be careful.
Change the remaining "landa_min" to "lambda_min" and "Lambda" to "lambda" (MATLAB is case sensitive !).

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Data Type Identification en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by