Примечание. Я не даю новый ответ, но сравниваю предложенные ответы.
Вариант A: использование bsxfun()
function xn = normalizeBsxfun(x)
mn = mean(x);
sd = std(x);
sd(sd==0) = eps;
xn = bsxfun(@minus,x,mn);
xn = bsxfun(@rdivide,xn,sd);
end
Вариант B: использование цикла for
function xn = normalizeLoop(x)
xn = zeros(size(x));
for ii=1:size(x,2)
xaux = x(:,ii);
xn(:,ii) = (xaux - mean(xaux))./mean(xaux);
end
end
Мы сравниваем обе реализации для разных размеров матрицы:
expList = 2:0.5:5;
for ii=1:numel(expList)
expNum = round(10^expList(ii));
x = rand(expNum,expNum);
tic;
xn = normalizeBsxfun(x);
ts(ii) = toc;
tic;
xn = normalizeLoop(x);
tl(ii) = toc;
end
figure;
hold on;
plot(round(10.^expList),ts,'b');
plot(round(10.^expList),tl,'r');
legend('bsxfun','loop');
set(gca,'YScale','log')
Результаты показывают, что для маленьких матриц bsxfun
быстрее. Но, разница пренебрежима для более высоких измерений, как это было также найдено в других post .
Ось X - это квадратный корень числа матричных элементов, а ось Y - время вычисления в секундах.