Эмуляция фиксированной точности в Python

Для университетского курса по численному анализу мы переходим от Maple к комбинации Numpy и Sympy для различных иллюстраций материала курса. Это потому, что студенты уже изучают Python семестр раньше.

Одна из трудностей, с которыми мы сталкиваемся, заключается в эмуляции фиксированной точности в Python. Maple позволяет пользователю указывать десятичную точность (скажем, 10 или 20 цифр), и с этого момента каждый расчет выполняется с такой точностью, чтобы вы могли видеть эффект ошибок округления. В Python мы попробовали несколько способов добиться этого:

  • Sympy имеет функцию округления до указанного числа цифр.
  • Mpmath поддерживает пользовательскую точность.

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

Наилучшим решением на данный момент являются пользовательские типы данных в Numpy. Используя float16, float32 и float64, мы смогли хотя бы дать представление о том, что может пойти не так. Проблема здесь в том, что нам всегда нужно использовать массивы из одного элемента и что мы ограничены этими тремя типами данных.

Существует ли что-то более гибкое для нашей цели? Или то, что мы ищем, спрятано где-то в документации mpmath? Конечно, есть обходные пути, заключающие каждый элемент вычисления в функцию округления, но это скрывает код для студентов.

1 ответ

Ты можешь использовать decimal, Есть несколько способов использования, например, localcontext или же getcontext,

Пример с getcontext из документации:

>>> from decimal import *
>>> getcontext().prec = 6
>>> Decimal(1) / Decimal(7)
Decimal('0.142857')

Пример localcontext использование:

>>> from decimal import Decimal, localcontext
>>> with localcontext() as ctx:
...     ctx.prec = 4
...     print Decimal(1) / Decimal(3)
... 
0.3333

Чтобы уменьшить объем ввода, вы можете сократить конструктор (пример из документации):

>>> D = decimal.Decimal
>>> D('1.23') + D('3.45')
Decimal('4.68')
Другие вопросы по тегам