2016-02-11 72 views
4

我发现这很难解释,但我会尽我所能通过一个例子。sympy中表达式的智能重写

考虑下面

from sympy import * 

a, x, b = symbols("a x b")  
y_pred = a * x  
loss = log(1 + exp(- b * y_pred)) 
grad = diff(loss, x, 1) 

grad赋值给变量grad表达有以下表现:

-a*b*exp(-a*b*x)/(1 + exp(-a*b*x)) 

现在我想操纵grad两种方式。

我想sympy尝试重写表达式1)grad,使得没有其条款的样子

exp(-a*b*x)/(1 + exp(-a*b*x))

2)我也希望它试图重写表达式,使它至少有一个词,看起来像这样1./(1 + exp(a*b*x))

所以在最后,grad变为:

-a*b/(1 + exp(a*b*x) 

注意1./(1 + exp(a*b*x))相当于exp(-a*b*x)/(1 + exp(-a*b*x)),但我不想提,到sympy明确:)。

我不确定这是否可行,但知道是否有可能在某种程度上做到这一点很有意思。

回答

1

cancel做到这一点

In [16]: cancel(grad) 
Out[16]: 
    -a⋅b 
────────── 
a⋅b⋅x 
ℯ  + 1 

这工作,因为它看到的表达-a*b*(1/A)/(1 + 1/A),其中A = exp(a*b*x)cancel改写合理的功能取消p/q(见SymPy教程cancel一节更信息)。

请注意,这只适用于因为它使用A = exp(a*b*x)而不是A = exp(-a*b*x)。因此,例如,cancel不会在这里做了类似的简化

In [17]: cancel(-a*b*exp(a*b*x)/(1 + exp(a*b*x))) 
Out[17]: 
     a⋅b⋅x 
-a⋅b⋅ℯ 
──────────── 
    a⋅b⋅x 
ℯ  + 1 
1

你只是想找simplify

>>> grad 
-a*b*exp(-a*b*x)/(1 + exp(-a*b*x)) 
>>> simplify(grad) 
-a*b/(exp(a*b*x) + 1) 
+0

权,似乎'simplify'工作在这种情况下,因为最简单的形式有'1 /(1 + EXP(A * B * X) )',但是'sympy'能够尝试用一些特定的用户定义的子表达式来尽可能地重写表达式吗?这就像谷歌搜索,你可以强制执行哪些条款应该出现或不出现在搜索结果中。我可以更新该问题以提供简化不起作用的示例。 – Curious

+0

那么,你可以使用你需要的特定简化('powsimp'''radsimp'''''''''''''''''''''')来代替直接使用'simplify''')如果这不是你意思是,那么我不知道,我对Sympy来说是比较新的 – L3viathan