为什么 "N choose k" 方法 scipy.misc.comb(n,k) 在 Python2.x 和 Python3.x 之间差异如此之大?
Why does the "N choose k" method, scipy.misc.comb(n,k) differ so much between Python2.x and Python3.x?
在欧拉项目解决问题(剧透)中,这对我来说是一个问题:
Python2.7.10 / 0.13.0b1: scipy.misc.comb(40,20) -> array(137846528819.9994)
Python3.5.0 / scipy 0.16.0: scipy.misc.comb(40,20) -> 137846528820.00006
令人沮丧的是,我了解到我必须对结果调用 round()
函数,而不是直接转换为 int()
或使用 math.floor()
/math.ceil()
作为 Python 2 / 3 一致性。
是什么导致了两个 Python / SciPy 版本之间的这种差异?
SciPy 开发人员没有首先在 scipy.misc.comb()
内对返回结果调用 round()
有什么原因吗?
如果使用 exact=True
参数,您可以获得相同的整数(长)值。
exact : bool, optional
If `exact` is False, then floating point precision is used, otherwise
exact long integer is computed.
我没有安装足够的版本,但我怀疑浮点数差异与版本 13 和 14 之间的代码更改有关。13 returns array()
,结果, 14(及更高版本)returns 浮点数 (numpy.float64).
我建议查看 Python 代码本身,看看有什么不同。在 exact
的情况下它们看起来是一样的,但是浮动的情况是完全不同的。
v 13:
from scipy import special
k,N = asarray(k), asarray(N)
lgam = special.gammaln
cond = (k <= N) & (N >= 0) & (k >= 0)
sv = special.errprint(0)
vals = exp(lgam(N+1) - lgam(N-k+1) - lgam(k+1))
sv = special.errprint(sv)
return where(cond, vals, 0.0)
v 14
k,N = asarray(k), asarray(N)
cond = (k <= N) & (N >= 0) & (k >= 0)
vals = binom(N, k)
if isinstance(vals, np.ndarray):
vals[~cond] = 0
elif not cond:
vals = np.float64(0)
return vals
exact
代码是迭代的,可能会比较慢(当N,k在100s时):
val = 1
for j in xrange(min(k, N-k)):
val = (val*(N-j))//(j+1)
在欧拉项目解决问题(剧透)中,这对我来说是一个问题:
Python2.7.10 / 0.13.0b1: scipy.misc.comb(40,20) -> array(137846528819.9994)
Python3.5.0 / scipy 0.16.0: scipy.misc.comb(40,20) -> 137846528820.00006
令人沮丧的是,我了解到我必须对结果调用 round()
函数,而不是直接转换为 int()
或使用 math.floor()
/math.ceil()
作为 Python 2 / 3 一致性。
是什么导致了两个 Python / SciPy 版本之间的这种差异?
SciPy 开发人员没有首先在 scipy.misc.comb()
内对返回结果调用 round()
有什么原因吗?
如果使用 exact=True
参数,您可以获得相同的整数(长)值。
exact : bool, optional If `exact` is False, then floating point precision is used, otherwise exact long integer is computed.
我没有安装足够的版本,但我怀疑浮点数差异与版本 13 和 14 之间的代码更改有关。13 returns array()
,结果, 14(及更高版本)returns 浮点数 (numpy.float64).
我建议查看 Python 代码本身,看看有什么不同。在 exact
的情况下它们看起来是一样的,但是浮动的情况是完全不同的。
v 13:
from scipy import special
k,N = asarray(k), asarray(N)
lgam = special.gammaln
cond = (k <= N) & (N >= 0) & (k >= 0)
sv = special.errprint(0)
vals = exp(lgam(N+1) - lgam(N-k+1) - lgam(k+1))
sv = special.errprint(sv)
return where(cond, vals, 0.0)
v 14
k,N = asarray(k), asarray(N)
cond = (k <= N) & (N >= 0) & (k >= 0)
vals = binom(N, k)
if isinstance(vals, np.ndarray):
vals[~cond] = 0
elif not cond:
vals = np.float64(0)
return vals
exact
代码是迭代的,可能会比较慢(当N,k在100s时):
val = 1
for j in xrange(min(k, N-k)):
val = (val*(N-j))//(j+1)