【问题标题】:What are the best practices for floating-point comparisons in Matlab?Matlab中浮点比较的最佳实践是什么?
【发布时间】:2014-05-23 08:38:39
【问题描述】:

显然,浮点比较总是很棘手。我的(科学)代码中有很多断言检查,所以我经常必须检查总和是否相等以及类似的问题。

是否有一种快速简便/最佳实践的方法来执行这些检查?

我能想到的最简单的方法是为固定容差浮动比较构建一个自定义函数,但这对我来说似乎很难看。我更喜欢内置的解决方案,或者至少是非常清晰易懂的解决方案。

【问题讨论】:

    标签: matlab floating-point


    【解决方案1】:

    我认为它很可能必须是您自己编写的函数。可以这么说,我经常使用三样东西来运行计算向量测试:

    最大绝对误差

    return max(abs(result(:) - expected(:))) < tolerance
    

    这会逐点计算最大绝对误差,并告诉您这是否小于某个容差。

    最大错误计数

    return sum( (abs(result(:) - expected(:))) < tolerance )
    

    这将返回超出公差范围的点数。修改返回百分比也很容易。

    均方根误差

    return norm(result(:) - expected(:)) < rmsTolerance
    

    由于存在这些和许多其他标准来比较浮点数组,我建议编写一个函数来接受计算结果、预期结果、容差和比较方法。通过这种方式,您可以使您的检查变得非常紧凑,并且比试图解释您在 cmets 中所做的事情要简单得多。

    【讨论】:

    • 使用eps 表示容差通常是个好主意。此外,R2013a 及更高版本在单元测试框架中具有 assertEqual 语句,这将有所帮助。
    • 确实如此,但有时可能还不够,因为您可能在某些计算过程中多次丢失精度。
    • 谢谢,eps() 听起来是个好主意。我实际上希望在单元测试框架之外有某种 assertEqual。
    【解决方案2】:

    如果输入非常大或非常小的数字,任何固定公差都会失败,最简单的解决方案是使用eps 来获得双精度:

    abs(A-B)<eps(A)*4
    

    4 是一个完全任意的数字,在大多数情况下就足够了。

    【讨论】:

      【解决方案3】:

      不知道任何特殊的内置解决方案。也许使用eps 函数?

      例如,您可能知道这将导致 False(即0):

      >> 0.1 + 0.1 + 0.1 == 0.3
      
      ans =
      
           0
      

      但使用 eps 你可以执行以下操作,结果符合预期:

      >> (0.1+0.1+0.1) - 0.3  < eps     
      
      ans =
      
           1
      

      【讨论】:

      • 您应该将数量级传递给eps,因为eps(10000) 大于默认值eps(1)
      【解决方案4】:

      我在 xUnit 方面有很好的经验,这是一个 Matlab 的单元测试框架。安装好之后就可以使用了:

      • assertVectorsAlmostEqual(a,b)(检查向量之间的 normwise 接近度;可配置的绝对/相对容差和合理的默认值)
      • assertElementsAlmostEqual(a,b)(相同的检查,但每个条目都按元素进行 - 所以[1 1e-12][1 -1e-9] 将与前者比较,但与后者不相等)。

      它们经过充分测试,使用速度快且清晰易读。函数名称很长,但使用任何像样的编辑器(或 Matlab 编辑器)您都可以将它们写为assertV&lt;tab&gt;

      【讨论】:

        【解决方案5】:

        对于同时了解 MATLAB 和 Python (NumPy) 的人来说,检查以下 Python 函数的代码可能会很有用:

        numpy.allclose(a, b, rtol=1e-05, atol=1e-08)
        numpy.isclose(a, b, rtol=1e-05, atol=1e-08, equal_nan=False)
        

        【讨论】:

        • 这个问题是关于 MATLAB,而不是 Python numpy。仔细阅读问题标题和标签。此外,这对于那些不熟悉 Python 和numpy 的人来说可能没有建设性,因此检查这些的实现是没有用的。
        • 我的经验是很多人同时使用matlab和python,所以对那些人来说做代码交叉检查很有用
        • 根据我在 StackOverflow 上的经验,很多在这里回答 MATLAB 问题的人并不了解 Python。我可能是这里为数不多的同时对两者都比较了解的人之一,鉴于我的观点,这个答案没有用。你是否想离开它取决于你,但我会留下我的反对票。并不是我认为您的答案在技术上不正确,而是因为您在标签不兼容的问题中放置了答案。
        • 但是,如果您将等效的 numpy 代码翻译到 MATLAB,那么这是一个非常有用的答案,我倾向于投票。这样,您不仅可以指出 numpy 已有的功能,而且还为我们提供了在 MATLAB 中执行此操作的方法。
        猜你喜欢
        • 2012-09-25
        • 1970-01-01
        • 2010-09-11
        • 1970-01-01
        • 2017-03-28
        • 1970-01-01
        相关资源
        最近更新 更多