フィルターのクリア

How can I make this code faster?

2 ビュー (過去 30 日間)
Sherwin
Sherwin 2016 年 12 月 27 日
コメント済み: per isakson 2016 年 12 月 29 日
Hi, I have a cell array, like the attached image, named SA.
In each column of this array, I want to select the cells that are not empty, two by two (for eachmple if there are 3 cells in a column which are not empty, we have 3C2=3 selections, 1&2,1&3,2&3) and compare the elements of these two selected cells in a way that each element of the first cell is compared to all of the elements of the second selected cell then each time the absolute difference is less than 2 one unit is added to S. This is done for the second and rest of the elements of the first cell and when all of the nonempty cells in a column are compared the whole procedure is repeated for the next columns. I'm so sorry about the poor explanation. So here is my code for the aforementioned procedure, maybe it helps.
S = 0;
for p = 1:9 %Each Column of SA
for b = 1:8 %Each Row of SA
for j = 1:8 % Another Row
if j>b %If the second selected row number is greater than the first
if numel(SA{b,p})~= 0 && numel(SA{j,p})~= 0 %and if none of the cells are empty
for m = 1:numel(SA{b,p}) %select one element from the first cell
for n = 1:numel(SA{j,p}) % and one element from the second cell
if abs(SA{b,p}(m)- SA{j,p}(n)) <= 2 %if the difference is less than 2
S = S +1; % add one unit to S
end
end
end
end
end
end
end
end
As you can guess this code needs a lot of time to run. So are there any other faster ways to code this? Thank you so much in advance. P.S. There are 9 columns and 8 rows in SA. mat-file is atached.
  2 件のコメント
per isakson
per isakson 2016 年 12 月 28 日
編集済み: per isakson 2016 年 12 月 28 日
  • The chance to get an answer increases if you upload a mat-file, which contains SA
  • Am I correct that the input of your code is SA and the output is S ?
Sherwin
Sherwin 2016 年 12 月 28 日
編集済み: Sherwin 2016 年 12 月 28 日
Thank you so much, yes you are right. S is calculated according to the SA array using the explained procedure. and, I'll attach it right away, thank you.

サインインしてコメントする。

採用された回答

per isakson
per isakson 2016 年 12 月 28 日
編集済み: per isakson 2016 年 12 月 28 日
I've done three things
  • Put the code in a function, because I'm more comfortable with functions than with scripts
  • Removed the references to cell arrays from the inner loops. That increases the speed an order of magnitude. See SAbp = SA{b,p};.
  • Vectorized the innermost loop, which doubles the speed.
function [ S, S1 ] = cssm( SA )
S = 0;
S1 = 0;
for p = 1:9 %Each Column of SA
for b = 1:8 %Each Row of SA
SAbp = SA{b,p};
for j = 1:8 % Another Row
SAjp = SA{j,p};
if j>b %If the second selected row number is greater than the first
if numel(SAbp)~= 0 && numel(SAjp)~= 0 %and if none of the cells are empty
for m = 1:numel(SAbp) %select one element from the first cell
% for n = 1:numel(SAjp) % and one element from the second cell
% le2 = abs(SAbp(m)- SAjp(n)) <= 2;
% if le2 %if the difference is less than 2
% S = S +1; % add one unit to S
% end
% end
S1 = S1 + sum( double( abs( SAbp(m) - SAjp ) <= 2 ) );
end
end
end
end
end
end
end
Run with and without the innermost loop
>> tic, [ S, S1 ] = cssm( SA ), toc
S =
0
S1 =
19119
Elapsed time is 0.031820 seconds.
Note that tic,toc and profile show different results of the comparisons of speed between the different versions of the code. I think that's because the "JIT/Accelerator" is less aggressive when profile is running.
  4 件のコメント
Sherwin
Sherwin 2016 年 12 月 28 日
I can't thank you enough. I am so grateful.
per isakson
per isakson 2016 年 12 月 29 日
I'm glad to hear that my answer is useful, thanks!

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeLogical についてさらに検索

タグ

Community Treasure Hunt

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

Start Hunting!

Translated by