zero division error in python uncertainties package

瘦欲@ 提交于 2019-12-07 14:29:37

问题


Why does the following zero division error occur?

>>> 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

Shouldn't these both just return 0.0?


回答1:


The situation is quite subtle:

  1. On one hand, you're right, both results should mathematically be 0.

    In fact, the behavior should be the same as Python's:

    >>> 0.**0.3
    0.0
    

    When the exponent has an uncertainty the result should thus be exactly 0 (no uncertainty), since the Python result is always 0.

    The case a = 0±0 is special: a**x is 0 for positive x, even if x has an uncertainty (the result is undefined for zero or negative x values). On the other hand, if a=0±0.1, the value of a**x is undefined because one cannot take the (real) power of a negative number (and a can be negative, if it has a non-zero uncertainty) (unless one uses complex numbers, which is not the purpose of the uncertainties package).

  2. On the other hand, the uncertainties module allows users to change the uncertainties of numbers at any time and still get correct results. This clashes with the "ideal" mathematical results above: if a = 0±0, then the result of a**x might later be undefined; reciprocally, if a = 0±0.3, the result should be undefined, but should somehow become 0 if the uncertainty of a is later changed to 0.

Technically, this all boils down to the fact that a**x with 0 < x < 1 is defined in a = 0 but is not differentiable there: the case of a zero uncertainty should work (the function is defined), but a non-zero uncertainty must yield an error (the derivative is not defined). Both of these cases have to somehow be handled dynamically, since the uncertainties can be changed on-the-fly by the user.

This is an interesting situation, so I will think again about whether the uncertainties module can be modified in some elegant way and accomodate this issue.

PS: Starting with version 2.3.5, the uncertainties package correctly handles the cases of the question, and more generally all cases where a number with uncertainty actually has a zero uncertainty (even if the same number but with a non-zero uncertainty would give an undefined error through linear propagation of error, like in the question).




回答2:


I think the ZeroDivisionError is going to happen whenever the exponent is less than 1. The section of code that is choking is trying to take the derivative. My hazy recollection of high-school calculus tells me that the derivative of x ** y is y * x ** (y - 1).

That said, I agree that it would be intuitive for your examples to evaluate to 0. Either our intuition is wrong (as bad as my calculus is, I have no idea about how real mathematicians and scientists want uncertainties to work, and the guy who wrote this package seems to know what he's doing, plus he included a lot of tests), or perhaps we are indeed right and he needs to add handling for the special case of raising zero (with zero uncertainty) to a power.



来源:https://stackoverflow.com/questions/10198753/zero-division-error-in-python-uncertainties-package

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!