2.3 指數對數與三角恆等式#
本節目標#
- 了解 SymPy 對指數律與對數律的自動化簡行為
- 熟練
expand_log()、logcombine()與force參數 - 學會
powsimp()、powdenest()處理冪次結構 - 熟練三角恆等式工具:
trigsimp()、expand_trig() - 體會
simplify(exp(I*pi))帶來的驚喜
從數學開始:指數、對數、三角的核心恆等式#
本章的核心恆等式:
\[ a^m a^n = a^{m+n}, \qquad \log(mn) = \log m + \log n \]
\[ \sin^2\theta + \cos^2\theta = 1, \qquad e^{i\pi} = -1 \]
但符號運算系統對這些式子的處理有微妙之處:在複數域上,某些「顯而易見」的等式其實不成立。例如 \(\log(xy) = \log x + \log y\) 對複數未必成立,甚至對負實數也不成立( \(\log((-1)(-1)) = 0\) ,但 \(\log(-1) + \log(-1) = 2\pi i\) )。這就是 SymPy 預設保守、需要 force 的原因。
指數律:冪次的自動合併#
SymPy 對乘法中的同底數冪會自動合併:
from sympy import symbols, exp, sqrt, simplify
x, y = symbols('x y')
print(x**2 * x**3) # x**5(自動)
print(sqrt(2) * sqrt(6)) # 2*sqrt(3)(自動)
但冪的冪 \((a^m)^n = a^{mn}\) 預設不展開——因為在複數域上 \(n\) 非整數時可能出錯( \((x^2)^{1/2} \ne x\) 若 \(x<0\) ):
print((x**2)**(S(1)/2)) # 不展開,維持 sqrt(x**2)
print((x**2)**3) # x**6(整數冪則自動展開)
powsimp 與 powdenest#
from sympy import powsimp, powdenest
n = symbols('n', positive=True)
print(powsimp(x**a * y**a)) # (x*y)**a(合併不同底的同次冪)
print(powdenest((x**a)**b)) # x**(a*b)(在適當假設下攤開)
對數:expand_log 與 logcombine#
對數的乘法律預設不會自動套用,因為需要「參數為正」的條件:
from sympy import log
print(log(x*y)) # log(x*y),不動
print(log(x) + log(y)) # log(x) + log(y),不動
expand_log():把 log 拆開#
a = symbols('a', positive=True)
b = symbols('b', positive=True)
print(expand_log(log(a*b))) # log(a) + log(b)
print(expand_log(log(a**3))) # 3*log(a)
print(expand_log(log(a/b))) # log(a) - log(b)
注意:若變數沒有 positive 假設,expand_log() 會拒絕拆開:
print(expand_log(log(x*y))) # log(x*y),因為 x 可能是負數
force 參數:強制套用#
若你確定變數在正數範圍(或只是想形式操作),可以加 force=True:
print(expand_log(log(x*y), force=True)) # log(x) + log(y)
logcombine():把 log 合併#
print(logcombine(log(x) + log(y))) # 不動(無假設)
print(logcombine(log(a) + log(b))) # log(a*b)(a, b 為正)
print(logcombine(log(x) + log(y), force=True)) # log(x*y)
三角恆等式:trigsimp 與 expand_trig#
trigsimp():化簡三角表達式#
from sympy import trigsimp, sin, cos, tan
print(trigsimp(sin(x)**2 + cos(x)**2)) # 1
print(trigsimp((2*tan(x)*cos(x)**2 - 1)/(1 + tan(x)**2)))
# -cos(x)**2
print(trigsimp(sin(x)/cos(x))) # tan(x)?—— 看情況
expand_trig():展開三角函數#
expand_trig() 套用和角公式等,方向與 trigsimp() 相反:
from sympy import expand_trig
print(expand_trig(sin(x + y)))
# sin(x)*cos(y) + sin(y)*cos(x)
print(expand_trig(cos(2*x)))
# 2*cos(x)**2 - 1
print(expand_trig(tan(2*x)))
# 2*tan(x)/(1 - tan(x)**2)
驗證 \(\sin^2+\cos^2=1\)#
驗證恆等式的標準做法:做差、化簡、看是否為 0。
from sympy import simplify
print(simplify(sin(x)**2 + cos(x)**2 - 1)) # 0
print(trigsimp(sin(x)**2 + cos(x)**2 - 1)) # 0
也可以用 rewrite 換底再化簡:
from sympy import exp, I
expr = sin(x)**2 + cos(x)**2 - 1
print(simplify(expr.rewrite(exp))) # 0(用歐拉公式改寫後化簡)
驚喜時刻:simplify(exp(I*pi)) = -1#
歐拉公式 \(e^{i\pi} = \cos\pi + i\sin\pi = -1\) 。在 SymPy 裡,這件事是自動發生的:
from sympy import exp, I, pi, simplify
print(exp(I*pi)) # -1(自動!)
print(exp(I*pi/2)) # I
print(exp(I*2*pi)) # 1
print(simplify(exp(I*pi) + 1)) # 0
因為 \(e^{i\theta}\) 對 \(\theta\) 為 \(\pi\) 的有理倍數時,SymPy 會直接用單位根的精確值化簡。這是符號系統「懂得數學」的漂亮展示。
動手實驗:驗證五個三角恆等式#
from sympy import (symbols, sin, cos, tan, sec, csc,
trigsimp, simplify, expand_trig)
x, y = symbols('x y', real=True)
# 恆等式 1:sin(2x) = 2 sin(x) cos(x)
lhs = expand_trig(sin(2*x))
rhs = 2*sin(x)*cos(x)
print(simplify(lhs - rhs)) # 0
# 恆等式 2:cos(2x) = cos^2(x) - sin^2(x)
lhs = expand_trig(cos(2*x))
rhs = cos(x)**2 - sin(x)**2
print(simplify(lhs - rhs)) # 0
# 恆等式 3:1 + tan^2(x) = sec^2(x)
expr = 1 + tan(x)**2 - sec(x)**2
print(trigsimp(expr)) # 0
# 恆等式 4:1 + cot^2(x) = csc^2(x)
expr = 1 + 1/tan(x)**2 - csc(x)**2
print(simplify(expr)) # 0
# 恆等式 5:sin(x + y) = sin x cos y + cos x sin y
lhs = expand_trig(sin(x + y))
rhs = sin(x)*cos(y) + cos(x)*sin(y)
print(simplify(lhs - rhs)) # 0
五個輸出都是 0,即五個恆等式全部驗證成功。
實驗延伸:
- 驗證和角公式 \(\cos(x+y) = \cos x\cos y - \sin x\sin y\) 。
- 對
trigsimp(1/tan(x))觀察結果——是 \(\cot(x)\) 還是別的形式?不同版本 SymPy 可能有差異。 - 試著不用
expand_trig,只用歐拉公式rewrite(exp)驗證 \(\sin(2x) = 2\sin x\cos x\) 。 - 檢驗 \(\log(xy) = \log x + \log y\) 在「無假設」「positive 假設」「force=True」三種情況下的行為差異。
小結與練習#
本節學會了:
- SymPy 自動合併同底數冪的乘法,但不自動展開 \((a^m)^n\)
expand_log()拆對數、logcombine()合對數,正負號安全性由假設系統把關,必要時用force=Truepowsimp()、powdenest()處理冪次結構trigsimp()化簡、expand_trig()展開三角函數;驗證恆等式 = 做差化簡看是否為 0exp(I*pi)自動化為 \(-1\) ,歐拉公式深植於系統中
練習:
- 化簡 \(\frac{\sin^4 x - \cos^4 x}{\sin x - \cos x}\) ,並與 \(\sin x + \cos x\) 比對。
- 用
expand_log與假設系統化簡 \(\log\left(\frac{a^2 b}{c}\right)\) (設 \(a,b,c\) 皆正)。 - 驗證半角公式 \(\sin^2\frac{x}{2} = \frac{1 - \cos x}{2}\) 。
- 計算 \(e^{i\pi/3}\) 、 \(e^{i\pi/6}\) 的精確值,並用
simplify驗證 \(e^{i\theta}\) 的模長恆為 \(1\) 。