matthiasm@8
|
1 function [x,n]=localmaxmin(y,xn)
|
matthiasm@8
|
2 %LOCALMAXMIN(Y) Local Maxima and Minima.
|
matthiasm@8
|
3 % X = LOCALMAXMIN(Y) or LOCALMAXMIN(Y,'max') for vector Y returns a logical
|
matthiasm@8
|
4 % vector X the same size as Y such that Y(X) contains the local maxima in Y.
|
matthiasm@8
|
5 %
|
matthiasm@8
|
6 % N = LOCALMAXMIN(Y,'min') for vector Y returns a logical vector N the same
|
matthiasm@8
|
7 % size as Y such that Y(N) contains the local minima in Y.
|
matthiasm@8
|
8 %
|
matthiasm@8
|
9 % [X,N] = LOCALMAXMIN(Y) for vector Y returns logical vectors X and N such
|
matthiasm@8
|
10 % that Y(X) contains the local maxima and Y(N) contains the local minima.
|
matthiasm@8
|
11 %
|
matthiasm@8
|
12 % When Y is a matrix, outputs are logical array(s) the same size as Y, and
|
matthiasm@8
|
13 % the minima and/or maxima are computed down the rows of each column in Y.
|
matthiasm@8
|
14 %
|
matthiasm@8
|
15 % See also MAX, MIN.
|
matthiasm@8
|
16
|
matthiasm@8
|
17 % D.C. Hanselman, University of Maine, Orono, ME 04469
|
matthiasm@8
|
18 % MasteringMatlab@yahoo.com
|
matthiasm@8
|
19 % Mastering MATLAB 7
|
matthiasm@8
|
20 % 2006-03-08
|
matthiasm@8
|
21
|
matthiasm@8
|
22 mm=['min';'max'];
|
matthiasm@8
|
23 if nargin==1
|
matthiasm@8
|
24 xn='max';
|
matthiasm@8
|
25 elseif nargin~=2
|
matthiasm@8
|
26 error('localmaxmin:NotEnoughInputArguments',...
|
matthiasm@8
|
27 'One or Two Input Arguments Required.')
|
matthiasm@8
|
28 end
|
matthiasm@8
|
29 if ~ischar(xn) || isempty(strcmp(xn,mm))
|
matthiasm@8
|
30 error('localmaxmin:UnknownArgument','Unknown Second Input Argument.')
|
matthiasm@8
|
31 end
|
matthiasm@8
|
32 if ~isnumeric(y) || ~isreal(y)
|
matthiasm@8
|
33 error('localmaxmin:IncorrectDataType','Y Must be Real Valued.')
|
matthiasm@8
|
34 end
|
matthiasm@8
|
35 ysiz=size(y);
|
matthiasm@8
|
36 isrow=ysiz(1)==1;
|
matthiasm@8
|
37 if isrow % if row, convert to column for now
|
matthiasm@8
|
38 y=y';
|
matthiasm@8
|
39 ysiz(1)=ysiz(2);
|
matthiasm@8
|
40 ysiz(2)=1;
|
matthiasm@8
|
41 end
|
matthiasm@8
|
42 if ysiz(1)<4
|
matthiasm@8
|
43 error('localmaxmin:InsufficientData','Y Must Have at Least 4 Elements.')
|
matthiasm@8
|
44 end
|
matthiasm@8
|
45 x=false(ysiz);
|
matthiasm@8
|
46
|
matthiasm@8
|
47 sdiff=sign(diff(y));
|
matthiasm@8
|
48 zdiff=sdiff==0;
|
matthiasm@8
|
49 idz=find(sum(zdiff)); % columns where zero differences appear
|
matthiasm@8
|
50
|
matthiasm@8
|
51 if strcmp(xn,'min') || nargout==2 % get minima
|
matthiasm@8
|
52 x(2:end-1,:)=diff(sdiff)==2;
|
matthiasm@8
|
53 x(1,:)=sdiff(1,:)>0;
|
matthiasm@8
|
54 x(end,:)=sdiff(end,:)<0;
|
matthiasm@8
|
55 if any(zdiff)
|
matthiasm@8
|
56 ir=1:ysiz(1);
|
matthiasm@8
|
57 for k=idz % handle columns with zero differences
|
matthiasm@8
|
58 itmp=ir;
|
matthiasm@8
|
59 itmp(zdiff(:,k))=[];
|
matthiasm@8
|
60 if all(sdiff(:,k)==0) % entire column is flat
|
matthiasm@8
|
61 x(:,k)=true;
|
matthiasm@8
|
62 else
|
matthiasm@8
|
63 tmp=diff(sign(diff(y(itmp,k))))==2;
|
matthiasm@8
|
64 x(itmp(tmp)+1,k)=true;
|
matthiasm@8
|
65 if sdiff(1,k)==0
|
matthiasm@8
|
66 nr=find(sdiff(:,k)>0,1);
|
matthiasm@8
|
67 nf=find(sdiff(:,k)<0,1);
|
matthiasm@8
|
68 if ~(isempty(nr)||isempty(nf))
|
matthiasm@8
|
69 x(1,k)=nr<nf;
|
matthiasm@8
|
70 end
|
matthiasm@8
|
71 end
|
matthiasm@8
|
72 if sdiff(end,k)==0
|
matthiasm@8
|
73 nr=find(sdiff(:,k)>0,1,'last');
|
matthiasm@8
|
74 nf=find(sdiff(:,k)<0,1,'last');
|
matthiasm@8
|
75 if ~(isempty(nr)||isempty(nf))
|
matthiasm@8
|
76 x(end,k)=nr<nf;
|
matthiasm@8
|
77 end
|
matthiasm@8
|
78 end
|
matthiasm@8
|
79 end
|
matthiasm@8
|
80 end
|
matthiasm@8
|
81 end
|
matthiasm@8
|
82 if isrow
|
matthiasm@8
|
83 x=x.';
|
matthiasm@8
|
84 end
|
matthiasm@8
|
85 if nargout==2
|
matthiasm@8
|
86 n=x;
|
matthiasm@8
|
87 end
|
matthiasm@8
|
88 end
|
matthiasm@8
|
89 if strcmp(xn,'max') || nargout==2 % get maxima
|
matthiasm@8
|
90 x=false(ysiz);
|
matthiasm@8
|
91 x(2:end-1,:)=diff(sdiff)==-2;
|
matthiasm@8
|
92 x(1,:)=sdiff(1,:)<0;
|
matthiasm@8
|
93 x(end,:)=sdiff(end,:)>0;
|
matthiasm@8
|
94 if any(zdiff)
|
matthiasm@8
|
95 ir=1:ysiz(1);
|
matthiasm@8
|
96 for k=idz % handle columns with zero differences
|
matthiasm@8
|
97 itmp=ir;
|
matthiasm@8
|
98 itmp(zdiff(:,k))=[];
|
matthiasm@8
|
99 if all(sdiff(:,k)==0) % entire column is flat
|
matthiasm@8
|
100 x(:,k)=true;
|
matthiasm@8
|
101 else
|
matthiasm@8
|
102 tmp=diff(sign(diff(y(itmp,k))))==-2;
|
matthiasm@8
|
103 x(itmp(tmp)+1,k)=true;
|
matthiasm@8
|
104 if sdiff(1,k)==0
|
matthiasm@8
|
105 nr=find(sdiff(:,k)>0,1);
|
matthiasm@8
|
106 nf=find(sdiff(:,k)<0,1);
|
matthiasm@8
|
107 if ~(isempty(nr)||isempty(nf))
|
matthiasm@8
|
108 x(1,k)=nr>nf;
|
matthiasm@8
|
109 end
|
matthiasm@8
|
110 end
|
matthiasm@8
|
111 if sdiff(end,k)==0
|
matthiasm@8
|
112 nr=find(sdiff(:,k)>0,1,'last');
|
matthiasm@8
|
113 nf=find(sdiff(:,k)<0,1,'last');
|
matthiasm@8
|
114 if ~(isempty(nr)||isempty(nf))
|
matthiasm@8
|
115 x(end,k)=nr>nf;
|
matthiasm@8
|
116 end
|
matthiasm@8
|
117 end
|
matthiasm@8
|
118 end
|
matthiasm@8
|
119 end
|
matthiasm@8
|
120 end
|
matthiasm@8
|
121 if isrow
|
matthiasm@8
|
122 x=x';
|
matthiasm@8
|
123 end
|
matthiasm@8
|
124 end
|