【Pythonで学ぶ線形代数学講座(5)】コーシー・シュワルツの不等式と三角不等式
コーシー・シュワルツの不等式
角度による内積の定義を再掲します。
\[\boldsymbol{v}\cdot\boldsymbol{w}=\parallel\boldsymbol{v}\parallel\parallel\boldsymbol{w}\parallel\cos\theta\tag{1}\]
右辺の $\cos\theta$ は $-1$ から $1$ の値に制限されるので、内積の絶対値について次の不等式が成り立ちます。
\[|\boldsymbol{v}\cdot\boldsymbol{w}|\ \leq\ \parallel\boldsymbol{v}\parallel\parallel\boldsymbol{w}\parallel\tag{2}\]
この式を コーシー・シュワルツの不等式 (Cauchy–Schwarz inequality) とよびます。等号は $\boldsymbol{v}$ と $\boldsymbol{w}$ が互いに平行のとき(互いに同じ方向または逆向きであるとき)に成立します(下図)。

ベクトル $\boldsymbol{v}=\begin{bmatrix}2\\3\end{bmatrix}$ と $\boldsymbol{w}=\begin{bmatrix}2\\5\end{bmatrix}$ について、コーシー・シュワルツの不等式が成り立つことを確認してみます。
# python_cauchy_schwarz_inequality
# In[1]
import numpy as np
from scipy.linalg import norm
# ベクトルを定義
v = np.array([2, 3])
w = np.array([2, 5])
# |v・w|を計算
a = np.abs(np.dot(v, w))
# |v||w|を計算
b = norm(v) * norm(w)
# |v||w|-|v・w|
print("|v||w|-|v・w| : {:.3f}".format(b - a))
# |v||w|-|v・w| : 0.416
任意のベクトルを受け取って、コーシー・シュワルツの不等式が成り立つことを確認する関数も載せておくので、ぜひ色々なベクトルで試してみてください。
# In[2]
def check_cauchy_schwarz(u, v):
"""
ベクトルu,vを受け取りコーシー・シュワルツの不等式が成り立つかどうかを確認する関数
Parameters:
u(numpy.ndarray):ベクトルu
v(numpy.ndarray):ベクトルv
Returns:
bool:コーシー・シュワルツの不等式が成り立つ場合はTrue、そうでない場合はFalse。
"""
# 内積を計算
inner_product = np.dot(u, v)
# コーシー・シュワルツの不等式の確認
return np.abs(inner_product) <= norm(u) * norm(v)
# 例として、ベクトル u, v を定義
u_example = np.array([2, 3])
v_example = np.array([4, -1])
# 10組のランダムなベクトルについて、コーシーシュワルツ不等式が成り立つことを確認
rng = np.random.default_rng(0)
for i in range(10):
u = rng.integers(100, size=2)
v = rng.integers(100, size=2)
print(u, v, check_cauchy_schwarz(u,v))
'''
[85 63] [51 26] True
[30 4] [7 1] True
[17 81] [64 91] True
[50 60] [97 72] True
[63 54] [55 93] True
[27 81] [67 0] True
[39 85] [55 3] True
[76 72] [84 17] True
[ 8 86] [ 2 54] True
[ 8 29] [48 42] True
'''
三角不等式
内積の定義式 (1) とコーシー・シュワルツの不等式 (2) を使うと、2 つのベクトルの和についての評価式を得ることができます。
\[\parallel\boldsymbol{v}+\boldsymbol{w}\parallel\ \leq\ \parallel\boldsymbol{v}\parallel+\parallel\boldsymbol{w}\parallel\tag{3}\]
これは 三角不等式 (triangle inequality) とよばれる有名な式で、三角形の 2 辺の長さの和が他の 1 辺の長さより大きいことを表しています(ほとんど自明の事実です)。

等号は $\boldsymbol{v}$ と $\boldsymbol{w}$ が平行のとき(つまり三角形がつぶれて直線になるとき)に成立します。三角不等式の証明は簡単です:
\[\begin{align*}\parallel\boldsymbol{v}+\boldsymbol{w}\parallel ^2&=\parallel\boldsymbol{v}\parallel ^2+2\boldsymbol{v}\cdot\boldsymbol{w}+\parallel\boldsymbol{w}\parallel^2\\[6pt]&\ \leq\ \parallel\boldsymbol{v}\parallel^2+2\parallel\boldsymbol{v}\parallel\parallel\boldsymbol{w}\parallel+\parallel\boldsymbol{w}\parallel^2\\[6pt]&\ =\ (\parallel\boldsymbol{v}\parallel+\parallel\boldsymbol{w}\parallel)^2\end{align*}\]
先ほどと同じベクトル $\boldsymbol{v}=\begin{bmatrix}2\\3\end{bmatrix}$ と $\boldsymbol{w}=\begin{bmatrix}2\\5\end{bmatrix}$ について、三角不等式が成り立つことを確認しておきます。
# python_triangle_inequality
# In[1]
import numpy as np
from scipy.linalg import norm
# ベクトルを定義
v = np.array([2, 3])
w = np.array([2, 5])
# |v+w|を計算
a = norm(v + w)
# |v|+|w|を計算
b = norm(v) + norm(w)
# |v|+|w|-|v+w|
print("|v|+|w|-|v+w| : {:.3f}".format(b - a))
# |v|+|w|-|v+w| : 0.046
以下のコードは、任意のベクトルを受け取って三角不等式が成り立つことをチェックする関数です。
# In[2]
def check_triangle_inequality(u, v):
"""
ベクトルu,vを受け取り、三角不等式が成り立つかどうかを確認する関数
Parameters:
u(numpy.ndarray):ベクトル u
v(numpy.ndarray):ベクトル v
Returns:
bool: 三角不等式が成り立つ場合はTrue、そうでない場合はFalse。
"""
# 三角不等式の確認
return np.linalg.norm(u + v) <= norm(u) + norm(v)
# 例として、ベクトル u, v を定義
u_example = np.array([2, 3])
v_example = np.array([4, -1])
# 関数を使って確認
result_example = check_triangle_inequality(u_example, v_example)
print("ベクトル", u_example, "と", v_example, "に対する三角不等式の結果:", result_example)
# ベクトル[2 3]と[4 -1]に対する三角不等式の結果: True
コメント
「三角形の一番長い辺が他の二辺の和よりも長いこと」とありますが、逆ではないでしょうか?2辺の和のほうが長い、が正解ではないでしょうか。
申し訳ありませんでした。御指摘の通りです。
記事は訂正しておきました。
サイトの記事のすべてを一人ではチェックできないので、ミスを指摘していただけると本当に助かります。今後もよろしくお願いします。