Reputation: 6865
I found this to be tricky to explain, but I'll do my best through an example.
Consider the expression assigned to the variable grad
below
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
has the following expression:
-a*b*exp(-a*b*x)/(1 + exp(-a*b*x))
Now I want to manipulate grad
in two ways.
1) I want sympy
to try rewrite the expression grad
such that none of its terms look like
exp(-a*b*x)/(1 + exp(-a*b*x))
.
2) I also want it to try to rewrite the expression such that it has at least one term that look like this 1./(1 + exp(a*b*x))
.
So at the end, grad
becomes:
-a*b/(1 + exp(a*b*x)
Note that 1./(1 + exp(a*b*x))
is equivalent to exp(-a*b*x)/(1 + exp(-a*b*x))
but I don't want to mention that to sympy
explicitly :).
I'm not sure if this is feasible at all, but it would be interesting to know whether it's possible to do this to some extent.
Upvotes: 4
Views: 585
Reputation: 91560
cancel
does this
In [16]: cancel(grad)
Out[16]:
-a⋅b
──────────
a⋅b⋅x
ℯ + 1
This works because it sees the expression as -a*b*(1/A)/(1 + 1/A)
, where A = exp(a*b*x)
, and cancel
rewrites rational functions as canceled p/q
(see the section on cancel in the SymPy tutorial for more information).
Note that this only works because it uses A = exp(a*b*x)
instead of A = exp(-a*b*x)
. So for instance, cancel
won't do the similar simplification here
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
Upvotes: 1
Reputation: 27283
Are you just looking for simplify
?
>>> grad
-a*b*exp(-a*b*x)/(1 + exp(-a*b*x))
>>> simplify(grad)
-a*b/(exp(a*b*x) + 1)
Upvotes: 1