Оптимизация l oop: простые операции, но большое количество итераций занимает много времени - PullRequest
0 голосов
/ 04 февраля 2020

Я выполняю фрагмент кода Matlab, который занимает почти 70 часов, и я уверен, что есть более эффективный способ его написания, но я не могу понять, как это сделать. Цикл за 1 итерацию занимает 1 секунду. Проблема, конечно, в том, что длина (i) равна 186144.

braindip = normrnd(0, 50, 186144,3);
nobrain = normrnd(0, 45, 25014656,3);

ok = 1; 
alpha = 2;
h = waitbar(0,'Please wait...');
dip_away = nan(size(braindip));
for i = 1:size(braindip,1)
  tic
  h_norm = repmat(braindip(i,:), size(nobrain,1),1);
  nn = sqrt(sum((h_norm - nobrain).^2,2));

  if min(nn) > alpha
    dip_away(ok,:) = braindip(i,:);
    ok = ok+1;
  end
  toc
  waitbar(i / size(braindip,1))
end

Есть ли у кого-нибудь умное предложение для оптимизации этого l oop? Огромное спасибо!

1 Ответ

0 голосов
/ 04 февраля 2020

Предполагая, что вы используете MATLAB 2016b или более позднюю версию, которая поддерживает автоматическое вещание c, вы можете изменить:

h_norm = repmat(braindip(i,:), size(nobrain,1),1);
nn = sqrt(sum((h_norm - nobrain).^2,2));

на

nn = sqrt(sum((braindip(i,:) - nobrain).^2,2));

Второй вариант: устранить sqrt. Используйте:

nn_qbd = sum((braindip(i,:) - nobrain).^2,2);
if min(nn_qbd) > alpha_qbd

Где alpha_qbd=alpha.^2, очевидно, рассчитывается только один раз заранее. Это приводит к третьему шагу, нет необходимости хранить nn_qbd в переменной. Вас интересует только минимум:

nn_qbd_min = min(sum((braindip(i,:) - nobrain).^2,2));
if nn_qbd_min > alpha_qbd

При сравнении исходного кода с третьим вариантом время выполнения примерно сокращается вдвое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...