【问题标题】:Floating point precision matlab filter2浮点精度matlab滤波器2
【发布时间】:2012-11-19 13:36:29
【问题描述】:

我遇到了由 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__ 示例

【问题讨论】:

  • 这不是filter2的问题,只是matlab的工作方式。它最多只能存储 14 位小数用于任何计算。
  • @Dennis:我的代码示例表明,如果我手动进行计算 (y_),我会得到正确的答案。而在 filter2 示例中我没有。那为什么不是 filter2 相关的问题呢?
  • 如果我的解决方案似乎不适用,请解释为什么需要进行舍入。
  • 我没有得到和你一样的结果(R2010b);我只是得到69.5 两个....你是什么版本?
  • @DennisJaheruddin:嗯嗯……不。 Matlab 对任何双精度数使用 IEEE754(阅读this)。那么你从哪里获得“14 位数”的知识呢?

标签: matlab floating-point filtering


【解决方案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 需要更强大的数学能力(精确地处理正弦和余弦)。

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

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

【讨论】:

    【解决方案2】:

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

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

    所以如果你想看看你的两个数字是否匹配,你可以这样做:

    abs(y-y_)
    

    【讨论】:

    • 我的建议是,根本不要对它们进行四舍五入,只需检查它们是否相同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    相关资源
    最近更新 更多