1 | function [xymax,smax,xymin,smin] = extrema2(xy,varargin)
|
---|
2 | %EXTREMA2 Gets the extrema points from a surface.
|
---|
3 | % [XMAX,IMAX,XMIN,IMIN] = EXTREMA2(X) returns the maxima and minima
|
---|
4 | % elements of the matriz X ignoring NaN's, where
|
---|
5 | % XMAX - maxima points in descending order (the bigger first and so on)
|
---|
6 | % IMAX - linear indexes of the XMAX
|
---|
7 | % XMIN - minima points in descending order
|
---|
8 | % IMIN - linear indexes of the XMIN.
|
---|
9 | % The program uses EXTREMA.
|
---|
10 | %
|
---|
11 | % The extrema points are searched only through the column, the row and
|
---|
12 | % the diagonals crossing each matrix element, so it is not a perfect
|
---|
13 | % mathematical program and for this reason it has an optional argument.
|
---|
14 | % The user should be aware of these limitations.
|
---|
15 | %
|
---|
16 | % [XMAX,IMAX,XMIN,IMIN] = EXTREMA2(X,1) does the same but without
|
---|
17 | % searching through the diagonals (less strict and perhaps the user gets
|
---|
18 | % more output points).
|
---|
19 | %
|
---|
20 | % DEFINITION (from http://en.wikipedia.org/wiki/Maxima_and_minima):
|
---|
21 | % In mathematics, maxima and minima, also known as extrema, are points in
|
---|
22 | % the domain of a function at which the function takes a largest value
|
---|
23 | % (maximum) or smallest value (minimum), either within a given
|
---|
24 | % neighbourhood (local extrema) or on the function domain in its entirety
|
---|
25 | % (global extrema).
|
---|
26 | %
|
---|
27 | % Note: To change the linear index to (i,j) use IND2SUB.
|
---|
28 | %
|
---|
29 | % Example:
|
---|
30 | % [x,y] = meshgrid(-2:.2:2,3:-.2:-2);
|
---|
31 | % z = x.*exp(-x.^2-y.^2); z(10,7)= NaN; z(16:19,13:17) = NaN;
|
---|
32 | % surf(x,y,z), shading interp
|
---|
33 | % [zmax,imax,zmin,imin] = extrema2(z);
|
---|
34 | % hold on
|
---|
35 | % plot3(x(imax),y(imax),zmax,'bo',x(imin),y(imin),zmin,'ro')
|
---|
36 | % for i = 1:length(zmax)
|
---|
37 | % text(x(imax(i)),y(imax(i)),zmax(i),[' ' num2str(zmax(i))])
|
---|
38 | % end
|
---|
39 | % for i = 1:length(zmin)
|
---|
40 | % text(x(imin(i)),y(imin(i)),zmin(i),[' ' num2str(zmin(i))])
|
---|
41 | % end
|
---|
42 | % hold off
|
---|
43 | %
|
---|
44 | % See also EXTREMA, MAX, MIN
|
---|
45 |
|
---|
46 | % Written by
|
---|
47 | % Lic. on Physics Carlos Adrián Vargas Aguilera
|
---|
48 | % Physical Oceanography MS candidate
|
---|
49 | % UNIVERSIDAD DE GUADALAJARA
|
---|
50 | % Mexico, 2005
|
---|
51 | %
|
---|
52 | % nubeobscura@hotmail.com
|
---|
53 |
|
---|
54 | % From : http://www.mathworks.com/matlabcentral/fileexchange
|
---|
55 | % File ID : 12275
|
---|
56 | % Submited at: 2006-09-14
|
---|
57 | % 2006-11-11 : English translation from spanish.
|
---|
58 | % 2006-11-17 : Accept NaN's.
|
---|
59 | % 2006-11-22 : Fixed bug in INDX (by JaeKyu Suhr)
|
---|
60 | % 2007-04-09 : Change name to MAXIMA2, and definition added.
|
---|
61 |
|
---|
62 | M = size(xy);
|
---|
63 | if length(M) ~= 2
|
---|
64 | error('Entry must be a matrix.')
|
---|
65 | end
|
---|
66 | N = M(2);
|
---|
67 | M = M(1);
|
---|
68 |
|
---|
69 | % Search peaks through columns:
|
---|
70 | [smaxcol,smincol] = extremos(xy);
|
---|
71 |
|
---|
72 | % Search peaks through rows, on columns with extrema points:
|
---|
73 | im = unique([smaxcol(:,1);smincol(:,1)]); % Rows with column extrema
|
---|
74 | [smaxfil,sminfil] = extremos(xy(im,:).');
|
---|
75 |
|
---|
76 | % Convertion from 2 to 1 index:
|
---|
77 | smaxcol = sub2ind([M,N],smaxcol(:,1),smaxcol(:,2));
|
---|
78 | smincol = sub2ind([M,N],smincol(:,1),smincol(:,2));
|
---|
79 | smaxfil = sub2ind([M,N],im(smaxfil(:,2)),smaxfil(:,1));
|
---|
80 | sminfil = sub2ind([M,N],im(sminfil(:,2)),sminfil(:,1));
|
---|
81 |
|
---|
82 | % Peaks in rows and in columns:
|
---|
83 | smax = intersect(smaxcol,smaxfil);
|
---|
84 | smin = intersect(smincol,sminfil);
|
---|
85 |
|
---|
86 | % Search peaks through diagonals?
|
---|
87 | if nargin==1
|
---|
88 | % Check peaks on down-up diagonal:
|
---|
89 | [iext,jext] = ind2sub([M,N],unique([smax;smin]));
|
---|
90 | [sextmax,sextmin] = extremos_diag(iext,jext,xy,1);
|
---|
91 |
|
---|
92 | % Check peaks on up-down diagonal:
|
---|
93 | smax = intersect(smax,[M; (N*M-M); sextmax]);
|
---|
94 | smin = intersect(smin,[M; (N*M-M); sextmin]);
|
---|
95 |
|
---|
96 | % Peaks on up-down diagonals:
|
---|
97 | [iext,jext] = ind2sub([M,N],unique([smax;smin]));
|
---|
98 | [sextmax,sextmin] = extremos_diag(iext,jext,xy,-1);
|
---|
99 |
|
---|
100 | % Peaks on columns, rows and diagonals:
|
---|
101 | smax = intersect(smax,[1; N*M; sextmax]);
|
---|
102 | smin = intersect(smin,[1; N*M; sextmin]);
|
---|
103 | end
|
---|
104 |
|
---|
105 | % Extrema points:
|
---|
106 | xymax = xy(smax);
|
---|
107 | xymin = xy(smin);
|
---|
108 |
|
---|
109 | % Descending order:
|
---|
110 | [temp,inmax] = sort(-xymax); clear temp
|
---|
111 | xymax = xymax(inmax);
|
---|
112 | smax = smax(inmax);
|
---|
113 | [xymin,inmin] = sort(xymin);
|
---|
114 | smin = smin(inmin);
|
---|
115 |
|
---|
116 |
|
---|
117 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
---|
118 |
|
---|
119 | function [smax,smin] = extremos(matriz)
|
---|
120 | % Peaks through columns or rows.
|
---|
121 |
|
---|
122 | smax = [];
|
---|
123 | smin = [];
|
---|
124 |
|
---|
125 | for n = 1:length(matriz(1,:))
|
---|
126 | [temp,imaxfil,temp,iminfil] = extrema(matriz(:,n)); clear temp
|
---|
127 | if ~isempty(imaxfil) % Maxima indexes
|
---|
128 | imaxcol = repmat(n,length(imaxfil),1);
|
---|
129 | smax = [smax; imaxfil imaxcol];
|
---|
130 | end
|
---|
131 | if ~isempty(iminfil) % Minima indexes
|
---|
132 | imincol = repmat(n,length(iminfil),1);
|
---|
133 | smin = [smin; iminfil imincol];
|
---|
134 | end
|
---|
135 | end
|
---|
136 |
|
---|
137 |
|
---|
138 | function [sextmax,sextmin] = extremos_diag(iext,jext,xy,A)
|
---|
139 | % Peaks through diagonals (down-up A=-1)
|
---|
140 |
|
---|
141 | [M,N] = size(xy);
|
---|
142 | if A==-1
|
---|
143 | iext = M-iext+1;
|
---|
144 | end
|
---|
145 | [iini,jini] = cruce(iext,jext,1,1);
|
---|
146 | [iini,jini] = ind2sub([M,N],unique(sub2ind([M,N],iini,jini)));
|
---|
147 | [ifin,jfin] = cruce(iini,jini,M,N);
|
---|
148 | sextmax = [];
|
---|
149 | sextmin = [];
|
---|
150 | for n = 1:length(iini)
|
---|
151 | ises = iini(n):ifin(n);
|
---|
152 | jses = jini(n):jfin(n);
|
---|
153 | if A==-1
|
---|
154 | ises = M-ises+1;
|
---|
155 | end
|
---|
156 | s = sub2ind([M,N],ises,jses);
|
---|
157 | [temp,imax,temp,imin] = extrema(xy(s)); clear temp
|
---|
158 | sextmax = [sextmax; s(imax)'];
|
---|
159 | sextmin = [sextmin; s(imin)'];
|
---|
160 | end
|
---|
161 |
|
---|
162 |
|
---|
163 | function [i,j] = cruce(i0,j0,I,J)
|
---|
164 | % Indexes where the diagonal of the element io,jo crosses the left/superior
|
---|
165 | % (I=1,J=1) or right/inferior (I=M,J=N) side of an MxN matrix.
|
---|
166 |
|
---|
167 | arriba = 2*(I*J==1)-1;
|
---|
168 |
|
---|
169 | si = (arriba*(j0-J) > arriba*(i0-I));
|
---|
170 | i = (I - (J+i0-j0)).*si + J+i0-j0;
|
---|
171 | j = (I+j0-i0-(J)).*si + J;
|
---|
172 |
|
---|
173 |
|
---|
174 | % Carlos Adrián Vargas Aguilera. nubeobscura@hotmail.com |
---|