How to improve my inefficient code?
조회 수: 1 (최근 30일)
이전 댓글 표시
Hi all,
I have a 21x288 table (attached).
I have a function that compares the variables and calculates the ICC (attached). For my purposes, I am running the following comparisons:
1 vs 2, 1 vs 3, 1 vs 4
5 vs 6, 5 vs 7, 5 vs 8
9 vs 10, 9 vs 11, 9 vs 12
and so on until the end of the table (numbers refers to columns)
I am planning to do so as below. Can this be done in a more efficient way?
load 'data'
data1=data(:,1:4:end); %get all data from data collection 1 into one table
data2=data(:,2:4:end); %get all data from data collection 2 into one table
data3=data(:,3:4:end); %get all data from data collection 3 into one table
data4=data(:,4:4:end); %get all data from data collection 4 into one table
%% Variable 1
% Comparison 1 (data collection 1 vs data collection 2)
p_acc_z_mean_1vs2=[data1(:,1),data2(:,1)];
p_acc_z_mean_1vs2 = table2array (p_acc_z_mean_1vs2);
[r_p_acc_z_mean_1vs2]=ICC(p_acc_z_mean_1vs2,'C-k',0.05,0.5);
% Comparison 2 (data collection 1 vs data collection 3)
p_acc_z_mean_1vs3=[data1(:,1),data3(:,1)];
p_acc_z_mean_1vs3 = table2array (p_acc_z_mean_1vs3);
[r_p_acc_z_mean_1vs3]=ICC(p_acc_z_mean_1vs3,'C-k',0.05,0.5);
% Comparison 3 (data collection 1 vs data collection 4)
p_acc_z_mean_1vs4=[data1(:,1),data4(:,1)];
p_acc_z_mean_1vs4 = table2array (p_acc_z_mean_1vs4);
[r_p_acc_z_mean_1vs4]=ICC(p_acc_z_mean_1vs4,'C-k',0.05,0.5);
%% Repeat the above for the remaining 71 variables
댓글 수: 4
Johan
2022년 3월 1일
편집: Johan
2022년 3월 1일
Maybe this would work for you ?
%transform your table in an array
workdata = table2array(data);
for i = 1:4:size(workdata,2)
for j = 1:3
%apply your function to your data comparing i column to i+j columns
[tosave] = ICC([workdata(:,i),workdata(:,i+j)],'C-k',0.05,0.5);
%storing the results in a structure
results(i).r_p_acc_z_mean(j) = tosave';
end
end
채택된 답변
Johan
2022년 3월 1일
편집: Johan
2022년 3월 1일
(modified from comment to get rid of empty rows)
Maybe this would work for you ?
%transform your table in an array
workdata = table2array(data);
k=1;
for i = 1:4:size(workdata,2)
for j = 1:3
%apply your function to your data comparing i column to i+j columns
[tosave] = ICC([workdata(:,i),workdata(:,i+j)],'C-k',0.05,0.5);
%storing the results in a structure
results(k).r_p_acc_z_mean(j) = tosave';
end
k=k+1;
end
댓글 수: 2
Johan
2022년 3월 1일
Yes my bad, I put the k=k+1 statement in the wrong for loop, I edited the answer above to fix it
추가 답변 (2개)
Jan
2022년 3월 1일
This is a first point to start from:
load 'data'
Calling load without catching the output creates variables dynamically. This can impede the JIT-acceleration massively can low down the code especially in loops. In addition it makes debugging much harder, because it is not visible in the code, if a specific name is a variable or a function.
Avoid hiding indices in the names of variables as in "p_acc_z_mean_1vs3". Use an array instead. Then you can call the variables in a loop using indices.
The JIT acceleration can suffer from changing the types of variables. Avoid to create a new table and convert it to an array using the same name:
p_acc_z_mean_1vs2 = [data1(:,1), data2(:,1)]; % Create 2 tables and join them
p_acc_z_mean_1vs2 = table2array (p_acc_z_mean_1vs2); % Expensive re-typing
A cheaper version:
p_acc_z_mean_1vs2 = data2{:,1:2}; % Numeric matrix in one step
Matt J
2022년 3월 1일
편집: Matt J
2022년 3월 1일
It would improve things modestly if you just convert all the data to an array from the get-go. It doesn't look like you're exploiting the features of table form in any way.
load 'data'
data=table2array(data);
data1=data(:,1:4:end); %get all data from data collection 1 into one table
data2=data(:,2:4:end); %get all data from data collection 2 into one table
data3=data(:,3:4:end); %get all data from data collection 3 into one table
data4=data(:,4:4:end); %get all data from data collection 4 into one table
However, I think the only significant gains that can happen is if you rewrite/vectorize ICC.m so that it processes many variables simultaneously, e.g.., to support syntax like this:
M=permute( cat(3,data1,data2) ,[1,3,2]);
out = ICC(M,'C-k',0.05,0.5);
댓글 수: 3
Matt J
2022년 3월 1일
Yes, because you haven't rewritten ICC.m ! You've just used it as if it is already ready to receive input in that form.
참고 항목
카테고리
Help Center 및 File Exchange에서 Logical에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!