收集sympy中的相似术语
Collect similar terms in sympy
我正在用 SymPy 解决 Maxwell Garnett equation:
solveset(Eq((e-m)/(e+2*m) = n*(a-m)/(a+2*m)), m)
是否可以像 Mathematica 那样通过将相似的项组合在一起来简化解决方案?
我找到的最接近的食谱是 SymPy: How to collect multi-variable terms?,但不能直接适用于此。
我已经进步到:
但是如何获得更紧凑的形式?
可以调用 collect
并为其提供一个应用于收集后系数的函数,因此我们可以使用 factor 对系数进行因式分解:
In [2]: e, a, m, n = symbols('e, a, m, n')
In [3]: sol = solveset(Eq((e-m)/(e+2*m), n*(a-m)/(a+2*m)), m)
In [4]: s1, s2 = sol.args[0]
In [5]: s1
Out[5]:
_____________________________________________________________________________
╱ 2 2 2 2 2 2 2 2 2
2⋅a⋅n + a - e⋅n - 2⋅e ╲╱ 4⋅a ⋅n + 4⋅a ⋅n + a + 4⋅a⋅e⋅n - 26⋅a⋅e⋅n + 4⋅a⋅e + e ⋅n + 4⋅e ⋅n + 4⋅e
───────────────────── - ────────────────────────────────────────────────────────────────────────────────
4⋅(n - 1) 4⋅(n - 1)
In [6]: s1.collect(e, lambda c: c.factor() if c.is_polynomial() else c)
Out[6]:
_______________________________________________________
╱ 2 2 ⎛ 2 ⎞ 2 2
a⋅(2⋅n + 1) + e⋅(-n - 2) ╲╱ a ⋅(2⋅n + 1) + 2⋅a⋅e⋅⎝2⋅n - 13⋅n + 2⎠ + e ⋅(n + 2)
──────────────────────── - ──────────────────────────────────────────────────────────
4⋅(n - 1) 4⋅(n - 1)
In [7]: s2.collect(e, lambda c: c.factor() if c.is_polynomial() else c)
Out[7]:
_______________________________________________________
╱ 2 2 ⎛ 2 ⎞ 2 2
a⋅(2⋅n + 1) + e⋅(-n - 2) ╲╱ a ⋅(2⋅n + 1) + 2⋅a⋅e⋅⎝2⋅n - 13⋅n + 2⎠ + e ⋅(n + 2)
──────────────────────── + ──────────────────────────────────────────────────────────
4⋅(n - 1) 4⋅(n - 1)
is_polynomial
检查是为了阻止 collect
在完成递归子表达式后将 factor
应用于最终表达式(对 factor 的最终调用再次展开所有内容)。可能有更好的检查可用于更一般的情况。
问题定义不明确。有无数种方法可以将多项式写成多项式乘积的和。完全展开的形式是独一无二的。如果整个多项式可以对整数进行因式分解,则这种因式分解也是唯一的。但是将它写成多项式乘积的和可以有无数种方法。
我正在用 SymPy 解决 Maxwell Garnett equation:
solveset(Eq((e-m)/(e+2*m) = n*(a-m)/(a+2*m)), m)
是否可以像 Mathematica 那样通过将相似的项组合在一起来简化解决方案?
我找到的最接近的食谱是 SymPy: How to collect multi-variable terms?,但不能直接适用于此。
我已经进步到:
可以调用 collect
并为其提供一个应用于收集后系数的函数,因此我们可以使用 factor 对系数进行因式分解:
In [2]: e, a, m, n = symbols('e, a, m, n')
In [3]: sol = solveset(Eq((e-m)/(e+2*m), n*(a-m)/(a+2*m)), m)
In [4]: s1, s2 = sol.args[0]
In [5]: s1
Out[5]:
_____________________________________________________________________________
╱ 2 2 2 2 2 2 2 2 2
2⋅a⋅n + a - e⋅n - 2⋅e ╲╱ 4⋅a ⋅n + 4⋅a ⋅n + a + 4⋅a⋅e⋅n - 26⋅a⋅e⋅n + 4⋅a⋅e + e ⋅n + 4⋅e ⋅n + 4⋅e
───────────────────── - ────────────────────────────────────────────────────────────────────────────────
4⋅(n - 1) 4⋅(n - 1)
In [6]: s1.collect(e, lambda c: c.factor() if c.is_polynomial() else c)
Out[6]:
_______________________________________________________
╱ 2 2 ⎛ 2 ⎞ 2 2
a⋅(2⋅n + 1) + e⋅(-n - 2) ╲╱ a ⋅(2⋅n + 1) + 2⋅a⋅e⋅⎝2⋅n - 13⋅n + 2⎠ + e ⋅(n + 2)
──────────────────────── - ──────────────────────────────────────────────────────────
4⋅(n - 1) 4⋅(n - 1)
In [7]: s2.collect(e, lambda c: c.factor() if c.is_polynomial() else c)
Out[7]:
_______________________________________________________
╱ 2 2 ⎛ 2 ⎞ 2 2
a⋅(2⋅n + 1) + e⋅(-n - 2) ╲╱ a ⋅(2⋅n + 1) + 2⋅a⋅e⋅⎝2⋅n - 13⋅n + 2⎠ + e ⋅(n + 2)
──────────────────────── + ──────────────────────────────────────────────────────────
4⋅(n - 1) 4⋅(n - 1)
is_polynomial
检查是为了阻止 collect
在完成递归子表达式后将 factor
应用于最终表达式(对 factor 的最终调用再次展开所有内容)。可能有更好的检查可用于更一般的情况。
问题定义不明确。有无数种方法可以将多项式写成多项式乘积的和。完全展开的形式是独一无二的。如果整个多项式可以对整数进行因式分解,则这种因式分解也是唯一的。但是将它写成多项式乘积的和可以有无数种方法。