-
Notifications
You must be signed in to change notification settings - Fork 5
/
peakdet.cc
126 lines (114 loc) · 2.94 KB
/
peakdet.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
* Copyright (C) 2016 Andreas Weber <[email protected]>
*
* This program is based on Eli Billauers peakdet.m
* from http://billauer.co.il/peakdet.html
*
* from his page:
* "Eli Billauer, 3.4.05 (Explicitly not copyrighted).
* This function is released to the public domain; Any use is allowed."
*/
#include <octave/oct.h>
DEFUN_DLD (peakdet, args, nargout,
"-*- texinfo -*-\n\
@deftypefn {Loadable Function} {[@var{maxtab}, @var{mintab}] =} peakdet (@var{v}, @var{delta})\n\
finds the local maxima and minima \"peaks\" in the vector @var{v}.\n\
If @var{v} is a Matrix, return maximas and minimas for each column\n\
@end deftypefn")
{
octave_value_list retval;
int nargin = args.length ();
if (nargin != 2)
{
print_usage ();
return retval;
}
//FIXME: check, dass v is a vector and doesn't have complex numbers
//ColumnVector x (args(0).vector_value ());
Matrix v = args(0).matrix_value ();
int nr = v.rows ();
int nc = v.columns ();
double delta = args(1).double_value ();
if (error_state || delta <= 0)
error ("peakdet: delta has to be a real value > 0");
Cell ret_max(nc, 1);
Cell ret_min(nc, 1);
for (int j=0; j<nc; ++j)
{
Matrix mintab(nr, 1);
Matrix maxtab(nr, 1);
double mn = v(0, j);
double mx = v(0, j);
int mnpos = 0;
int mxpos = 0;
int num_max = 0;
int num_min = 0;
bool lookformax = 1;
double t;
for (int k=1; k<nr; ++k)
{
t = v(k, j);
if (t > mx)
{
mx = t;
mxpos = k;
}
if (t < mn)
{
mn = t;
mnpos = k;
}
if (lookformax)
{
if (t < (mx-delta))
{
maxtab(num_max++) = mxpos+1;
mn = t;
mnpos = k;
lookformax = 0;
}
}
else
{
if (t > mn+delta)
{
mintab(num_min++) = mnpos+1;
mx = t;
mxpos = k;
lookformax = 1;
}
}
}
maxtab.resize(num_max, 1);
mintab.resize(num_min, 1);
ret_max(j) = maxtab;
ret_min(j) = mintab;
}
if (nc > 1)
{
retval(0) = ret_max;
retval(1) = ret_min;
}
else
{
// Nur 1 Spalte -> Vektor zurückgeben
retval(0) = ret_max(0);
retval(1) = ret_min(0);
}
return retval;
}
/*
%!test
%! t=linspace(0,10,1000);
%! old_state = randn ('seed');
%! restore_state = onCleanup (@() randn ('seed', old_state));
%! randn ('seed', 10);
%! x=0.3*sin(t) + sin(1.3*t) + 0.9*sin(4.2*t) + 0.02*randn(size(t));
%! [maxtab, mintab] = peakdet(x', 0.5);
%! max_ref=[48 178 329 496 637 784 936];
%! min_ref=[112 273 411 558 716 856];
%!
%! assert(maxtab,max_ref')
%! assert(mintab,min_ref')
%!
*/