Precision of numbers problem (I think)
4 views (last 30 days)
Show older comments
I have a matrix with 4 columns. I'd like to do something very simple, which is average all numbers in Column 4 given specific numbers in Column 2 but I end up with NaNs for 2 of the 7 means with the code below.
I have a sample "new_data.mat" attached.
This is the Matlab script I'm trying to get to work (rounding alone has not solved the problem):
clear all; clc; close all
alldir = dir(['SS*']);
P = pwd;
for d = 1:size(alldir,1)
PathName = [P, '\', alldir(d).name, '\Behaviour\'];
cd(PathName)
FileName = dir('ID*_PRIM_beh_all.mat');
new_data = cell2mat(struct2cell(load(FileName.name))); % example in my dropbox linked above
phys_diffs = 0:.15:.90;
for k = 1:7
step = phys_diffs(k);
avgdiffRT(k) = mean(new_data(new_data(:, 2) == step, 4));
end
alldiffRT(d, :) = avgdiffRT;
end
If I use the function "round" and take the loop out, i.e. average each of the 7 steps "manually" it works:
rounded = round(new_data(:, 2), 2);
avgRTphysdiff1 = mean(new_data(rounded == 0, 4));
avgRTphysdiff2 = mean(new_data(rounded == .15, 4));
etc
Does somebody have an idea how to get the loop to work?
1 Comment
Stephen23
on 1 Oct 2021
Edited: Stephen23
on 1 Oct 2021
"Does somebody have an idea how to get the loop to work?"
Do NOT use ROUND. It is not a robust approach, and should be avoided.
Nor should you compare for exact equivalence of floating point numbers, e.g. using EQ or ISMEMBER.
The simple, robust, recommended approach is to compare the absolute difference against a tolerance:
tol = 1e-5; % pick the tolerance to suit your needs.
abs(A-B)<tol
Answers (1)
Konrad
on 1 Oct 2021
Hi Phillip,
yes, it has to do with precision.
ismember(phys_diffs,new_data(:,2))
% ans =
% 1×7 logical array
% 1 0 1 1 1 1 0
This shows that the 2nd and the last value in phy_diffs (.15 and .9) do not appear in new_data(:,2). (And the mean of nothing is NaN)
But values very close to these two numbers do appear. So what you could do is to round new_data(:,2), e.g. to two digits:
idx = round(new_data(:, 2),2) == step;
avgdiffRT(k) = mean(new_data(idx, 4));
Regards, Konrad
See Also
Categories
Find more on Logical 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!