在较大的分数中收集分数表达式(sympy)
Collecting a fraction expression within a larger fraction (sympy)
我正在使用 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
条款可以收集。
如何让 sympy 执行此操作?
Python 第一个表达式代码为您节省时间:
t*(h + l)/(l*(h + l*sin(theta))*cos(theta))
我真的不知道你是否可以使用正则表达式,但如果可以,你可以使用 re.sub
将 h
的所有实例替换为 (h/1)
。或者如果表达式是一个字符串,您可以使用 str.replace
来做同样的事情。
所以我使用了 x = h/l
和 y = t/l
并进行了替换。然后简化。这给了我
x*(y + 1)/((y + sin(theta))*cos(theta))
我想这就是你想要的。我看不出如何简化 "with respect to" h/l
但这行得通...
基于 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 /
即引入两个变量x和y来代替h/l 和 t/l (In[4]),反转等式以获得替换字典 (In[7])。替换、简化(去掉 l),然后将 x 和 y[=25 替换回原始值=].一个变量仍然被简化了。
应该告诉 .subs( ... ) 不要在替换后计算表达式。不知道现在支持不支持
除非您将这些比率放在一起,否则领先的分数将穿过分界线。有两种 glom 方法:使用 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/l
和 h/l
实际上是具有复杂名称的符号。 (您甚至可以使用乳胶作为符号名称。)
我正在使用 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
条款可以收集。
如何让 sympy 执行此操作?
Python 第一个表达式代码为您节省时间:
t*(h + l)/(l*(h + l*sin(theta))*cos(theta))
我真的不知道你是否可以使用正则表达式,但如果可以,你可以使用 re.sub
将 h
的所有实例替换为 (h/1)
。或者如果表达式是一个字符串,您可以使用 str.replace
来做同样的事情。
所以我使用了 x = h/l
和 y = t/l
并进行了替换。然后简化。这给了我
x*(y + 1)/((y + sin(theta))*cos(theta))
我想这就是你想要的。我看不出如何简化 "with respect to" h/l
但这行得通...
基于 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 /
即引入两个变量x和y来代替h/l 和 t/l (In[4]),反转等式以获得替换字典 (In[7])。替换、简化(去掉 l),然后将 x 和 y[=25 替换回原始值=].一个变量仍然被简化了。
应该告诉 .subs( ... ) 不要在替换后计算表达式。不知道现在支持不支持
除非您将这些比率放在一起,否则领先的分数将穿过分界线。有两种 glom 方法:使用 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/l
和 h/l
实际上是具有复杂名称的符号。 (您甚至可以使用乳胶作为符号名称。)