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