matthiasm@8: function [x,n]=localmaxmin(y,xn) matthiasm@8: %LOCALMAXMIN(Y) Local Maxima and Minima. matthiasm@8: % X = LOCALMAXMIN(Y) or LOCALMAXMIN(Y,'max') for vector Y returns a logical matthiasm@8: % vector X the same size as Y such that Y(X) contains the local maxima in Y. matthiasm@8: % matthiasm@8: % N = LOCALMAXMIN(Y,'min') for vector Y returns a logical vector N the same matthiasm@8: % size as Y such that Y(N) contains the local minima in Y. matthiasm@8: % matthiasm@8: % [X,N] = LOCALMAXMIN(Y) for vector Y returns logical vectors X and N such matthiasm@8: % that Y(X) contains the local maxima and Y(N) contains the local minima. matthiasm@8: % matthiasm@8: % When Y is a matrix, outputs are logical array(s) the same size as Y, and matthiasm@8: % the minima and/or maxima are computed down the rows of each column in Y. matthiasm@8: % matthiasm@8: % See also MAX, MIN. matthiasm@8: matthiasm@8: % D.C. Hanselman, University of Maine, Orono, ME 04469 matthiasm@8: % MasteringMatlab@yahoo.com matthiasm@8: % Mastering MATLAB 7 matthiasm@8: % 2006-03-08 matthiasm@8: matthiasm@8: mm=['min';'max']; matthiasm@8: if nargin==1 matthiasm@8: xn='max'; matthiasm@8: elseif nargin~=2 matthiasm@8: error('localmaxmin:NotEnoughInputArguments',... matthiasm@8: 'One or Two Input Arguments Required.') matthiasm@8: end matthiasm@8: if ~ischar(xn) || isempty(strcmp(xn,mm)) matthiasm@8: error('localmaxmin:UnknownArgument','Unknown Second Input Argument.') matthiasm@8: end matthiasm@8: if ~isnumeric(y) || ~isreal(y) matthiasm@8: error('localmaxmin:IncorrectDataType','Y Must be Real Valued.') matthiasm@8: end matthiasm@8: ysiz=size(y); matthiasm@8: isrow=ysiz(1)==1; matthiasm@8: if isrow % if row, convert to column for now matthiasm@8: y=y'; matthiasm@8: ysiz(1)=ysiz(2); matthiasm@8: ysiz(2)=1; matthiasm@8: end matthiasm@8: if ysiz(1)<4 matthiasm@8: error('localmaxmin:InsufficientData','Y Must Have at Least 4 Elements.') matthiasm@8: end matthiasm@8: x=false(ysiz); matthiasm@8: matthiasm@8: sdiff=sign(diff(y)); matthiasm@8: zdiff=sdiff==0; matthiasm@8: idz=find(sum(zdiff)); % columns where zero differences appear matthiasm@8: matthiasm@8: if strcmp(xn,'min') || nargout==2 % get minima matthiasm@8: x(2:end-1,:)=diff(sdiff)==2; matthiasm@8: x(1,:)=sdiff(1,:)>0; matthiasm@8: x(end,:)=sdiff(end,:)<0; matthiasm@8: if any(zdiff) matthiasm@8: ir=1:ysiz(1); matthiasm@8: for k=idz % handle columns with zero differences matthiasm@8: itmp=ir; matthiasm@8: itmp(zdiff(:,k))=[]; matthiasm@8: if all(sdiff(:,k)==0) % entire column is flat matthiasm@8: x(:,k)=true; matthiasm@8: else matthiasm@8: tmp=diff(sign(diff(y(itmp,k))))==2; matthiasm@8: x(itmp(tmp)+1,k)=true; matthiasm@8: if sdiff(1,k)==0 matthiasm@8: nr=find(sdiff(:,k)>0,1); matthiasm@8: nf=find(sdiff(:,k)<0,1); matthiasm@8: if ~(isempty(nr)||isempty(nf)) matthiasm@8: x(1,k)=nr0,1,'last'); matthiasm@8: nf=find(sdiff(:,k)<0,1,'last'); matthiasm@8: if ~(isempty(nr)||isempty(nf)) matthiasm@8: x(end,k)=nr0; matthiasm@8: if any(zdiff) matthiasm@8: ir=1:ysiz(1); matthiasm@8: for k=idz % handle columns with zero differences matthiasm@8: itmp=ir; matthiasm@8: itmp(zdiff(:,k))=[]; matthiasm@8: if all(sdiff(:,k)==0) % entire column is flat matthiasm@8: x(:,k)=true; matthiasm@8: else matthiasm@8: tmp=diff(sign(diff(y(itmp,k))))==-2; matthiasm@8: x(itmp(tmp)+1,k)=true; matthiasm@8: if sdiff(1,k)==0 matthiasm@8: nr=find(sdiff(:,k)>0,1); matthiasm@8: nf=find(sdiff(:,k)<0,1); matthiasm@8: if ~(isempty(nr)||isempty(nf)) matthiasm@8: x(1,k)=nr>nf; matthiasm@8: end matthiasm@8: end matthiasm@8: if sdiff(end,k)==0 matthiasm@8: nr=find(sdiff(:,k)>0,1,'last'); matthiasm@8: nf=find(sdiff(:,k)<0,1,'last'); matthiasm@8: if ~(isempty(nr)||isempty(nf)) matthiasm@8: x(end,k)=nr>nf; matthiasm@8: end matthiasm@8: end matthiasm@8: end matthiasm@8: end matthiasm@8: end matthiasm@8: if isrow matthiasm@8: x=x'; matthiasm@8: end matthiasm@8: end