How to replace zeros with other value in a big matrix fast

13 views (last 30 days)
Hi all, I have a programming efficiency question. I would like to replace zero value of a big matrix with mean value of it. I know how to do it.However, it takes forever. I do not know if I did it wrong or it actually takes so much time. I am wondering if there is a better way to do it for a big matrix as big as 3320*3320. Here is my code. Assume A is the 3320*3320 matrix. I wrote only
A(A==0)=mean(mean(A));
Please let me know if I did it wrong. If I did it right, can somebody suggest any faster way to do the same thing ? Thank you very much,

Accepted Answer

Matt Fig
Matt Fig on 14 Apr 2011
Don't double call these functions (MAX,MIN,SUM,MEAN,etc.). Learn to use the colon, it is your friend!
A(~A(:))=mean(A(:));
This will be somewhat faster. If you need even more speed, replace the call to mean with its definition.
A(~A(:)) = sum(A(:))/numel(A);
The thing is, with a very large array, it might just take some time!
Here is how I timed these, BTW. You can play around with other options as well! Run the function 3 times (the first time warms it up after a save). The time will print to the command window.
function [] = write_ones()
T1 = 0; % Time two different approches
T2 = 0;
for ii = 1:5
A = round(rand(3320))>.75;
tic
A(A==0)=mean(mean(A));
T1 = T1 + toc;
clear A
A = round(rand(3320))>.75; % A new A.
tic
A(~A(:)) = sum(A(:))/numel(A);
T2 = T2 + toc;
end
[T1 T2]
  7 Comments
Jan
Jan on 15 Apr 2011
James' Mex function profits from omitting the boundary checks, while Matlab seems to check the boundary for each single index - even for logical indexing. See http://www.mathworks.com/matlabcentral/newsreader/view_thread/295653 . Therefore a Mex can create partial copy using logical indexing about 3 times faster than in Matlab (Matlab 2009a, MSVC, even small arrays).

Sign in to comment.

More Answers (1)

Teja Muppirala
Teja Muppirala on 15 Apr 2011
Matt, I had originally thought the same thing (using a colon on the right hand side also might be faster), but I'm not able to reproduce your results: I consistently get that the second case is faster. (0.18s vs 0.15s)
function colontest
A = rand(3320); A(A < 0.9) = 0; B = A+0;
tic; A(~A(:)) = sum(A(:))/numel(A); toc;
tic; B(B == 0) = mean(mean(B)); toc;
  5 Comments
Jan
Jan on 15 Apr 2011
My observations suggest that MEAN(X) is parallelized in modern Matlab version: The columns are processed in different threads for large matrices, while MEAN(X(:)) seems to run in a single thread. Therefore MEAN(MEAN(X)) can be faster.
Andrei Bobrov
Andrei Bobrov on 15 Apr 2011
Dear Jan, my "research" :)
1. compare mean(...(:)) and mean(mean(...)) ->
>> A = +(round(rand(5000))>.75);tic,A(A(:)==0) = mean(mean(A));toc
Elapsed time is 0.528957 seconds.
>> A = +(round(rand(5000))>.75);tic,A(A(:)==0) = mean(A(:));toc
Elapsed time is 0.528977 seconds.
2. compare use '~' and '==' ->
>> A = +(round(rand(5000))>.75);tic,A(~A) = mean(mean(A));toc
Elapsed time is 0.669978 seconds.
>> A = +(round(rand(5000))>.75);tic,A(A==0) = mean(mean(A));toc
Elapsed time is 0.531413 seconds...

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!