3.3 不等式與區間#
本節目標#
- 學會用
solve_univariate_inequality()解一元不等式,用reduce_inequalities()處理多條件。 - 認識
Interval區間物件與集合運算(交集、聯集)。 - 理解解集合的表示:
FiniteSet、Interval、Union、ConditionSet。 - 掌握含絕對值、分母的不等式的注意事項(分母不為零、開閉區間)。
- 實驗:畫出 \(f(x) > 0\) 的解區間,與函數圖形互相印證。
數學概念:不等式的解是集合#
等式的解通常是有限個點;不等式
\[ f(x) > 0 \]
的解通常是一個或數個區間。解不等式的標準流程(手算):
- 找出「臨界點」: \(f(x) = 0\) 的根與 \(f(x)\) 無定義的點(分母為零處)。
- 這些臨界點把實數軸切成若干段。
- 在每段中取測試點判斷 \(f\) 的正負(符號表法)。
- 依不等號決定端點的開閉: \(\geq\) 含根(閉)、 \(>\) 不含根(開);無定義點一律開。
例:解 \(x^2 - 4 > 0\) 。臨界點 \(x = \pm 2\) ,符號表顯示在 \((-\infty, -2)\) 與 \((2, \infty)\) 為正,故解集為
\[ (-\infty, -2) \cup (2, \infty) \]
solve_univariate_inequality#
from sympy import symbols, solve_univariate_inequality, S, oo
x = symbols('x', real=True) # 不等式在實數域上討論
# 例 1:x^2 - 4 > 0
r1 = solve_univariate_inequality(x**2 - 4 > 0, x)
print(r1) # Union(Interval.open(-oo, -2), Interval.open(2, oo))
print(r1.as_set()) # 同上,明確轉成集合
# 例 2:x^2 - 4 <= 0(含等號 → 閉區間)
print(solve_univariate_inequality(x**2 - 4 <= 0, x)) # Interval(-2, 2)
# 例 3:一次不等式 2x - 3 >= 1
print(solve_univariate_inequality(2*x - 3 >= 1, x)) # Interval(2, oo)
# 例 4:嚴格不等式回傳開區間, relational 物件也可取得
sol = solve_univariate_inequality(x**2 < 9, x, relational=False)
print(sol) # Interval.open(-3, 3)
注意:宣告 x = symbols('x', real=True) 很重要——不等式只對實數有意義,先聲明變數的假設可避免 SymPy 嘗試複數域。
reduce_inequalities:多條件聯立#
多個不等式(或混合等式)要「同時成立」,就是取交集:
from sympy import symbols, reduce_inequalities, And, solve
x = symbols('x', real=True)
# 例 1:-1 < x < 5 且 x^2 >= 4 → 條件的交集
print(reduce_inequalities([-1 < x, x < 5, x**2 >= 4], x))
# Union(Interval(-2 ... ), ...) 視化簡結果
# 例 2:分式不等式 (x-1)/(x+2) > 0
# 手算:分子分母各找零點 -2, 1;符號表 → x < -2 或 x > 1
print(reduce_inequalities((x - 1)/(x + 2) > 0, x))
# Union(Interval.open(-oo, -2), Interval.open(1, oo)) ← -2 自動排除!
# 例 3:混合等式與不等式:x + y = 3 且 x > 0(兩變數)
y = symbols('y', real=True)
print(reduce_inequalities([x + y - 3, x > 0], x))
# (0, oo) → 因 y = 3 - x,條件只剩 x > 0
# 例 4:絕對值不等式 |x - 3| < 2
from sympy import Abs
print(reduce_inequalities(Abs(x - 3) < 2, x)) # (1 < x) & (x < 5) 即 Interval.open(1, 5)
reduce_inequalities 比 solve_univariate_inequality 更通用:可處理多變數、混合等式,輸出常是 And/Or 的邏輯組合,用 .as_set() 可轉成區間集合。
Interval 物件與集合運算#
from sympy import Interval, Union, S, oo, symbols, EmptySet
# 四種區間
print(Interval(1, 3)) # [1, 3] 閉區間
print(Interval.open(1, 3)) # (1, 3) 開區間
print(Interval.Lopen(1, 3)) # (1, 3] 左開右閉
print(Interval.Ropen(1, 3)) # [1, 3) 左閉右開
print(Interval(-oo, 2)) # (-oo, 2] 無窮區間(oo = ∞)
# 集合運算
A = Interval(0, 5)
B = Interval.open(3, 8)
print(A.intersect(B)) # Interval.Lopen(3, 5) 即 (3, 5]
print(A.union(B)) # [0, 8)
print(A - B) # 差集 [0, 3]
print(Interval(0, 1).intersect(Interval(2, 3))) # EmptySet
# 判斷歸屬
print(2.5 in B) # True
print(S(3) in B) # False(開區間不含 3)
# 與解集合結合:把解的邏輯條件轉為集合再操作
x = symbols('x', real=True)
s1 = (x**2 - 4 > 0).as_set() # 需要 assume real
print(s1) # Union(Interval.open(-oo, -2), Interval.open(2, oo))
幾何直覺:不等式的解集是數線上的「陰影區域」,Interval 與 Union 就是把陰影精確記錄下來的資料結構;交集對應「同時滿足兩條件」,聯集對應「滿足任一條件」。
解集合的表示:ConditionSet#
當 SymPy 無法化簡解集合時,它不會放棄,而是給一個「條件集合」——用描述法寫出的集合:
from sympy import symbols, solveset, S, ConditionSet, sin
x = symbols('x', real=True)
# solveset 回傳的永遠是集合
print(solveset(x**2 - 4, x, domain=S.Reals))
# {-2, 2} FiniteSet
print(solveset(sin(x), x, domain=S.Reals))
# ImageSet(Lambda(n, 2*n*pi), Integers) ∪ ImageSet(Lambda(n, 2*n*pi + pi), Integers)
# ← 無限多解:x = 2nπ 與 x = 2nπ + π(n ∈ ℤ),用映射表示
print(solveset(x**2 + x + 1, x, domain=S.Reals))
# EmptySet ← 判別式 < 0,實數域無解
# ConditionSet 的樣子:transcendental方程解不出來時
cset = solveset(sin(x) - x, x, domain=S.Reals)
print(cset)
# ConditionSet(x, Eq(sin(x) - x, 0), Reals)
# 讀法:「使 sin(x) - x = 0 的所有實數 x」——正確但未化簡
ConditionSet 的意義:解集合的描述法 \(\{x \in \mathbb{R} : \sin x - x = 0\}\) 。它保證答案的正確語義,即使演算法找不到閉式解。這類方程就要靠 3.4 節的數值方法。
含絕對值/分母的不等式:注意事項#
from sympy import symbols, reduce_inequalities, Abs, solve_univariate_inequality
x = symbols('x', real=True)
# 1. 絕對值不等式:|2x - 1| <= 5 → -5 <= 2x-1 <= 5 → -2 <= x <= 3
print(reduce_inequalities(Abs(2*x - 1) <= 5, x)) # -2 <= x, x <= 3
# 2. 分母不允許為零:1/x > 0
print(reduce_inequalities(1/x > 0, x)) # (0, oo) 開區間,0 被排除
print(reduce_inequalities(1/x >= 0, x)) # (0, oo) ← 依然不含 0!
# 關鍵:≥ 的「=」只在 f(x)=0 有定義處生效;分母零點永遠是開的
# 3. 危險陷阱:兩邊同乘 x 不等價!(x 的正負會翻轉不等號)
# 錯誤做法:x*(1/x) > 0*x → 1 > 0 恆真 ✗
# 正確做法:通分或分區間討論,交給 SymPy:
print(reduce_inequalities((x - 2)/x > 0, x))
# Union(Interval.open(-oo, 0), Interval.open(2, oo))
# 4. 根號不等式:sqrt(x) < 2,需兼顧定義域 x >= 0
from sympy import sqrt
print(reduce_inequalities(sqrt(x) < 2, x)) # [0, 4) ← 左端是閉(定義域)
三條鐵律:
- 分母零點永遠開,不論不等號是否有等號。
- 不等式兩邊不可隨意乘以含未知數的式子(會翻轉方向或產生偽解)。
- 定義域優先:根號、對數、分母都會限制解的範圍,SymPy 會自動處理,手算時要記得。
動手實驗:畫出 \(f(x) > 0\) 的解區間#
實驗目標:解出 \(f(x) = x^3 - 3x = x(x-\sqrt{3})(x+\sqrt{3})\) 大於 0 的區間,並用符號表 + 簡易畫圖印證。
from sympy import symbols, solve, reduce_inequalities, plot, Rational
x = symbols('x', real=True)
f = x**3 - 3*x
# 1. 臨界點
crit = sorted(solve(f, x), key=lambda r: float(r))
print(crit) # [-sqrt(3), 0, sqrt(3)]
# 2. 解不等式
sol = (f > 0).as_set()
print(sol)
# Union(Interval.open(-sqrt(3), 0), Interval.open(sqrt(3), oo))
# 3. 符號表:在每段取測試點
import itertools
pts = [-2, -1, Rational(1,2), 2] # 各段的測試點
for p in pts:
print(f"f({float(p):+.2f}) = {float(f.subs(x, p)):+.2f}")
# -2.36 -, +0.66 +, -1.38 -, +2.00 + → 與解集一致(正的區段即解)
# 4. 畫圖目視(細節見第 X 章 plot 篇;先嘗試執行)
p1 = plot(f, (x, -3, 3), line_color='blue', show=False)
p1.show() # 觀察 f > 0 的位置是否正是 (-√3, 0) 與 (√3, ∞)
實驗觀察:
- 三次曲線在根之間「正負交替」(單根處必變號),所以 \(f>0\) 的解是根之間的交替區段。
- 若把 \(f\) 改成 \(x^3 - 3x^2 = x^2(x-3)\) , \(x=0\) 是偶數重根,曲線不變號——解集變成 \((3, \infty)\) ,0 處 \(f=0\) 也不屬於 \(f>0\) 。動手驗證:
g = x**3 - 3*x**2
print((g > 0).as_set()) # Interval.open(3, oo)
print((g >= 0).as_set()) # {0} ∪ [3, oo) ← 0 是孤立點!
進一步挑戰:
- 解 \(\frac{x^2 - 1}{x + 2} \leq 0\) ,並用符號表逐段驗證(注意 \(x = -2\) 必須排除)。
- 解 \(|x^2 - 4| > 1\) ,把結果畫在數線示意圖上(用
Interval列印即可)。 - 對 \(f(x) = \sin x\) ( \(x \in [0, 2\pi]\) ),用
solveset(sin(x) > 0, x, domain=Interval(0, 2*pi))求解並畫圖印證。
小結與練習#
小結
- 不等式的解是集合:
Interval(區間)、FiniteSet(點)、Union(聯集)、EmptySet、ConditionSet(描述法)。 solve_univariate_inequality()解單變數不等式;reduce_inequalities()處理多條件與混合等式;.as_set()把邏輯條件轉為集合。- 分母零點永遠排除;等號只在函數有定義的零點生效;定義域(根號、對數)會收縮解集。
- 臨界點 + 符號表是手算與程式共同的骨架;重根處函數可能不變號,解集會出現孤立點。
練習
- 解 \(x^2 - 2x - 3 \geq 0\) ,寫出精確的區間聯集,並說明每個端點為何是閉的。
- 解 \(\frac{2x - 1}{x - 3} < 1\) (先移項通分再解,避免直接交叉相乘)。
- 解 \(|x + 1| + |x - 2| \leq 5\) ,與手算的分段討論對照。
- 求 \(\sqrt{x + 1} - \sqrt{x} > \frac{1}{2}\) 的解集(存在嗎?用
reduce_inequalities驗證你的手算結論)。 - 對 \(f(x) = x^4 - 5x^2 + 4\) ,用「臨界點 + 符號表 +
.as_set()」三步驟解 \(f(x) > 0\) ,並用plot目視確認。