SymPy понимает, что Sum
и +
ездят на работу.
from sympy import symbols, Idx, IndexedBase, Sum
i, n = symbols("i n", cls=Idx)
x = IndexedBase("x", shape=(n,))
s = Sum(x[i] + 1, (i, 1, n))
t = Sum(x[i], (i, 1, n)) + Sum(1, (i, 1, n))
assert s.equals(t) # OK
Но для сложных выражений это не работает.
from sympy import symbols, Idx, IndexedBase, Sum
a, b = symbols("a b")
i, n = symbols("i n", cls=Idx)
w = IndexedBase("w", shape=(n,))
x = IndexedBase("x", shape=(n,))
y = IndexedBase("y", shape=(n,))
sum = lambda e: Sum(e, (i, 1, n))
sw = sum(w[i])
mx = sum(w[i] * x[i]) / sw
my = sum(w[i] * y[i]) / sw
d = w[i] * ((a * (x[i] - mx) - (y[i] - my)))**2
e = w[i] * (a * mx + b - my)**2
f = w[i] * 2 * (a * (x[i] - mx) - (y[i] - my)) * (a * mx + b - my)
s = sum(d + e + f)
t = sum(d) + sum(e) + sum(f)
assert s.equals(t) # The assert fails
Как мы можем объяснить SymPy, что это преобразование на самом деле нормально?
Отредактирован комментарий об ошибке подтверждения. равно сравнивает 2 выражения.
Работает ли это, если d, e, f
— простые выражения? Возможно, вы просто столкнулись с чем-то слишком сложным, чтобы Symy мог его проанализировать.
@user24714692 Перед редактированием был комментарий # d, e, f = 3 rather large expressions
. Итак, они были определены, ФП просто опустил определения для краткости. С тех пор они добавили определения.
Вы можете использовать expand()
и simplify()
:
from sympy import symbols, Idx, IndexedBase, Sum, expand, simplify
a, b = symbols("a b")
i, n = symbols("i n", cls=Idx)
w = IndexedBase("w", shape=(n,))
x = IndexedBase("x", shape=(n,))
y = IndexedBase("y", shape=(n,))
sum = lambda e: Sum(e, (i, 1, n))
sw = sum(w[i])
mx = sum(w[i] * x[i]) / sw
my = sum(w[i] * y[i]) / sw
d = w[i] * ((a * (x[i] - mx) - (y[i] - my)))**2
e = w[i] * (a * mx + b - my)**2
f = w[i] * 2 * (a * (x[i] - mx) - (y[i] - my)) * (a * mx + b - my)
s = sum(d + e + f)
t = sum(d) + sum(e) + sum(f)
se, te = expand(s), expand(t)
ss, ts = simplify(se), simplify(te)
print(ss.equals(ts))
Принты
Истинный
SymPy предпочитает не выполнять автоматическое упрощение, поэтому уместно ожидать, что некоторые действия будут сделаны, чтобы показать, что выражения одинаковы. Если бы равенства были изменены для расширения, это могло бы сработать для вас, но это работает только diff = factor_terms(simplify(self - other), radical=True)
в самом начале.
SymPy предпочитает не выполнять автоматическое упрощение, поэтому уместно ожидать, что некоторые действия будут сделаны, чтобы показать, что выражения одинаковы. Если бы equals
был изменен для расширения, возможно, это сработало бы для вас, но diff = factor_terms(simplify(self - other), radical=True)
это работает только в самом начале.
@smichr Я бы хотел помочь SymPy понять структуру уравнения, но как?
Как следует из ответа, используйте expand
, например так: expand(s-t).equals(0) -> True?
Трудно дать хороший ответ, если вы не предоставите работоспособный код, демонстрирующий проблему. Вы также не объяснили, что означает «Fail»: что возвращает
s.equals(t)
?