Wednesday 15 January 2014

performance - Count the number of rows between each instance of a value in a matrix -



performance - Count the number of rows between each instance of a value in a matrix -

assume next matrix:

mymatrix = [ 1 0 1 1 0 0 1 1 1 1 1 1 0 1 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 ];

given above (and treating each column independently), i'm trying create matrix contain number of rows since lastly value of 1 has "shown up". example, in first column, first 4 values become 0 since there 0 rows between each of rows , previous value of 1.

row 5 become 1, row 6 = 2, row 7 = 3, row 8 = 4. since row 9 contains 1, become 0 , count starts 1 time again row 10. final matrix should this:

finalmatrix = [ 0 1 0 0 2 1 0 0 0 0 0 0 1 0 0 2 1 1 3 2 2 4 0 3 0 1 4 1 2 5 2 3 6 3 4 0 4 5 0 5 6 0 ];

what way of accomplishing this?

edit: i'm using next code:

[numrow,numcol] = size(mymatrix); onecolumn = 1:numrow; finalmatrix = repmat(onecolumn',1,numcol); tosubtract = zeros(numrow,numcol); m=1:numcol rowswithones = find(mymatrix(:,m)); mm=1:length(rowswithones); tosubtract(rowswithones(mm):end,m) = rowswithones(mm); end end finalmatrix = finalmatrix - tosubtract;

which runs 5 times faster bsxfun solution posted on many trials , info sets (which 1500 x 2500 in size). can code above optimized?

find + diff + cumsum based approach -

offset_array = zeros(size(mymatrix)); k1 = 1:size(mymatrix,2) = mymatrix(:,k1); widths = diff(find(diff([1 ; a])~=0)); idx = find(diff(a)==1)+1; offset_array(idx(idx<=numel(a)),k1) = widths(1:2:end); end finalmatrix1 = cumsum(double(mymatrix==0) - offset_array); benchmarking

the benchmarking code comparing above mentioned approach against 1 in question listed here -

clear mymatrix = round(rand(1500,2500)); %// create random input array k = 1:50000 tic(); elapsed = toc(); %// warm tic/toc end disp('------------- find+diff+cumsum based approach') %//'# tic offset_array = zeros(size(mymatrix)); k1 = 1:size(mymatrix,2) = mymatrix(:,k1); widths = diff(find(diff([1 ; a])~=0)); idx = find(diff(a)==1)+1; offset_array(idx(idx<=numel(a)),k1) = widths(1:2:end); end finalmatrix1 = cumsum(double(mymatrix==0) - offset_array); toc clear finalmatrix1 offset_array idx widths disp('------------- original approach') %//'# tic [numrow,numcol] = size(mymatrix); onecolumn = 1:numrow; finalmatrix = repmat(onecolumn',1,numcol); %//'# tosubtract = zeros(numrow,numcol); m=1:numcol rowswithones = find(mymatrix(:,m)); mm=1:length(rowswithones); tosubtract(rowswithones(mm):end,m) = rowswithones(mm); end end finalmatrix = finalmatrix - tosubtract; toc

the results got -

------------- find+diff+cumsum based approach elapsed time 0.311115 seconds. ------------- original approach elapsed time 7.587798 seconds.

performance matlab matrix

No comments:

Post a Comment