2016-08-10 66 views
2

如果我在sympy中使用simplify()函數,log((exp(x)+1)/exp(x))確實簡化爲log(1+exp(-x)),但是,當我閱讀文檔時,簡化函數是「可能會不必要的慢」,我嘗試了其他簡化方法,但其中沒有一種方法可行, m想知道如何將ln((exp(x)+1)/exp(x))簡化爲如log(1+exp(-x))這樣的格式,而不用調用simplify()。sympy如何將ln((exp(x)+1)/ exp(x))簡化爲log(1 + exp(-x))?

+0

您是否體驗過「不必要的慢」的功能?數學函數的簡化不是一件特別容易的任務。我會查看http://docs.sympy.org/dev/modules/simplify/simplify.html以幫助理解該功能的功能。 – vielmetti

+0

我認爲另一個問題是它是不可預測的,因爲它根據它的長度來選擇答案。我的工作是比較兩個方程,所以我確實需要結果是可預測的,我試圖使用簡化文檔中的函數,但是除非使用了簡化(),否則無法使它們中的任何一個工作。 –

+0

期望的結果立即出現...我使用Sympy 1.0。 – comer

回答

3

您可以更直接地使用sympy.polys.polytools.cancel(),它可以作爲表達式的方法與.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 

編輯:這不是一個穩定的解決方案,我會建議你看看asmeurer's answer,他建議使用expand()

+0

我注意到它在不同版本中表現不同,我更新到最新版本(1.0。 1.dev0),但它完美的工作,但它不會取消在1.0版 –

+0

@MichaelYuxiDong'取消'在SymPy 1.0中爲我工作。 – asmeurer

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中有一些簡化函數的指南。

+0

這顯然比絆倒'cancel'更好的答案:) – miradulo