3

Numpy 的 log 方法为 log(0) 提供 -inf。该值具有可比性:

>>> np.log(0) == np.log(0)
True

现在在单元测试中,以下工作正常:

self.assertEqual(np.log(0),np.log(0))

但这失败了:

self.assertAlmostEqual(np.log(0),np.log(0))

为什么会有这样的行为?这是一个错误还是有意的?如果需要,我如何检查两个浮点值是否几乎相等,并且对于 -inf 也能正常工作?

4

3 回答 3

5

从 unittest 的文档中,assertAlmostEqual(a, b)默认等同于round(a-b, 7) == 0. 所以在你的情况下,你有:

In [8]: np.log(0) - np.log(0)
Out[8]: nan

In [9]: round(np.log(0) - np.log(0), 7)
Out[9]: nan

In [11]: np.nan == 0
Out[11]: False

这就解释了为什么你的测试失败了。

为了使它工作使用unittest2这里是一个例子:

import unittest2
import numpy as np

class Test_Assertions(unittest2.TestCase):
    def test_float_inf(self):
        self.assertAlmostEqual(float('inf'), float('inf'))

    def test_numpy_inf(self):
        self.assertAlmostEqual(np.log(0),np.log(0))


unittest2.main()

输出:

..
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

注意:在 unittest2assertAlmostEqual()中,首先测试两个对象是否相等,如果是,那么结果是肯定的,否则做魔法(几乎相等),这就是它起作用的原因。它也应该在新的python版本(2.7>)中工作,因为它们中的大多数都实现了unittest2功能(我不确定这一点,因为我的工作站中没有python 2.7>)。

希望这可以帮助:)

于 2011-03-21T14:31:43.550 回答
4

Inf 和任何有限值之间的差异是 Inf 或 -Inf。这是 IEEE754 规范的一部分。由于assertAlmostEqual使用减法,这解释了行为。

以下是 FSUB 的 Intel x86 文档中的相关表格:

在此处输入图像描述

要解决您的问题,您将需要对 Inf 进行特殊情况处理。

于 2011-03-21T11:31:52.690 回答
3

I'd say that the difference between -∞ and -∞ can be as much as ∞. Therefore, they aren't really "almost equal".

If you want to ignore this special case, then something like this might be useful:

if valueA != valueB:
  self.assertAlmostEqual(valueA, valueB)
于 2011-03-21T11:27:45.753 回答