Сделать цикл for в Matlab быстрее с помощью arrayfun? - PullRequest
3 голосов
/ 21 июня 2011

В настоящее время у меня есть следующая часть кода:

for i = 2:N-1
  res(i) = k(i)/m(i)*x(i-1) -(c(i)+c(i+1))/m(i)*x(N+i) +e(i+1)/m(i)*x(i+1);
end

где переменные k, m, c и e - векторы размера N, а x - вектор размера 2 * N. Есть ли способ сделать это намного быстрее, используя что-то вроде arrayfun !? Я не мог понять это :( Я особенно хочу сделать это быстрее, запустив позже графический процессор, и поэтому, arrayfun также был бы полезен, так как Matlab не поддерживает распараллеливание for-циклов, и я не хочу покупать оболочку пакет ... Большое спасибо!

Ответы [ 2 ]

6 голосов
/ 21 июня 2011

Вам не нужно использовать arrayfun.Это работает, если использовать какую-то умную индексацию:

    clear all

    N=20;
    k=rand(N,1);
    m=rand(N,1);
    c=rand(N,1);
    e=rand(N,1);
    x=rand(2*N,1);

    % for-based implementation
    %Watch out, you are not filling the first element of forres!
    forres=zeros(N-1,1); %Initialize array first to gain some speed.
    for i = 2:N-1
      forres(i) = k(i)/m(i)*x(i-1) -(c(i)+c(i+1))/m(i)*x(N+i) +e(i+1)/m(i)*x(i+1);
    end

    %vectorized implementation
    parres=k(2:N-1)./m(2:N-1).*x(1:N-2) -(c(2:N-1)+c(3:N))./m(2:N-1).*x(N+2:2*N-1) +e(3:N)./m(2:N-1).*x(3:N);

    %compare results; strip the first element from forres
    difference=forres(2:end)-parres %#ok<NOPTS>
5 голосов
/ 21 июня 2011

Во-первых, MATLAB поддерживает параллельные циклы через PARFOR . Тем не менее, это не имеет большого шанса ускорить такого рода вычисления, так как объем вычислений невелик по сравнению с объемом данных, которые вы читаете и пишете.

Чтобы реструктурировать вещи для GPUArray " arrayfun ", вам нужно сделать так, чтобы все ссылки на массивы в теле цикла ссылались на итерацию цикла, и чтобы цикл выполнялся по всему диапазону. Вы должны быть в состоянии сделать это путем смещения некоторых массивов и заполнения фиктивными значениями. Например, вы можете добавить все свои массивы к NaN и заменить x(i-1) новой переменной x_1 = [x(2:N) NaN]

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