2

我正在使用 IPython(Anaconda 发行版)和 sympy 符号数学库。

我有以下表达式:

       t⋅(h + l)       
───────────────────────
l⋅(h + l⋅sin(θ))⋅cos(θ)

我想重新安排它以获取(h/l)(t/l)

    (t/l)⋅((h/l)+1)
─────────────────────
((h/l)+sin(θ))⋅cos(θ)

这很容易手工完成;只需将分数的两边除以l并重新排列即可。

到目前为止,我对 sympy 的内置函数并不满意。

我试过使用expand后跟collect(expr,h/l),但它不会改变表达式。我怀疑这行不通,因为一开始就没有h/l收集的条款。

我怎样才能得到同情呢?

第一个表达式的 Python 代码可节省您的时间: t*(h + l)/(l*(h + l*sin(theta))*cos(theta))

4

4 回答 4

1

基于 strubbly 的想法:

In [2]: expr = t *(h +l )/(l *(h +l *sin (theta ))*cos (theta ))

In [3]: expr
Out[3]: 
           t*(h + l)           
-------------------------------
l*(h + l*sin(theta))*cos(theta)

In [4]: repl1 = [x-h/l, y-t/l]

In [7]: repl2 = solve(repl1, t, l)

In [8]: repl2
Out[8]: 
    h     h*y 
{l: -, t: ---}
    x      x  
In [9]: simplify(expr.subs(repl2)).subs({x: h/l, y: t/l})
Out[9]: 
            /h    \          
          t*|- + 1|          
            \l    /          
-----------------------------
  /h             \           
l*|- + sin(theta)|*cos(theta)
  \l             /   

即引入两个变量xy来替换h/lt/l (In[4]),将等式取反得到替换字典(In[7])。替换、简化(去掉l),然后用原始值替换xy。一个变量仍然被简化了。

应该告诉.subs( ... )在替换后不要评估表达式。不知道目前是否支持。

于 2015-09-17T10:56:21.080 回答
0

所以我使用x = h/ly = t/l替换。然后简化。这给了我

       x*(y + 1)/((y + sin(theta))*cos(theta))

我认为这是你想要的。我看不出如何简化“相对于” h/l,但这有效......

于 2015-09-16T19:46:06.830 回答
0

除非您将这些比率混合在一起,否则领先的分数将跨越分割线。有两种方法可以使用:使用 UnevaluatedExpr 和使用“符号技巧”。首先是 UnevaluatedExpr:

>>> from sympy import UnevaluatedExpr as UE
>>> eq
t*(h + l)*cos(th)/(l*(h + l*sin(th)))
>>> factor_terms(_.subs(t, UE(t/l)*l).subs(h, UE(h/l)*l))
cos(th)*(sin(th) + h/l)**(-1)*(1 + h/l)*(t/l)

请注意订单与您希望的不一样。所以现在用一个看起来像 UE的符号替换那个UE:

>>> _.replace(lambda x: isinstance(x, UE), lambda x: Symbol(str(x)))
t/l*(h/l + 1)*cos(th)/(h/l + sin(th))

所以看起来像你想要的。t/lh/l实际上是具有复杂名称的符号。(您甚至可以使用乳胶作为符号名称。)

于 2021-11-14T00:52:33.177 回答
-1

我真的不知道您是否可以使用正则表达式,但如果可以,您可以使用re.sub替换所有实例hwith (h/1)。或者如果表达式是一个字符串,你可以用str.replace它来做同样的事情。

于 2015-09-16T16:07:15.827 回答