开发者

Fast technique for normalizing a matrix in MATLAB

I want to normalise each column of a matrix in Matlab. I have tried two implementations:

Option A:

mx=max(x);
mn=min(x);
mmd=mx-mn;
for i=1:size(x,1)
    xn(i,:)=((x(i,:)-mn+(mmd==0))./(mmd+(mmd==0)*2))*2-1; 
end

Option B:

mn=mean(x);
sdx=std(x);
for i=1:size(x,1)
    xn(i,:)=(x(i,:)-mn)./(sdx+(sdx==0));
end

However, these options take too much time for my data, e.g. 3-4 seconds on a 5000x53 mat开发者_如何学编程rix. Thus, is there any better solution?


Use bsxfun instead of the loop. This may be a bit faster; however, it may also use more memory (which may be an issue in your case; if you're paging, everything'll be really slow).

To normalize with mean and std, you'd write

mn = mean(x);
sd = std(x);
sd(sd==0) = 1;

xn = bsxfun(@minus,x,mn);
xn = bsxfun(@rdivide,xn,sd);


Remember, in MATLAB, vectorizing = speed.

If A is an M x N matrix,

A = rand(m,n);
minA = repmat(min(A), [size(A, 1), 1]);
normA = max(A) - min(A);               % this is a vector
normA = repmat(normA, [length(normA) 1]);  % this makes it a matrix
                                       % of the same size as A
normalizedA = (A - minA)./normA;  % your normalized matrix


Note: I am not providing a freshly new answer, but I am comparing the proposed answers.

Option A: Using 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

Option B: Using a for-loop

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

We compare both implementations for different matrix sizes:

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') 

The results show that for small matrices, the bsxfun is faster. But, the difference is neglect able for higher dimensions, as it was also found in other post.

Fast technique for normalizing a matrix in MATLAB

The x-axis is the squared root number of matrix elements, while the y-axis is the computation time in seconds.


Let X be a m x n matrix and you want to normalize column wise.

The following matlab code does it

XMean = repmat(mean(X),m,1);
XStd = repmat(std(X),m,1);
X_norm = (X - XMean)./(XStd);

The element wise ./ operator is explained here: http://www.mathworks.in/help/matlab/ref/arithmeticoperators.html

Note: As op mentioned, this is simply a faster solution and performs the same task as looping through the matrix. The underlying implementation of this inbuilt function makes it work faster


Note: This code works in Octave and MATLAB versions R2016b or higher.

function X_norm = normalizeMatrix(X)      
      mu = mean(X); %mean    
      sigma = std(X); %standard deviation   
      X_norm = (X - mu)./sigma;    
end


How about using

normc(X)

that would normalize the matrix X columnwise. You need to include the Neural Network Toolbox in your install though.


How about this?

A = [7, 2, 6; 3, 8, 4]; % a 2x3 matrix

Asum = sum(A); % sum the columns

Anorm = A./Asum(ones(size(A, 1), 1), :); % normalise the columns

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜