sympy如何将ln((exp(x)+1)/ exp(x))简化为log(1 + exp(-x))?

时间:2016-08-10 17:50:58

标签: python sympy

如果我在sympy中使用simplify()函数,log((exp(x)+1)/exp(x))会简化为log(1+exp(-x)),但是,当我阅读文档时,简化函数“可能会不必要地慢”,我尝试过其他简化方法,但它们不起作用,所以我想知道如何在不调用simplify()的情况下将ln((exp(x)+1)/exp(x))简化为log(1+exp(-x))这样的形式。

2 个答案:

答案 0 :(得分:4)

您要使用的确切函数取决于您正在处理的表达式的一般形式。 cancel显然有效,但也许只是偶然。一般来说,cancel会取消分子和分母中的常见因子,例如cancel((x**2 - 1)/(x - 1)) - > x + 1。我认为这只是在这里工作,因为它代表了exp(-x)方面的表达。如果它改为使用exp(x),则不会简化,因为(x + 1)/x没有任何共同因素。这可能就是您在不同版本中看到来自cancel的不同结果的原因。有关详细信息,请参阅this issue

对于此表达式,我将使用 expand()(或更具针对性的expand_mul)。 expand会将分母分配给分子,即(exp(x) + 1)/exp(x)将变为exp(x)/exp(x) + 1/exp(x)。然后,SymPy会自动取消exp(x)/exp(x)1并将1/exp(x)转换为exp(-x)(它们在内部都以相同的方式表示)。

In [1]: log((exp(x)+1)/exp(x)).expand()
Out[1]:
   ⎛     -x⎞
log⎝1 + ℯ  ⎠

tutorial中某些简化功能的指南。

答案 1 :(得分:3)

您可以更直接地使用sympy.polys.polytools.cancel()asmeurer's answer可用作.cancel()表达式的方法。

>>> from sympy.abc import x
>>> from sympy import *
>>> my_expr = log((exp(x)+1)/exp(x))
>>> my_expr.cancel()
log(1 + exp(-x))

这就是在simplify()内简化表达式的工作。

一个非常天真的基准:

>>> import timeit
>>> %timeit my_expr.simplify()
100 loops, best of 3: 7.78 ms per loop
>>> %timeit my_expr.cancel()
1000 loops, best of 3: 972 µs per loop

修改:这不是一个稳定的解决方案,我建议您查看expand()他建议使用{{3}}的地方。