Я пишу приложение Matlab, которое вычисляет какую-то матрицу. Я пытаюсь заменить циклы for в моей программе на основе векторных вычислений, однако, я застрял.Как векторизовать цикл 'for' в Matlab
До сих пор я понял, что это просто образец часть кода:
kernel = zeros(5,5,5);
offset = 3;
sig=1;
for x=-2:2
for y=-2:2
for z=-2:2
IN = x.^2/(sig^2) + y.^2/(sig^2) + z.^2/(sig^2);
kernel(offset+x, offset+y, offset+z) = exp(-IN/2);
end
end
end
можно заменить такой конструкции:
[x,y,z] = ndgrid(-2:2,-2:2,-2:2);
IN = x.^2/(sig^2) + y.^2/(sig^2) + z.^2/(sig^2);
kernel = exp(-IN/2);
и дают одинаковые результаты. Но что, если мне нужно сделать некоторые небольшие изменения:
kernel = zeros(5,5,5);
offset = 3;
sig=1;
%sample 3x3 matrix
R=magic(3)/10;
for x=-2:2
for y=-2:2
for z=-2:2
% calculation of new x, y, z
point = [x,y,z]*R;
IN = (point(1)^2)/(sig^2) + (point(2)^2)/(sig^2) + (point(3)^2)/(sig^2);
kernel(offset+x, offset+y, offset+z) = exp(-IN/2);
end
end
end
Как я могу ускорить эту конструкцию? Можно ли легко векторизовать? Я совершенно новичок в Matlab, поэтому я был бы признателен за любую помощь. Большое спасибо!
Отличный ответ, спасибо! Работает как шарм. Странно, однако, цикл работает в несколько раз быстрее в этом случае ... Очевидно, arrayfun слишком оптимизирован. – user3299285
@ user3299285 Для меня версия arrayfun была намного быстрее. Многое зависит от того, сколько у вас циклов и сколько работы вы выполняете на каждой итерации. Для такой маленькой петли (всего 27 итераций) ее очень быстро начать с абсолютных значений, так что ее не так много. Кроме того, норма берет квадратный корень (который медленнее по сравнению с другими арифметическими операциями) только для того, чтобы возвращаться назад и сразу округлять результаты. Если вы хотите лучше сравнить скорость цикла vs arrayfun, замените тело цикла той же функцией, что и arrayfun. –
Боюсь, я не могу согласиться. Даже с заменой тела на ту же функцию я получил лучшие результаты, чем с arrayfun. Кажется, что arrayfun действительно не слишком быстро: http://stackoverflow.com/questions/12522888/arrayfun-can-be-significantly-slower-than-an-explicit-loop-in-matlab-why – user3299285