第 2 章 式子變形與因式分解¶

本章將說明如何利用 Python 的 SymPy 來進行代數式的變形,包括:

  • 展開(expand)與化簡(simplify)
  • 因式分解(factor)與分組整理(collect)
  • 有理式的化簡與部分分式分解(cancel, apart)
  • 代入(substitution)與等式驗證

這些技巧不只是為了「算快一點」,更重要的是幫助你理解代數結構、看出規律, 在後續的方程式、不等式、微積分、機率統計中都有廣泛應用。

2.1 匯入 SymPy 與符號設定¶

先匯入 SymPy 並建立常用的符號變數:

In [1]:
import sympy as sp
sp.init_printing()  # 讓輸出以較漂亮的數學格式顯示

x, y, a, b, c = sp.symbols('x y a b c')
x, y, a, b, c
Out[1]:
$\displaystyle \left( x, \ y, \ a, \ b, \ c\right)$

2.2 展開:expand¶

在高中數學中,我們經常需要展開多項式,例如 $(x+1)^3$、$(x-2)(x+3)$。SymPy 提供 expand 來自動完成這些工作:

In [2]:
expr1 = (x + 1)**3
expr2 = (x - 2)*(x + 3)

sp.expand(expr1), sp.expand(expr2)
Out[2]:
$\displaystyle \left( x^{3} + 3 x^{2} + 3 x + 1, \ x^{2} + x - 6\right)$

如果式子中同時有乘法與括號,expand 也能協助處理:

In [3]:
expr3 = (x + 1)*(x**2 - x + 2)
sp.expand(expr3)
Out[3]:
$\displaystyle x^{3} + x + 2$

2.3 化簡:simplify、expand、factor 的比較¶

所謂「化簡」其實沒有唯一標準答案:

  • 有時候我們希望把式子展開成多項式形式(方便比較係數)。
  • 有時候我們希望把式子寫成因式分解的形式(方便看出零點或公因式)。

SymPy 中常用的幾個函數:

  • expand(expr):盡量展開乘法與括號。
  • factor(expr):嘗試將多項式因式分解。
  • simplify(expr):做「一般性的」化簡(有時候會展開,有時候會合併)。

來看一個例子:

In [4]:
expr = (x + 1)*(x - 2) + (x + 1)*(x + 3)
print("原式:")
display(expr)

print("expand:")
display(sp.expand(expr))

print("factor:")
display(sp.factor(expr))

print("simplify:")
display(sp.simplify(expr))
原式:
$\displaystyle \left(x - 2\right) \left(x + 1\right) + \left(x + 1\right) \left(x + 3\right)$
expand:
$\displaystyle 2 x^{2} + 3 x + 1$
factor:
$\displaystyle \left(x + 1\right) \left(2 x + 1\right)$
simplify:
$\displaystyle \left(x + 1\right) \left(2 x + 1\right)$

2.4 因式分解:factor¶

高中常見的因式分解:

  • 二次式 $x^2 + px + q$ 的分解
  • 完全平方公式、平方差公式

SymPy 的 factor 可以幫助我們檢查手算結果是否正確,也可以直接找到分解形式:

In [5]:
expr_quad = x**2 + 5*x + 6
sp.factor(expr_quad)
Out[5]:
$\displaystyle \left(x + 2\right) \left(x + 3\right)$

再看一些不同型態的例子:

In [6]:
expr_square = x**2 + 2*x + 1
expr_diff  = x**2 - 9
expr_mixed = x**3 - x

display(sp.factor(expr_square))
display(sp.factor(expr_diff))
display(sp.factor(expr_mixed))
$\displaystyle \left(x + 1\right)^{2}$
$\displaystyle \left(x - 3\right) \left(x + 3\right)$
$\displaystyle x \left(x - 1\right) \left(x + 1\right)$

2.5 以某變數分組整理:collect¶

有時候多項式中同時含有多個變數,我們希望依照其中一個變數來分組,便於觀察其係數。這時可使用 collect:

In [7]:
expr_mixed_xy = x*y + x**2*y + 3*x*y**2 + y
display(expr_mixed_xy)
display(sp.collect(expr_mixed_xy, x))  # 以 x 為主分組
display(sp.collect(expr_mixed_xy, y))  # 以 y 為主分組
$\displaystyle x^{2} y + 3 x y^{2} + x y + y$
$\displaystyle x^{2} y + x \left(3 y^{2} + y\right) + y$
$\displaystyle 3 x y^{2} + y \left(x^{2} + x + 1\right)$

這在後續處理多變數方程、微分方程時會很有用,因為我們可以把「同一個變數或未知函數」的係數分組起來。

2.6 有理式的化簡:cancel¶

有理式是多項式的比值,例如:

$\dfrac{x^2 - 1}{x^2 - x}$。

我們常會先進行因式分解,再約分公因式。cancel 可以自動幫我們完成這件事:

In [8]:
expr_rat = (x**2 - 1) / (x**2 - x)
display(expr_rat)
display(sp.cancel(expr_rat))
$\displaystyle \frac{x^{2} - 1}{x^{2} - x}$
$\displaystyle \frac{x + 1}{x}$

注意:對於分母為 0 的點,原式與化簡後的式子在定義域上可能不同, 數學上仍須留意「定義域」與「可約分但不可約掉限制」的問題。

2.7 部分分式分解:apart¶

在微積分中計算有理函數的積分時,常會用到部分分式分解。 SymPy 提供 apart 將有理式拆成較簡單分式之和:

In [9]:
expr_rat2 = (2*x + 3) / (x**2 - x)
display(expr_rat2)
display(sp.apart(expr_rat2))
$\displaystyle \frac{2 x + 3}{x^{2} - x}$
$\displaystyle \frac{5}{x - 1} - \frac{3}{x}$

這個結果在第 11 章(積分)中會再次出現,當時你就會體會到: 為什麼把有理式拆成幾個簡單分式,會讓積分變得容易很多。

2.8 代入(subs)與等式驗證¶

在代數式中,代入特定值是一個基本動作。SymPy 使用 subs 來完成:

In [10]:
expr = x**2 - 5*x + 6
expr_2 = expr.subs(x, 2)
expr_3 = expr.subs(x, 3)
expr_2, expr_3
Out[10]:
$\displaystyle \left( 0, \ 0\right)$

等式驗證的常見策略:

  1. 將等式左邊與右邊都化簡,看看是否可以化成同一個式子。
  2. 隨機代入幾個數值檢查(不能作為嚴格證明,但可作為快速檢查)。

例如,驗證恒等式:

$(x+1)^2 = x^2 + 2x + 1$:

In [11]:
left = (x + 1)**2
right = x**2 + 2*x + 1

print("左邊展開後:")
display(sp.expand(left))

print("右邊化簡後:")
display(sp.simplify(right))

print("左邊 - 右邊:")
display(sp.simplify(left - right))
左邊展開後:
$\displaystyle x^{2} + 2 x + 1$
右邊化簡後:
$\displaystyle x^{2} + 2 x + 1$
左邊 - 右邊:
$\displaystyle 0$

如果 left - right 化簡後得到 0,就意味著這個等式對所有 $x$ 都成立(在符號運算的定義域內)。

2.9 啟發性例子一:一般化二次式因式分解¶

在課堂上,我們常學到:

$x^2 + px + q$ 能否因式分解?

SymPy 可以直接對帶有參數 $p, q$ 的二次式做因式分解:

In [12]:
p, q = sp.symbols('p q')
expr_pq = x**2 + p*x + q
sp.factor(expr_pq)
Out[12]:
$\displaystyle p x + q + x^{2}$

你會發現,SymPy 並不會直接給出一般因式分解(因為需視 $p, q$ 的關係而定), 但我們可以改用「解根」的方式理解這個結構:

In [13]:
roots = sp.solve(sp.Eq(expr_pq, 0), x)
roots
Out[13]:
$\displaystyle \left[ - \frac{p}{2} - \frac{\sqrt{p^{2} - 4 q}}{2}, \ - \frac{p}{2} + \frac{\sqrt{p^{2} - 4 q}}{2}\right]$

從這裡,我們可以連結到熟悉的公式:

$x = \dfrac{-p \pm \sqrt{p^2 - 4q}}{2}$。

如果你把 $(x - r_1)(x - r_2)$ 展開,就會重新得到 $x^2 + px + q$,此處的符號運算幫助你理解公式的「來源」,而不只是結果。

2.10 啟發性例子二:探索連乘積的模式¶

考慮下列乘積:

$P_n = (x-1)(x-2)\cdots(x-n)$。

手算展開非常困難,但我們可以用 SymPy 展開前幾個例子,觀察係數的規律:

In [14]:
for n in range(1, 6):
    expr = 1
    for k in range(1, n+1):
        expr *= (x - k)
    print(f"n = {n} 時:")
    display(sp.expand(expr))
n = 1 時:
$\displaystyle x - 1$
n = 2 時:
$\displaystyle x^{2} - 3 x + 2$
n = 3 時:
$\displaystyle x^{3} - 6 x^{2} + 11 x - 6$
n = 4 時:
$\displaystyle x^{4} - 10 x^{3} + 35 x^{2} - 50 x + 24$
n = 5 時:
$\displaystyle x^{5} - 15 x^{4} + 85 x^{3} - 225 x^{2} + 274 x - 120$

你可以思考:

  • 常數項(不含 $x$ 的項)與 $1\cdot 2\cdot 3\cdots n$ 有什麼關係?
  • $x^{n-1}$ 的係數與 $1 + 2 + \cdots + n$ 有什麼關係?

透過電腦展開幾個具體例子,再回頭從數學上思考推理,是理解「組合數」與「係數意義」的好方法。

2.11 啟發性例子三:為積分做準備的代數變形¶

考慮未來在微積分中會遇到的積分:

$\displaystyle \int \dfrac{2x + 3}{x^2 - x}\,dx$。

手算時,我們往往會先做部分分式分解,把 integrand 寫成幾個較簡單分式之和。 SymPy 可以直接幫我們進行分解:

In [15]:
expr_int = (2*x + 3) / (x**2 - x)
display(sp.apart(expr_int))
$\displaystyle \frac{5}{x - 1} - \frac{3}{x}$

接著,在第 11 章中,你會看到如何利用這個分解結果將積分拆開來計算。 這個例子說明了「代數變形」其實是為後續運算鋪路的工具,而不是孤立存在的技能。

2.12 本章小結¶

本章你學到了:

  • 如何用 expand 展開代數式,如何用 factor 進行因式分解。
  • simplify 做一般性化簡,collect 依特定變數分組。
  • cancel 化簡有理式、apart 進行部分分式分解。
  • 使用 subs 代入變數值,並用 simplify(left - right) 來檢查等式是否為恆等式。

請記得:SymPy 是你的「代數實驗室」,可以讓你快速檢查計算、探索規律, 但數學上的理解與證明仍然需要你的思考。

2.13 練習題¶

請在本 Notebook 中新增儲存格,試著完成以下練習:

  1. 展開與化簡
    (a) 使用 expand 展開 $(x-2)(x+3)(x+1)$。
    (b) 將你展開後的結果,再用 factor 看看能否還原回原本的因式形式。

  2. 因式分解練習
    使用 factor 對下列式子進行因式分解,並觀察與課本中常見公式的關係:
    (a) $x^2 - 7x + 12$
    (b) $x^3 - x$
    (c) $4x^2 - 9$。

  3. collect 的應用
    令 $$E = x^2y + 3xy^2 + 2x^2 + 5x.$$
    (a) 使用 collect(E, x) 觀察以 $x$ 為主的分組結果。
    (b) 使用 collect(E, y) 觀察以 $y$ 為主的分組結果。
    思考:哪一種表示方式在什麼情境下比較方便?

  4. 有理式化簡與部分分式
    (a) 對 $\dfrac{x^2 - 4}{x^2 - x - 2}$ 使用 cancel 進行化簡。
    (b) 對同一個有理式使用 apart,觀察結果有何不同。
    (c) 思考:哪一種形式適合用來觀察定義域?哪一種形式適合用來做積分?

  5. 等式驗證
    使用 SymPy 檢查下列等式是否為恒等式:
    (a) $(x+2)^2 = x^2 + 4x + 4$
    (b) $(x-1)(x+1) = x^2 - 1$
    (c) $x^3 - 1 = (x-1)(x^2 + x + 1)$
    提示:可以計算 sp.simplify(左邊 - 右邊)。

  6. 加分題(思考與探索)
    (a) 利用程式產生 $P_n = (x-1)(x-2)\cdots(x-n)$ 的展開式,觀察 $x^{n-1}$ 的係數, 試著猜測它與 $1+2+\cdots+n$ 的關係。
    (b) 使用不同的 $n$ 值(例如 3, 4, 5, 6),將觀察到的數字記錄下來, 看看能否找出某種規律,並用文字寫下你的推測。

回首頁