Python OverflowError:在不同的运行中以不同方式引发数学范围错误

时间:2014-09-13 07:20:14

标签: python numpy scipy overflow exponent

我的程序似乎几乎任意崩溃。

我的代码包括以下两行:

z[i, j] = -math.exp(oneminusbeta[j, i])
weights[i,j] = math.exp(beta[j,i] + oneminusbeta[j,i])

我之前在包含2个维度的数据上运行了我的整个代码,它是7341 x 648。我完全没有运行该代码的问题。

但是现在我使用的数据大约是其十倍。这是71678 x 648,我收到了这个错误:

OverflowError: math range error

我没有在任何具体问题上得到这个。我在每行代码之前记录注释,以便我可以看到导致崩溃的原因,并且看起来崩溃发生在上面提到的第二行(weights[i,j] = math.exp(beta[j,i] + oneminusbeta[j,i]))上。 / p> 事情是,它在不同时间崩溃。 起初,它在weights[30816, 42]坠毁。然后在weights[55399, 43]。然后在z[33715,45]。但是所有3个案例的数据都相同。

问题是什么?这是与python的内存相关问题吗?顺便说一句,我也在使用Numba

修改

我忘了提及,我已经设置了阈值,以便exp()函数中的内容不会超过709或-708,所以从技术上来说不应该是溢出

2 个答案:

答案 0 :(得分:2)

您的计算结果无法在您的计算机上显示。这可能意味着math.exp(...)大于约10 308 ,或者传递给math.exp()的参数大于约710。

尝试在每次计算前打印beta[j,i]oneminusbeta[j,i]的值。

事实上,您不必在每行代码之前打印注释。相反,尝试使用try块包装计算,如下所示:

try:
  weights[i,j] = math.exp(beta[j,i] + oneminusbeta[j,i])
except OverflowError:
  print "Calculation failed! j=%d i=%d beta=%f oneminusbeta=%f"%(j,i,beta[j,i],oneminusbeta[j,i])
  raise

答案 1 :(得分:1)

你的溢出几乎肯定是真正的溢出;你的一个值太大而不适合Python float(意思是C double)。


那么,为什么每次都会在不同的地方发生?

因为你正在使用Numba。

Numba JIT - 编译你的代码。如果它检测到没有争用,它可以重新排序你的代码 - 或者至少在理论上,它可以在多个内核或GPU上并行运行它(尽管我认为如果你明确地用它编码它,你现在只能得到GPU计算numba.cuda)。

无论如何,这意味着通过代码的路径可能是不确定的。如果有多个地方可能发生溢出,则无法预测哪一个会失败并触发异常。


无论如何,这并不重要。如果你的计算量很大,你必须解决这个问题。事实上,每次不同的溢出不应该使 更难调试 - 特别是因为它显然通常在一个地方发生,而不是总是如此。