Ошибка нулевого деления в пакете неопределенностей питона
Почему возникает следующая ошибка деления на ноль?
>>> 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
?
2 ответа
Ситуация довольно тонкая:
С одной стороны, вы правы, оба результата математически должны быть 0.
Фактически, поведение должно быть таким же, как в Python:
>>> 0.**0.3 0.0
Когда у показателя есть неопределенность, результат должен быть точно 0 (нет неопределенности), так как результат Python всегда равен 0.
Дело
a = 0±0
особенный:a**x
0 для положительногоx
, даже еслиx
имеет неопределенность (результат не определен для нуля или отрицательногоx
ценности). С другой стороны, еслиa=0±0.1
, значениеa**x
не определено, потому что нельзя принять (реальную) силу отрицательного числа (иa
может быть отрицательным, если имеет ненулевую неопределенность) (если только не используются комплексные числа, что не является целью пакета неопределенностей).С другой стороны, модуль неопределенностей позволяет пользователям изменять неопределенности чисел в любое время и при этом получать правильные результаты. Это противоречит "идеальным" математическим результатам, указанным выше: если
a = 0±0
, то результатa**x
может позже быть неопределенным; взаимно, еслиa = 0±0.3
, результат должен быть неопределенным, но должен как-то становиться равным 0, если неопределенностьa
позже изменен на 0.
Технически все это сводится к тому, что Это интересная ситуация, поэтому я снова подумаю о том, можно ли каким-то элегантным образом изменить модуль неопределенностей, и учту ли это проблему. PS: Начиная с версии 2.3.5, пакет неопределенностей правильно обрабатывает случаи вопроса, а в более общем случае - все случаи, когда число с неопределенностью фактически имеет нулевую неопределенность (даже если то же самое число, но с ненулевой неопределенностью даст неопределенная ошибка через линейное распространение ошибки, как в вопросе).a**x
с 0
Я думаю ZeroDivisionError
будет происходить всякий раз, когда показатель степени меньше 1. Удушающий фрагмент кода пытается получить производную. Мое туманное воспоминание об исчислении средней школы говорит мне, что производная от x ** y
является y * x ** (y - 1)
,
Тем не менее, я согласен, что ваши примеры будут интуитивно понятны для оценки 0. Либо наша интуиция неверна (как бы плохо ни было мое исчисление, я понятия не имею, как настоящие математики и ученые хотят, чтобы неопределенности работали, и парень, который написал, что этот пакет, кажется, знает, что он делает, плюс он включил много тестов), или, возможно, мы действительно правы, и ему нужно добавить обработку для особого случая возведения нуля (с нулевой неопределенностью) в степень.