【问题标题】:Can Sympy simplify a rational expression by collecting multiple terms?Sympy 可以通过收集多个项来简化有理表达式吗?
【发布时间】:2020-08-19 11:48:45
【问题描述】:

给定一个有理表达式 E 如下所示,我希望使用 Sympy 将其简化为类似于 F 的内容(在下面的 Python 代码的第二块中定义):

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),但在某些情况下,在何处/如何“拆分”此类复合分数当然可能是不明确的。

【问题讨论】:

    标签: python sympy simplify


    【解决方案1】:

    这里的情况是你有两个词的Add。可以使用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) 
    

    变量的顺序实际上是由打印机在显示表达式时确定的,不一定与 args 的内部顺序相同,也不一定与创建表达式时使用的顺序相同。不过,调用 signsimp 可以规范化表达式中的减号

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

    【讨论】:

      猜你喜欢
      • 2021-06-23
      • 2017-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-11
      • 1970-01-01
      相关资源
      最近更新 更多