summaryrefslogtreecommitdiff
path: root/extrema.m
diff options
context:
space:
mode:
Diffstat (limited to 'extrema.m')
-rw-r--r--extrema.m146
1 files changed, 146 insertions, 0 deletions
diff --git a/extrema.m b/extrema.m
new file mode 100644
index 0000000..2a9d265
--- /dev/null
+++ b/extrema.m
@@ -0,0 +1,146 @@
+function [xmax,imax,xmin,imin] = extrema(x)
+%EXTREMA Gets the global extrema points from a time series.
+% [XMAX,IMAX,XMIN,IMIN] = EXTREMA(X) returns the global minima and maxima
+% points of the vector X ignoring NaN's, where
+% XMAX - maxima points in descending order
+% IMAX - indexes of the XMAX
+% XMIN - minima points in descending order
+% IMIN - indexes of the XMIN
+%
+% DEFINITION (from http://en.wikipedia.org/wiki/Maxima_and_minima):
+% In mathematics, maxima and minima, also known as extrema, are points in
+% the domain of a function at which the function takes a largest value
+% (maximum) or smallest value (minimum), either within a given
+% neighbourhood (local extrema) or on the function domain in its entirety
+% (global extrema).
+%
+% Example:
+% x = 2*pi*linspace(-1,1);
+% y = cos(x) - 0.5 + 0.5*rand(size(x)); y(40:45) = 1.85; y(50:53)=NaN;
+% [ymax,imax,ymin,imin] = extrema(y);
+% plot(x,y,x(imax),ymax,'g.',x(imin),ymin,'r.')
+%
+% See also EXTREMA2, MAX, MIN
+
+% Written by
+% Lic. on Physics Carlos Adrián Vargas Aguilera
+% Physical Oceanography MS candidate
+% UNIVERSIDAD DE GUADALAJARA
+% Mexico, 2004
+%
+% nubeobscura@hotmail.com
+
+% From : http://www.mathworks.com/matlabcentral/fileexchange
+% File ID : 12275
+% Submited at: 2006-09-14
+% 2006-11-11 : English translation from spanish.
+% 2006-11-17 : Accept NaN's.
+% 2007-04-09 : Change name to MAXIMA, and definition added.
+
+
+xmax = [];
+imax = [];
+xmin = [];
+imin = [];
+
+% Vector input?
+Nt = numel(x);
+if Nt ~= length(x)
+ error('Entry must be a vector.')
+end
+
+% NaN's:
+inan = find(isnan(x));
+indx = 1:Nt;
+if ~isempty(inan)
+ indx(inan) = [];
+ x(inan) = [];
+ Nt = length(x);
+end
+
+% Difference between subsequent elements:
+dx = diff(x);
+
+% Is an horizontal line?
+if ~any(dx)
+ return
+end
+
+% Flat peaks? Put the middle element:
+a = find(dx~=0); % Indexes where x changes
+lm = find(diff(a)~=1) + 1; % Indexes where a do not changes
+d = a(lm) - a(lm-1); % Number of elements in the flat peak
+a(lm) = a(lm) - floor(d/2); % Save middle elements
+a(end+1) = Nt;
+
+% Peaks?
+xa = x(a); % Serie without flat peaks
+b = (diff(xa) > 0); % 1 => positive slopes (minima begin)
+ % 0 => negative slopes (maxima begin)
+xb = diff(b); % -1 => maxima indexes (but one)
+ % +1 => minima indexes (but one)
+imax = find(xb == -1) + 1; % maxima indexes
+imin = find(xb == +1) + 1; % minima indexes
+imax = a(imax);
+imin = a(imin);
+
+nmaxi = length(imax);
+nmini = length(imin);
+
+% Maximum or minumim on a flat peak at the ends?
+if (nmaxi==0) && (nmini==0)
+ if x(1) > x(Nt)
+ xmax = x(1);
+ imax = indx(1);
+ xmin = x(Nt);
+ imin = indx(Nt);
+ elseif x(1) < x(Nt)
+ xmax = x(Nt);
+ imax = indx(Nt);
+ xmin = x(1);
+ imin = indx(1);
+ end
+ return
+end
+
+% Maximum or minumim at the ends?
+if (nmaxi==0)
+ imax(1:2) = [1 Nt];
+elseif (nmini==0)
+ imin(1:2) = [1 Nt];
+else
+ if imax(1) < imin(1)
+ imin(2:nmini+1) = imin;
+ imin(1) = 1;
+ else
+ imax(2:nmaxi+1) = imax;
+ imax(1) = 1;
+ end
+ if imax(end) > imin(end)
+ imin(end+1) = Nt;
+ else
+ imax(end+1) = Nt;
+ end
+end
+xmax = x(imax);
+xmin = x(imin);
+
+% NaN's:
+if ~isempty(inan)
+ imax = indx(imax);
+ imin = indx(imin);
+end
+
+% Same size as x:
+imax = reshape(imax,size(xmax));
+imin = reshape(imin,size(xmin));
+
+% Descending order:
+[temp,inmax] = sort(-xmax); clear temp
+xmax = xmax(inmax);
+imax = imax(inmax);
+[xmin,inmin] = sort(xmin);
+imin = imin(inmin);
+
+
+% Carlos Adrián Vargas Aguilera. nubeobscura@hotmail.com \ No newline at end of file