我真的很难从数组中找到加权和。 我有一个叫做频率[28]的数组(1D大小28)和相同大小的相同索引数组,叫做peak [28]。数组总是有一个值或零。我想要实现的是通过数组,从频率和幅度数组中检索两个值,同时忽略零。另外,我并没有试图找到整个阵列的加权平均值。
我想我不是很清楚。
例如说
frequency[n] = [0,0,0, a,b, 0,0,0, c,d,e, 0,0, f]
peak[n] = [0,0,0, z,y, 0,0,0, x,w,v, 0,0, u]
因此,我想忽略前三个区,因为它们为零,并找到(a,b)与(z,y)配对的加权平均值,然后忽略接下来的三个区间,然后再次找到(c,d, e)与(x,w,v)等配对。
请注意,我在数组中的值(大小是固定的)不是固定的。可能出现值的索引总是不同的。
我已经附加了检索数组的代码片段。 任何建议或指导都会有很大的帮助!
// peak search
threshold = 0;
for (ctr=0; ctr<n1; ctr++)
{
peak[ctr] = 0; // initialise arrays
freq_bin[ctr] =0;
frequency[ctr] = 0;
// magnitude calculation from fft output
fft_mag[ctr] = 10*(sqrt((fft_output[ctr].r * fft_output[ctr].r) + (fft_output[ctr].i * fft_output[ctr].i)))/(n);
threshold = 12;
if (fft_mag[ctr] >= threshold) // extract fft magnitudes only above threshold
{
peak[ctr] = fft_mag[ctr]; // store magnitude above threshold into peak array
freq_bin[ctr] = ctr; // location of each magnitude above threshold
frequency[ctr] = (freq_bin[ctr]*(10989/n)); // frequency calculation from magnitude location
}
}
对于不对代码进行评论,我深表歉意。
peak[ctr]
包含fft输出的峰值大小frequency[ctr]
包含相应的fft峰值幅度的频率值。 我有来自fft的多个峰值,输出数组看起来像这样;
peak[28] = [0 0 0 0 0 0 0 0 0 0 14 0 0 0 0 0 0 14 0 0 0 29 74 45 0 0 0 0]
frequency[28] = [0 0 0 0 0 0 0 0 0 0 462 0 0 0 0 0 0 714 0 0 0 924 966 1008 0 0 0 0]
因此,我需要计算:
答案 0 :(得分:0)
您可以将其视为状态机。它一次读取一个符号,并根据它改变状态。
有两种状态:起始状态和已读取某些数据的状态。
在起始状态下,如果下一个符号为零,则保持此状态。如果没有,请处理符号并更改状态。
在另一个状态中,如果下一个符号为零,则发出结果并更改状态。如果没有,请处理它。如果在此状态下遇到结束,则发出结果。
这是一个非常干净的Python实现:
class Averager:
def __init__(self):
self.averages = []
self.sumOfNumbers = 0
self.count = 0
def addToAverage(self, number, weight):
self.sumOfNumbers += number * weight
self.count += weight
def emitAverage(self):
self.averages.append(self.sumOfNumbers / self.count)
self.sumOfNumbers = 0
self.count = 0
def averagesOf(data, weights):
averager = Averager()
dataRead = False
def emitIfData():
if dataRead:
averager.emitAverage()
for number, weight in zip(data, weights):
if number == 0:
emitIfData()
dataRead = False
else:
averager.addToAverage(number, weight)
dataRead = True
emitIfData()
return averager.averages
print(averagesOf([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 462, 0, 0, 0, 0, 0, 0, 714, 0, 0, 0, 924, 966, 1008, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 29, 74, 45, 0, 0, 0, 0]))
输出:
[462.0, 714.0, 970.5405405405405]
答案 1 :(得分:0)
这里有一些近似于MCVE(How to create a Minimal, Complete, and Verifiable Example?)的代码。除此之外,我通过在非零数据集之前和之间留下一组零来压缩操作/感兴趣的数据。在这个问题中,3项加权平均值的计算似乎是错误的:
- 平均3 =(29x924 + 74x966 + 45x1008)/(29 + 74 + 45)= 938.8 Hz
这与该计划的计算一致。
代码:
#include <stdio.h>
int main(void)
{
enum { NUM_ENTRIES = 28 };
/* Input data */
double peak[NUM_ENTRIES] = { 0, 14, 0, 14, 0, 29, 74, 45, 0, };
double freq[NUM_ENTRIES] = { 0, 462, 0, 714, 0, 924, 966, 1008, 0, };
/* Output data */
double bin_av[NUM_ENTRIES];
int bin_lo[NUM_ENTRIES];
int bin_hi[NUM_ENTRIES];
int out = 0;
int ctr = 0;
while (ctr < NUM_ENTRIES)
{
/* Skip zeroed entries */
while (ctr < NUM_ENTRIES && (peak[ctr] == 0.0 || freq[ctr] == 0.0))
ctr++;
if (ctr < NUM_ENTRIES)
{
bin_lo[out] = ctr;
bin_hi[out] = ctr;
double w_sum = 0.0;
double f_sum = 0.0;
while (ctr < NUM_ENTRIES && (peak[ctr] != 0.0 && freq[ctr] != 0.0))
{
bin_hi[out] = ctr;
w_sum += peak[ctr] * freq[ctr];
f_sum += peak[ctr];
ctr++;
}
bin_av[out++] = w_sum / f_sum;
}
}
for (int i = 0; i < out; i++)
printf("%d .. %d: %6.1f\n", bin_lo[i], bin_hi[i], bin_av[i]);
return 0;
}
示例输出:
1 .. 1: 462.0
3 .. 3: 714.0
5 .. 7: 970.5
有足够的空间来改善输出(例如,回显输入数据的相关子集并不是一个坏主意。)
有了这个框架,您可以通过从FFT输出中的值计算peak
和freq
中的值,而不是使用硬编码数组,来回到使场景复杂化。 / p>