2017-01-10 5 views
5

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

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

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

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

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

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

+2

Вы может захотеть взглянуть на [десятичный модуль] (https: //docs.python.o rg/2/library/decimal.html) (пункт № 5). Также использование 'numpy' datatypes - хорошая идея! Я не понимаю, почему вы должны использовать их вместе с массивами. 'numpy.float16()' создает вам поплавок нужного типа данных. –

ответ

3

Вы можете использовать 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')