Dapatkah Sympy menyederhanakan ekspresi rasional dengan mengumpulkan banyak suku?
Diberikan ekspresi rasional E
seperti di bawah ini, saya ingin menggunakan Sympy untuk menyederhanakannya menjadi sesuatu yang terlihat seperti F
(didefinisikan dalam blok kedua kode Python di bawah):
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() ))
Ini cetakan
⎛ 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)
Namun, ekspresi tersebut dapat - secara manual - disederhanakan lebih lanjut, yang hasilnya saya beri label 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())
Output ini
n⋅(-A + B)⋅(c - t) n⋅(-B + C)⋅(-b + t)
────────────────── + ───────────────────
(-a + c)⋅(-b + c) (-b + c)⋅(-b + d)
0
Saya telah melihat berbagai opsi termasuk factor()
, collect()
dan apart()
, tetapi tidak satu pun dari ini yang tampaknya menghasilkan ekspresi yang memiliki struktur yang sama seperti F
. Ada petunjuk tentang cara melanjutkan?
Selain itu, saya bertanya-tanya apakah fungsi cetak cantik Sympy dapat diubah entah bagaimana
- Pertahankan urutan asli variabel di pembilang dan penyebut (misalnya,
B - A
bukan-A + B
). Saat ini pesanan dibalik dalam banyak kasus, yang terlihat agak jelek dengan tanda minus di awal. - Perlihatkan pecahan komposit sebagai hasil perkalian pecahan sederhana (misalnya,
a/b c/d
bukanac/bd
), meskipun dalam kasus tertentu hal ini tentu saja bisa ambigu di mana / bagaimana cara "memisahkan" pecahan komposit tersebut.
Jawaban
Situasi di sini adalah Anda memiliki salah satu Add
dari dua istilah. Setiap istilah secara terpisah dapat disederhanakan menggunakan factor
tetapi faktor yang harus dibatalkan berbeda untuk masing-masing sehingga memanggil factor
keseluruhan Add
gagal untuk menemukan kemungkinan pembatalan.
Dengan pemikiran tersebut kita perlu berhati-hati dalam memproses ketentuan Add
secara mandiri yang dapat kita lakukan dengan mengakses .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)
Urutan variabel sebenarnya ditentukan oleh printer saat menampilkan ekspresi dan belum tentu sama dengan urutan internal args atau urutan yang digunakan saat Anda membuat ekspresi. Panggilan untuk signsimp
dapat menormalkan tanda minus dalam ekspresi
In [123]: signsimp(_)
Out[123]:
n⋅(A - B)⋅(c - t) n⋅(B - C)⋅(b - t)
- ───────────────── + ─────────────────
(a - c)⋅(b - c) (b - c)⋅(b - d)