Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 随时间平滑值:移动平均还是更好?_Algorithm_Theory_Moving Average - Fatal编程技术网

Algorithm 随时间平滑值:移动平均还是更好?

Algorithm 随时间平滑值:移动平均还是更好?,algorithm,theory,moving-average,Algorithm,Theory,Moving Average,我现在正在编写一些东西,从硬件罗盘中获取一系列随时间变化的值。这个指南针非常精确,并且经常更新,结果是如果它稍微抖动,我会得到一个奇数值,这个值与它的邻居非常不一致。我想消除这些值 在阅读了一些文章之后,我想要的似乎是高通滤波器、低通滤波器或移动平均。移动平均值我可以用它来计算,只需保留最后5个值的历史记录,然后在我的代码下游使用这些值的平均值,我曾经使用过最新的值 我认为,这应该可以很好地消除这些抖动,但我觉得这可能效率很低,而且这可能是合适的程序员已知的问题之一,有一个非常巧妙的数学解决方案

我现在正在编写一些东西,从硬件罗盘中获取一系列随时间变化的值。这个指南针非常精确,并且经常更新,结果是如果它稍微抖动,我会得到一个奇数值,这个值与它的邻居非常不一致。我想消除这些值

在阅读了一些文章之后,我想要的似乎是高通滤波器、低通滤波器或移动平均。移动平均值我可以用它来计算,只需保留最后5个值的历史记录,然后在我的代码下游使用这些值的平均值,我曾经使用过最新的值

我认为,这应该可以很好地消除这些抖动,但我觉得这可能效率很低,而且这可能是合适的程序员已知的问题之一,有一个非常巧妙的数学解决方案

然而,我是那些糟糕的自学成才的程序员之一,没有任何正规的教育,哪怕是与计算机科学或数学有点模糊的联系。仔细阅读一下,这可能是一个高通或低通滤波器,但我找不到任何能解释像我这样的黑客对这些算法对一系列值的影响的术语,更不用说数学是如何工作的了。举例来说,给出的答案在技术上确实回答了我的问题,但只是那些可能已经知道如何解决问题的人能够理解的术语

这将是一个非常可爱和聪明的人,他可以用一个艺术毕业生可以理解的术语来解释这是一个什么样的问题,以及解决方案是如何工作的

移动平均线我可以和。。。 但我觉得很可能 效率很低

移动平均线真的没有理由是低效的。将所需的数据点数量保留在某个缓冲区中(如循环队列)。在每个新数据点上,弹出最旧的值并从总和中减去,然后推送最新的值并将其添加到总和中。因此,每个新数据点实际上只需要一个pop/push、一个加法和一个减法。移动平均值总是这个移位和除以缓冲区中的数值

如果您同时从多个线程接收数据,那么它会变得有点棘手,但因为您的数据来自一个硬件设备,这在我看来非常可疑


哦,还有:糟糕的自学成才的程序员联合起来了

如果您试图删除偶尔出现的奇数值,低通滤波器是您确定的三个选项中最好的。低通滤波器允许低速变化,如手动旋转罗盘引起的变化,而拒绝高速变化,如道路颠簸引起的变化

移动平均线可能是不够的,因为数据中单个“光点”的影响将影响多个后续值,具体取决于移动平均线窗口的大小

如果很容易检测到奇数值,您甚至可以使用完全忽略它们的故障排除算法:

if (abs(thisValue - averageOfLast10Values) > someThreshold)
{
    thisValue = averageOfLast10Values;
}
下面是一个guick图来说明:


第一个图形是输入信号,有一个令人不快的小故障。第二个图表显示了10个样本移动平均数的效果。最后一张图是10个样本的平均值和上面显示的简单故障检测算法的组合。当检测到故障时,将使用10个样本的平均值,而不是实际值。

如果移动平均值必须很长才能达到所需的平滑,并且实际上不需要任何特定的内核形状,那么最好使用指数衰减的移动平均值:

a(i+1) = tiny*data(i+1) + (1.0-tiny)*a(i)
选择
tiny
作为适当的常数(例如,如果选择tiny=1-1/N,其平均值将与大小为N的窗口相同,但在较旧的点上分布不同)


无论如何,由于移动平均线的下一个值仅取决于上一个值和您的数据,因此您不必保持队列或任何东西。你可以这样想,“好吧,我有了一个新的点,但我并不真的相信它,所以我将保留80%的旧的测量估计值,只相信这个新的数据点20%”。这与说“好吧,我只相信这个新的点20%,我将使用我相信相同数量的其他4个点”差不多,除了没有明确地接受其他4个点,您假设上次所做的平均值是合理的,因此您可以使用以前的工作。

如果使用正确的值,指数衰减移动平均值可以“手动”使用趋势计算。如果您正在寻找“具有10%平滑度的指数平滑移动平均线”,请参阅,了解如何使用笔和纸快速完成此操作。但既然你有一台计算机,你可能想做二进制移位,而不是十进制移位;)


这样,您只需要为当前值设置一个变量,为平均值设置一个变量。下一个平均值可以从中计算出来。

有一种称为距离门的技术,可以很好地处理低发生率的伪采样。假设使用上述一种过滤技术(移动平均、指数),一旦拥有“足够”的历史记录(一个时间常数),就可以在将新的传入数据样本添加到计算之前测试其合理性

需要了解信号的最大合理变化率。将原始样本与最近的平滑值进行比较,如果差值的绝对值大于允许范围,则丢弃该样本(或用一些启发式方法代替,例如基于斜率的预测;微分或双指数平滑的“趋势”预测值)

移动平均值