function [yp,xp] = tolpk(tol,y,x)
% TOLPK All peaks raising above adjacent valeys by a tolerance
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% The function tests differences between peaks and adjacent valeys of an
% arbitrary function and returns indeces of peaks raising above
% neighbouring valeys more than an allowed tolerance. The function finds
% at least one highest peak even in case of small ripple (noise) over
% all function values.
%
% Call of the function:
% I = tolpk(tol,y);
% Input arguments:
% tol = Tolerance for skipping over small peaks
% >0 tolerance in units of y,
% <0 tolerance in percents of the maximum peak of y
% y = samples of the function y(x) for monotone sequence of x,
% x = argument of the function y(x).
% If no x is given, vector x = 1:length(y) will be generated.
% Output parameter:
% yp = vector of peaks with relative heights greater than tol, and
% maximum peak including
% xp = argument values of yp.
%
% Example:
% tol = -5; % tol = 5% of y_{max}
% x = 0:.1:2*pi;
% y = sin(x)+.15*cos(51.23*x)+.07*sin(141*x)+1;
% plot(x,y); hold on, grid on
% [yp,xp] = tolpk(tol,y,x); % coordinates of accepted peaks
% plot(xp,yp,'*r')
% hold off
% Miroslav Balda
% miroslav AT balda DOT cz
% 2009-01-06 v 1.0
if ~exist('extr.m','file'),
error([' Download function extr (FEX Id=10272) from File Exchange']);
end
if tol<0, tol=abs(max(y)*tol/100); end % convert percents into y-units
L = extr(y);
yx = y(L{1}|L{2}); % all peaks and valeys of y
if L{1}(1), yx=[yx(2), yx]; end
if L{1}(end), yx=[yx, yx(end-1)]; end
dy = abs(diff(yx));
K = dy(1:2:end-1)>tol & dy(2:2:end)>tol; % logical indeces of peaks>tol
yh = y(L{1}); % all peaks of y
[ym,k] = max(yh); % highest peak
K(k) = true;
yp = yh(K); % peaks out of tolerance
if nargout>1
if nargin<3, x=1:length(y); end % if x not given
xp = x(L{1});
xp = xp(K); % arguments of yp
end