Using "find" for finding decimal values
Show older comments
Hi
I use the matlab command importdata:
X = importdata('filename.csv');
to read in a csv file with three columns.
Now, for finding a specific values in the matrix X, I simple use the find command as follows:
idx = find(X(:,1 ) == 17)
But, the same seems not to be possible for decimal numbers. This for instance would not work:
idx = find(X(:,1 ) == 17.9203)
even though 17.9203 is to be found in the original csv file. What is the problem and what can I do?
Thanks
Accepted Answer
More Answers (4)
Azzi Abdelmalek
on 13 Dec 2012
Try
idx = find(abs(X(:,1 )-17.9203)<eps)
2 Comments
Substracting two numbers in the magnitude of 20 can have a roundoff error of eps(20). Then this is better:
idx = find(abs(X(:,1 ) - 17.9203) <= eps(17.9203)) % EDITED: was "<"
Even 10*eps(17.9203) would be a reliable limit.
[EDITED] Thanks, Kye. I cannot test this currently. But I assume that even "<=" can fail, when the values are at the limits of 2^n. Does eps(16 + eps(16)) reply eps(32)? Then a factor of 2 would be obligatory.
Kye Taylor
on 13 Dec 2012
should be <=
There is no exact representation of decimal floating point numbers in binary format for all values. You find a lot of corresponding discussion in this forum:
0.1 + 0.2 - 0.3 == 0
>> false
This is no bug, but the expected behaviour, when floating point numbers are represented with a limited precision.
A consequence is, that you cannot compare numbers like 17.9203 and 17.92029999999999999999 sufficiently and even the display in the command window can be rather confusing.
MiauMiau
on 13 Dec 2012
7 Comments
Azzi Abdelmalek
on 13 Dec 2012
What do you get when you type
min(abs(X(:)-17.9203))
MiauMiau
on 13 Dec 2012
Please do not post "a very small number" but the actual value. And the source of this small number has been explained already.
Differences between two numbers a and b can have a round-off error of eps(max(a, b)). Therefore checking < eps(17.9203) is not sufficient, because you need at least "<=", but an additional factor of 2 or 16 is more likely to match your needs reliably.
These effects are not horrible. They should be explained exhaustively in the very first lesson for numerical computations. Limited accuracy is not only an effect in applied numerics but you find this in the nature of physical effects also. The number of physical effects which are well defined for more than 15 significant digits is extremely small.
Azzi Abdelmalek
on 13 Dec 2012
It's obvious to find find(min(abs(X(:,1)-12.8487))) equal to 1, because min(abs(X(:,1)-12.8487)) is a scalar. Finding a very smal number, means that the number 12.8487 exists in your matrix, and for problems caused by how matlab stores numbers, you can't get, sometimes, the exact equality.
@Azzi: This is not a problem of Matlab. The IEEE-754 standard for the type double is well established and used in almost all numerical programming environments, e.g. it is hard coded in the processor architectures except for a small number of exceptions (I assume Walter knows some). You will find exactly the same effects, when you program this in C, FORTRAN, Haskel, VisualBasic or directly in machine code.
Azzi Abdelmalek
on 13 Dec 2012
Yes, I said Matlab because we are working with Matlab. I think, representing real numbers for numerical programming is almost similar to what an ADC (analogic-digital converter) do. There is a quantification of a real number, which means there is an error of quantification which depends on the number of used bits and method.
Jan
on 13 Dec 2012
@Azzi: I've stressed this detail, because the OP seems to be confused about this topic already. I did not assume, that you struggle with floating point arithmetics.
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!