Rで 線形代数:コーシー・シュワルツの不等式 を確認します。
1. コーシー・シュワルツの不等式 (Cauchy-Schwarz Inequality) とは
定義
コーシー・シュワルツの不等式は、
2つのベクトル u
と v
があるとき、その内積の絶対値は、それぞれのベクトルの長さ(ノルム)の積以下である、
という関係を表します。
数式で書くと以下のようになります。
|u ⋅ v| ≤ ||u|| ||v||
-
u ⋅ v
: ベクトルu
とv
の内積(ドット積)。 -
| |
: 絶対値。 -
||u||
: ベクトルu
のノルム(ユークリッドノルム、つまり長さ)。√(u₁² + u₂² + ...)
-
||v||
: ベクトルv
のノルム。√(v₁² + v₂² + ...)
両辺を2乗した以下の形で表されることもありますが、同値です。
(u ⋅ v)² ≤ ||u||² ||v||²
幾何学的な意味:射影と直角三角形
この不等式は、内積の幾何学的な定義から直感的に理解できます。 ベクトル u
と v
のなす角を θ
とすると、内積は以下のように定義されます。
u ⋅ v = ||u|| ||v|| cos(θ)
この式の両辺に絶対値をとると、
|u ⋅ v| = | ||u|| ||v|| cos(θ) | = ||u|| ||v|| |cos(θ)|
ここで、cos(θ)
は必ず -1 ≤ cos(θ) ≤ 1
の範囲にあるので、その絶対値 |cos(θ)|
は 0 ≤ |cos(θ)| ≤ 1
となります。 したがって、
|u ⋅ v| = ||u|| ||v|| × (|cos(θ)|)
(ここで |cos(θ)|
は1以下の数)
となり、|u ⋅ v|
は ||u|| ||v||
と等しいか、それより小さくなることがわかります。
等号が成立する条件
この不等式で等号(=
)が成立するのは、|cos(θ)| = 1
のときです。
|cos(θ)| = 1
となるのは、θ = 0
または θ = π
(180度) のとき、つまり 2つのベクトルが互いに平行な関係にあるときです。
- ベクトル
u
とv
が同じ向きを向いている(v = c u
,c > 0
) - ベクトル
u
とv
が正反対の向きを向いている(v = c u
,c < 0
)
つまり、2つのベクトルが線形従属(一方が他方の定数倍で表せる)である場合に限り、等号が成立します。
ベクトルが少しでも違う方向を向いていると、必ず <
の関係になります。
2. Rによるシミュレーション
Rを使って、ランダムに生成したベクトルに対してコーシー・シュワルツの不等式が常に成り立つことを確認します。また、等号が成立する特別なケースもシミュレーションします。
Rコード
# --------------------------------------------------
# コーシー・シュワルツの不等式のシミュレーション
# --------------------------------------------------
# ベクトルの内積を計算する関数
<- function(u, v) {
dot_product sum(u * v)
}
# ベクトルのノルム(長さ)を計算する関数
<- function(v) {
norm_vec sqrt(sum(v^2))
}
# --- シナリオ1: ランダムなベクトルで不等式が成り立つことの確認 ---
cat("--- シナリオ1: ランダムなベクトル ---\n")
# 3次元のランダムなベクトルを2つ生成
<- 20250625
seed set.seed(seed)
<- rnorm(3)
u <- rnorm(3)
v
cat("ベクトルu:", u, "\n")
cat("ベクトルv:", v, "\n")
# 不等式の左辺を計算: |u・v|
<- abs(dot_product(u, v))
lhs
# 不等式の右辺を計算: ||u|| * ||v||
<- norm_vec(u) * norm_vec(v)
rhs
cat("\n左辺 |u・v|:", lhs, "\n")
cat("右辺 ||u||*||v||:", rhs, "\n")
cat("\n不等式の検証:", lhs, "<=", rhs, "->", lhs <= rhs, "\n")
cat("→ 不等式は成り立っています。\n\n")
# --- シナリオ2: 等号が成立するケース(ベクトルが平行な場合) ---
cat("--- シナリオ2: 等号が成立するケース(平行なベクトル) ---\n")
# ベクトルu'を定義
<- c(1, 2, 3)
u_prime
# u'と平行なベクトルv'を作成 (v' = 2 * u')
<- 2 * u_prime
v_prime
cat("ベクトルu':", u_prime, "\n")
cat("ベクトルv':", v_prime, "\n")
# 不等式の左辺と右辺を計算
<- abs(dot_product(u_prime, v_prime))
lhs_parallel <- norm_vec(u_prime) * norm_vec(v_prime)
rhs_parallel
cat("\n左辺 |u'・v'|:", lhs_parallel, "\n")
cat("右辺 ||u'||*||v'||:", rhs_parallel, "\n")
cat("\n不等式の検証:", lhs_parallel, "<=", rhs_parallel, "->", lhs_parallel <= rhs_parallel, "\n")
# Rの数値計算上の微小な誤差を考慮して、等しいかを確認
<- all.equal(lhs_parallel, rhs_parallel)
are_equal cat("左辺と右辺は等しいか? ->", isTRUE(are_equal), "\n")
cat("→ ベクトルが平行な場合、等号が成立することが確認できました。\n\n")
# --- シナリオ3: 多数のベクトルでシミュレーション ---
cat("--- シナリオ3: 1000回のシミュレーション ---\n")
<- 1000
n_sim <- logical(n_sim) # 結果を格納するベクトル
results
for (i in 1:n_sim) {
# 2次元から10次元までのランダムな次元数のベクトルを生成
<- sample(2:10, 1)
dim <- rnorm(dim)
vec1 <- rnorm(dim)
vec2
# 不等式を検証
<- abs(dot_product(vec1, vec2))
lhs_sim <- norm_vec(vec1) * norm_vec(vec2)
rhs_sim
<- (lhs_sim <= rhs_sim)
results[i]
}
# すべてのシミュレーションで不等式が成り立ったか確認
if (all(results)) {
cat(n_sim, "回のシミュレーションすべてで、コーシー・シュワルツの不等式が成り立ちました。\n")
else {
} cat("不等式が成り立たないケースが見つかりました。\n")
}
--- シナリオ1: ランダムなベクトル ---
ベクトルu: 1.52588 0.4194963 -1.078101
ベクトルv: -1.269916 -0.6472587 -0.3926426
左辺 |u・v|: 1.785954
右辺 ||u||*||v||: 2.830977
不等式の検証: 1.785954 <= 2.830977 -> TRUE
→ 不等式は成り立っています。
--- シナリオ2: 等号が成立するケース(平行なベクトル) ---
ベクトルu': 1 2 3
ベクトルv': 2 4 6
左辺 |u'・v'|: 28
右辺 ||u'||*||v'||: 28
不等式の検証: 28 <= 28 -> TRUE
左辺と右辺は等しいか? -> TRUE
→ ベクトルが平行な場合、等号が成立することが確認できました。
--- シナリオ3: 1000回のシミュレーション ---
1000 回のシミュレーションすべてで、コーシー・シュワルツの不等式が成り立ちました。
実行結果と解説
シナリオ1では、ランダムに生成した2つのベクトルに対して、不等式の左辺(内積の絶対値)と右辺(ノルムの積)を計算します。結果として、
左辺 < 右辺
となり、不等式が成り立っていることがわかります。シナリオ2では、意図的に平行なベクトル(
v' = 2 * u'
)を作成します。この場合、左辺と右辺の値が一致し、不等式の等号が成立する条件をシミュレーションで確認できます。シナリオ3では、さまざまな次元数のランダムなベクトルを多数生成し、繰り返し不等式を検証します。結果として、1000回すべての試行で不等式が成立していることを確認できます。
以上です。