浮点精度matlab滤波器2

时间:2012-11-19 13:36:30

标签: matlab floating-point filtering

我有由filter2引起的舍入错误。 这是一个最小的代码示例:

format long

x=[ 0 0 0 0 0
 64 65 72 74 72
 104 111 109 106 112];

h=[ 0 0 0 0 0
 0 0.500000000000000 0 0.500000000000000 0
 0 0 0 0 0]

y=filter2(h,x, 'valid')
y_= x(2,2)/2 + x(2,4)/2
y__= sum(sum(x .* h))    
round(y)
round(y_)
round(y__)

结果

y = 69.499999999999986
y_ = 69.500000000000000
y_ = 69.500000000000000
ans = 69
ans = 70
ans = 70

我猜这是在fft域(或类似的东西)中进行过滤的结果。不幸的是,在验证测试向量时,这给我带来了问题,我再次生成FPGA实现。

如何修复/避免此错误?

PS我使用matlab 2007b。

编辑:2007a至2007b 编辑2:添加了y__示例

2 个答案:

答案 0 :(得分:1)

使用浮点运算执行的操作产生近似结果是预期的行为。浮点运算使用固定的位数来表示数字,每个浮点运算的结果四舍五入到最接近的可表示数字(除非设置了另一个舍入模式)。

特别是,执行FFT需要许多值的正弦和余弦,并且正弦和余弦不能精确表示,并且对这些值和FFT数据中的值的算术产生许多不能完全表示的中间结果。因此,FFT的结果预计是近似的。

对浮点FFT误差的研究表明,误差行为通常很好。但是,你不能指望结果会落在69.5的“正确”一侧,导致你想要的四舍五入。从本质上讲,期望对FFT结果进行舍入将产生精确结果是错误的。

通常,使用更高精度的浮点格式可以减少错误的大小。因此,使用更高的精度可以产生更接近理想结果的FFT结果。但是,请考虑进行舍入工作所需的内容。任何数字69.5或稍大一些都会变为70.任何略低于69.5的数字都会变为69,这是你不想要的。因此,根据需要进行舍入,无论错误有多小,都不会产生产生小于69.5的数字的错误。但是,每种浮点格式都有某些错误。 因此,没有精确性可以保证产生可以按照您希望的方式舍入的结果。(通过设置舍入模式可以稍微控制错误,从而根据需要向上或向下舍入。但是,FFT是一个复杂的操作,在最终产品中获得所需的舍入将需要在每个中间操作中控制舍入,这是不切实际的。)

因此,浮点FFT不会产生您想要的结果。您可以选择的一些选项是:

  • 改变你的期望;不要指望过滤器产生与精确算术相同的结果。
  • 使用直接算术执行滤波器,而不是FFT。 (我不使用Matlab,也不建议在Matlab中这样做的好方法。)请注意,只要所有中间值都以浮点格式表示,使用浮点算法执行此操作将产生精确结果。这通常仅适用于过滤器和数据中具有“简单”值的小型过滤器。 (为此目的,并假设二进制浮点格式,“简单”值是可以在浮点格式的小数部分中仅用几位表示的值,即那些是两个整数幂的总和的值。它们彼此接近,例如.625,即2 -1 +2 -3 。)
  • 使用精确算术。一些数学软件,如Maple和Mathematica,支持精确算术。据我所知,Matlab没有。这通常需要使用直接算术而不是FFT来执行滤波器,因为执行FFT完全需要更高的数学能力(精确地操纵正弦和余弦)。

既然你说这是用于测试,我建议你:

  • 允许结果中出现小错误。小错误是浮点运算的典型值,通常不会指示您正在测试的过滤器中的错误。您在测试中寻找的错误通常会产生大量错误。
  • 如果足够则使用直接算术,或者必要时使用精确算术。这将消耗更多的处理器时间。但是,测试通常不需要高性能,因此可以使用更多的处理器时间。

答案 1 :(得分:0)

处理此问题的标准方法是避免浮点比较。

不是检查两件事是否相等,而是检查绝对差是否小于某个epsilon。

因此,如果您想查看两个数字是否匹配,您可以这样做:

abs(y-y_)