[37] | 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 |
---|