I have data that always looks something like this:
alt text http://michaelfogleman.com/static/images/chart.png
I need an algorithm to locate the three peaks.
direct approach, something like this:
#include
#include
#define MAXN 100
double smooth(double arr[], int n, int i)
{
double l,r,smoo;
l = (i - 1 < 0)?arr[0]:arr[i-1];
r = (i + 1 >= n)?arr[n-1]:arr[i+1];
smoo = (l + 2*arr[i] + r)/4;
return smoo;
}
void findmax(double arr[], int n)
{
double prev = arr[0];
int i;
int goup = 1;
for(i = 0; i < n; i++)
{
double cur = smooth(arr,n,i);
if(goup) {
if(prev > cur && i > 0) {
printf("max at %d = %lf\n", i-1, arr[i-1]);
goup = 0;
}
} else {
if(prev < cur)
goup = 1;
}
prev = cur;
}
}
int main()
{
double arr[MAXN] = {0,0,1,2,3,4,4,3,2,2,3,4,6,8,7,8,6,3,1,0};
int n = 20, i;
for(i = 0; i < n; i++)
printf("%.1lf ",arr[i]);
printf("\n");
findmax(arr,n);
return 0;
}
output:
0.0 0.0 1.0 2.0 3.0 4.0 4.0 3.0 2.0 2.0 3.0 4.0 6.0 8.0 7.0 8.0 6.0 3.0 1.0 0.0
max at 6 = 4.000000
max at 14 = 7.000000
1) set state = goup: going upward the curve;
2) if previuos value is greater than current then there was maximum:
print it and
set state to godown
3) while in godown state wait until previous is less then current and switch to (1)
to reduce noise use some smoothing function smooth()