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