0

我遇到了由 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 Edit2:添加了 y__ 示例

4

2 回答 2

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 需要更高的数学能力(精确地处理正弦和余弦)。

既然你说这是为了测试,我建议你:

  • 允许结果中有小错误。小错误是浮点运算的典型特征,通常并不表示您正在测试的过滤器中存在错误。您在测试中寻找的错误通常会产生大量错误。
  • 如果足够,请使用直接算术,如果需要,请使用精确算术。这将消耗更多的处理器时间。但是,测试通常不需要高性能,因此可以使用更多的处理器时间。
于 2012-11-20T02:00:50.270 回答
0

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

与其检查两个事物是否相等,不如检查绝对差是否小于某个 epsilon。

因此,如果您想查看您的两个数字是否匹配,您可以执行以下操作:

abs(y-y_)
于 2012-11-19T14:02:09.467 回答