Как упростить длинные символы c выражений в SymPy - PullRequest
0 голосов
/ 07 апреля 2020

Я работал над некоторыми интеграциями, и хотя система работает, она занимает гораздо больше времени, чем нужно.

Проблема в том, что выражения состоят из множества страниц, и хотя они Только 3 переменные, sy.simplify просто вылетает из ядра через 4 часа или около того.

Есть ли способ сделать такие длинные выражения более компактными?

РЕДАКТИРОВАТЬ:

Попытка воссоздать тестовое выражение, используя cse. Я не могу действительно заменить символы, чтобы сделать окончательное выражение, равное 1-му

sy.var('a:c x')
testexp = sp.log(x)+a*(0.5*x)**2+(b*(0.5*x)**2+b+sp.log(x))/c
r, e = sy.cse(testexp)
FinalFunction = sy.lambdify(r[0:][0]+(a,b,c,x),e[0])
Points = sy.lambdify((a,b,c,x),r[0:][1])
FinalFunction(Points(1,1,1,1),1,1,1,1)

>>>NameError: name 'x1' is not defined

1 Ответ

2 голосов
/ 07 апреля 2020

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

>>> from sympy import solve
>>> var('a:c x');solve(a*x**2+b*x+c, x)
(a, b, c, x)
[(-b + sqrt(-4*a*c + b**2))/(2*a), -(b + sqrt(-4*a*c + b**2))/(2*a)]
>>> r, e = cse(_)
>>> for i in r: pprint(Eq(*i))
...
        _____________
       ╱           2
x₀ = ╲╱  -4⋅a⋅c + b
      1
x₁ = ───
     2⋅a
>>> for i in e: pprint(i)
...
x₁⋅(-b + x₀)
-x₁⋅(b + x₀)

Вы по-прежнему будете иметь длинные выражения, но они будут представлены более компактно (и более эффективно для вычислений), если cse способен идентифицировать повторные подвыражения.

Чтобы использовать это в SymPy, вы можете создать две лямбда-выражения: одну для преобразования переменных в значения замены, а другую для использования этих значения:

>>> v = (a,b,c,x)
>>> Pts = Lambda(v, tuple([i[1] for i in r]+list(v)))
>>> Pts(1,2,3,4)
(2*sqrt(2)*I, 1/2, 1, 2, 3, 4)
>>> Func = Lambda(tuple([i[0] for i in r]+list(v)), tuple(e))
>>> Func(*Pts(1,2,3,4))
(-1 + sqrt(2)*I, -1 - sqrt(2)*I)
...