Как автоматизировать упрощение выражения с помощью заданных подвыражений в SymPy - PullRequest
2 голосов
/ 23 февраля 2020

Я хочу сократить длинное уравнение с более короткими выражениями. Вот простой пример:

from sympy.abc import z, h, m, G
y = 0.2 * m  + 0.2 * z * m +z - h
y_1 = y.subs({m + z * m: G})
print(y_1)

Ожидаемый результат - z - h + 0.2 * G, но он не заменяет выражение. Я знаю, что проблема в 0.2. Есть ли способ исправить это автоматически?

ИЛИ может быть другое решение: устранение общего подвыражения (cse (y)), которое неэффективно, так как работает с условиями по умолчанию для создания подвыражений.

Ответы [ 2 ]

2 голосов
/ 23 февраля 2020

К сожалению, насколько я знаю, subs просто не так мощен (пока?). Вы можете попытаться автоматизировать разбиение вашей замены m + z * m: G на две отдельные замены z: G / m - 1 и m: G / (z + 1) и упростить между ними.

from sympy.abc import z, h, m, G
y = 0.2 * m + z - h + 0.2 * z * m
y_1 = y.subs({m + z * m: G})
print(y_1)
y_2 = y.subs({z: G / m - 1, m: G / (z + 1)}).simplify()
print(y_2)
y_3 = y_2.subs({G / m - 1: z, G / (z + 1): m}).simplify()
print(y_3)

Который имеет следующий вывод:

-h + 0.2*m*z + 0.2*m + z
0.2*G + G/m - h - 1
0.2*G - h + z

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

from sympy import *
from sympy.abc import z, h, m, G

def elaborate_subs(expr, old, new):
    subs = {}
    for symbol in old.free_symbols:
        solution = solve(Eq(old, new), symbol, simplify=False)
        if solution:
            subs[symbol] = solution[0]
    expr = expr.subs(subs).simplify()
    expr = expr.subs({v: k for k, v in subs.items()}).simplify()
    return expr

y = 0.2 * m + z - h + 0.2 * z * m
print(elaborate_subs(y, m + z * m, G))

Который имеет ожидаемый результат:

0.2*G - h + z
1 голос
/ 23 февраля 2020

Я не думаю, что метод subs работает так, как вы думаете. Он просто заменяет термин переданным входным значением. Например,

expr = cos(x)
expr.subs(x, 0)#here 0 is replaced with x
print(expr) # 1, sinces cos(0) is 1

#Or

expr = x**3 + 4*x*y - z
expr.subs([(x, 2), (y, 4), (z, 0)])
print(expr) #40

Как вы можете видеть, в вашем методе sub вы не указали, что именно нужно заменить. Следуйте приведенным выше примерам в качестве руководства, и оно должно работать. Вы можете прочитать больше здесь

...