Sympy peut-il simplifier une expression rationnelle en collectant plusieurs termes ?
Étant donné une expression rationnelle E
telle que celle ci-dessous, je cherche à utiliser Sympy pour la simplifier en quelque chose qui ressemble à F
(défini dans le deuxième bloc de code Python ci-dessous):
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() ))
Cela imprime
⎛ 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)
Cependant, l'expression peut être - manuellement - simplifiée davantage, dont le résultat que j'ai étiqueté 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())
Cela produit
n⋅(-A + B)⋅(c - t) n⋅(-B + C)⋅(-b + t)
────────────────── + ───────────────────
(-a + c)⋅(-b + c) (-b + c)⋅(-b + d)
0
J'ai examiné diverses options, notamment factor()
, collect()
et apart()
, mais aucune d'entre elles ne semble produire d'expressions ayant la même structure que F
. Des pointeurs sur la façon de procéder?
De plus, je me demandais si la jolie fonction d'impression de Sympy pouvait être modifiée d'une manière ou d'une autre pour
- Conservez l'ordre d'origine des variables au numérateur et au dénominateur (par exemple
B - A
au lieu de-A + B
). Actuellement, l'ordre est inversé dans la plupart des cas, ce qui semble plutôt moche avec les principaux signes moins. - Afficher les fractions composites comme des produits de fractions simples (par exemple
a/b c/d
au lieu deac/bd
), bien que dans certains cas, il puisse bien sûr être ambigu où/comment "séparer" ces fractions composites.
Réponses
La situation ici est que vous avez un Add
de deux termes. Chaque terme séparément peut être simplifié en utilisant factor
mais les facteurs à annuler sont différents pour chacun, donc l'appel factor
dans son ensemble Add
ne permet pas de trouver l'annulation possible.
Dans cet esprit, nous devons faire attention à traiter les termes de Add
manière indépendante, ce que nous pouvons faire en accédant à .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)
L'ordre des variables est en fait déterminé par l'imprimante lors de l'affichage de l'expression et n'est pas nécessairement le même que l'ordre interne des arguments ou nécessairement l'ordre utilisé lors de la création de l'expression. Un appel à signsimp
peut normaliser les signes moins dans l'expression
In [123]: signsimp(_)
Out[123]:
n⋅(A - B)⋅(c - t) n⋅(B - C)⋅(b - t)
- ───────────────── + ─────────────────
(a - c)⋅(b - c) (b - c)⋅(b - d)