matlab 版本
function [maxtab, mintab]=peakdet(v, delta, x)
%PEAKDET Detect peaks in a vector
% [MAXTAB, MINTAB] = PEAKDET(V, DELTA) finds the local
% maxima and minima ("peaks") in the vector V.
% MAXTAB and MINTAB consists of two columns. Column 1
% contains indices in V, and column 2 the found values.
%
% With [MAXTAB, MINTAB] = PEAKDET(V, DELTA, X) the indices
% in MAXTAB and MINTAB are replaced with the corresponding
% X-values.
%
% A point is considered a maximum peak if it has the maximal
% value, and was preceded (to the left) by a value lower by
% DELTA.
% Eli Billauer, 3.4.05 (Explicitly not copyrighted).
% This function is released to the public domain; Any use is allowed.
maxtab = [];
mintab = [];
v = v(:); % Just in case this wasn't a proper vector
if nargin < 3
x = (1:length(v))';
else
x = x(:);
if length(v)~= length(x)
error('Input vectors v and x must have same length');
end
end
if (length(delta(:)))>1
error('Input argument DELTA must be a scalar');
end
if delta <= 0
error('Input argument DELTA must be positive');
end
mn = Inf; mx = -Inf;
mnpos = NaN; mxpos = NaN;
lookformax = 1;
for i=1:length(v)
this = v(i);
if this > mx, mx = this; mxpos = x(i); end
if this < mn, mn = this; mnpos = x(i); end
if lookformax
if this < mx-delta
maxtab = [maxtab ; mxpos mx];
mn = this; mnpos = x(i);
lookformax = 0;
end
else
if this > mn+delta
mintab = [mintab ; mnpos mn];
mx = this; mxpos = x(i);
lookformax = 1;
end
end
end
改写成java版本
public class Peakdet {
public List<Valley> Peakdet(Double[] vector, double triggerDelta) {
return Peakdet(vector, 0, vector.length, triggerDelta);
}
public List<Valley> Peakdet(Double[] vector, int offset, int length, double triggerDelta) {
double mn = Double.POSITIVE_INFINITY;
double mx = Double.NEGATIVE_INFINITY;
double mnpos = Double.NaN;//初始化数据为NAN
double mxpos = Double.NaN;
int lookformax = 1;//标记,1代表峰,0代表谷
List<Peak> maxtab_tmp = new ArrayList<>();//波峰集合
List<Valley> mintab_tmp = new ArrayList<>();//波谷集合
for (int i = offset; i < length; i++) {//[0 length)
double a = vector[i];
if (a > mx) {
mx = a;
mxpos = vector[i];
}
if (a < mn) {
mn = a;
mnpos = vector[i];
}
if (lookformax == 1) {//当为波峰时
if (a < mx - triggerDelta) {
maxtab_tmp.add(new Peak(mxpos, i));
mn = a;
mnpos = vector[i];
lookformax = 0;
}
} else {
if (a > mn + triggerDelta) {
mintab_tmp.add(new Valley(mnpos, i));
mx = a;
mxpos = vector[i];
lookformax = 1;
}
}
}
return mintab_tmp;
}
static class Peak {
public final double height;
public final int index;
private Peak(double height, int index) {
this.height = height;
this.index = index;
}
@Override
public String toString() {
return "Peak{" + "height=" + -1*height + ", index=" + index + '}';
}
}
static class Valley {
public final double height;
public final int index;
private Valley(double height, int index) {
this.height = height;
this.index = index;
}
@Override
public String toString() {
return "Valley{" + "height=" +-1* height + ", index=" + index + '}';
}
}
}
Python版本
import sys
from numpy import NaN, Inf, arange, isscalar, array
def peakdet(v, delta, x = None):
maxtab = []
mintab = []
if x is None:
x = arange(len(v))
v = asarray(v)
if len(v) != len(x):
sys.exit('Input vectors v and x must have same length')
if not isscalar(delta):
sys.exit('Input argument delta must be a scalar')
if delta <= 0:
sys.exit('Input argument delta must be positive')
mn, mx = Inf, -Inf
mnpos, mxpos = NaN, NaN
lookformax = True
for i in arange(len(v)):
this = v[i]
if this > mx:
mx = this
mxpos = x[i]
if this < mn:
mn = this
mnpos = x[i]
if lookformax:
if this < mx-delta:
maxtab.append((mxpos, mx))
mn = this
mnpos = x[i]
lookformax = False
else:
if this > mn+delta:
mintab.append((mnpos, mn))
mx = this
mxpos = x[i]
lookformax = True
return array(maxtab), array(mintab)