SineWavePeaks - Find peaks (or troughs) in a sine wave. Find the peaks (or troughs) in a sine wave. The algorithm can either determine the mid-points between the zero-crossings, or the zeros of the derivative of the signal. This assumes a minimum of 10 samples per positive/negative phase. USAGE [t,peaks] = SineWavePeaks(sineWave,<options>) sineWave sinewave <a href="matlab:help samples">samples</a> <options> optional list of property-value pairs (see table below) ========================================================================= Properties Values ------------------------------------------------------------------------- 'mode' 'peaks' or 'troughs' (default = 'peaks') 'method' 'zero' for zero-crossings (default), 'diff' for derivative 'smooth' smoothing kernel (in samples) for derivative (default = 5) =========================================================================
0001 function [t,peaks] = SineWavePeaks(sineWave,varargin) 0002 0003 %SineWavePeaks - Find peaks (or troughs) in a sine wave. 0004 % 0005 % Find the peaks (or troughs) in a sine wave. The algorithm can either determine 0006 % the mid-points between the zero-crossings, or the zeros of the derivative of 0007 % the signal. This assumes a minimum of 10 samples per positive/negative phase. 0008 % 0009 % USAGE 0010 % 0011 % [t,peaks] = SineWavePeaks(sineWave,<options>) 0012 % 0013 % sineWave sinewave <a href="matlab:help samples">samples</a> 0014 % <options> optional list of property-value pairs (see table below) 0015 % 0016 % ========================================================================= 0017 % Properties Values 0018 % ------------------------------------------------------------------------- 0019 % 'mode' 'peaks' or 'troughs' (default = 'peaks') 0020 % 'method' 'zero' for zero-crossings (default), 'diff' for derivative 0021 % 'smooth' smoothing kernel (in samples) for derivative (default = 5) 0022 % ========================================================================= 0023 0024 % Copyright (C) 2004-2011 by Michaƫl Zugaro 0025 % 0026 % This program is free software; you can redistribute it and/or modify 0027 % it under the terms of the GNU General Public License as published by 0028 % the Free Software Foundation; either version 3 of the License, or 0029 % (at your option) any later version. 0030 0031 % Default values 0032 mode = 'peaks'; 0033 method = 'zero'; 0034 smooth = 5; 0035 0036 if nargin < 1 | mod(length(varargin),2) ~= 0, 0037 error('Incorrect number of parameters (type ''help <a href="matlab:help SineWavePeaks">SineWavePeaks</a>'' for details).'); 0038 end 0039 0040 % Parse parameter list 0041 for i = 1:2:length(varargin), 0042 if ~ischar(varargin{i}), 0043 error(['Parameter ' num2str(i+2) ' is not a property (type ''help <a href="matlab:help SineWavePeaks">SineWavePeaks</a>'' for details).']); 0044 end 0045 switch(lower(varargin{i})), 0046 case 'mode', 0047 mode = lower(varargin{i+1}); 0048 if ~isastring(mode,'peaks','troughs'), 0049 error('Incorrect value for property ''mode'' (type ''help <a href="matlab:help SineWavePeaks">SineWavePeaks</a>'' for details).'); 0050 end 0051 0052 case 'method', 0053 method = lower(varargin{i+1}); 0054 if ~isastring(method,'zero','diff'), 0055 error('Incorrect value for property ''method'' (type ''help <a href="matlab:help SineWavePeaks">SineWavePeaks</a>'' for details).'); 0056 end 0057 0058 case 'smooth', 0059 smooth = lower(varargin{i+1}); 0060 if ~isdscalar(smooth), 0061 error('Incorrect value for property ''smooth'' (type ''help <a href="matlab:help SineWavePeaks">SineWavePeaks</a>'' for details).'); 0062 end 0063 0064 otherwise, 0065 error(['Unknown property ''' num2str(varargin{i}) ''' (type ''help <a href="matlab:help SineWavePeaks">SineWavePeaks</a>'' for details).']); 0066 end 0067 end 0068 0069 0070 if strcmp(method,'zero'), 0071 0072 % Find downward and upward going zero-crossings 0073 previous = sineWave(1:end-1,2); 0074 current = sineWave(2:end,2); 0075 down = find(previous > 0 & current < 0); 0076 up = find(previous < 0 & current > 0); 0077 % Keep only appropriately ordered pairs of zero-crossings 0078 if strcmp(mode,'troughs'), 0079 if up(1) < down(1), up = up(2:end); end 0080 if down(end) > up(end), down = down(1:end-1); end 0081 else 0082 if down(1) < up(1), down = down(2:end); end 0083 if up(end) > down(end), up = up(1:end-1); end 0084 end 0085 t = (sineWave(down,1)+sineWave(up,1))/2; 0086 peaks = interp1(sineWave(:,1),sineWave(:,2),t); 0087 0088 elseif strcmp(method,'diff'), 0089 0090 d = diff(Smooth(sineWave(:,2),smooth)); 0091 % [b,a] = cheby2(4,20,[4 20]*(sineWave(2,1)-sineWave(1,1))); 0092 % d = [diff(sineWave(:,1))+sineWave(1:end-1,1) filtfilt(b,a,d)]; 0093 n = length(d); 0094 D = zeros(n,1); 0095 for i = 1:10, 0096 % disp(['i=' int2str(i) ', D(' int2str(max([i-2 1])) ':' int2str(min([n n+i-3])) ')+=d(' int2str(max([5-i-1 1])) ':' int2str(min([n n-i+3])) ') [lengths: ' int2str(length(max([i-2 1]):min([n n+i-3]))) ', ' int2str(length(max([5-i-1 1]):min([n n-i+3]))) ']']); 0097 D(max([i-2 1]):min([n n+i-3])) = D(max([i-2 1]):min([n n+i-3])) + d(max([5-i-1 1]):min([n n-i+3])); 0098 end 0099 d = [diff(sineWave(:,1))+sineWave(1:end-1,1) D]; 0100 0101 % Find downward and upward going zero-crossings 0102 previous = d(1:end-1,2); 0103 current = d(2:end,2); 0104 if strcmp(mode,'troughs'), 0105 up = find(previous < 0 & current > 0); 0106 t = d(up,1); 0107 else 0108 down = find(previous > 0 & current < 0); 0109 t = d(down,1); 0110 end 0111 peaks = interp1(sineWave(:,1),sineWave(:,2),t); 0112 0113 % figure;hold on; 0114 % plot(sineWave(:,1),sineWave(:,2),'b'); 0115 % plot(d(:,1),d(:,2),'r'); 0116 % plot(t,zeros(size(t)),'k+','linestyle','none'); 0117 % for i = 1:length(peaks), 0118 % plot([t(i) t(i)],[peaks(i) peaks(i)],'g+','linestyle','none'); 0119 % end 0120 end