MATLAB Answers

Subtraction of 2 matrices of the same dimensions and values, gives large floating point values instead of 0!

Hello,
I have a question on something that is seemingly simple but i can't figure out where i may have gone wrong.
I am working on EEG signal analysis and modelling . My task is to test the accuracy of Interpolation of an EEG data with all working electrodes against an EEG data that is produced with broken/damaged electrodes.
The test of accuracy is given by a factor called RDM and its following formula (According to Meijs, et. al 1989)
% Relative difference measure
function rdm = calc_rdm(m1, m2)
M1=norm(m1);
M2=norm(m2);
rdm = norm((m1/M1)-(m2/M2));
end
This function works well with regular integers and floating point values with rand too! But when i enter my data( column vectors of same dimensions), until the line m1/M1 and m2/M2 , everything works fine . At the subtraction is where i get values like e-17 instead of a 0! Here is a Minimum Working Example:
m1= m2 =
0.0010
0.0035
-0.0045
0.0016
0.0005
-0.0027
-0.0010
0.0005
0.0069
0.0053
-0.0027
0.0058
0.0014
-0.0001
0.0013
-0.0005
-0.0003
0.0030
0.0037
0.0027
0.0013
-0.0024
0.0014
0.0032
0.0009
0.0020
0.0014
-0.0003
0.0006
-0.0015
0.0018
-0.0021
rdm= 1.43e-16
For simplicity, i set both vectors to the same values. After checking the code step by step, i figure that the subtraction of the two matrices gives these values!
Any inputs will be appreciated. Thank you!!

  0 Comments

Sign in to comment.

2 Answers

Answer by Rik
on 10 Apr 2019
Edited by Rik
on 10 Apr 2019
 Accepted Answer

Welcome to the world of floating point calculation. Computers store values in binary, which sometimes requires rounding. This rounding can result in values being different in the last bit, where they should be the same. This then results in a value on the order of when it should be 0.
This is the reason why you shouldn't always use == to test for equality, and why functions like uniquetol and ismembertol exist.

  7 Comments

My input data is in the order of e-4! While comparing 2 vectors/matrices i am suppsoed to get an error in terms of RDM perhaps something in the range of e-2 or e-3. Until the matrix division the values were still in the order of e-04 but once i subtracted accroding to the formula above, the result displayed a vector in the range of e-16!
Thanks!
Nothing unexpected there, if you subtract numbers of the same magnitude, expect to get very small numbers. Again if the result is around 1e-16 when you started with something around 1e-4 it means it's 0.
values = repelem(1e-4, 1, 10); %10 values of magnitude 1e-4
othervalue = 1e-3; %another value of magnitude 1e-3
>>sum(values) - othervalues
ans =
2.16840434497101e-19
The two values are very close to each other, but not exactly equal due to the limited precision of floating point numbers. So what you're seeing instead of zero, is the accumulated error.

Sign in to comment.


Answer by Guillaume
on 10 Apr 2019

"gives large floating point values"
" i get values like e-17"
1e-17 is 0.00000000000000001, that's not large!. That's 15 orders of magnitude smaller than the numbers you started with and only about 50 times larger than the precision of these numbers (eps(0.001) is ~2e-19). What you get is expected, floating point numbers have limited precision and when you combine them small inaccuracies add up. For example, see:
>>0.1 + 0.1 + 0.1 - 0.3
ans =
5.5511e-17
When the magnitude of the result is so much smaller than the numbers you started with, you can consider it 0.

  2 Comments

Thank you! But what if the column vectors are of different values this time and i still get the result in the range of e-16? I mean if i drop more electrodes out, at some point i would expect an error albeit small! Is there any simple way of calling precise values? Can i use round(x,N)?
It's all to do with the magnitude of the numbers. If your numbers are around 1e-2, then their precision is around 2e-19, so any result of that magnitude can be considered 0. If your numbers start around 1e-10, then the precision is around 1-e26, so I'd consider any number below 1e-23 the same as 0.
You can find the precision of your numbers with eps. In your case, I'd use the eps of the maximum of your vectors to give you an idea of the precision of your result
if abs(rdm) < 1000 * eps(max([m1; m2])) %magnitude is so small to be the same as 0
rdm = 0;
end

Sign in to comment.