IssamLaradji
IssamLaradji

Reputation: 6865

Smart rewriting of expressions in sympy

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

Answers (2)

asmeurer
asmeurer

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

L3viathan
L3viathan

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

Related Questions