Simpy Solver не хватает памяти при использовании символа в exp () - PullRequest
1 голос
/ 01 мая 2019

Я пытаюсь научиться использовать sympy, поэтому я выбрал простую задачу для попытки.когда я пытаюсь использовать решатель Sympy для решения e^(-(ln(2)/8) * t) - 10^-6, в конце концов мой repl вылетает с ошибкой нехватки памяти.Кажется, что-то с тем, как он интерпретирует метод exp (), что я не совсем уверен, что я делаю неправильно.

from math import log as ln
from sympy import exp as e, symbols as sym, solve

t = sym('t')
hl = 8.0197
k = ln(2)/hl #lambda 
expression = e(-k * t) -10**-6

# 10^6 = e^(-k * t)
days = solve(,t)
print(days)

Это должно решить до ~ 159,5, но, как уже было отмечено, это приводит к сбою repl.с “ipython3” terminated by signal SIGSEGV (Address boundary error)

1 Ответ

2 голосов
/ 01 мая 2019

10**-6 - подозрительно небольшое число.

Так как числа с плавающей точкой страшны , мы можем решить проблему, аналогичную той, которую вы ставите, используя красивые безопасные целые числа:

from math import log as ln
import sympy
from sympy import symbols as sym

t  = sym('t')
hl = 8.0197
k  = 4
expression = sympy.exp(-k * t) - 3

days = sympy.solve(expression,t)
print(days)

Это мгновенно возвращает:

[log(3**(3/4)/3) + I*pi, log(3**(3/4)/3), log(-3**(3/4)*I/3), log(3**(3/4)*I/3)]

Итак, мы сразу знаем, что проблема связана с использованием чисел с плавающей запятой. Оказывается, это известная проблема в SymPy. Обратите внимание, что, поскольку существует четыре возможных решения уравнения, однако для обработки чисел с плавающей запятой требуется много работы в четыре раза.

Поскольку работа с числами с плавающей запятой может привести к потере точности , особенно если динамический диапазон чисел большой, SymPy преобразует входные данные с плавающей запятой в точные дробные представления. Это может привести к очень большим числам, которые замедляют вычисления.

Решение состоит в том, чтобы по возможности избегать чисел с плавающей запятой и, в более общем случае, решать символическое уравнение и подставлять после него:

from math import log as ln
import sympy
from sympy import symbols as sym

t = sym('t')
k = sym('k')
c = sym('c')
expression = sympy.exp(-k * t) - c

days = sympy.solve(expression,t)
print(days)

Это дает:

[log(1/c)/k]

Что можно оценить, используя

hl   = 8.0197
kval = ln(2)/hl #lambda 
days[0].subs([(k,kval), (c, 10**-6)])

, что дает

159.845200455409
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...