C 平滑输入数据,无需使用数组或动态分配

C 平滑输入数据,无需使用数组或动态分配,c,signal-processing,moving-average,C,Signal Processing,Moving Average,我正在尝试平滑输入数据(实际正值),而不使用数组或动态分配。可能吗 结束条件是用户输入负数。例如: input: 1 2 3 4 5 -1 output: 1.5 2 3 4 4.5 如果您的问题是“我可以在不使用数组或动态分配的情况下声明未定义数量的变量吗?”,答案是否定的。您可以使用移动平均值来实现这一点。以最简单的形式 const int smooth_factor = 3; // the higher the value the more smooth it is. int sam

我正在尝试平滑输入数据(实际正值),而不使用数组或动态分配。可能吗

结束条件是用户输入负数。例如:

 input: 1 2 3 4 5 -1
output: 1.5 2 3 4 4.5 

如果您的问题是“我可以在不使用数组或动态分配的情况下声明未定义数量的变量吗?”,答案是否定的。

您可以使用移动平均值来实现这一点。以最简单的形式

const int smooth_factor = 3; // the higher the value the more smooth it is.
int samples = 0;
int total = 0;         // make long or long long if danger of overflow.

int smoothed(int new_sample)
{
   if (samples == smooth_factor)
   {
      total -= total / smooth_factor;
      samples -= 1;
   }
   total += new_sample;
   samples += 1;
   return total / samples;
}
实际上,如果使用两个平滑因子的幂,并使用移位操作,而不是按平滑因子除法,可能会使它更有效。 如果您愿意预先设定total和num样本的种子,也可以去掉if语句

const int smooth_factor = 16; // the higher the value the more smooth it is.
int total = 129;              // e.g. 129 = sum of first 16 samples

int smoothed(int new_sample)
{
      total -= total >> 4;
      total += new_sample;
      return total >> 4;
}
如果对多个值进行平滑处理,则可以删除其中一个偏移而不会产生显著影响(但我将把它作为练习)

没有内存,无法“过滤”信号。句号

使用n个内存插槽,可以实现FIR滤波器或IIR滤波器(或两者的组合)

如果你不喜欢数组符号
a[5],b[5]
那么可以通过声明单个变量的数组来改变规则,比如

 static a0=0,a1=0,a2=0,a3=0,   b0=0,b1=0,b2=0,b3=0;

 output = b3* B3 + b2*B2 + b1*B1 + b0* B0; // where B0..B3 are constant coefficients
 b3=b2;b2=b1;b1=b0; b0=new_sample;  // This is FIR filter (Finite impulse response)

 a0=output;
 output += a3*A3 + a2*A2 + a1*A1;   // and this implements an IIR filter
 a3=a2;a2=a1;a1=a0;                 // Infinite impulse response

数组的概念仍然存在。

如果可以将状态保存在几个变量或寄存器中而不是数组元素中,则可以使用IIR(或递归)过滤器进行实时处理。搜索DSP双四阶滤波器,这是IIR滤波器,在逐个采样处理数据时只需要4个状态变量


请注意,IIR滤波器将产生一些频率相关的非线性相位延迟。“平滑”的输出在相应的输入后经过一定数量的采样后才会出现,并且可能会在形状上出现偏差。

当你真正要问的是算法问题时,用一堆语言标记来射击你的帖子并没有真正的帮助。我不知道你脑子里有什么样的过滤,为什么会有过滤器,但是当然有过滤器不需要整个信号历史才能运作(正确的技术术语我可以逃脱。卡尔曼滤波器就是这种类型的一个例子)。我已经删除了java和C++标签,因为这个问题只与C有关。(我有没有提到想象是一个垂死的动物?):-)我不是说没有其他解决方案(比如提出的那个)。但是OP似乎没有尝试过很多东西,所以我不想发布一个,因为他只是给了他一些代码,而不是自己尝试输入。这不是移动平均线。移动平均需要存储N个优化前的样本,即可以存储前一个和,添加传入样本,并在“滑动窗口”中减去最后一个样本。此外,滑动窗口可以实现为循环缓冲区,优选大小为2^n,即使窗口的大小较小。