1 | function [xmax,imax,xmin,imin] = extrema(x)
|
---|
2 | %EXTREMA Gets the global extrema points from a time series.
|
---|
3 | % [XMAX,IMAX,XMIN,IMIN] = EXTREMA(X) returns the global minima and maxima
|
---|
4 | % points of the vector X ignoring NaN's, where
|
---|
5 | % XMAX - maxima points in descending order
|
---|
6 | % IMAX - indexes of the XMAX
|
---|
7 | % XMIN - minima points in descending order
|
---|
8 | % IMIN - indexes of the XMIN
|
---|
9 | %
|
---|
10 | % DEFINITION (from http://en.wikipedia.org/wiki/Maxima_and_minima):
|
---|
11 | % In mathematics, maxima and minima, also known as extrema, are points in
|
---|
12 | % the domain of a function at which the function takes a largest value
|
---|
13 | % (maximum) or smallest value (minimum), either within a given
|
---|
14 | % neighbourhood (local extrema) or on the function domain in its entirety
|
---|
15 | % (global extrema).
|
---|
16 | %
|
---|
17 | % Example:
|
---|
18 | % x = 2*pi*linspace(-1,1);
|
---|
19 | % y = cos(x) - 0.5 + 0.5*rand(size(x)); y(40:45) = 1.85; y(50:53)=NaN;
|
---|
20 | % [ymax,imax,ymin,imin] = extrema(y);
|
---|
21 | % plot(x,y,x(imax),ymax,'g.',x(imin),ymin,'r.')
|
---|
22 | %
|
---|
23 | % See also EXTREMA2, MAX, MIN
|
---|
24 |
|
---|
25 | % Written by
|
---|
26 | % Lic. on Physics Carlos Adrián Vargas Aguilera
|
---|
27 | % Physical Oceanography MS candidate
|
---|
28 | % UNIVERSIDAD DE GUADALAJARA
|
---|
29 | % Mexico, 2004
|
---|
30 | %
|
---|
31 | % nubeobscura@hotmail.com
|
---|
32 |
|
---|
33 | % From : http://www.mathworks.com/matlabcentral/fileexchange
|
---|
34 | % File ID : 12275
|
---|
35 | % Submited at: 2006-09-14
|
---|
36 | % 2006-11-11 : English translation from spanish.
|
---|
37 | % 2006-11-17 : Accept NaN's.
|
---|
38 | % 2007-04-09 : Change name to MAXIMA, and definition added.
|
---|
39 |
|
---|
40 |
|
---|
41 | xmax = [];
|
---|
42 | imax = [];
|
---|
43 | xmin = [];
|
---|
44 | imin = [];
|
---|
45 |
|
---|
46 | % Vector input?
|
---|
47 | Nt = numel(x);
|
---|
48 | if Nt ~= length(x)
|
---|
49 | error('Entry must be a vector.')
|
---|
50 | end
|
---|
51 |
|
---|
52 | % NaN's:
|
---|
53 | inan = find(isnan(x));
|
---|
54 | indx = 1:Nt;
|
---|
55 | if ~isempty(inan)
|
---|
56 | indx(inan) = [];
|
---|
57 | x(inan) = [];
|
---|
58 | Nt = length(x);
|
---|
59 | end
|
---|
60 |
|
---|
61 | % Difference between subsequent elements:
|
---|
62 | dx = diff(x);
|
---|
63 |
|
---|
64 | % Is an horizontal line?
|
---|
65 | if ~any(dx)
|
---|
66 | return
|
---|
67 | end
|
---|
68 |
|
---|
69 | % Flat peaks? Put the middle element:
|
---|
70 | a = find(dx~=0); % Indexes where x changes
|
---|
71 | lm = find(diff(a)~=1) + 1; % Indexes where a do not changes
|
---|
72 | d = a(lm) - a(lm-1); % Number of elements in the flat peak
|
---|
73 | a(lm) = a(lm) - floor(d/2); % Save middle elements
|
---|
74 | a(end+1) = Nt;
|
---|
75 |
|
---|
76 | % Peaks?
|
---|
77 | xa = x(a); % Serie without flat peaks
|
---|
78 | b = (diff(xa) > 0); % 1 => positive slopes (minima begin)
|
---|
79 | % 0 => negative slopes (maxima begin)
|
---|
80 | xb = diff(b); % -1 => maxima indexes (but one)
|
---|
81 | % +1 => minima indexes (but one)
|
---|
82 | imax = find(xb == -1) + 1; % maxima indexes
|
---|
83 | imin = find(xb == +1) + 1; % minima indexes
|
---|
84 | imax = a(imax);
|
---|
85 | imin = a(imin);
|
---|
86 |
|
---|
87 | nmaxi = length(imax);
|
---|
88 | nmini = length(imin);
|
---|
89 |
|
---|
90 | % Maximum or minumim on a flat peak at the ends?
|
---|
91 | if (nmaxi==0) && (nmini==0)
|
---|
92 | if x(1) > x(Nt)
|
---|
93 | xmax = x(1);
|
---|
94 | imax = indx(1);
|
---|
95 | xmin = x(Nt);
|
---|
96 | imin = indx(Nt);
|
---|
97 | elseif x(1) < x(Nt)
|
---|
98 | xmax = x(Nt);
|
---|
99 | imax = indx(Nt);
|
---|
100 | xmin = x(1);
|
---|
101 | imin = indx(1);
|
---|
102 | end
|
---|
103 | return
|
---|
104 | end
|
---|
105 |
|
---|
106 | % Maximum or minumim at the ends?
|
---|
107 | if (nmaxi==0)
|
---|
108 | imax(1:2) = [1 Nt];
|
---|
109 | elseif (nmini==0)
|
---|
110 | imin(1:2) = [1 Nt];
|
---|
111 | else
|
---|
112 | if imax(1) < imin(1)
|
---|
113 | imin(2:nmini+1) = imin;
|
---|
114 | imin(1) = 1;
|
---|
115 | else
|
---|
116 | imax(2:nmaxi+1) = imax;
|
---|
117 | imax(1) = 1;
|
---|
118 | end
|
---|
119 | if imax(end) > imin(end)
|
---|
120 | imin(end+1) = Nt;
|
---|
121 | else
|
---|
122 | imax(end+1) = Nt;
|
---|
123 | end
|
---|
124 | end
|
---|
125 | xmax = x(imax);
|
---|
126 | xmin = x(imin);
|
---|
127 |
|
---|
128 | % NaN's:
|
---|
129 | if ~isempty(inan)
|
---|
130 | imax = indx(imax);
|
---|
131 | imin = indx(imin);
|
---|
132 | end
|
---|
133 |
|
---|
134 | % Same size as x:
|
---|
135 | imax = reshape(imax,size(xmax));
|
---|
136 | imin = reshape(imin,size(xmin));
|
---|
137 |
|
---|
138 | % Descending order:
|
---|
139 | [temp,inmax] = sort(-xmax); clear temp
|
---|
140 | xmax = xmax(inmax);
|
---|
141 | imax = imax(inmax);
|
---|
142 | [xmin,inmin] = sort(xmin);
|
---|
143 | imin = imin(inmin);
|
---|
144 |
|
---|
145 |
|
---|
146 | % Carlos Adrián Vargas Aguilera. nubeobscura@hotmail.com |
---|