MATLABでの行列演算入門
はじめに
MATLABは「Matrix Laboratory」の略称で、その名の通り行列演算を得意とするプログラミング環境です。本記事では、MATLAB初心者の方向けに行列演算の基本から実践的な使い方まで、演習を交えながら解説します。
目次
1. 行列の基本
1.1 行列とは
行列は数値を長方形状に配列したもので、MATLABではすべてのデータが行列として扱われます。
% スカラー(1×1の行列)
a = 5
% 行ベクトル(1×nの行列)
row_vec = [1 2 3 4 5]
% 列ベクトル(n×1の行列)
col_vec = [1; 2; 3; 4; 5]
% 行列(m×nの行列)
A = [1 2 3; 4 5 6; 7 8 9]
演習1:基本的な行列を作成してみよう
以下のコードを実行して、行列の基本を確認しましょう。
% 演習1: 様々な行列を作成
scalar = 10;
row_vector = [2 4 6 8];
column_vector = [1; 3; 5; 7];
matrix_2x3 = [1 2 3; 4 5 6];
% サイズを確認
size(scalar) % 1×1
size(row_vector) % 1×4
size(column_vector) % 4×1
size(matrix_2x3) % 2×3
2. 行列の作成方法
2.1 直接入力による作成
% スペースまたはカンマで列を区切る
A = [1 2 3; 4 5 6]
B = [1, 2, 3; 4, 5, 6] % カンマでも可
% セミコロンで行を区切る
C = [1 2; 3 4; 5 6]
2.2 組み込み関数による作成
% ゼロ行列
Z = zeros(3, 4) % 3×4のゼロ行列
% 1行列
O = ones(2, 3) % 2×3の1行列
% 単位行列
I = eye(4) % 4×4の単位行列
% 乱数行列
R = rand(3, 3) % 0-1の一様乱数
N = randn(3, 3) % 標準正規分布の乱数
% 対角行列
D = diag([1 2 3 4]) % 対角要素が1,2,3,4の対角行列
2.3 数列を使った作成
% コロン演算子
x = 1:5 % [1 2 3 4 5]
y = 0:0.5:2 % [0 0.5 1 1.5 2]
z = 10:-2:0 % [10 8 6 4 2 0]
% linspace関数
t = linspace(0, 1, 5) % 0から1まで5等分
% reshape関数
A = 1:12;
B = reshape(A, 3, 4) % 3×4行列に変形
演習2:様々な行列を作成してみよう
% 演習2: 以下の行列を作成してください
% 1. 5×5のゼロ行列
ex2_1 = zeros(5, 5);
% 2. 3×3の単位行列
ex2_2 = eye(3);
% 3. 1から20までの整数を含む4×5の行列
ex2_3 = reshape(1:20, 4, 5);
% 4. 0からπまでを100等分した行ベクトル
ex2_4 = linspace(0, pi, 100);
% 5. 対角要素が[5, 10, 15]の対角行列
ex2_5 = diag([5, 10, 15]);
% 結果を確認
disp('演習2-3の結果:');
disp(ex2_3);
3. 行列の基本演算
3.1 四則演算
A = [1 2; 3 4];
B = [5 6; 7 8];
% 加算・減算
C = A + B
D = A - B
% 行列の乗算
E = A * B % 行列積
% 要素ごとの乗算・除算
F = A .* B % 要素ごとの積
G = A ./ B % 要素ごとの除算
% べき乗
H = A^2 % 行列の2乗(A*A)
I = A.^2 % 要素ごとの2乗
3.2 転置
A = [1 2 3; 4 5 6];
% 転置
A_transpose = A' % または transpose(A)
% 複素共役転置を避ける場合
A_transpose2 = A.' % 単純転置(複素数の場合に違いが出る)
演習3:行列演算を実践しよう
% 演習3: 以下の計算を実行してください
A = [2 4; 6 8];
B = [1 3; 5 7];
% 1. A + B を計算
result1 = A + B;
% 2. A * B を計算(行列積)
result2 = A * B;
% 3. A .* B を計算(要素ごとの積)
result3 = A .* B;
% 4. Aの転置行列を作成
result4 = A';
% 5. A^2 と A.^2 の違いを確認
result5_matrix = A^2; % 行列の2乗
result5_element = A.^2; % 要素ごとの2乗
disp('A * B(行列積):');
disp(result2);
disp('A .* B(要素ごとの積):');
disp(result3);
4. 要素へのアクセスと操作
4.1 インデックスによるアクセス
A = [1 2 3 4; 5 6 7 8; 9 10 11 12];
% 単一要素へのアクセス
element = A(2, 3) % 2行3列の要素(7)
% 行・列の抽出
row2 = A(2, :) % 2行目全体
col3 = A(:, 3) % 3列目全体
% 部分行列の抽出
submatrix = A(1:2, 2:4) % 1-2行、2-4列の部分行列
% 線形インデックス
A(5) % 5番目の要素(列優先で数える)
4.2 論理インデックス
A = [1 2 3; 4 5 6; 7 8 9];
% 条件を満たす要素の抽出
idx = A > 5; % 5より大きい要素の論理インデックス
elements = A(idx) % 該当する要素を抽出
% 条件を満たす要素の置換
A(A < 5) = 0 % 5未満の要素を0に置換
演習4:行列要素の操作
% 演習4: 行列の要素操作
M = magic(4); % 4×4の魔方陣を作成
% 1. 2行3列の要素を取得
ex4_1 = M(2, 3);
% 2. 3行目全体を取得
ex4_2 = M(3, :);
% 3. 1列目と4列目を取得
ex4_3 = M(:, [1 4]);
% 4. 10より大きい要素をすべて100に置換
M_copy = M;
M_copy(M_copy > 10) = 100;
% 5. 対角要素を取得
ex4_5 = diag(M);
disp('元の魔方陣:');
disp(M);
disp('10より大きい要素を100に置換:');
disp(M_copy);
5. 特殊な行列演算
5.1 行列の情報取得
A = [1 2 3; 4 5 6];
% サイズ関連
[m, n] = size(A) % 行数と列数
num_elements = numel(A) % 要素数
len = length(A) % 最大次元の長さ
% 統計関数
max_val = max(A) % 各列の最大値
min_val = min(A) % 各列の最小値
sum_col = sum(A) % 各列の和
sum_all = sum(A, 'all') % 全要素の和
mean_val = mean(A) % 各列の平均
5.2 行列の変形と結合
A = [1 2; 3 4];
B = [5 6; 7 8];
% 結合
C = [A B] % 水平結合
D = [A; B] % 垂直結合
% 変形
E = reshape(A, 1, 4) % 1×4に変形
F = A(:) % 列ベクトルに変換
% 回転・反転
G = rot90(A) % 90度回転
H = fliplr(A) % 左右反転
I = flipud(A) % 上下反転
5.3 線形代数演算
A = [4 2; 1 3];
% 行列式
det_A = det(A)
% 逆行列
inv_A = inv(A)
% 固有値・固有ベクトル
[V, D] = eig(A) % V: 固有ベクトル, D: 固有値(対角行列)
% 階数
rank_A = rank(A)
% ノルム
norm_A = norm(A) % 行列のノルム
演習5:行列の解析
% 演習5: 行列の様々な性質を調べる
A = [2 -1 0; -1 2 -1; 0 -1 2];
% 1. 行列式を計算
ex5_1 = det(A);
% 2. 逆行列を計算し、A * A^(-1) = I を確認
ex5_2 = inv(A);
check_identity = A * ex5_2;
% 3. 固有値を計算
ex5_3 = eig(A);
% 4. 各行の和と各列の和を計算
ex5_4_row = sum(A, 2); % 各行の和
ex5_4_col = sum(A, 1); % 各列の和
% 5. 最大値と最小値の位置を見つける
[max_val, max_idx] = max(A(:));
[min_val, min_idx] = min(A(:));
[max_row, max_col] = ind2sub(size(A), max_idx);
[min_row, min_col] = ind2sub(size(A), min_idx);
fprintf('行列式: %.2f\n', ex5_1);
fprintf('最大値 %d は (%d, %d) の位置\n', max_val, max_row, max_col);
fprintf('最小値 %d は (%d, %d) の位置\n', min_val, min_row, min_col);
6. 実践演習
演習6-1:連立方程式を解く
% 連立方程式 Ax = b を解く
% 2x + 3y - z = 1
% x - y + 2z = 3
% 3x + y - z = 2
A = [2 3 -1; 1 -1 2; 3 1 -1];
b = [1; 3; 2];
% 方法1: 逆行列を使う
x1 = inv(A) * b;
% 方法2: バックスラッシュ演算子(推奨)
x2 = A \ b;
fprintf('解: x = %.2f, y = %.2f, z = %.2f\n', x2(1), x2(2), x2(3));
% 検証
check = A * x2 - b;
fprintf('検証(Ax - b): [%.10f, %.10f, %.10f]\n', check(1), check(2), check(3));
演習6-2:画像処理の基礎
% 簡単な画像フィルタリング
% 5×5のランダム画像を作成
img = randi([0 255], 5, 5);
% 平均化フィルタ(3×3)
filter = ones(3, 3) / 9;
% 手動でフィルタリング(境界は無視)
filtered = zeros(size(img));
for i = 2:4
for j = 2:4
neighborhood = img(i-1:i+1, j-1:j+1);
filtered(i, j) = sum(sum(neighborhood .* filter));
end
end
disp('元の画像:');
disp(img);
disp('フィルタ後:');
disp(filtered);
演習6-3:データ解析
% 成績データの解析
% 5人の学生の3科目の成績
scores = [85 90 78;
92 88 85;
78 82 90;
88 85 92;
90 92 88];
% 各学生の平均点
student_avg = mean(scores, 2);
% 各科目の平均点
subject_avg = mean(scores, 1);
% 全体の平均と標準偏差
total_avg = mean(scores, 'all');
total_std = std(scores(:));
% 最高得点の学生と科目を特定
[max_score, idx] = max(scores(:));
[student, subject] = ind2sub(size(scores), idx);
fprintf('学生別平均: ');
fprintf('%.1f ', student_avg);
fprintf('\n科目別平均: ');
fprintf('%.1f ', subject_avg);
fprintf('\n全体平均: %.1f, 標準偏差: %.1f\n', total_avg, total_std);
fprintf('最高得点: %d点(学生%d、科目%d)\n', max_score, student, subject);
7. よくあるエラーと対処法
7.1 次元の不一致
% エラーの例
A = [1 2 3];
B = [4; 5; 6];
% C = A + B; % エラー:次元が一致しない
% 対処法
C = A' + B; % Aを転置して次元を合わせる
7.2 インデックスエラー
A = [1 2 3; 4 5 6];
% element = A(3, 2); % エラー:3行目は存在しない
% 対処法:サイズを確認
[m, n] = size(A);
if 3 <= m && 2 <= n
element = A(3, 2);
else
disp('インデックスが範囲外です');
end
7.3 演算子の間違い
A = [1 2; 3 4];
B = [5 6; 7 8];
% 要素ごとの演算と行列演算の違い
C1 = A * B; % 行列積
C2 = A .* B; % 要素ごとの積
% べき乗も同様
D1 = A^2; % 行列の2乗(A*A)
D2 = A.^2; % 要素ごとの2乗
まとめ
本記事では、MATLABにおける行列演算の基本から実践的な使い方まで解説しました。重要なポイントは以下の通りです:
- MATLABではすべてがベクトル・行列として扱われる
- **ドット演算子(.)**の有無で演算の意味が変わる
- インデックスは1から始まる(0からではない)
- 列優先でデータが格納される
- 豊富な組み込み関数を活用することで効率的なプログラミングが可能
次のステップ
- より高度な線形代数演算(LU分解、QR分解、特異値分解など)
- 疎行列の扱い方
- 並列計算による高速化
- Symbolic Math Toolboxを使った記号計算
MATLABの行列演算をマスターすることで、科学技術計算、データ解析、機械学習など様々な分野で効率的なプログラミングが可能になります。ぜひ実際に手を動かして練習してみてください!