Monday 15 March 2010

matlab - Calculate a "running" maximum of a vector -



matlab - Calculate a "running" maximum of a vector -

i have next matrix keeps track of starting , ending points of info ranges (the first column represents "starts" , sec column represents "ends"):

mymatrix = [ 162 199; %// represents range 162:199 166 199; %// represents range 166:199 180 187; %// , on... 314 326; 323 326; 397 399; 419 420; 433 436; 576 757; 579 630; 634 757; 663 757; 668 757; 676 714; 722 757; 746 757; 799 806; 951 953; 1271 1272 ];

i need eliminate ranges (ie. rows) contained within larger range nowadays in matrix. illustration ranges [166:199] , [180:187] contained within range [162:199] , thus, rows 2 , 3 need removed.

the solution thought of calculate sort of "running" max on sec column subsequent values of column compared determine whether or not need removed. implemented utilize of for loop follows:

currentmax = mymatrix(1,2); %//set first value maximum [sizeofmatrix,~] = size(mymatrix); %//determine number of rows rowstoremove = false(sizeofmatrix,1); %//pre-allocate final vector of logicals m=2:sizeofmatrix if mymatrix(m,2) > currentmax %//if new max reached, update currentmax... currentmax = mymatrix(m,2); else rowstoremove(m) = true; %//... else mark row removal end end mymatrix(rowstoremove,:) = [];

this correctly removes "redundant" ranges in mymatrix , produces next matrix:

mymatrix = 162 199 314 326 397 399 419 420 433 436 576 757 799 806 951 953 1271 1272

onto questions:

1) seem there has improve way of calculating "running" max for loop. looked accumarray , filter, not figure out way functions. there potential alternative skips for loop (some kind of vectorized code more efficient)?

2) there different (that is, more efficient) way accomplish final goal of removing ranges contained within larger ranges in mymatrix? don't know if i'm over-thinking whole thing...

approach #1

bsxfun based brute-force approach -

mymatrix(sum(bsxfun(@ge,mymatrix(:,1),mymatrix(:,1)') & ... bsxfun(@le,mymatrix(:,2),mymatrix(:,2)'),2)<=1,:)

few explanations on proposed solution:

compare starts indices against each other "contained-ness" , ends indices. note "contained-ness" criteria has either of these 2 :

greater or equal starts , lesser or equal ends lesser or equal starts , greater or equal ends.

i happen go first option.

see rows satisfy @ to the lowest degree 1 "contained-ness" , remove have desired result.

approach #2

if okay output has sorted rows according first column , if there lesser number of local max's, can seek alternative approach -

mymatrix_sorted = sortrows(mymatrix,1); col2 = mymatrix_sorted(:,2); max_idx = 1:numel(col2); while 1 col2_selected = col2(max_idx); n = numel(col2_selected); labels = cumsum([true ; diff(col2_selected)>0]); idx1 = accumarray(labels, 1:n ,[], @(x) findmax(x,col2_selected)); if numel(idx1)==n break; end max_idx = max_idx(idx1); end out = mymatrix_sorted(max_idx,:); %// desired output

associated function code -

function ix = findmax(indx, s) [~,ix] = max(s(indx)); ix = indx(ix); return;

matlab matrix vectorization

No comments:

Post a Comment