为什么会发生以下零分割错误?
>>> from uncertainties import ufloat
>>> a = ufloat((0,0))
>>> x = ufloat((0.3,0.017))
>>> a**x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/uncertainties/__init__.py", line 601, in f_with_affine_output
if arg.derivatives
File "<string>", line 1, in <lambda>
ZeroDivisionError: 0.0 cannot be raised to a negative power
>>> 0.0**x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/uncertainties/__init__.py", line 601, in f_with_affine_output
if arg.derivatives
File "<string>", line 1, in <lambda>
ValueError: math domain error
这两者都不应该只返回0.0
吗?
答案 0 :(得分:3)
情况非常微妙:
一方面,你是对的,两个结果在数学上都应为0。
实际上,行为应该与Python的行为相同:
>>> 0.**0.3
0.0
当指数具有不确定性时,结果应如此 完全为0(无不确定性),因为Python结果始终为0。
案例a = 0±0
很特殊:a**x
对于正x
为0,即使
x
有不确定性(结果未定义为零或负数
x
值)。另一方面,如果a=0±0.1
,a**x
的值
是不确定的,因为一个人不能承担负面的(实际)力量
数字(和a
可以是负数,如果它具有非零不确定性)(除非使用
复数,这不是不确定性的目的
封装)。
另一方面,不确定性模块允许用户随时改变数字的不确定性,并仍然得到正确的结果。这与上面的“理想”数学结果发生冲突:如果a = 0±0
,则a**x
的结果可能稍后未定义;相反,如果a = 0±0.3
,结果应该是未定义的,但如果a
的不确定性后来改为0,则应该以某种方式变为0.
从技术上讲,这一切都归结为a**x
0&lt; {0} x&lt; 1在a = 0中定义但在那里不可微分:零不确定性的情况应该起作用(函数被定义),但非零不确定性必须产生误差(导数未定义)。这两种情况都必须以某种方式动态处理,因为用户可以即时更改不确定性。
这是一个有趣的情况,所以我会再次考虑是否可以以一种优雅的方式修改不确定性模块并适应这个问题。
PS :从版本2.3.5开始, the uncertainties package正确处理问题的案例,更常见的是所有情况下实际存在不确定性的情况具有零不确定性(即使相同的数字但具有非零不确定性会通过误差的线性传播给出未定义的错误,如问题中所示)。
答案 1 :(得分:0)
我认为只要指数小于1,就会发生ZeroDivisionError
。窒息的代码部分试图采用衍生产品。我对高中微积分的模糊回忆告诉我x ** y
的导数是y * x ** (y - 1)
。
那就是说,我同意你的例子评估为0是直观的。要么我们的直觉是错误的(就像我的微积分一样糟糕,我不知道关于真正的数学家和科学家希望不确定性起作用,写这个包的人似乎知道他在做什么,加上他包括了很多测试),或者我们确实是对的,他需要为提高零的特殊情况添加处理(与对于权力来说是零不确定性。