Rで 線形代数:行列のランク を試みます。
行列のランクを求めるコード
行列のランクとは、その行列の線形独立な列(または行)ベクトルの最大数です。これは、ガウスの消去法を使って行列を階段行列 (Row Echelon Form) に変形し、その結果の非ゼロ行(要素がすべてゼロではない行)の数を数えることで求められます。
以下に、ガウスの消去法を実装して行列のランクを計算する関数 fun_rank
を示します。
# ガウスの消去法により行列のランクを計算する関数
# A: 入力行列
# tol: 浮動小数点数の計算誤差を考慮するための許容誤差
<- function(A, tol = 1e-10) {
fun_rank # 行列をコピーして、元の行列を変更しないようにする
<- A
M
# 行数と列数を取得
<- nrow(M)
m <- ncol(M)
n
# ランク(非ゼロ行の数)を初期化
<- 0
rank # 現在注目しているピボット行
<- 1
pivot_row
# 各列について処理を進める
for (j in 1:n) {
# 全ての行がピボットとして確定したら終了
if (pivot_row > m) {
break
}
# --- 部分ピボット選択 (Partial Pivoting) ---
# 数値的安定性のために、pivot_row以降で絶対値が最大の要素をピボットとして探す
<- pivot_row
i <- i
max_row <- abs(M[i, j])
max_val
# pivot_rowより下の行を探索
if (i < m) {
for (k in (i + 1):m) {
if (abs(M[k, j]) > max_val) {
<- abs(M[k, j])
max_val <- k
max_row
}
}
}
# ピボット(列の最大値)が許容誤差より小さい場合、
# この列は線形従属とみなし、次の列に移る
if (max_val < tol) {
next
}
# --- 行の交換 ---
# 見つけた最大値を持つ行を現在のpivot_rowと交換する
if (max_row != pivot_row) {
<- M[pivot_row, ]
temp_row <- M[max_row, ]
M[pivot_row, ] <- temp_row
M[max_row, ]
}
# --- 前進消去 (Forward Elimination) ---
# pivot_rowより下のすべての行について、j列目の要素を0にする
# (ただし、pivot_rowが最終行でない場合)
if (pivot_row < m) {
for (i in (pivot_row + 1):m) {
# 消去するための係数を計算
<- M[i, j] / M[pivot_row, j]
factor # 行の基本変形(下の行から、ピボット行の倍数を引く)
<- M[i, ] - factor * M[pivot_row, ]
M[i, ]
}
}
# ピボットが見つかったので、ランクを1増やし、次のピボット行に進む
<- rank + 1
rank <- pivot_row + 1
pivot_row
}
return(rank)
}
コードのテスト
ランクが3の行列
<- matrix(c(1, 2, 3, 0, 1, 4, 5, 6, 0), nrow = 3, byrow = TRUE)
A_full_rank cat("--- ランク計算のテスト ---\n")
cat("行列 A_full_rank:\n")
print(A_full_rank)
cat("実装によるランク:", fun_rank(A_full_rank), "\n") # 期待値: 3
cat("組み込み関数によるランク:", qr(A_full_rank)$rank, "\n\n")
--- ランク計算のテスト ---
行列 A_full_rank:
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 0 1 4
[3,] 5 6 0
実装によるランク: 3
組み込み関数によるランク: 3
ランクが2の行列(3列目が1列目+2列目)
<- matrix(c(1, 2, 3, 4, 5, 9, 6, 7, 13), nrow = 3, byrow = TRUE)
B_rank_deficient cat("行列 B_rank_deficient:\n")
print(B_rank_deficient)
cat("実装によるランク:", fun_rank(B_rank_deficient), "\n") # 期待値: 2
cat("組み込み関数によるランク:", qr(B_rank_deficient)$rank, "\n")
行列 B_rank_deficient:
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 9
[3,] 6 7 13
実装によるランク: 2
組み込み関数によるランク: 2
以上です。