Ошибка нулевого деления в пакете неопределенностей питона

Почему возникает следующая ошибка деления на ноль?

>>> 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 ответа

Решение

Ситуация довольно тонкая:

  1. С одной стороны, вы правы, оба результата математически должны быть 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 может быть отрицательным, если имеет ненулевую неопределенность) (если только не используются комплексные числа, что не является целью пакета неопределенностей).

  2. С другой стороны, модуль неопределенностей позволяет пользователям изменять неопределенности чисел в любое время и при этом получать правильные результаты. Это противоречит "идеальным" математическим результатам, указанным выше: если a = 0±0, то результат a**x может позже быть неопределенным; взаимно, если a = 0±0.3, результат должен быть неопределенным, но должен как-то становиться равным 0, если неопределенность a позже изменен на 0.

Технически все это сводится к тому, что a**x с 0

Это интересная ситуация, поэтому я снова подумаю о том, можно ли каким-то элегантным образом изменить модуль неопределенностей, и учту ли это проблему.

PS: Начиная с версии 2.3.5, пакет неопределенностей правильно обрабатывает случаи вопроса, а в более общем случае - все случаи, когда число с неопределенностью фактически имеет нулевую неопределенность (даже если то же самое число, но с ненулевой неопределенностью даст неопределенная ошибка через линейное распространение ошибки, как в вопросе).

Я думаю ZeroDivisionError будет происходить всякий раз, когда показатель степени меньше 1. Удушающий фрагмент кода пытается получить производную. Мое туманное воспоминание об исчислении средней школы говорит мне, что производная от x ** y является y * x ** (y - 1),

Тем не менее, я согласен, что ваши примеры будут интуитивно понятны для оценки 0. Либо наша интуиция неверна (как бы плохо ни было мое исчисление, я понятия не имею, как настоящие математики и ученые хотят, чтобы неопределенности работали, и парень, который написал, что этот пакет, кажется, знает, что он делает, плюс он включил много тестов), или, возможно, мы действительно правы, и ему нужно добавить обработку для особого случая возведения нуля (с нулевой неопределенностью) в степень.

Другие вопросы по тегам