Javascript “查找本地”;“平坦”;除了噪声数据的局部极大值和极小值

Javascript “查找本地”;“平坦”;除了噪声数据的局部极大值和极小值,javascript,c++,algorithm,signal-processing,data-processing,Javascript,C++,Algorithm,Signal Processing,Data Processing,有一个记录数为10000s的时间应力谱 以10e-5至1HZ的随机频率记录时间戳应力 开始时,我试图找到: 局部峰谷,波动高于一定阈值(如0.6个单位) 这是一种过滤噪音和记录压力显著变化的非常简单的方法 我在网上搜索,常用的方法是去噪,找到局部最大值和最小值 另一方面,我用以下方式实现的遗留代码(Javascript) 函数过滤频谱(res,minor){ var filted=[];//已过滤次循环的数组 var lookformax=1;//1表示查找最大值,0表示查找最小值 无功电流

有一个记录数为10000s的时间应力谱

以10e-5至1HZ的随机频率记录时间戳应力

开始时,我试图找到:

  • 局部峰谷,波动高于一定阈值(如0.6个单位)
  • 这是一种过滤噪音和记录压力显著变化的非常简单的方法
我在网上搜索,常用的方法是去噪,找到局部最大值和最小值

另一方面,我用以下方式实现的遗留代码(Javascript)

函数过滤频谱(res,minor){
var filted=[];//已过滤次循环的数组
var lookformax=1;//1表示查找最大值,0表示查找最小值
无功电流应力;
var mx_指数=0;
var mn_指数=0;
对于(变量i=0;ires[mx_index].psi){
mx_指数=i;
}
如果(当前应力恢复[mn_索引].psi+轻微){
push(res[mn_index]);
mx_指数=i;
lookformax=1;
}
}
回流过滤;
}
输出如下图所示的结果没有问题

现在光谱由峰谷类型的点表示

但是,如果图片“强>平< /强>,则中间有一些区域。过度简化忽略了平坦区域,错误地表述了峰谷的斜率/(或频率)

是否有一些简单的算法将原始信号转换为峰平谷类型的表示

我对DSP还不太熟悉。提前感谢您的建议和反馈

就像下图中的红色虚线一样

一个想法是:

  • 始终选择系列的第一个点和最后一个点
  • 寻找通过这两个端点偏离直线最大的点,并选择该点
  • 在新选择的点将序列拆分为两个,使该点是第一个子序列中的最后一个点,第二个子序列中的第一个点。然后使用递归将上述算法应用于这两个子序列
  • 当发现的最大偏差小于阈值时,停止递归。在这种情况下,只保留端点
这是一个实现,在一个数据集上有一个演示,与您在问题中所描述的类似,但它是一个简单的
[x,y]
对数组,因为我无法从您的问题中完全看出您的数据是如何构造的(但是
y
似乎对应于
psi
):

函数简化(多段线,maxdy){
函数重现(第一个,最后一个){
设[x0,y0]=多段线[第一];
设[x1,y1]=多段线[last];
设m=(y1-y0)/(x1-x0);
设localMaxdy=0;
让选择=0;
for(设i=first+1;ilocalMaxdy){
选择=i;
localMaxdy=dy;
}
}
返回localMaxdy
一个想法是:

  • 始终选择系列的第一个点和最后一个点
  • 寻找通过这两个端点偏离直线最大的点,并选择该点
  • 在新选择的点将序列拆分为两个,使该点是第一个子序列中的最后一个点,第二个子序列中的第一个点。然后使用递归将上述算法应用于这两个子序列
  • 当发现的最大偏差小于阈值时停止递归。在这种情况下,只保留端点
这是一个实现,在一个数据集上有一个演示,与您在问题中所描述的类似,但它是一个简单的
[x,y]
对数组,因为我无法从您的问题中完全看出您的数据是如何构造的(但是
y
似乎对应于
psi
): function filtSpectrum(res, minor){ var filted = []; //array of filted minor cycles var lookformax = 1; // 1 for look for max, 0 for look for min var currentstress; var mx_index = 0; var mn_index = 0; for (var i=0; i < arrayLength; i++){ currentstress = res[i].psi; if(currentstress > res[mx_index].psi){ mx_index = i; } if (currentstress < res[mn_index].psi){ mn_index = i; } if(lookformax === 1){ if(currentstress < res[mx_index].psi - minor){ filted.push(res[mx_index]); mn_index = i; lookformax =0; } }else if (currentstress > res[mn_index].psi + minor){ filted.push(res[mn_index]); mx_index = i; lookformax = 1; } } return filted; }