C语言实现Matlab中findpeaks函数

更改了内容,加入测试代码

代码环境是 vs2015




#include "stdafx.h"
#include <stdlib.h>
#include <iostream>

/*
* 函数:  findPeaks
* 参数:  *src        源数据数组
*          src_lenth   源数据数组长度
*          distance    峰与峰,谷与谷的搜索间距
*          *indMax     找到的峰的index数组
*          *indMax_len 数组长度
*          *indMin     找到的谷的index数组
*          *indMin_len 数组长度
*/
void findPeaks(double *src, double src_lenth, double distance, int *indMax, int *indMax_len, int *indMin, int *indMin_len)
{
	int *sign = (int*)malloc(src_lenth * sizeof(int));
	int max_index = 0,
		min_index = 0;
	*indMax_len = 0;
	*indMin_len = 0;

	for (int i = 1; i<src_lenth; i++)
	{
		double diff = src[i] - src[i - 1];
		if (diff>0)          sign[i - 1] = 1;
		else if (diff<0) sign[i - 1] = -1;
		else                sign[i - 1] = 0;
	}
	for (int j = 1; j<src_lenth - 1; j++)
	{
		double diff = sign[j] - sign[j - 1];
		if (diff<0)      indMax[max_index++] = j;
		else if (diff>0)indMin[min_index++] = j;
	}

	int *flag_max_index = (int *)malloc(sizeof(int)*(max_index>min_index ? max_index : min_index));
	int *idelete = (int *)malloc(sizeof(int)*(max_index>min_index ? max_index : min_index));
	int *temp_max_index = (int *)malloc(sizeof(int)*(max_index>min_index ? max_index : min_index));
	int bigger = 0;
	double tempvalue = 0;
	int i, j, k;
	//波峰  
	for (int i = 0; i < max_index; i++)
	{
		flag_max_index[i] = 0;
		idelete[i] = 0;
	}
	for (i = 0; i < max_index; i++)
	{
		tempvalue = -1;
		for (j = 0; j < max_index; j++)
		{
			if (!flag_max_index[j])
			{
				if (src[indMax[j]] > tempvalue)
				{
					bigger = j;
					tempvalue = src[indMax[j]];
				}
			}
		}
		flag_max_index[bigger] = 1;
		if (!idelete[bigger])
		{
			for (k = 0; k < max_index; k++)
			{
				idelete[k] |= (indMax[k] - distance <= indMax[bigger] & indMax[bigger] <= indMax[k] + distance);
			}
			idelete[bigger] = 0;
		}
	}
	for (i = 0, j = 0; i < max_index; i++)
	{
		if (!idelete[i])
			temp_max_index[j++] = indMax[i];
	}
	for (i = 0; i < max_index; i++)
	{
		if (i < j)
			indMax[i] = temp_max_index[i];
		else
			indMax[i] = 0;
	}
	max_index = j;

	//波谷  
	for (int i = 0; i < min_index; i++)
	{
		flag_max_index[i] = 0;
		idelete[i] = 0;
	}
	for (i = 0; i < min_index; i++)
	{
		tempvalue = 1;
		for (j = 0; j < min_index; j++)
		{
			if (!flag_max_index[j])
			{
				if (src[indMin[j]] < tempvalue)
				{
					bigger = j;
					tempvalue = src[indMin[j]];
				}
			}
		}
		flag_max_index[bigger] = 1;
		if (!idelete[bigger])
		{
			for (k = 0; k < min_index; k++)
			{
				idelete[k] |= (indMin[k] - distance <= indMin[bigger] & indMin[bigger] <= indMin[k] + distance);
			}
			idelete[bigger] = 0;
		}
	}
	for (i = 0, j = 0; i < min_index; i++)
	{
		if (!idelete[i])
			temp_max_index[j++] = indMin[i];
	}
	for (i = 0; i < min_index; i++)
	{
		if (i < j)
			indMin[i] = temp_max_index[i];
		else
			indMin[i] = 0;
	}
	min_index = j;

	*indMax_len = max_index;
	*indMin_len = min_index;

	free(sign);
	free(flag_max_index);
	free(temp_max_index);
	free(idelete);
}

int main()
{
	double array[30] = {
		0.01513671875,
		- 0.0751953125,
		0.01318359375,
		0.0498046875,
		- 0.0458984375,
		- 0.0087890625,
		0.07373046875,
		- 0.06494140625,
		0.03564453125,
		0.03759765625,
		- 0.052734375,
		0.080078125,
		- 0.0185546875,
		- 0.0048828125,
		0.00341796875,
		- 0.03564453125,
		0.04541015625,
		0.02001953125,
		0.06298828125,
		0.02734375,
		0.0302734375,
		0.01220703125,
		0.02294921875,
		0.01220703125,
		0.0185546875,
		0.00048828125,
		0.00439453125,
		- 0.015625,
		- 0.00341796875,
		- 0.02197265625	};
	int peakFs[30] = { 0 };			//不知道会找到几个,故申请的稍大
	int peakFs_len = 0;				
	int peakFs2[30] = { 0 };		//不知道会找到几个,故申请的稍大
	int peakFs2_len = 0;
	findPeaks(array, 30, 5, peakFs, &peakFs_len, peakFs2, &peakFs2_len);
	std::cout << "找到的峰的下标:" << std::endl;
	for (int i = 0; i < peakFs_len; i++)
		std::cout << peakFs[i] << std::endl;
	std::cout << "找到的谷的下标:" << std::endl;
	for (int i = 0; i < peakFs2_len; i++)
		std::cout << peakFs2[i] << std::endl;
	system("pause");
    return 0;
}


测试结果:(若图小,请打开新窗口去看)



评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值