明确要求不产生假设的假设策略

时间:2018-09-19 17:06:30

标签: python numpy python-hypothesis

from functools import partial
import hypothesis as h
import hypothesis.strategies as hs
import hypothesis.extra.numpy as hnp
import numpy as np


floats_notnull = partial(hs.floats, allow_nan=False, allow_infinity=False)
complex_notnull = partial(hs.complex_numbers, allow_nan=False, allow_infinity=False)

data_strategy_real = hnp.arrays(
    np.float64,
    hs.tuples(hs.integers(min_value=2, max_value=50),
              hs.integers(min_value=2, max_value=5)),
    floats_notnull()
)

data_strategy_complex = hnp.arrays(
    np.complex64,
    hs.tuples(hs.integers(min_value=2, max_value=50), hs.just(1)),
    complex_notnull()
)

data_strategy = hs.one_of(data_strategy_real, data_strategy_complex)

如果多次运行data_strategy.example(),您会注意到结果中的某些值具有无限的实部或虚部。我的目的是明确禁止无限或NaN零件。

我在做什么错了?

更新:如果我使用

data_strategy = hs.lists(complex_notnull, min_size=2, max_size=50)

并将其转换为测试中的数组,问题似乎消失了。复数溢出了吗?我没有收到关于假说溢出的常见弃用警告。

如果我使用

data_strategy = data_strategy_real

没有inf出现。

2 个答案:

答案 0 :(得分:3)

  

complex64类型太小并且正在溢出。假说以某种方式未能抓住这一点。

是的,此问题的根本原因是,您生成了 64位有限浮点数,然后将其强制转换为32位(因为array = np.array(['1', '2', '3', 'string']) def safe_float(x): try: x = float(x) except: pass return x array = np.array(list(map(safe_float, array)), dtype=object) print(array) array([1.0, 2.0, 3.0, 'string'], dtype=object) 是一对32-位浮动)。您可以使用complex64的{​​{1}}参数来解决此问题:

width=32

并且您没有得到通常的溢出检查,因为目前it's only implemented for floats and integers。我已经打开(编辑并修复)issue #1591来检查复杂和字符串类型。

答案 1 :(得分:1)

complex64类型太小并且正在溢出。假说以某种方式未能抓住这一点。

切换到complex128暂时解决了该问题。