Sympyは複数の用語を収集することで有理式を単純化できますか?

Aug 19 2020

E以下のような有理式を考えると、Sympyを使用して次のように単純化することを検討していますF(以下のPythonコードの2番目のブロックで定義されています)。

import sympy as sp

a, b, c, d, n, t, A, B, C = sp.symbols('a, b, c, d, n, t, A, B, C', real = True)

E = n/(c-b) * ( B - (c-b)/(c-a)*A - (b-a)/(c-a)*B ) * (c-t)/(c-b) + n/(c-b) * ( (d-c)/(d-b)*B + (c-b)/(d-b)*C - B ) * (t-b)/(c-b)

print(sp.pretty( E ))
print(sp.pretty( E.simplify() ))

このプリント

           ⎛     B⋅(-c + d)   C⋅(-b + c)⎞             ⎛  A⋅(-b + c)   B⋅(-a + b)    ⎞
n⋅(-b + t)⋅⎜-B + ────────── + ──────────⎟   n⋅(c - t)⋅⎜- ────────── - ────────── + B⎟
           ⎝       -b + d       -b + d  ⎠             ⎝    -a + c       -a + c      ⎠
───────────────────────────────────────── + ─────────────────────────────────────────
                        2                                           2                
                (-b + c)                                    (-b + c)
                
                
-n⋅((a - c)⋅(b - t)⋅(-B⋅(b - d) + B⋅(c - d) + C⋅(b - c)) + (b - d)⋅(c - t)⋅(A⋅(b - c) + B⋅(a - b) - B⋅(a - c))) 
────────────────────────────────────────────────────────────────────────────────────────────────────────────────
                                                           2                                                    
                                            (a - c)⋅(b - c) ⋅(b - d) 

ただし、式を手動でさらに簡略化することができます。その結果、次のようにラベルを付けましたF

F = n/(c-a) * (B - A) * (c-t)/(c-b) + n/(d-b) * (C - B) * (t-b)/(c-b)

print(sp.pretty( F ))
print((F-E).simplify())

この出力

n⋅(-A + B)⋅(c - t)   n⋅(-B + C)⋅(-b + t)
────────────────── + ───────────────────
(-a + c)⋅(-b + c)     (-b + c)⋅(-b + d) 


0

私は、以下を含む様々な選択肢の中に見てきたfactor()collect()そしてapart()、これらはいずれも同じ構造を持つ式を得ているように見えるんF。続行する方法についてのポインタはありますか?

さらに、Sympyのきれいな印刷機能をどうにかして微調整できるかどうか疑問に思いました

  1. 分子と分母の両方で変数の元の順序を保持します(たとえば、のB - A代わりに-A + B)。現在、ほとんどの場合、順序が反転しています。これは、先頭のマイナス記号でかなり醜いように見えます。
  2. 複合分数を単純な分数の積として(たとえばではa/b c/dなくac/bd)表示しますが、場合によっては、そのような複合分数をどこで/どのように「分割」するかがあいまいになることもあります。

回答

2 OscarBenjamin Aug 23 2020 at 21:35

ここでの状況はAdd、2つの用語のうちの1つがあるということです。各用語は個別に使用して簡略化できますfactorが、キャンセルする要素はそれぞれ異なるためfactor、全体として呼び出すと、Addキャンセルの可能性を見つけることができません。

そのことを念頭に置いAddて、以下にアクセスすることで実行できる独立した条件を処理するように注意する必要があります.args

In [122]: E.func(*(factor(term) for term in E.args))
Out[122]: 
n⋅(A - B)⋅(-c + t)   n⋅(B - C)⋅(-b + t)
────────────────── - ──────────────────
 (a - c)⋅(b - c)      (b - c)⋅(b - d) 

変数の順序は、実際には式を表示するときにプリンターによって決定され、引数の内部順序や、式を作成したときに使用された順序と必ずしも同じではありません。signsimpただし、への呼び出しは、式のマイナス記号を正規化できます。

In [123]: signsimp(_)
Out[123]: 
  n⋅(A - B)⋅(c - t)   n⋅(B - C)⋅(b - t)
- ───────────────── + ─────────────────
   (a - c)⋅(b - c)     (b - c)⋅(b - d)