Dapatkah Sympy menyederhanakan ekspresi rasional dengan mengumpulkan banyak suku?

Aug 19 2020

Diberikan ekspresi rasional Eseperti 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

  1. Pertahankan urutan asli variabel di pembilang dan penyebut (misalnya, B - Abukan -A + B). Saat ini pesanan dibalik dalam banyak kasus, yang terlihat agak jelek dengan tanda minus di awal.
  2. Perlihatkan pecahan komposit sebagai hasil perkalian pecahan sederhana (misalnya, a/b c/dbukan ac/bd), meskipun dalam kasus tertentu hal ini tentu saja bisa ambigu di mana / bagaimana cara "memisahkan" pecahan komposit tersebut.

Jawaban

2 OscarBenjamin Aug 23 2020 at 21:35

Situasi di sini adalah Anda memiliki salah satu Adddari dua istilah. Setiap istilah secara terpisah dapat disederhanakan menggunakan factortetapi faktor yang harus dibatalkan berbeda untuk masing-masing sehingga memanggil factorkeseluruhan Addgagal untuk menemukan kemungkinan pembatalan.

Dengan pemikiran tersebut kita perlu berhati-hati dalam memproses ketentuan Addsecara 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 signsimpdapat 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)