matlec - 情報通信システム研究室

立命館大学理工学部電気電子工学科
鷹羽研究室・久保研究室
プレ卒研資料
MATLAB プログラミングの基礎(前編)
はじめに
この文書では初めて MATLAB を使う人を対象に,基本的な文法,基本コマンドの使用方法について解説し
ています.ただし完全な文法やコマンド仕様の解説を目指したわけではなく,先輩のプログラムを参考に勉強
したり MATLAB を研究活動に活用していく際に役立つと思われる,実際的な MATLAB 使用方法を例を挙
げて紹介することを目標としました.
より詳細な文法,コマンドの使用方法については種々の解説書や,MATLAB のヘルプ等を参照して学習す
るようにしてください.特に MATLAB に標準で付いてくるヘルプでは,この文書で解説している内容を含
め,MATLAB 使用方法のチュートリアル,関数の仕様,実際的な工学の問題を解く(またはシミュレーショ
ンする)といったデモが紹介されています.
この文書である程度の使い方を理解した後は,ぜひ一度「ヘルプ」を試してください.またここで紹介した
各種コマンド以外にも,MATLAB にはさまざまな関数が用意されているので,実際にプログラミングに取り
組む際にはヘルプを活用して色々と探求してください.
(この文書のグラフなどはカラー表示を前提に原稿を作成しました.カラー表示で見たい場合やサンプルプ
ログラムを利用したい場合は http://www.kubolab.se.ritsumei.ac.jp/ にアクセスして,“matlab” で検
索してください)
立命館大学理工学部電気電子工学科 鷹羽研・川畑研・久保研 プレ卒研資料
「MATLAB プログラミングの基礎」 第 1 版(2009 年 4 月),第 2 版(2009 年 12 月),第 3 版(2010 年 12 月),第 4 版(2012 年 12 月)
作成: 久保幸弘,
修正: 茶畑亮(2010 年度 B4)
目次
第1章
1.1
1.2
1.3
1.4
1.5
1.6
MATLAB とは
1
基礎の基礎の基礎
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1.1.1
コマンドウィンドでの足し算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1.1.2
変数の利用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
行列の生成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
1.2.1
行列を打ち込む方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
1.2.2
空行列 [
]. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
1.2.3
zeros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
1.2.4
ones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
1.2.5
eye . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
1.2.6
一様乱数: rand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
1.2.7
正規乱数: randn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
1.2.8
部分行列を用いて大きな行列を作る
. . . . . . . . . . . . . . . . . . . . . . . . . . .
6
行列の演算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
1.3.1
基本的な演算子 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
1.3.2
行列の要素へのアクセス
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
1.3.3
便利な行列演算機能 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
1.3.4
比較演算子と論理演算子
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
1.3.5
行列に対する比較・論理演算子 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
特別な命令 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
1.4.1
ファイル操作系 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
1.4.2
数値表示のフォーマット
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13
1.4.3
ヘルプ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
M-ファイルによるプログラミング . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
1.5.1
スクリプト M-ファイルの例
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
1.5.2
ファンクション M-ファイルの例 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
1.5.3
制御構文 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
if 文による分岐 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
for 文による繰り返し . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
図の表示 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
図と figure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
1.6.1
i
1.7
第2章
2.1
2.2
第3章
3.1
3.2
3.3
3.4
1.6.2
plot,bar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
1.6.3
ヒストグラムを描く—hist
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
1.6.4
figure コマンドの詳細 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
24
1.6.5
axis コマンドで,座標軸に関する設定を行う . . . . . . . . . . . . . . . . . . . . . . .
25
その他の便利な機能 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
1.7.1
ワークスペースを保存する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
26
1.7.2
乱数発生器について . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
1.7.3
複数行にわたる式(コマンド) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
1.7.4
fprintf はファイルに書き出すこともできる . . . . . . . . . . . . . . . . . . . . . . . .
28
MATLAB プログラミングの基礎
29
“ : ”(コロン)演算子 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
29
2.1.1
単純に演算子としてみる
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
29
2.1.2
制御構文でのコロン演算子 “ : ” . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
30
2.1.3
行列の範囲指定を行うコロン演算子 “ : ” . . . . . . . . . . . . . . . . . . . . . . . . .
30
2.1.4
行列の部分的な削除 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
主な MATLAB コマンド一覧 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
MATLAB プログラミング実際編
44
デジタル信号を扱ってみる . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
44
3.1.1
正弦波のサンプリング . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
44
3.1.2
MATLAB で DTMF 信号を鳴らしてみよう . . . . . . . . . . . . . . . . . . . . . . .
46
正規分布を描く . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
52
3.2.1
標準正規分布を描いてみる . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
52
3.2.2
分散を変化させて描いてみる . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
53
3.2.3
ezplot コマンドの利用
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
53
3.2.4
参考—プロットの編集 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
54
3.2.5
2 次元の正規分布 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
55
最小 2 乗法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
3.3.1
直線による近似 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
3.3.2
指数関数による近似 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
62
3.3.3
多項式による近似 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
63
カルマンフィルタ
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
69
3.4.1
時系列信号を描いてみる
3.4.2
カルマンフィルタの応用(その1)
. . . . . . . . . . . . . . . . . . . . . . . . . . .
71
3.4.3
カルマンフィルタの応用(その2)
. . . . . . . . . . . . . . . . . . . . . . . . . . .
72
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
69
第 1 章,第2章の参考文献 (MATLAB の基本)
78
第3章の参考文献(応用プログラミング)
79
ii
第1章
MATLAB とは
MATLAB はアメリカの The MathWorks Inc. 社によって開発,販売されている強力,有名な行列演算ソ
フトです.
MATLAB はその名前の由来が MATrix LABoratory であることからもわかるように,行列操作を大変得
意としています.また,行列計算、ベクトル演算、グラフ化や 3 次元表示などの豊富なライブラリを持ってお
り,単に演算を行う「計算機」としての利用だけでなく,一連の計算手順を「プログラム」として記述し,実
行することができる「プログラミング言語」です.
プログラミング言語は,インタープリタとコンパイラに大別できます.学部で学習した FORTRAN や C
言語はコンパイラの部類に属します.プログラムをエディタ等で作成し,コンパイルして実行可能なファイル
に変換してから実行したはずです.これに対して MATLAB はインタープリタの部類に属します.インター
プリタでは,プログラムに記述された演算や処理を一つずつ解釈しながら実行されていきます.したがって,
ソースプログラムを実行することはもちろん,MATLAB(のコマンドウィンド)に直接コマンドを打ち込み
ながら処理を行っていくこともできます.
MATLAB 言語の文法は基本的に C や FORTRAN に似ていますので,これらの文法の基礎知識のある人
なら,かなり簡単に習得することができます.上にも書きましたが,MATLAB では行列の扱いがかなり簡単
で,特に変数の型やサイズにうるさい C 言語をすでに学習している人には多少「気持ちの悪い」言語といえる
かも知れません.しかし,MATLAB 言語の簡便な記法や,便利なグラフ作成機能,膨大な数値演算ライブラ
リを駆使すると,プログラム作成の効率を大幅にアップできること間違いなしで,多くの企業の開発現場でも
利用されています.
1.1 基礎の基礎の基礎
1.1.1 コマンドウィンドでの足し算
ここでは,基本的な演算,行列を生成する方法とそれを手助けする基本的なコマンド(関数)について説明
します.「プログラミング」については,この節ではとりあえず忘れてください.MATLAB を起動すると,
一般的には図 1.1 のような画面が出てきます.この節では,“Command Window” と書かれているウィンド
ウにコマンドを打ち込むことで MATLAB を利用していきます.
とりあえず 1 + 1 を計算してみましょう.
1
図 1.1
MATLAB の画面
>> 1+1
ans =
2
このように,コマンドウィンドウで数値を扱い,演算を行うことができます.
1.1.2 変数の利用
変数 a に 1 を,変数 b に 2 を代入して,a+b を計算するには,次のように打ち込みます.
>> a = 1
a =
1
>> b = 2
b =
2
>> a + b
ans =
3
実際に打ち込んでみるとすぐに分かりますが,MATLAB のコマンドプロンプト(入力待ちの状態で表示
されている文字)は “>>” です.MATLAB はインタープリタですから,入力された命令に対してその都度
応答を返します.上の例では,最初に,変数 a に 1 を代入する命令 a = 1 を入力しています.その結果,
MATLAB が a の内容を表示しています.言葉で書くとややこしいですが,実際に打ち込んでみると何てこと
ありません.また,コマンドウィンドウに変数名を打ち込むことで,その変数に格納されている内容を表示す
2
ることができます.
面白いのは,変数 a や b を使う際に,C 言語や FORTRAN 言語で行ったような変数の宣言をする必要がな
いということです.使いたいときに変数を使用できます.「型」も気にする必要はありません(MATLAB で
は文字以外は勝手に全部 double 型で扱われます).
1.2 行列の生成
1.2.1 行列を打ち込む方法
では,MATLAB の最大の特徴である,行列の扱いについてみていきましょう.次のような,行列 A を考
えます.
[
A=
1 2
3 4
]
(1.1)
この行列を MATLAB 上で生成するには,次のようなコマンドを打ち込みます.
>> A = [1 2; 3 4]
A =
1
2
3
4
このコマンドを実行すると,変数 A に行列が代入されます.前節の例でも示しましたが,MATLAB では変
数の宣言を事前に行う必要がありません(変数が使用された時点で勝手に生成されます)
.“[ ]” に囲まれた部
分は行列を意味します.行列の内容は行単位で記述し,各要素はスペース,またはカンマ “ , ” によって区切
られます.セミコロン “ ; ” は行の区切りを意味します.行列の生成は,セミコロンの代わりに改行を入力し
て,次のようにしても構いません.
>> A = [ 1 2
3 4]
ここでは,生成する行列の要素として数値(定数)を指定していますが,当然変数を用いることも可能です.
>> x=2
>> A = [x/2 x; x*2 x+1]
は次の行列 A を生成します.
[
A=
1 2
4 3
]
(1.2)
変数に代入された値を参照したい場合は,コマンドウィンドウにその変数名を打ち込めば表示されます.
3
図 1.2 Array Editor の画面
>> A
A =
1
4
2
3
また MATLAB の “Workspace” ウィンドウに,現在メモリ上に保持されている変数名と値,最小値,最大
値などが表示されます.ワークスペースの変数名をダブルクリックすれば,図 1.2 のような “Array Editor”
が表示され,その変数の内容が表示されます.
一度使用された変数は,MATLAB を終了するまで,またはメモリをクリアするまで保持されます.メモリ
をクリアするには,“clear” コマンドを使います.clear コマンドを使うと,全ての変数はリセットされますか
ら,例えば変数名 A を打ち込んでも,その変数は存在しない旨の警告が出ます.
>> clear
>> A
??? ’A’ は未定義の関数、または変数です
1.2.2 空行列 [ ]
“[ ]” に囲まれた部分は行列を意味しますが,括弧内に数値を指定しない場合は,その行列は空行列となり
ます.
>> A = []
A =
[]
4
1.2.3 zeros
zeros は,全ての要素が 0 である行列を生成する関数です.
例えば,次のコマンドは,3 行 2 列の零行列 A を生成します.
>> A = zeros(3, 2)
A =
0
0
0
0
0
0
1.2.4 ones
ones は,全ての要素が 1 である行列を生成する関数です.例えば,次のコマンドは,3 行 2 列の,全要素が
1 の行列 A を生成します.
>> A = ones(3, 2)
A =
1
1
1
1
1
1
1.2.5 eye
eye は対角要素が 1,それ以外の要素が 0 であるような行列を生成します.したがって,生成する行列が正
方行列の場合は単位行列が生成されます.3 × 3 の単位行列は次のように生成できます.
>> A = eye(3)
A =
1
0
0
1
0
0
0
0
1
5
正方でない場合は,例えば次のようになります.
>> A = eye(2, 3)
A =
1
0
0
0
1
0
1.2.6 一様乱数: rand
rand は 0 ∼ 1 の範囲の一様乱数を生成します.例えば次のコマンドは,一様乱数を要素とするサイズ 2 × 3
の行列を生成します.
>> A = rand(2, 3)
A =
0.8147
0.1270
0.9058
0.9134
0.6324
0.0975
1.2.7 正規乱数: randn
randn は標準正規分布にしたがう乱数を生成します.例えば次のコマンドは,正規乱数からなる 2 × 3 の行
列を生成します.
>> A = randn(2, 3)
A =
-0.4326
0.1253
-1.6656
0.2877
-1.1465
1.1909
1.2.8 部分行列を用いて大きな行列を作る
行列やベクトルを組み合わせて,大きな行列を作ることもできます.例えば 2 行 2 列の単位行列を 4 つ組み
合わせて大きな行列を作ってみます.
>> A = eye(2)
>> B = [A A; A A]
2 行 2 列の単位行列を 4 つ並べて,4 行 4 列の行列 B を生成しています.実行結果は次のようになります.
6
A =
1
0
0
1
1
0
1
0
0
1
0
1
B =
1
0
1
0
0
1
0
1
このような使い方は,次元が合ってさえいれば,並べるものが行列,ベクトル,スカラのいずれであっても
問題なく使用できます.ある行列に対して,1 行(列)付け足すことも同様に記述でき,実際のプログラミン
グではかなり役に立ちます.
1.3 行列の演算
1.3.1 基本的な演算子
基本的な加減乗除の演算子,“+”,“−”,“∗”,“/” はスカラ同士の演算の場合,通常の数学的意味と同様の
演算を行います.演算の優先順位も数学的な記述と同等で,以下の例のように括弧を用いた演算も可能です.
>> (1 + 2) * 8 / 12 - 4
ans =
-2
演算子 “+”,“−”,“∗” はそのまま行列の演算にも適用できます.例えば次のように,行列の足し算,引き
算,掛け算を行うことができます.
>> A = [1 2 ; 4 3]
>> B = [5 7 ; 11 9]
>> A + B
ans =
6
9
15
12
>> A - B
ans =
-4
-7
-5
-6
>> A * B
ans =
27
53
25
55
7
当然,行列のサイズが正しくない場合はエラーとなります.例えば次のように,2 × 2 行列と 3 × 2 行列の
和を求めた場合,MATLAB はエラーを出力して演算を中止します.
>> A = [1 2 ; 4 3]
>> B = [5 7 ; 11 9; 13 15]
>> A + B
??? エラー: ==> plus
行列の次元は同じである必要があります
スカラと行列の演算については,次のように加減乗除の演算子は個々の行列の要素に作用します.
>> A = [1 2 ; 4 3]
>> b = 2
>> A + b
ans =
3
6
4
5
>> A * b
ans =
2
8
4
6
>> A / b
ans =
0.5000
2.0000
1.0000
1.5000
さまざまなプログラムを考えるとき,行列の要素ごとの乗算,除算を行いたい場合があります.このような
ときは,乗算,除算の演算子 “∗”,“/” の前に “ . ”(ピリオド)を付けることで実現できます.例えば
[
A=
1 2
4 3
]
[
,
B=
4
3
1
3
]
[
に対して
を求めたい場合は次のようにして実現できます.
8
1×4 2×1
4×3 3×3
]
[
や
1/4 2/1
4/3 3/3
]
>> A = [1 2 ; 4 3]
>> B = [4 1 ; 3 3]
>> A .* B
ans =
4
12
2
9
>> A ./ B
ans =
0.2500
1.3333
2.0000
1.0000
1.3.2 行列の要素へのアクセス
行列の変数名に,( ) を付けることで,その要素の値にアクセスできます.行列 A の i 行 j 列要素は次のよ
うに記述します.
>> A(i, j)
コロン “ : ” 演算子を用いることで,要素の範囲を指定することができます.例えば,
• A(1:2, 2) は行列 A の(1∼2)行,2 列目の要素(列ベクトル)
• A(2, :) は行列 A の 2 行目,全列の要素(行ベクトル)
• A(:, 3) は行列 A の全行,3 列目の要素(列ベクトル)
となります.以下に例を示します.
>> A = [1 2 3; 6 5 4]
>> A(1:2, 1)
ans =
1
6
>> A(2, :)
ans =
6
5
4
>> A(:, 3)
ans =
3
4
9
上の例からも分かるように,MATLAB では行列(配列)のインデックスは 1 から始まることに注意が必要
です.なお,行列の範囲外にアクセスした場合,MATLAB はエラーを出力して処理を中止します.
>> A(3,1)
??? インデックスが行列の次元を超えています
1.3.3 便利な行列演算機能
行列演算をサポートする機能(コマンド)が豊富に用意されています.いくつかの例を示しておきます
行列の転置
>> A = [1 2; 4 3]
>> A’
ans =
1
4
2
3
逆行列
>> inv(A)
ans =
-0.6000
0.8000
0.4000
-0.2000
行列式
>> det(A)
ans =
-5
階数(ランク)
>> rank(A)
ans =
2
10
固有値
>> eig(A)
ans =
-1
5
1.3.4 比較演算子と論理演算子
MATLAB では,基本的に全ての数値は double 型の実数値として扱われます(実際には変数を宣言する必
要もありませんので,整数でも実数でも全て実数扱いです).真理値も実数で扱われ,“真” は非 0,“偽” は 0
です.比較演算子としては,以下のようなものが用意されています.
• a == b :
a = b のとき真
• a ~= b :
a ̸= b のとき真
• a < b
:
a < b のとき真
• a > b
:
a > b のとき真
• a <= b :
a ≤ b のとき真
• a >= b :
a ≥ b のとき真
論理演算子には以下のようなものがあります.
• a & b
:
a と b の論理積
• a | b
:
a と b の論理和
• ~a
:
a の否定
• xor(a, b) :
a と b の排他的論理和
11
1.3.5 行列に対する比較・論理演算子
比較演算子,論理演算子を行列に対して使用すると,これらの演算子は行列の各要素に対して作用します.
固有値
>> A = [1 2; 4 3]
>> A==1
ans =
1
0
0
0
>> (A==1) & (A==1)
ans =
1
0
0
0
>> (A==1) | (A==3)
ans =
1
0
0
1
1.4 特別な命令
演算に関するコマンド以外に,MATLAB の動作に関するコマンドがあります.先に説明した “clear” コマ
ンドなどもこの部類です.
1.4.1 ファイル操作系
基本的には GUI でも操作可能ですが,コマンドウィンドウでも,UNIX および DOS コマンドに似たコマ
ンドでファイル操作等が可能です.
ファイル操作系のコマンド
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
ls
:
dir
:
pwd
:
cd
:
more
:
type
:
copyfile:
delete :
mkdir
:
rmdir
:
カレントディレクトリのファイル名一覧を表示
同上
カレントディレクトリのパスを表示
カレントディレクトリの変更
ファイル内容の表示
ファイル内容の表示
ファイルのコピー
ファイルの削除
新規ディレクトリの作成
ディレクトリの削除
12
1.4.2 数値表示のフォーマット
コマンドウィンドウに表示される数値の表示形式を以下の format コマンドで変更することができます.な
お,format は表示形式を変更するだけで,内部の演算精度には影響しません.同様の設定は GUI を使用して
(ファイルメニュー → 設定 → コマンドウィンドウ)行うことができます.
数値表示形式の変更
>> a=5.3333332222222333444555555566
を代入したときの表示例を示します.
>> format short
a = 5.3333
>> format long
a = 5.333333222222233
>> format short e
a = 5.3333e+000
>> format long e
a = 5.333333222222233e+000
>> format short g
a = 5.3333
>> format long g
a = 5.33333322222223
>> format hex
a = 401555554de0758c
(5 桁のスケーリングされた固定小数点)
(15 桁のスケーリングされた固定小数点)
(5 桁の浮動小数点)
(15 桁の浮動小数点)
(5 桁の固定小数点または浮動小数点の最良表示)
(15 桁の固定小数点または浮動小数点の最良表示)
(16 進数表示)
13
1.4.3 ヘルプ
この文書の冒頭でも述べましたが,「ヘルプ」を活用して MATLAB 言語の文法や,関数,コマンドの使用
方法を確かめながらプログラム作成を行えます.イルカやその他のアニメーションが出てくる,どこかの役に
立たないヘルプよりも何倍も役に立ちます.
例として,先に出てきた,単位行列を作る関数(コマンド)“eye” のヘルプを見てみましょう.
ヘルプの表示
>> help eye
EYE
単位行列
EYE(N) は、N 行 N 列の単位行列です。
EYE(M,N) または EYE([M,N]) は、対角要素が 1 で、それ以外の要素が 0 の
M 行 N 列の行列です。
EYE(SIZE(A)) は、A と同じサイズの単位行列です。
引数なしの EYE は、スカラ 1 です。
EYE(M,N,CLASSNAME) または EYE([M,N],CLASSNAME) は、対角要素上にクラス
CLASSNAME の 1 をもち、それ以外の要素が 0 である M 行 N 列の行列です。
注意 : サイズの入力 M と N は、非負の整数である必要があります。
非負の整数は、0 として扱われます。
例 :
x = eye(2,3,’int8’);
参考 speye, ones, zeros, rand, randn.
上の例のように,基本的な使い方は,“help コマンド名” です.このように,コマンドウィンドウで help コ
マンドを用いて表示する以外に,MATLAB のヘルプメニューからヘルプウィンドウを表示して,コマンドを
検索することもできます.ヘルプ最後の方には,「参考」として関連性があると考えられる他のコマンドが表
示されます.この「参考」は結構有益で,知らなかったコマンドを学習したり,
「こんな使い方もあるのか」と
気付くきっかけになったりもします.
1.5 M-ファイルによるプログラミング
MATLAB に対する命令(コマンド)を,テキストファイル(通常,拡張子 “m”)に記述することで,演
算処理を連続して行うことができます.このようなファイル(ソースプログラム)は M-ファイルと呼ばれま
す.M-ファイルには,スクリプト M-ファイルと,ファンクション(関数)M-ファイルがあります.スクリプ
ト M-ファイルは,C 言語の main プログラムのようなもので,実行したい一連の処理を記述します.ファン
クション M-ファイルは,処理を「関数」として記述したもので,コマンドウィンドや,スクリプト M-ファイ
ル,ファンクション M-ファイル等から呼び出して使用することができます.以下で,M-ファイルの使用方法
を,例を通して見ていきましょう.
14
1.5.1 スクリプト M-ファイルの例
まずは,スクリプト M-ファイルを作成してみます.以下の内容を,ファイル名 “ex1.m” として作成し保存
します.ファイルの作成には,MATLAB 画面内で起動するエディタを利用しても良いですし,秀丸などのテ
キストエディタを使用しても構いません.MATLAB のエディタ機能は,MATLAB 統合開発環境の一部とし
て実装されていますから,ソースプログラムを見ながら変数内の値を確かめたり,ブレークポイントを設定し
てデバッグできたり,色々便利な機能が備わっています.極端な話,MS-Word で作成してテキストファイル
として保存しても作成可能ですが.......
ex1.m — スクリプト M-ファイルの例
clear all
% 行列を作成
A = [1 2; 4 3];
B = round( rand(2) * 2 );
% 計算
C = A + B;
D = A * B;
E = A .* B;
A
B
fprintf( ’C = A + B’ )
C
fprintf( ’D = A * B’ )
D
fprintf( ’E = A .* B’ )
E
MATLAB は基本的にフリーフォーマットですから,適当に字下げや改行を入れて,見やすいプログラムを
記述することを習慣づけましょう.“test.m” では,初めて使う関数(コマンド)がいくつか出てきています.
難しいものはありませんから,ヘルプを活用して調べてみましょう(round は四捨五入,fprintf はシングル
クォーテーションで括られた文字列を画面に表示します)
.また,行末にセミコロン “ ; ” を付けることで,コ
マンドウィンドウへの表示が抑制されます.スクリプト M-ファイルを実行するには,その M-ファイルの名前
を拡張子無しでコマンドウィンドウに打ち込みます.
15
ex1.m の実行結果
>>ex1
A =
1
4
B =
1
0
C = A + B
C =
2
4
D = A * B
D =
1
4
E = A .* B
E =
1
0
2
3
0
2
2
5
4
6
0
6
1.5.2 ファンクション M-ファイルの例
M-ファイルの最初の行が “function” ではじまると,そのファイルはファンクション M-ファイルとなりま
す.“function” は,必ず M-ファイルの先頭に記述する必要があります(空白やコメントは入っていても良
い)
.したがって,一つの関数を作成するために,一つの M-ファイルを作成しなければなりません.
ファンクション M-ファイルはスクリプト M-ファイルと異なり,引数を持って関数計算を行います.
MATLAB のコマンドを自分で作成するイメージです.関数内で使用される変数は,基本的に MATLAB の
ワークスペースとは独立で,その関数内のみで利用できます.
ベクトル [x y z]T の長さ
f (x, y, z) =
√
x2 + y 2 + z 2
を計算する関数 “len” を作成してみましょう.
len.m —ベクトルの長さを求める関数
function r = len(a, b, c)
% 関数‘‘len’’
% ベクトルの長さを求める
r = sqrt( a^2 + b^2 + c^2);
関数に渡す値を引数と呼び,関数が返す値を返戻値と呼びます.この例の場合,関数 len は a, b, c を引数
として受け取り,長さを計算した結果 r を返戻値として返します.まず,この関数をコマンドウィンドウで
使ってみましょう.
16
関数 len —コマンドウィンドウでの使用例
>> len(1, 1, 1)
ans =
1.732050807568877
MATLAB 画面の Workspace を確認すると,関数 len の中で使用されている変数(a, b, c, r)はワークス
ペース内にないことがわかります.このように,関数内で使用された変数は,関数内で生成され消滅します.
もちろん,スクリプト M-ファイルや,他の関数から関数を呼び出して使用することもできます.次のよう
なスクリプト M-ファイルを作成し,関数 len を呼び出して使ってみましょう.
ex2.m —スクリプト M-ファイルから作成した関数を呼び出す
% ex2.m
x = 1;
y = 1;
z = 0;
vec_length = len(x, y, z)
変数 x, y, z に値を代入して関数 len に渡し,関数 len から返された値を変数 vec_length に代入していま
す.実行例は次のようになります.
ex2.m —実行例
>> ex2
vec_length =
1.414213562373095
スクリプト M-ファイル内で使用された変数は,clear されるまでワークスペースに保持されますから,この
場合,変数 x, y, z, vec_length は Workspace に表示されているはずです.
補足
• C 言語では,関数の返戻値は基本的に 1 つの値のみしかもつことができませんが,MATLAB では複数
の返戻値を持つことができます.もちろんベクトルや行列を返戻値とすることもできます.
• 関数は,“return” コマンドによって強制的に終了させることができます.
• ファンクション M-ファイルの “function” と書かれた行以降に連続するコメント行は,下に示すよう
に help コマンドを用いて表示することができます.関数を作成した場合は使い方などを簡単にまとめ
て書いておけばプログラム作成時に役立ちます.
関数 len のヘルプ表示
>> help len
関数‘‘len’’
ベクトルの長さを求める
17
1.5.3 制御構文
MATLAB は,ほとんどの計算機言語に見られるような制御構文を備えています.これは,M-ファイルを
用いてプログラムを作成する際に非常に重要なものになります.といっても,必ず M-ファイル内で使用する
必要はなく,コマンドウィンドウ内に制御構文を打ち込むことも可能ですが.....通常は M-ファイル内で使
用することが多いでしょう.
制御構文には,分岐を行う “if”,“switch”,繰り返しを行う “for”,“while” があります.どれも基本的な
構文ですが,ここでは基本中の基本である,if と for について説明します.その他のものについてはヘルプを
見て学習してみてください.サンプルプログラムも紹介されています.
if 文による分岐
まずは if 文の基本構文を示します.
if 文の基本構文
if 真理値 A
「処理 1」
elseif 真理値 B
「処理 2」
else
「処理 3」
end
if 文による分岐は,if から始まり,end で終わります.上の場合,真理値 A が非ゼロの場合,「処理 1」が
実行されます.また,真理値 A がゼロで,真理値 B が非ゼロならば「処理 2」が実行され,どの場合にも当て
はまらないときは「処理 3」が実行され終了します.他の計算機言語と同様に,elseif や else は無くても構
いませんし,if 文の構文を入れ子にして使用することも可能です.
if 文を用いたプログラム例を示します.
ex3.m—if 文を用いたプログラム例
% ex3.m
clear all
a = round( rand(1) );
if a == 1
fprintf(’ おもて\n’);
else
fprintf(’ うら\n’);
end
round は四捨五入を行う関数で,rand(1) は 0 ∼ 1 の範囲の一様乱数を 1 つ発生させますから,a の値は
1 または 0 となり,1 の場合に「おもて」,0 の場合に「うら」と表示されます.一様乱数を用いているので,
a = 1,a = 0 となる確率はそれぞれ 1/2 となりますから,このプログラムはコイン投げを計算機上で実現し
18
たものといえます.
for 文による繰り返し
for 文の基本構文は,繰り返し回数をカウントする変数として i を用いるとすると次のように記述できます.
この場合,i の値が 1∼10 まで,1 ずつ増やしながら(すなわち 10 回)for と end に囲まれた部分の処理が繰
り返し実行されます.もちろん for 文を入れ子にして多重ループを作成することも可能です.
for 文の基本構文
for i=1:10
「繰り返し処理される内容」
end
ex4.m—for 文を用いたプログラム例
% ex4.m
clear all
sum = 0;
for i = 1 : 10
sum = sum + i;
end
sum
ex4.m の実行例
>> ex4
sum =
55
break と continue
break や continue を用いることで,for や while などのループ処理を制御できます.ループの中で break が
実行されると,そのループは強制的に終了し,次の処理に移ります.また,continue が実行されると,その回
のループは終了し,再度ループの先頭から処理が始まります.
1.6 図の表示
計算結果をプロットしたグラフを作成してみましょう.C 言語などでこのような処理を行いたい場合は,計
算結果をいったんファイルに保存し,他のグラフ作成ソフトを用いてビジュアライズするか,自分でグラフ表
19
図 1.3 figure ウィンドウ
示プログラムを作成する必要があります.特に後者の方法は,相応の知識が必要となり簡単ではありません.
MATLAB ではグラフに限らず,画像なども非常に簡単なコマンドを用いて行うことができ,数値実験やプロ
グラム開発の大幅なスピードアップにつながります.また,作成したグラフ等を EPS 形式やイラストレータ
形式(ai)
,メタファイル(emf)で保存できますから,論文等への貼り込みも簡単です(といっても,論文作
成時などでは見栄えの細かい指定をしたくなることもあり,結局はグラフ作成専門のソフトを使用する場合も
ありますが.
...).
1.6.1 図と figure
MATLAB では,グラフや散布図,画像などの図は,figure と呼ばれるウィンドウに描画されます.figure
ウィンドウは,コマンドウィンドウか M-ファイル内で,「figure」コマンドを実行すれば生成できます.実際
にコマンドウィンドウで「figure」と打ち込んでみましょう.図 1.3 のような何も表示されていない窓が生成
されるはずです.このウィンドウに対して,後述の「plot」コマンド,「bar」コマンド等を用いてグラフの描
画を行います.また,
「axis」コマンドや,
「axes」コマンドで,細かな表示の調整などを行うことができます.
1.6.2 plot,bar
グラフ(単純な xy プロット)を作成するコマンド「plot」と,棒グラフを作成するコマンド「bar」を使ってみ
ましょう.figure ウィンドウが開いていない場合は,plot コマンドや bar コマンドを実行した際に MATLAB
によって新たな figure ウィンドウが生成され,そこにグラフが描画されます.figure ウィンドウが存在する状
態でこれらのコマンドを実行した場合,既に存在する figure のうちで最も最近に処理が行われた figure に対
してグラフが描画されます.
20
plot コマンドを使って,x-y 平面上に点 (1, 1) をプロットしてみます.コマンドウィンドウで以下のように
打ち込みます.
点 (1, 1) のプロット
>> plot(1, 1)
plot コマンドの第 1 引数は横軸の値,第 2 引数は縦軸の値になります.上のコマンドを実行すると,figure
ウィンドウ内に適切な軸が設定され,点 (1, 1) に小さい点が打たれます.plot コマンドの引数にはベクトルを
指定することができます.デフォルトでは,複数の点が指定された場合,それらをプロットし,線で繋がれま
す.例えば,以下のようにすると,点 (1, 1),(2, 5),(3, 10),(4, 4),(5, 3) がプロットされ,それぞれの点が
順番に線で繋がれます.
複数データのプロット
>> plot([1 2 3 4 5], [1 5 10 4 3])
さて,せっかくなので,m-ファイルを用いてもう少し複雑なグラフを表示してみましょう.
ex5.m—plot の使用例
% ex5.m
clear all
for i = 1 : 1000
x(i,1) = (i-1)/100;
y(i,1) = sin(x(i,1));
y(i,2) = cos(x(i,1));
end
plot(x,y);
この場合,x は横軸データが格納された 1000 × 1 ベクトル,y は縦軸データが格納された 1000 × 2 行列に
なります.y の 1 列目にサインの値が,y の 2 列目にコサインの値が入っています.この場合,x の行数と,y
の行数が同じである必要があります.ex5.m の実行結果は図 1.4 のようになります.
次に,bar コマンドを試してみます.
ex6.m—bar の使用例
% ex6.m
clear all
y = round( rand(10,1) * 10 )
bar(y);
実行結果は図 1.5 のようになります.0∼1 の範囲の一様乱数を 10 個発生させ,10 倍して四捨五入した
21
図 1.4 ex5.m の実行結果
図 1.5 ex6.m の実行結果
値を棒グラフで表示しています.plot コマンド,bar コマンド共に,横軸の値を省略した場合は,1 刻みで
MATLAB が勝手に横軸を生成して表示します.
1.6.3 ヒストグラムを描く—hist
ヒストグラムを描く,hist というコマンドもあります.コマンドの細かい動作はヘルプに説明されていま
すので,ここではごく簡単な使い方を示しておきます.単純にデータ列を hist コマンドの引数として渡すと,
MATLAB が区間を適当に設定してヒストグラムを描いてくれます.
22
ex7.m—hist の使用例
% ex7.m
clear all
close all
a = rand(10000,1);
b = randn(10000,1);
figure;
subplot(1,2,1);
hist(a);
subplot(1,2,2);
hist(b);
ex7.m では新しいコマンドがいくつか使われています.「close」は,現在開かれている figure ウィンドウを
閉じるコマンドで,「close all」とすることで全ての figure ウィンドウが閉じられます.必要に応じてプログ
ラム中で使用することで,グラフの表示を制御できます.
「subplot」コ マ ン ド は ,figure ウ ィ ン ド ウ を い く つ か に 分 割 し て グ ラ フ を 描 画 す る コ マ ン ド で す .
「subplot(1,2,1)」は figure ウィンドウを 1 行 2 列に分割した 1 番目の座標軸を意味します.したがって,
上のプログラムでは,1 つの figure ウィンドウを 1 行 2 列に分割し,1 番目(左側)に a のヒストグラムを,
2 番目(右側)に b のヒストグラムを描きます.a は一様乱数 10000 個の値が格納されているので,そのヒス
トグラムは平坦なものになっています.また,b は標準正規分布にしたがう乱数 10000 個の値が格納されてい
るので,そのヒストグラムは釣り鐘型になっていることが分かります.ex7.m の実行例は,図 1.6 です.
図 1.6 ex7.m の実行結果
23
1.6.4 figure コマンドの詳細
複数の figure ウィンドウを生成し,
1. figure ウィンドウ A に x をプロットし,
2. figure ウィンドウ B に y をプロットした後,
3. 再び figure ウィンドウ A に戻って z をプロットしたい
というような状況は,MATLAB を使用していく中でよく生じます.MATLAB では,figure ウィンドウごと
に割り当てられた番号を用いてどのウィンドウに対して操作を行うかを明示することができます.figure ウィ
ンドウの番号を用いた例を以下に示します.
ex8.m—figure ウィンドウの指定
% ex8.m
clear all
close all
figure(1);
plot([1 2 3 4 5]);
%figure ウィンドウ (1) を生成
%figure ウィンドウ (1) にプロット
figure(2);
plot([1 5 9 4 2]);
%figure ウィンドウ (2) を生成
%figure ウィンドウ (2) にプロット
figure(1);
plot([5 4 3 2 1]);
%figure ウィンドウ (1) を指定
%figure ウィンドウ (1) にプロット
ex8.m を実行すると,初めに figure ウィンドウ (1) が生成され,ベクトル [1 2 3 4 5] がプロットされます.
その後,figure ウィンドウ (2) が生成され,ベクトル [1 5 9 4 2] がプロットされます.最後に,再び figure
ウィンドウ (1) が指定され,figure ウィンドウ (1) に,ベクトル [5 4 3 2 1] がプロットされて終了します.こ
の場合,figure ウィンドウ (1) では 2 つのデータが描画されますが,プロットは上書きされるため,プログラ
ム終了時にはベクトル [5 4 3 2 1] のプロットしか見ることができません.
前に描画したデータを残して,新しいプロットを重ねて描画するためには,前の描画を残しておくコマンド
「hold on」を使います.例えば ex8.m で,figure ウィンドウ (1) に前の描画を残してプロットするためには次
のようにします.逆に,hold on を解除するためには,hold off コマンドを用います.
24
図 1.7 fig:axis コマンドの使用例
ex9.m—hold on の使用
% ex9.m
clear all
close all
figure(1);
plot([1 2 3 4 5]);
%figure ウィンドウ (1) を生成
%figure ウィンドウ (1) にプロット
figure(2);
plot([1 5 9 4 2]);
%figure ウィンドウ (2) を生成
%figure ウィンドウ (2) にプロット
figure(1);
hold on;
plot([5 4 3 2 1]);
%figure ウィンドウ (1) を指定
%figure ウィンドウ (1) にプロット
1.6.5 axis コマンドで,座標軸に関する設定を行う
「axis」は,座標軸のライン,目印,数値を設定するコマンドです.ここでは,座標軸の数値範囲を指定する
方法のみを示しておきます.その他の使い方についてはヘルプを参照してください.コマンドウィンドウで以
下のコマンドを試してみましょう.この場合,X 軸の範囲が −1 ∼ 7,Y 軸の範囲が −3 ∼ 10 に設定されま
す.実行結果は,図 1.7 のようになります.
axis コマンドの使用
>>plot([1 2 3 4 5]);
% ベクトル [1 2 3 4 5] をプロット
>>axis([-1, 7, -3, 10]);
25
図 1.8 fig:plot 用各種コマンドの使用例
axis コマンドの他にも,グラフ描画領域にグリッドを付ける「grid」,X 軸および Y 軸のタイトルを付ける
「xlabel」
,
「ylabel」や,グラフ全体のタイトルを付ける「title」などがあります.一つ一つ試してみましょう.
実行例を図 1.8 に示しています
title, xlabel, ylabel, grid の使用例
>>plot([1 2 3 4 5]);
>>axis(-1, 7, -3, 10);
>>title(’ 各種コマンドの使用例’);
>>xlabel(’x 軸データの説明’);
>>ylabel(’y 軸データの説明’);
>>grid on;
% ベクトル [1 2 3 4 5] をプロット
%X および Y 軸の範囲を設定
% グラフのタイトルを付ける
%x 軸の説明を付ける
%y 軸の説明を付ける
% グリッドを表示する
1.7 その他の便利な機能
1.7.1 ワークスペースを保存する
MATLAB を用いて計算した結果や,変数の内容などは clear されない限りワークスペースに保持されてい
ます.このワークスペースの内容をファイルに保存し,必要なときに利用できるようにするのが MAT ファイ
ル(拡張子 mat)です.ワークスペースを MAT ファイルに保存するには,“save” コマンドを使用します.
ワークスペースを MAT ファイルに保存する
>>save( ’test’ )
このコマンドを実行するとワークスペースの内容が,ファイル “test.mat” に保存されます.また,MAT
ファイルの内容を読み出すには,“load” コマンドを用います.
26
ワークスペースを MAT ファイルから読み出す
>>load( ’test’ )
save や load は,上のようなコマンドを用いる以外に,ファイルメニューから「ワークスペースを保存」,ま
たは「データのインポート」を選択することで GUI を用いて操作することも可能です.
1.7.2 乱数発生器について
MATLAB の乱数発生器はいくつかのパラメータをもち,全ての乱数はこれらのパラメータに基づいて生成
されます.乱数を発生させるコマンドには,rand や randn がありますが,これらのコマンドに文字列「state」
を引数として渡すことで,乱数発生器の動作を制御できます.また,第 2 引数としてパラメータを指定するこ
とで,乱数発生器のパラメータを設定することができます.
乱数発生器のパラメータを表示する
>>rand( ’state’ )
乱数発生器にパラメータを設定する
%(変数 s にパラメータが格納されている場合)
>>rand( ’state’, s )
乱数発生器のパラメータを保持しておくことで,同じ乱数列を生成することができますから,同条件でシ
ミュレーションを行わなければならない場合や,プログラムの挙動を再現したい場合などに有効です.
例えば randn 関数を用いて 10 個の正規乱数を 2 回発生させた場合,通常は異なった系列が得られます. コ
マンド「rand(10,1)」を何度か実行してみて,異なる系列が生成されていることを確かめてみましょう.一方,
以下のようにすると,乱数を発生させる際のパラメータを同じものに設定できるので,同一の系列を得ること
ができます.
乱数発生器の実験—同じ系列を発生させる
>>s = rand(’state’);
>>a = rand(10,1);
>>rand(’state’, s);
>>b = rand(10,1);
1.7.3 複数行にわたる式(コマンド)
MATLAB はインタープリタですから,種々の処理は基本的に行単位で行われます.そのため,一つの処理
を複数行にわたって記述する際には,行末に “...”(ピリオド 3 つ)を付けることで,処理の記述が次の行に及
んでいることを示す必要があります.当然ですが,この規則は M-ファイルでもコマンドウィンドウでも同様
27
に適用されます.
複数行にわたる式—行末にピリオド 3 つ
>> a=1, b=2,
f=6, g=7,
>> a = a + b
+ f
+ j
a =
55
c=3, d=4,
h=8, i=9,
+ c + d +
+ g + h +
e=5, ...
j=10;
e ...
i ...
1.7.4 fprintf はファイルに書き出すこともできる
fprintf 関数は,第 1.5.3 節で「与えられた引数(文字列)をコマンドウィンドウに表示する」関数として用
いましたが,ファイルへ出力させて保存することもできます.簡単な使用例を以下に示します.
fprintf 関数によるファイルへの出力
>>
>>
>>
>>
fp = fopen(’output.txt’, ’wt’);
fprintf(fp, ’ ファイルへの出力\n’ );
fprintf(fp, ’ こんにちは\n’ );
fclose(fp);
ファイルを取り扱う際には,C 言語のときと同じようにファイルのオープン,クローズといった処理が必要
となります.fopen はファイルを開く関数です.1 行目では,
「output.txt」と言う名前のファイルを,テキス
ト書き込みモード「wt」でオープンしています.ファイルがオープンされると,そのファイルとファイル内
の位置を指し示す番号(C 言語のファイルポインタに相当)が MATLAB により割り当てられます.これを
ファイル ID(FID)と呼び,上の例ではファイル ID を変数 fp に代入しています.次に,fprintf 関数により,
ファイル ID「fp」により指定されるファイルに,2 つの文字列「ファイルへの出力」,「こんにちは」が改行
「\n」付きで書き込まれています.最後にファイル ID「fp」により指定されるファイルを fclose 関数によりク
ローズしています.
なお,ここでは単にファイルをオープンし,クローズすることしかしていませんが,実際は「ファイルを開
くことができたか?」という確認をするべきです.正常にファイルがオープンされた場合は FID が非負の値
となります.また,ここではテキストファイルを書き出す例のみを示しましたが,もちろん,テキストファイ
ルを読み込んだり,バイナリファイルを取り扱うことも可能です.
上のコマンドを実行して作成されたファイルを確認してみましょう.テキストモードで書き込んでいま
すから,作成されたファイルは秀丸などのテキストエディタで内容を確認することができます.上の場合,
ファイルが保存される場所は MATLAB のカレントディレクトリになります.「カレントディレクトリ」とは
MATLAB が現在作業中のディレクトリという意味で,MATLAB のツールバー内に表示されています.
28
第2章
MATLAB プログラミングの基礎
第 1 章では MATLAB プログラミングに取り組むために,最低限必要になると考えられる基本的なコマ
ンド等を説明しました.第 2 章では,第 1 章で理解を妨げるおそれがあるため説明を省いた部分の補足と,
MATLAB に組み込まれている関数群の簡単な説明(リスト)を示します.ただし,各種の関数を詳細に説明
することはしません.「こんな計算もコマンド一発でできるのか!」と,MATLAB の便利さを実感すること
に役立ててください....各々の関数を使用する際には各自でヘルプを参照し,詳細な使用方法を確認するよ
うにしてください.
2.1 “ : ”(コロン)演算子
“ : ”(コロン)演算子は色々な使い方ができます.これを自在に操ることができれば,MATLAB プログラ
ミングを行う中で,ベクトル,行列の扱いをより一層簡単,単純に記述することができる優れものです.ここ
では,コロン演算子の代表的な使い方を説明します.
2.1.1 単純に演算子としてみる
第 1 章で説明したように,ベクトル a = [1 2 3 4] の生成は,次のようなコマンドで行うことができました.
>>a = [1 2 3 4]
これと同じことが,コロン演算子を用いて簡単に記述することができます.コマンドと,実行例を示し
ます.
コロン演算子によるベクトル a = [1 2 3 4] の生成
>> a = 1 : 4
a =
1
2
3
4
このコマンドの意味を言葉で書くと,
「1 から 4 までの数を,1 刻みで並べた行ベクトルを作成し,変数 a に
29
代入」ということになります.このコマンドを応用すると,例えば「0 から 1 までを,0.1 刻みで」というよう
なこともできます.コマンドと実行例は次のようになります.
コロン演算子によるベクトル(0.1 刻み)の生成
>> a = 0 : 0.1 : 1
a =
0 0.1000 0.2000 0.3000 0.4000 0.5000 0.6000 0.7000 0.8000 0.9000 1.0000
では,上の例で,刻み幅を 0.33 にしたらどうなるか試してみましょう.
コロン演算子によるベクトル(0.33 刻み)の生成
>> a = 0 : 0.33 : 1
a =
0
0.3300
0.6600
0.9900
当然といえば当然ですが,0.33 では等間隔に分割できないため,0 から 0.99 で作られるベクトルとなって
います.細かい動作ですが,プログラムで種々の処理を行う場合には注意が必要です.特に,上限や下限を変
数によって与える場合などは間違いが起こりやすい部分です.
2.1.2 制御構文でのコロン演算子 “ : ”
あまり意味はないかも知れませんが,制御構文 for でのコロン演算子についてみてみます.for 文の書き方を
思い出してください.変数 i で回数をカウントし,3 回繰り返し処理を行う場合は以下のような構文でした.
for i = 1 : 3
「繰り返しを行う処理」
end
ここでもコロン演算子 “ : ” が使われています.このコロンも前節と同様に行ベクトルを生成しています.
すなわち,上のコードは次のように書くこともできます.
for i = [1 2 3]
「繰り返しを行う処理」
end
2.1.3 行列の範囲指定を行うコロン演算子 “ : ”
上に示したように,コロン演算子 “ : ” は基本的に行ベクトルを生成するものとして捉えることができます.
これを行列の範囲を指定するインデックスに使用すれば,行列の範囲指定をとても簡単に記述することができ
30
ます.例えば,次のようなコマンドを実行した場合を考えます.
>> A = [1 2 3; 9 8 7 ]
>> B = A(:,2:3)
実行結果は次のようになります.
A =
1
9
2
8
2
8
3
7
3
7
B =
行列の範囲指定で,コロン演算子が単独で使用された場合,「全ての行(または列)」を意味します.した
がって,コマンド “B = A(:,2:3)” の意味は,行列 A の「全行,2∼3 列」の部分行列を変数 B に代入するこ
とになります.コロン演算子を用いて,行列のインデックスを表すベクトルを作っているのです.では,次の
ようなコマンドを実行した場合はどうなるか確かめてみましょう.
>> A = [1 2 3; 9 8 7]
>> B = A(:, [1 3])
実行結果は次のようになります.
A =
1
9
2
8
1
9
3
7
3
7
B =
つまり,行列 A の 1 列目と 3 列目を取りだして新しい行列を生成しているわけです.このように,行列のイ
ンデックスにベクトルを指定できるのはなかなか強力で便利な機能といえます.
2.1.4 行列の部分的な削除
第 1.2.2 節で説明したように,“ [ ] ” は空行列を表す演算子でした.これと,前節のコロン演算子を用いれ
ば,行列の行や列を部分的に削除するような操作を簡単に行うことができます.3 × 4 行列の 2,3 列目を削除
31
する例を以下に示しておきます.
>> A = [1 2 3 4; 5 6 7 8; 9 10 11 12]
A =
1
2
3
4
5
6
7
8
9
10
11
12
>> A(:, 2:3) = [ ]
A =
1
4
5
8
9
12
2.2 主な MATLAB コマンド一覧
よく利用されると考えられる MATLAB コマンドの一覧と,簡単な説明を以下に示します.詳細な使用方
法についてはヘルプを活用してください.
変数とワークスペースの管理
clear
メモリから項目を削除
load
ディスクからの変数の読み込み
save
ワークスペース変数をディスクに保存
length
ベクトルの長さ
size
配列の次元
コマンドウインドウの制御
echo
実行中の M-ファイルのエコー表示
format
出力書式の制御
ファイルおよび操作環境に関する操作
echo
実行中の M-ファイルのエコー表示
format
出力書式の制御
cd
作業ディレクトリの変更
delete
ファイルとグラフィックスオブジェクトの削除
diary
ディスクファイルにセッションを保存
dir
ディレクトリのリスト表示
edit
M-ファイルの編集
fullfile
各部分から絶対パス名を作成
演算子と特殊記号
+
加算
32
-
減算
*
行列の乗算
.*
配列要素ごとの乗算
^
行列のべき乗
.^
配列要素ごとのべき乗
kron
Kronecker テンソル積
\
バックスラッシュ、左除算
/
スラッシュ、右除算
./ and .\
配列の右除算と左除算
:
コロン
( )
丸括弧
[ ]
鍵括弧
{}
中括弧
.
小数点
...
継続記号
,
カンマ
;
セミコロン
%
コメント文
!
オペレーティングシステムコマンドの実行
’
転置、引用符
.’
非共役転置
=
割り当て
==
等号
< >
比較演算子
&
論理積
|
論理和
~
否定
xor
排他的論理和
論理関数
all
すべての要素が非ゼロであるかどうかのテスト
any
非ゼロ要素があるかどうかのテスト
exist
変数または関数の存在のチェック
find
非ゼロ要素のインデックスと値を求めます
制御フロー
break
制御フロー構文からの脱出
case
Case 文の切り替え
else
条件付き実行ステートメント
33
elseif
条件付き実行ステートメント
end
for, while, switch, if ステートメントの終了、最終インデックス
error
エラーメッセージの表示
for
特定回数のステートメントの繰り返し
if
条件付き実行ステートメント
otherwise
switch ステートメントのデフォルト部分
return
呼び出し関数に戻ります
switch
式に基づき case 文間で切り替えます
warning
ワーニングメッセージの表示
while
不定回数の繰り返しステートメント
対話的入力
input
ユーザ入力の要求
keyboard
M-ファイルにキーボードを呼び出します
menu
ユーザ入力のメニューを作成
pause
一時的に実行を停止します
基本行列と基本配列
eye
単位行列
linspace
線形に等間隔なベクトルの作成
logspace
対数的に等間隔なベクトルの作成
ones
要素がすべて 1 である配列の作成
rand
一様分布の乱数、一様分布の乱数配列
randn
正規分布の乱数、正規分布の乱数配列
zeros
要素がすべて 0 である配列の作成
: (コロン
一定間隔のベクトルの作成
特殊変数と定数
i
虚数単位
Inf
無限大
j
虚数単位
NaN
不定値
pi
円周率,
時間と日付
calendar
カレンダ
clock
日付ベクトルとしての現在の時間
cputime
CPU 経過時間
date
現在の日付
34
datenum
日付のシリアル番号
datestr
日付の文字列の書式
datevec
日付の成分
eomday
月の最後の日
etime
経過時間
now
現在の日付と時間
tic, toc
ストップウオッチタイマ
weekday
曜日
行列操作
cat
配列の結合
diag
対角行列、行列の対角要素
fliplr
左右方向への行列要素の交換
flipud
上下方向への行列要素の交換
repmat
配列の複製と拡大
reshape
配列の次元の変更
rot90
行列の 90 度回転
tril
行列の下三角部分
triu
行列の上三角部分
: (colon)
配列の表示、配列の並べ替え
特殊な行列
compan
コンパニオン行列
gallery
テスト行列
hadamard
Hadamard 行列
hankel
Hankel 行列
hilb
Hilbert 行列
invhilb
逆 Hilbert 行列
magic
魔方陣
pascal
Pascal 行列
toeplitz
Toeplitz 行列
wilkinson
Wilkinson の固有値テスト行列
初等数学関数
abs
絶対値
acos, acosh
逆余弦と逆双曲線余弦
acot, acoth
逆余接と逆双曲線余接
acsc, acsch
逆余割と逆双曲線余割
angle
位相角
35
asec, asech
逆正割と逆双曲線正割
asin, asinh
逆正弦と逆双曲線正弦
atan, atanh
逆正接と逆双曲線正接
atan2
4 象現逆正接
ceil
無限大方向への丸め
conj
複素共役
cos, cosh
余弦と双曲線余弦
cot, coth
余接と双曲線余接
csc, csch
余割と双曲線余割
exp
指数関数
fix
ゼロ方向への丸め
floor
負の無限大方向への丸め
gcd
最大公約数
imag
複素数の虚部
lcm
最小公倍数
log
自然対数
log2
底を 2 とした対数
log10
常用対数 (底が 10)
mod
モジュラス (除算後の符号付き剰余)
real
複素数の実部
rem
除算の剰余
round
最も近い整数への丸め
sec, sech
正割と双曲線正割
sign
符号関数
sin, sinh
正弦と双曲線正弦
sqrt
平方根
tan, tanh
正接と双曲線正接
特殊数学関数
airy
Airy 関数
besselh
第 3 種 Bessel 関数 (Hankel 関数)
besseli, besselk
修正 Bessel 関数
besselj, bessely
Bessel 関数
beta, betainc, betaln
Beta 関数
ellipj
Jacobi 楕円関数
ellipke
第 1 種、第 2 種完全楕円積分
erf, erfc, erfcx, erfinv
誤差関数
expint
積分指数
36
gamma,
gammainc,
Gamma 関数
gammaln
legendre
同伴 Legendre 関数
pow2
底を 2 としたべき乗
rat, rats
有理数近似
座標系の変換
cart2pol
Cartesian 座標系から極座標系または円筒座標系への変換
cart2sph
Cartesian 座標系から球座標系への変換
pol2cart
極座標系または円筒座標系から Cartesian 座標系への変換
sph2cart
球座標系から Cartesian 座標系への変換
行列解析
cond
行列の条件数 (逆行列について)
condeig
行列の条件数 (固有値について)
det
行列式
norm
ベクトルや行列のノルム
null
行列のヌル空間
orth
行列により作成される空間の大きさ
rank
行列のランク
rcond
行列の条件数の推定の逆数
rref, rrefmovie
行の階段型への変換
subspace
2 つの部分空間間の角度
trace
対角要素の和
線形方程式
\ /
線形方程式の解法
chol
Cholesky 分解
inv
逆行列
lscov
共分散を指定した最小二乗解
lu
行列の LU 分解
nnls
非負最小二乗
pinv
Moore-Penrose 擬似逆行列
qr
直交三角分解
固有値と特異値
balance
固有値計算の精度の改良
cdf2rdf
複素対角型から実ブロック対角型への変換
eig
固有値と固有ベクトル
37
hess
Hessenberg 型行列
poly
特性多項式
qz
一般化固有値に対する QZ 分解
rsf2csf
実 Schur 型から複素 Schur 型への変換
schur
Schur 分解
svd
特異値分解
行列関数
expm
行列の指数計算
funm
行列関数の計算
logm
行列の対数
sqrtm
行列の平方根
データ解析の基本演算子
convhull
凸包
cumprod
累積積
cumsum
累積和
cumtrapz
累積台形数値積分
delaunay
Delaunay 三角形分割
dsearch
最近傍点の検索
factor
素因数
inpolygon
多角形内の点の検出
max
配列の最大要素
mean
配列の平均値
median
配列の中央値
min
配列の最小要素
perms
可能なすべての順列
polyarea
多角形の範囲
primes
素数のリストの作成
prod
配列要素の積
sort
要素を昇順に並べ替えます
sortrows
行を昇順に並べ替えます
std
標準偏差
sum
配列要素の和
trapz
台形数値積分
tsearch
Delaunay 三角形の検索
voronoi
Voronoi 線図
有限差分
38
del2
離散ラプラシアン
diff
差分と近似導関数
gradient
勾配
相関
corrcoef
相関係数
cov
共分散行列
フィルタリングとコンボリューション
conv
コンボリューションと多項式の乗算
conv2
2 次元のコンボリューション
deconv
デコンボリューションと多項式の除算
filter
無限インパルス応答 (IIR) または有限インパルス応答 (FIR) フィルタによる
データのフィルタ処理
filter2
2 次元デジタルフィルタリング
フーリエ変換
abs
絶対値
angle
位相角
cplxpair
複素数を複素共役数の組合わせに並べ替えます
fft
1 次元高速フーリエ変換
fft2
2 次元高速フーリエ変換
fftshift
0 番目の遅延をスペクトル中心に移動
ifft
1 次元逆高速フーリエ変換
ifft2
2 次元逆高速フーリエ変換
nextpow2
与えられた数値より大きい 2 のべき乗数
unwrap
位相角の修正
ベクトル関数
cross
ベクトルのクロス積
intersect
2 つのベクトルの共通部分
ismember
集合内のメンバの検出
setdiff
2 つのベクトルの差集合の出力
setxor
2 つのベクトルの排他的論理和
union
2 つのベクトルの和集合
unique
ベクトルの一意的な要素
多項式
conv
コンボリューションと多項式の乗算
39
deconv
デコンボリューションと多項式の乗算
poly
特性多項式
polyder
多項式の導関数
polyeig
多項式の固有値問題
polyfit
多項式近似
polyval
多項式の計算
polyvalm
行列を引数とする多項式の計算
residue
部分分数展開と多項式係数の変換
roots
多項式の根
データ補間
griddata
データのグリッド化
interp1
1 次元補間 (table lookup)
interp2
2 次元データ補間 (table lookup)
interp3
3 次元データ補間 (table lookup)
interpft
FFT 法を使った 1 次元補間
interpn
多次元データ補間 (table lookup)
meshgrid
3 次元プロットのための X 行列と Y 行列の作成
ndgrid
多次元関数と補間に対する配列の作成
spline
キュービックスプライン補間
ファンクション関数 - 非線形数値法
dblquad
数値重積分
fmin
1 変数関数の最小化
fmins
多変数関数の最小化
fzero
1 変数関数のゼロ点の算出
ode45,
ode23,
ode113,
ode15s,
常微分方程式の解法
ode23s
odefile
ODE ソルバに対する常微分方程式の定義
odeget
odeset で作成される構造体 options からプロパティを抽出
odeset
ODE ソルバへの入力に対して構造体 options を作成または変更
quad, quad8
数値積分
基本スパース行列
spdiags
スパース帯行列またはスパース対角行列の抽出と作成
speye
スパース単位行列
sprand
スパース一様分布乱数行列
sprandn
スパース正規分布乱数行列
40
sprandsym
スパース対称乱数行列
フル行列からスパース行列への変換
find
非ゼロ要素のインデックスと値を求めます
full
スパース行列からフル行列への変換
sparse
スパース行列の作成
spconvert
スパース行列の外部書式から行列を取り込みます
一般音声関数
sound
ベクトルを音声に変換
.WAV 音声関数
wavread
Microsoft WAVE (.wav) 音声ファイルを読み込みます
wavwrite
Microsoft WAVE (.wav) 音声ファイルを書き出します
文字列の操作
deblank
文字列の最後から空白を削除
findstr
他の文字列内にある文字列の検出
lower
文字列を小文字に変換
strcat
文字列の結合
strcmp
文字列の比較
strjust
キャラクタ配列の位置の調整
strmatch
適合する文字列の検出
strncmp
2 つの文字列の最初の n 個のキャラクタの比較
strrep
文字列の検索と置換
strtok
文字列の最初のトークン
strvcat
文字列の垂直方向の結合
upper
文字列を大文字に変換
文字列から数値への変換
char
数値を文字列に変換
int2str
整数を文字列に変換
mat2str
行列を文字列に変換
num2str
数値を文字列に変換
sprintf
データを書式付きで文字列に書き出します
sscanf
書式を制御して文字列を読み込みます
str2num
文字列を数値に変換
radix 変換
41
bin2dec
2 進数を 10 進数に変換
dec2bin
10 進数を 2 進数に変換
dec2hex
10 進数を 16 進数に変換
hex2dec
IEEE 16 進数を 10 進数に変換
hex2num
16 進数を倍精度数値に変換
ファイルのオープンとクローズ
fclose
1 つ以上のファイルのクローズ
fopen
ファイルのオープンまたはオープンしたファイルの情報の取得
書式なし入出力
fread
ファイルからバイナリデータを読み込みます
fwrite
バイナリデータをファイルに書き出します
書式付き入出力
fgetl
ファイルのつぎの行を行の終端子なしで文字列として出力
fgets
ファイルのつぎの行を終端子付きで文字列として出力
fprintf
データを書式付きでファイルに書き出します
fscanf
データを書式付きでファイルから読み込みます
ファイル中の位置
feof
EOF(ファイルの終了) のテスト
ferror
ファイル入出力エラーの状態を調べます
frewind
ファイルのリワインド
fseek
ファイルの位置指示子の設定
ftell
ファイルの位置指示子の取得
文字列の変換
sprintf
書式付きデータを文字列に書き出します
sscanf
書式を制御して文字列を読み込みます
ファイル入出力特殊関数
dlmread
ASCII デリミタ付きファイルを行列に読み込みます
dlmwrite
行列を ASCII デリミタ付きファイルに書き出します
imfinfo
グラフィックスファイルの情報の出力
imread
グラフィックスファイルからイメージを読み込みます
imwrite
イメージをグラフィックスファイルに書き出します
42
ビット単位の関数
bitand
ビット単位の論理積
bitcmp
ビットの補数
bitor
ビット単位の論理和
bitmax
最大の浮動小数点整数
bitset
ビットの設定
bitshift
ビット単位のシフト
bitget
ビットを取り込みます
bitxor
ビット単位の排他的論理和
43
立命館大学理工学部電気電子工学科
鷹羽研究室・久保研究室
プレ卒研資料
MATLAB プログラミングの基礎(後編)
第3章
MATLAB プログラミング実際編
ここでは,いくつかの例題について実際に m ファイルプログラムを作成してみます.MATLAB の文法は
そんなに複雑なものではありませんから,ここで示すプログラム例を参考にして実際のプログラミングに慣れ
てください.プログラミングは色々な例(お手本)を参考にして,慣れていくのが習得への早道だと思います.
第 2 章では MATLAB の基本コマンド群を紹介しましたが,MATLAB にはこれらの関数以外にも,Tool
Box という形でさまざまな関数が用意されています(オプション).例えば,信号処理に関する処理を行う場
合には「Signal Processing Tool Box」,画像処理を行う場合には「Image Processing Tool Box」等々があ
り,代表的な処理は既に関数として提供されている場合があります.ここでは,ToolBox の関数については説
明しませんが,具体的な問題についてプログラミングを行う場合には,まず ToolBox の関数を調べてみるの
も良いでしょう(ToolBox のアップデートは結構早く,最近論文発表されたような処理方法もいち早く関数化
されていたりします!).
3.1 デジタル信号を扱ってみる
3.1.1 正弦波のサンプリング
振幅 1,周波数 1[kHz] の正弦波信号
y(t) = sin(2π × 1000t)
を,サンプリング周期 T = 0.1[ms] でサンプリングした波形
y(nT ) = sin(2π × 1000nT )
をプロットしてみます.0 ≤ t ≤ 2.5[ms] としてプロットするプログラムは次のようになります.
正弦波のサンプリング (ex10.m)
clear all
close all
t = [0:0.1e-3:2.5e-3];
y = sin(2*pi*1000*t);
stem(t,y)
44
1
0.5
0
-0.5
-1
0
0.5
1
1.5
2
2.5
x 10
-3
図 3.1 ex10.m の実行例(正弦波のサンプリング)
1
0.5
0
-0.5
-1
0
0.5
1
1.5
2
2.5
x 10
-3
図 3.2 ex11.m の実行例(元の正弦波を重ねて表示する)
ex10.m の実行結果は図 3.2 のようになります.ちなみに,図 3.2 に元の正弦波を重ねて表示することを考え
てみます.このためには,0.1[ms] よりも短い間隔で正弦波の値を求め,それらのデータ点をプロットして線
で繋げば綺麗な表示が得られます.プログラムを以下の ex11.m として示します.
正弦波のサンプリング(元の正弦波を重ねて表示する)(ex11.m)
clear all
close all
t = 0:0.1e-3:2.5e-3;
y = sin(2*pi*1000*t);
stem(t,y)
t = 0:0.1e-4:2.5e-3;
y = sin(2*pi*1000*t);
hold on
plot(t,y)
45
3.1.2 MATLAB で DTMF 信号を鳴らしてみよう
sound 関数の利用法
MATLAB で音声データを扱ってみます.いきなり音声?と思うかも知れませんが,ここでは複雑なフィル
タ処理やスペクトル解析は扱わず,単一周波数の正弦波とその組み合わせで作られる音声信号を PC で鳴らし
てみるに止めます.この例題でベクトルの扱い方や,for 構文による繰り返し等々に慣れてください.
PC 上でサウンドを扱う場合のファイルフォーマットにはさまざまなものがありますが,ここでは,音声信
号を単純に −1 ∼ 1 の範囲の値をもつ信号としてサンプリングしたデータを取り扱います.このようなデータ
が格納されたベクトルを Y,サンプリング周波数を Fs とすると,MATLAB 関数 sound を使用して,
>> sound(Y,Fs)
とすることで,PC 上で認識されている標準のサウンドデバイスで音声データを再生することができます.
MATLAB のデモとして,ハレルヤコーラスのデータが用意されていますので,これを使って音声データの
再生を試してみます.このデータは “handel.mat” という MAT ファイルに保存されているので,1.7.1 節で
説明した load コマンドで読み込むことができます.
>> load handel
読み込みが完了すると,変数 Fs にサンプリング周波数,変数 y にデータが格納された状態になります.この
場合,8.192[kHz] でサンプリングされたデータが 73113 個格納されていることがわかります.y をプロット
して,ハレルヤコーラスの音声データを見てみましょう.サンプリング周波数が 8.192[kHz] ですから,1 秒間
に 8192 個のデータがあることになります.したがって,横軸を時刻 t とすると,
>> t = [0:73112] / 8192;
>> plot(t,y)
とすることで,横軸に時間 [sec],縦軸に −1 ∼ 1 に規格化されたハレルヤコーラスのデータが表示されます.
表示例を図 3.3 に示しておきます.このデータを再生するには,先に示したように sound を使用します.
>> sound(y,Fs)
サウンドデバイスが正しく動作していれば,スピーカやヘッドフォンからコーラスが聞こえます.
0.5
0
-0.5
0
2
4
図 3.3
6
ハレルヤコーラスのデータプロット
46
8
単一周波数の音声とその組み合わせ
振幅 1,周波数 697[Hz] の正弦波 A,振幅 1,周波数 1209[Hz] の正弦波 B,および正弦波 A と正弦波 B の
合成波を 22.05[kHz] でサンプリングした 0.5 秒間分のデータを作成し,sound 関数で鳴らしてみましょう.
正弦波の再生(697[Hz] と 1209[Hz] を 0.5 秒間)(ex12.m)
clear all
close all
Fs = 22050; % サンプリング周波数
n = [0:Fs/2-1]; %0.5 秒分のデータ数
s_697
s_1209
c_1
= sin(2*pi*697/Fs*n);
= sin(2*pi*1209/Fs*n);
= (s_697 + s_1209)*0.5;
sound(s_697,Fs)
sound(s_1209,Fs)
sound(c_1,Fs)
t = n/Fs*1000; % 以下は正弦波のプロット用(プロットは初めの 100 個のみ)
subplot(1,3,1)
plot(t(1:50), s_697(1:50))
hold on
stem(t(1:50), s_697(1:50))
title(’ 正弦波 A’)
xlabel(’time[ms]’)
subplot(1,3,2)
plot(t(1:50), s_1209(1:50))
hold on
stem(t(1:50), s_1209(1:50))
title(’ 正弦波 B’)
xlabel(’time[ms]’)
subplot(1,3,3)
plot(t(1:50), c_1(1:50))
hold on
stem(t(1:50), c_1(1:50))
title(’ 合成波’)
xlabel(’time[ms]’)
サンプリング周波数が Fs のとき,1 秒間に Fs 個のサンプル値が得られますから,0.5 秒間では Fs/2-1 個の
サンプルとなります.また合成波に関しては,−1 ∼ 1 の範囲となるように,足し算した後で 0.5 をかけて規
格化しています.
ex12.m を実行すると,3 つの音程が 0.5 秒間ずつ連続して再生されるはずです.また,3 つの正弦波波形を
プロットした結果を,図 3.4 に示しておきます(図は見やすくなるように若干加工しています).
電話番号を鳴らしてみる
for 構文や if 構文,セル配列等の練習のためにもう少し遊んでみます.プッシュ回線で電話をかけるとき,
プッシュした番号に応じてピ,ポ,パという音が鳴ります.これは DTMF(Dual-Tone Multi-Frequency) と
いう技術で,0∼9 までの数字と*,#の 12 種類の符号を低群・高群の 2 つの音声周波数帯域の信号音で送信
47
̂
̂
̂
̂
̂
ᱜᒏᵄ#
VKOG=OU?
̂
̂
̂
̂
̂
ᱜᒏᵄ$
VKOG=OU?
̂
̂
̂
̂
วᚑᵄ
VKOG=OU?
図 3.4 697[Hz](左)
,1209[Hz](中),合成波(右)の波形
する方法です.別名「トーン信号」
「プッシュ信号」とも呼ばれます.DTMF 信号は音声伝送回路で伝送する
ため,全ての周波数は可聴帯域内に収まっており,図 3.5 に示すような 2 種類の正弦音波の合成音として生成
されます.
1029[Hz]
1336[Hz]
1477[Hz]
697[Hz]
1
2
3
770[Hz]
4
5
6
852[Hz]
7
8
9
941[Hz]
*
0
#
図 3.5 DTMF 信号の周波数成分
ここでは,電話番号が格納されたベクトルを引数として受け取り,その電話番号を DFMF 信号としてス
ピーカから送出する関数 dtmf を作成してみます.作成した関数を dtmf.m として以下に示します.
48
電話番号から DTMF 信号を生成する (dtmf.m)
function dtmf(number)
Fs = 22050;
n = [0:Fs/3]’;
L = length(number);
low = [sin(2*pi*697/Fs*n) sin(2*pi*770/Fs*n) sin(2*pi*852/Fs*n) sin(2*pi*941/Fs*n)];
high = [sin(2*pi*1209/Fs*n) sin(2*pi*1336/Fs*n) sin(2*pi*1477/Fs*n)];
for i = 1 : 4
for j = 1 : 3
Push{i,j} = (low(:,i) + high(:,j)) * 0.5;
end
end
for i = 1 : L
if number(i)==1,
if number(i)==2,
if number(i)==3,
if number(i)==4,
if number(i)==5,
if number(i)==6,
if number(i)==7,
if number(i)==8,
if number(i)==9,
if number(i)==0,
sound(Push{1,1},Fs);
sound(Push{1,2},Fs);
sound(Push{1,3},Fs);
sound(Push{2,1},Fs);
sound(Push{2,2},Fs);
sound(Push{2,3},Fs);
sound(Push{3,1},Fs);
sound(Push{3,2},Fs);
sound(Push{3,3},Fs);
sound(Push{4,2},Fs);
end
end
end
end
end
end
end
end
end
end
pause(0.5)
end
少々複雑ですが dtmf.m を見ていきます.サンプリングデータの作成は基本的に前節と同じです.ただし,
作成したデータを列ベクトルとして扱うために,データのインデックスである n が列ベクトルとなるように転
置演算子「’」を用いています.こうしておくことで,sin 関数で作成したサンプル値は列ベクトルとして得
られ,各周波数のサンプル値は行列 low および high に列ベクトルとして格納されます.
次に,図 3.5 にしたがって合成波形のサンプル値を作成します.作成されたデータは適当な配列に格納して
おけばよいのですが,実際に音を鳴らすときの取り扱いを簡単に(見やすく)記述するために,
「セル配列」と
呼ばれる配列にデータを格納しています.MATLAB での通常の配列は,単純に数学的な行列のイメージに
なっています.例えば,配列 A の (1,1) 要素は A(1,1) と記述でき,1 つのスカラー値が格納されます.これ
に対しセル配列では,その配列の要素はスカラー値に限らず,ベクトルや行列,文字列等々,なんでもありの
配列とイメージすればよいでしょう.C 言語での構造体のようなイメージです(MATLAB にも構造体の概念
はあります)
.セル配列は,通常の配列で使用する括弧「(
)」を「{ }」とすることで使用できます.例えば
>> C{1,1} = [1 2 3 4 ]
とすると,セル配列 C の{1,1}要素には,ベクトル [1 2 3 4 ] が代入されます.これを利用して,例えば
プッシュボタンの 1 を押したときのサンプル値を列ベクトルとして Push{1,1}に,プッシュボタン 5 のデー
タは Push{2,2}に代入しています.
以上で DTMF 信号のサンプルデータが作成されたので,後は電話番号が格納されているベクトル number
の各要素について場合分けをし,sound 関数を利用してスピーカから音を鳴らします.dtmf.m では 1 音鳴る
49
たびに pause(0.5) が実行されますが,これはプログラム実行中に 0.5 秒間停止する命令です.pause を入れ
ることで,音と音が 0.5 秒間隔で聞こえるようにしています*1 .
では実際にプッシュ回線でのダイヤル音を鳴らしてみましょう.関数 dtmf に電話番号をベクトルとして渡
せばよいのですから,例えば立命の代表番号なら
>> dtmf([0 7 7 5 6 1 1 1 1 1])
となります*2 .
■dtmf.m の別解 上の例では,練習のためにわざわざセル配列を導入して各数字の音データを取り扱いまし
た.しかしこの程度の処理ならば,Push を単なる行列として扱い,第 1 列にプッシュボタン 1 のデータ,第
2 列にプッシュボタン 2 のデータといった具合で格納しておけば十分かも知れません.セル配列を使用せずに
記述した例を以下の dtmf1.m に示しておきます.
dtmf.m の書き直し (dtmf1.m)
function dtmf1(number)
Fs = 22050;
n = [0:Fs/3]’;
L = length(number);
low = [sin(2*pi*697/Fs*n) sin(2*pi*770/Fs*n) sin(2*pi*852/Fs*n) sin(2*pi*941/Fs*n)];
high = [sin(2*pi*1209/Fs*n) sin(2*pi*1336/Fs*n) sin(2*pi*1477/Fs*n)];
Push = [];
for i = 1 : 4
for j = 1 : 3
Push =[Push (low(:,i) + high(:,j)) * 0.5];
end
end
number = number + 11*(number==0);
for i = 1 : L
sound(Push(:,number(i)),Fs)
pause(0.5);
end
このプログラムでは for の 2 重ループを使って,ボタン1,2,3,,,,,0に対応した DTMF 信号のサ
ンプリング値を列ベクトルとして作成し,行列 Push の列ベクトルとして順次右側に付け加えています.した
がって,行列 Push の第 1 列はボタン 1 の DTMF 信号,第 2 列はボタン 2 といった具合になります.
電話番号は,ベクトル number として渡されてきますから,number の各要素の値を行列 Push の列番号に
対応させて音を鳴らせばよいことになります.ただし,Push の第 10 列がボタン*,第 11 列がボタン 0,第
12 列がボタン#に対応していることに注意が必要です.つまり,ボタン 0 を鳴らす場合は Push の第 11 列を
使用する必要があります.dtmf.m で行ったように,個々の番号について if 構文で判定を行って処理しても
よいのですが,折角なのでここでは MATLAB チックなプログラミングをしています.
*1
pause 関数の引数を変更することで任意の時間プログラムを停止させることができます.また引数無しで実行した場合,任意の
キーが押されるまでプログラムが停止されます.プログラムのデバッグ時等にも便利です.
*2 プッシュ回線に接続されている電話機を使って,実際にダイヤルできることを確かめられます.PC の音量を適当に調節し,受話
器の送話口にスピーカまたはヘッドフォンを押し当ててプログラムを実行してみて下さい(確認済み!).
(携帯電話では,電話機
の仕様によると思います.通話ボタンを押して「ツー」が聞こえる携帯ならできるかも.
.
.
.
)
50
number = number + 11*(number==0);
の部分がそうです.例えば電話番号が「077-561-2660」とします.
number = [0 7 7 5 6 1 2 6 6 0]
すると,論理演算 number==0 の結果は,ベクトル number の要素が 0 である要素について “1”,0 でない要素
について “0” であるようなベクトルとなります.すなわち,
number == 0
----->>
ans = [1 0 0 0 0 0 0 0 0 1]
したがって
number = number + 11*(number==0);
の演算結果は
number = [11 7 7 5 6 1 2 6 6 11]
となり,number の各要素に対応した Push の列をデータとして鳴らせば目的が達成できるのです.
51
3.2 正規分布を描く
3.2.1 標準正規分布を描いてみる
正規分布の確率密度関数は
f (x) = √
1
2πσ 2
e−
(x−µ)2
2σ 2
(3.1)
であり,2 つのパラメータ(平均 µ,分散 σ 2 )で完全に特徴付けられる分布です.その形はよく知られている
ように釣り鐘形となります.ここでは,平均 0,分散 1 の標準正規分布の形状を MATLAB を使って描画して
みましょう.
標準正規分布を描く (ex13.m)
clear all
close all
mu = 0;
sig = 1;
x = [-5:0.1:5];
y = 1/sqrt(2*pi*sig^2) * exp(-(x-mu).^2/(2*sig^2));
plot(x,y)
この例では,x の範囲を −5 から 5 までの 0.1 刻みとし,各 x の値に対応する関数値を計算してベクトル y
に格納した後でプロットしています.“x.^2” は第 1.3 節で説明したように,ベクトル x の各要素の 2 乗とな
ります.プロットの結果は,図 3.6 のようになります.
図 3.6 ex13.m の実行例
52
3.2.2 分散を変化させて描いてみる
ex13.m を応用して,分散を変化させながら,複数の正規分布を重ねてプロットしてみましょう.標準偏差
の値を,0.5∼2.5 の 0.5 刻みとし,5 つの正規分布を重ねて表示してみます.プロットの結果は,図 3.7 のよ
うになります.
標準正規分布を描く (ex14.m)
clear all
close all
mu = 0;
x = [-5:0.1:5];
for sig = 0.5:0.5:2.5
y = 1/sqrt(2*pi*sig^2) * exp(-(x-mu).^2/(2*sig^2));
plot(x,y)
hold on
end
図 3.7 ex14.m の実行例
3.2.3 ezplot コマンドの利用
前節では,関数の値を実際に計算してプロットしていました.一方,MATLAB では簡単な関数に対して,
“ezplot” コマンドを利用することで,与えられた数式に対してプロットを行うことが可能です*3 .デフォルト
では,−2π ≤ x ≤ 2π の範囲で関数が描画されます.実際にコマンドを実行して確かめてみてください.
*3
数式処理的な動作が可能ということ.数式処理に長じたソフトウェアとしては Mathematica が有名.gnuplot なども数式を与え
ることで関数をプロットできる.
53
ezplot コマンドによる正規分布の描画
>> ezplot(’1/sqrt(2*pi)*exp(-x^2/2)’)
3.2.4 参考—プロットの編集
蛇足ですが,プロットの編集について少し説明しておきます.figure ウィンドウのメニューを操作すること
で,グラフ作成に必要なさまざまな操作を行うことができます.例えば,X 軸,Y 軸の範囲設定,目盛りの間
隔設定,プロットの表示・非表示の選択,プロットの色,線種,太さの設定,凡例の挿入,グリッドの有無等々
が設定できます.これらを適切に設定して,論文等に貼り込むグラフを綺麗に作成することができます*4 .
これらの操作方法は,実際にやってみるとすぐに分かってくると思いますので,ここでは詳しく説明しま
せんが,特筆すべきは,figure ウィンドウのテキストボックス内で,ギリシャ文字や添え字を指定するために
LATEX コマンドが利用可能ということです.プロットのタイトルを “1/sqrt(2¥pi)exp(-x^2/2)” とした
例を,図 3.8 に示しておきます.
図 3.8 プロットのテキストボックス内でギリシャ文字や添え字を使う
これ以上の複雑な数式などをグラフ中で使用したい場合は,MATLAB 内では対応不可能です.そのような
場合は,グラフを Illustrator 等のソフトウェアで編集,加工して仕上げる必要があります.MATLAB で作成
したグラフ(図 3.7)を EPS 形式で保存し,“TeX2img” というソフトで作成した数式のアウトラインを利用
*5 論文作成時等に参考にしてください.
して Illustrator で加工したグラフを図 3.9 に示しておきます.
*4
綺麗にといっても,MATLAB では表現に限界のある場合もあります.そのような場合は,他のグラフ作成ソフトを利用すること
になります.TEX との親和性があり,フリーで,使いやすく,表現力のあるソフトとしては,“plot32” や “Ngraph” が有名です.
*5 同じような働きをするソフトに「TeXpoint」というのがあります.これは PowerPoint のアドインソフトで,数式を L
AT X コ
E
マンドで打ち込み,そのまま PPT に貼り込める優れものです.
54
̂
̂
̂
̂
̂
図 3.9 MATLAB,TeX2img,Illustrator を活用して作成したグラフ
3.2.5 2 次元の正規分布
n 次元確率ベクトル X が平均 µ,共分散行列 R の正規性確率ベクトルであるとき,その(結合)確率密度
関数は
pX (x) =
1
1
exp{− [x − µ]T R−1 [x − µ]}
2
(2π)n/2 |R|1/2
(3.2)
と表されます.平均ゼロ,共分散行列が単位行列であるような,2 次元正規分布の確率密度関数を視覚化して
みましょう.(3.2) 式の各パラメータは次のようになります.
[
n = 2,
x = [ x1
µ = [ 0 0 ]T ,
R=
1
0
0
1
]
x2 ]T として,x1 ,x2 を −3 から 3 の範囲で 0.1 刻みで変化させて計算した (3.2) 式の値をプロッ
トするプログラムを以下に示します.
2 次元正規分布を描く (ex15.m)
clear all
close all
x1 = [-3:0.1:3];
x2 = [-3:0.1:3];
N = size(x1,2);
Rinv = inv(eye(2));
for i = 1:N
for j = 1:N
p(i,j) = [1/(2*pi)*exp(-0.5*[x1(i);x2(j)]’*Rinv*[x1(i);x2(j)])];
X1(i,j) = x1(i);
X2(i,j) = x2(j);
end
end
surf(X1,X2,p)
このプログラムでは,x1,x2 に −3 から 3 を 0.1 刻みにしたベクトルを格納し,ベクトル x1 の第 i 要素
と,ベクトル x2 の第 j 要素に対応した確率密度(pX (x))の値を,行列 p の (i,j) 要素に格納しています.
55
また,その時の x1 の第 i 要素を行列 X1 の (i,j) 要素,x2 の第 j 要素を行列 X2 の (i,j) 要素に格納してい
ます.こうすることで,行列 X1,X2,p の要素の対応がとれます.つまり,X1 の (i,j) 要素と X2 の (i,j)
要素に対応した確率密度は p の (i,j) 要素に格納されています.このような行列 X1,X2,p を用意してやる
と,3 次元のカラーサーフェイスを描画する関数 surf を利用して,簡単に (3.2) 式の形状を描画することがで
きます.実行例を図 3.10 に示します.
̂
̂
図 3.10
̂
̂
ex15.m の実行例(2 次元正規分布の描画 (µ = 0,R = I)
さて,もう一度 (3.2) 式を見て,確率密度 pX (x) がある値で一定となるような x の集合はどのような形状に
なるか考えてみます.変数は x なので,pX (x) が一定となるのは,[x − µ]T R−1 [x − µ] が一定となる場合で
あることがわかります.したがって,
[
µ = [ 0 0 ]T ,
R=
σ12
σ21
σ12
σ22
]
[
=
σ12
ρσ2 σ1
ρσ1 σ2
σ22
]
(ρ は相関係数)
として計算してみると,
=⇒
[x − µ]T R−1 [x − µ] = d2
(d: 定数)
{ 2
}
1
x1
2ρ
x22
−
x
x
+
= d2
1 2
1 − ρ2 σ12
σ1 σ2
σ22
(3.3)
となります.つまり,pX (x) が一定値(等確率)となる x1 ,x2 の集合は,x1 と x2 が無相関(ρ = 0,
σ12 = σ21 = 0)で,x1 と x2 の分散が等しい(σ12 = σ22 )場合,原点を中心とする円となることがわかりま
す.また,ρ = 0 で,σ12 ̸= σ22 の場合は,x1 軸上に長軸(短軸),x2 軸上に短軸(長軸)をもつ楕円となり,
ρ ̸= 0 の場合には,楕円を原点中心に回転させた形状となることがわかります.
以上の内容を実際に確かめてみましょう.MATLAB には,等高線を描画する関数 contour,およびその 3D
表示版である contour3 が用意されています.ex15.m の結果に対して等高線を描画すると図 3.11 のような結
果が得られ,等確率な点は円となっていることが確かめられます*6 .
*6
図 3.11 では,figure ウィンドウからプロパティエディタを呼び出し,軸の詳細なプロパティにおいて DataAspectRatio を各軸
で等しく設定することで,縦軸,横軸のスケールを等しく表示させています
56
>> contour(X1,X2,p)
>> contour3(X1,X2,p)
a
̂
̂
̂ a
̂
̂
̂
̂
̂
図 3.11 ex15.m の実行結果(µ = 0,R = I ,ρ = 0)に対する等高線の表示(左: contour 関数を使用し
た等高線.右: contour3 関数を使用した等高線の 3D 表示).
また,
[
µ = 0,
R=
2 0
0 1
]
とした場合のプロットを図 3.12 に,
[
µ = 0,
R=
2 1
1 1
]
とした場合のプロットを図 3.13 に示します.また,参考までに,図 3.13 の作成に使用したプログラムを下に
示しておきます.
57
̂
̂
̂
̂
̂
̂
̂
̂
̂
̂
図 3.12 µ = 0,σ12 = 2,σ22 = 1,σ12 = 0 とした場合の 2 次元正規分布のプロット(左: surf 関数によ
る 3D サーフェイス表示.中: contour 関数を使用した等高線.右: contour3 関数を使用した等高線の 3D
表示).
̂
̂
̂
̂
̂
̂
̂
̂
̂
̂
̂
̂
̂
̂
図 3.13 µ = 0,σ12 = 2,σ22 = 1,σ12 = 1 とした場合の 2 次元正規分布のプロット(左: surf 関数によ
る 3D サーフェイス表示.中: contour 関数を使用した等高線.右: contour3 関数を使用した等高線の 3D
表示).
58
参考 (図 3.13 の作成に使用したプログラム)
clear all
close all
x1 = [-3:0.1:3];
x2 = [-3:0.1:3];
N = size(x1,2);
Rinv = inv([2 1;1 1]);
for i = 1:N
for j = 1:N
p(i,j) = [1/(2*pi)*exp(-0.5*[x1(i);x2(j)]’*Rinv*[x1(i);x2(j)])];
X1(i,j) = x1(i);
X2(i,j) = x2(j);
end
end
subplot(1,3,1)
surf(X1,X2,p)
subplot(1,3,2)
contour(X1,X2,p)
subplot(1,3,3)
contour3(X1,X2,p)
59
3.3 最小 2 乗法
n 個の x の値 {xt ; t = 1, 2, . . . , n} に対して,未知パラメータ θ を含む関数 h(xt , θ) の値が {yt ; t =
1, 2, . . . , n} として測定されたとします.一般に測定には誤差が含まれており,その誤差は {yt − h(xt , θ); t =
1, 2, . . . , n} となります.この誤差の 2 乗和が最小となるように n 組のデータ (x1 , y1 ),(x2 , y2 ),. . .,(xn , yn )
から θ の推定値 θ̂ を求める(n 組のデータを関数 h(x, θ̂) で近似する)方法を最小 2 乗法といいます.
例えば,n 組のデータ (x1 , y1 ),(x2 , y2 ),. . .,(xn , yn ) に対して最小 2 乗法を適用し,直線
θ = [a b]T
h(x, θ) = ax + b,
(3.4)
で近似することを考えます.測定誤差を
et = yt − h(xt , θ),
t = 1, 2, . . . , n
(3.5)
と定義すると,n 組のデータについて
y1 = ax1 + b + e1
y2 = ax2 + b + e2
..
.
yn = axn + b + en
と書くことができます.ここで,



y=


y1
y2
..
.



,



H=

yn
x1
x2
..
.
1
1
..
.
xn
1



,




e=

e1
e2
..
.





en
と表現すると,
y = Hθ + e
(3.6)
となります.このとき,θ の推定値 θ̂ は
θ̂ = arg min
θ
= (H T H)
n
∑
n
∑
[
]2
et = arg min
yt − (axt + b) = arg min(y − Hθ)T (y − Hθ)
t=1
−1 T
θ
θ
t=1
H y
(3.7)
で計算できます.詳しい計算内容は [B6] を参照してください.
3.3.1 直線による近似
直線による近似の例として,電気抵抗の温度変化に関する問題を考えてみます.同じ物質で同一形状の導体
であっても,導体の温度が変化すれば抵抗値は変化します.一般の金属では温度と抵抗値はほぼ比例すること
が知られており,0[◦ C] での抵抗値を R0 ,温度係数を α0 とすると,温度 t での抵抗値は
Rt = R0 (1 + α0 t)
(3.8)
60
と表されます.いま,温度を変化させながら導体の抵抗値を測定したところ,次のようなデータが得られま
した.
温度
抵抗
0
0.215
10
0.220
20
0.230
30
0.247
40
0.250
50
0.258
最小 2 乗法により R0 と α0 を求めてみましょう.この問題は,近似式に R0 と α0 の積が含まれるため,一見
厄介に思われます.しかし本質は,抵抗値が温度に比例するということですから,
Rt ∼ a0 + a1 t
(3.9)
で近似すると考えて,a0 と a1 を求めた後で,R̂0 = a0 ,α̂0 =
プログラムと実行例は以下のようになります.
a1
a0
とすればよいことがわかります.MATLAB
直線による近似 (ex16.m)
clear all
close all
t = [0 10 20 30 40 50]’;
Rt = [0.215 0.220 0.230 0.247 0.250 0.258]’;
H = [ones(6,1) t];
a = inv(H’*H)*H’*Rt; % 最小 2 乗法の計算
R0 = a(1);
alpha0 = a(2)/a(1);
Rth = a(1) + a(2)*t;
fprintf(’R0 = %f,
% 近似直線上の点を求める
alpha0 = %f\n’, R0, alpha0);
plot(t,Rt,’ro’) % データ点を(赤い○,線無し)プロット
hold on
plot(t,Rth) % 近似直線を(デフォルト表示;マーカー無し,青い線)プロット
ex16.m の実行結果 (コマンドウィンドウの表示)
>> ex16
R0 = 0.213667,
alpha0 = 0.004306
以上の結果より,この問題における 6 組のデータ点は,直線
Rt = 0.213667(1 + 0.004306t)
(3.10)
で最小 2 乗近似されることがわかります.ex16.m では,図 3.14 のように 6 組のデータ点を赤い丸印でプロッ
トし,その上に近似直線を重ねてプロットしています.
補足
ex16.m では (3.7) 式を計算するために,逆行列を求める関数 inv を使用して,そのまま MATLAB プログ
ラムとして記述しましたが,最小 2 乗法の計算を行うアルゴリズムには色々なものがあり,MATLAB でも
61
図 3.14 ex16.m の実行結果(赤丸: データ点,青線: 近似直線)
いくつかの方法が実装されています.例えばバックスラッシュ演算子(ウィンドウズ上では「¥」と表示され
る)を用いる方法があり以下の用にして最小 2 乗法を解くことができます.
最小 2 乗法・計算方法の補足 (バックスラッシュ演算子の使用)
>> H \ Rt
ans =
2.1367e-001
9.2000e-004
上の結果を,ex16.m の計算結果(a = inv(H’*H)*H’*Rt)と比べてみてください.
3.3.2 指数関数による近似
n 組のデータ (x1 , y1 ),(x2 , y2 ),. . .,(xn , yn ) に対して最小 2 乗法を適用し,指数関数
h(x, θ) = aebx ,
θ = [a b]T
(3.11)
で近似することを考えます.一見やっかいですが,(3.11) 式の両辺の自然対数をとると,
log h(x, θ) = log a + bx
(3.12)
となります.ここで,h̃(x, θ) = log h(x, θ),ã = log a とおくと,この式は
h̃(x, θ) = ã + bx
(3.13)
となって,この問題は前節で考えた直線近似の問題に帰着できます.例として,次に示すダイオードの静特性
に関する問題を考えてみます.
いま,ダイオードに加えた電圧 V に対する電流 I の測定データが下表のように得られたとします.
V [mV]
I [mA]
100
0.0005
150
0.04
200
0.30
250
1.5
300
10
350
70
400
480
このデータに最小 2 乗法を適用して,次の指数関数で近似してみます.
I = aebV
(3.14)
62
両辺の対数をとると
log I = log a + bV
(3.15)
となりますから,データの組を (V1 , I1 ), . . . , (Vn , In ) と考え,



y=

log I1
log I2
..
.



,




H=

log In
1
1
..
.
V1
V2
..
.





1 Vn
とすると,
[
log a
b
]
= (H T H)−1 H T y
(3.16)
となります.以下に,MATLAB プログラムおよびデータ点,近似曲線をプロットした結果を示しておき
ます.
指数関数による近似 (ex17.m)
clear all
close all
V = [100 150 200 250 300 350 400]’;
I = [0.0005 0.04 0.30 1.5 10 70 480]’;
y = log(I);
H = [ones(7,1) V];
X = inv(H’*H)*H’*y; % 最小 2 乗法の計算
a = exp(X(1));
b = X(2);
fprintf(’log(a) = %f, b = %f\n’, X(1), X(2));
fprintf(’a = %f, b = %f\n’, a, X(2));
VV =[0:400];
Ih = a*exp(b*VV); % 近似曲線上の点を求める
plot(V,I,’ro’) % データ点を(赤い○,線無し)プロット
hold on
plot(VV,Ih) % 近似直線を(デフォルト表示;マーカー無し,青い線)プロット
ex17.m の実行結果 (コマンドウィンドウの表示)
>> ex17
log(a) = -10.514304, b = 0.042690
a = 0.000027, b = 0.042690
3.3.3 多項式による近似
問題としては前出の 2 つと同様なものですが,RC 回路の過渡現象について考えます.図 3.16 のような回
63
800
600
400
200
0
0
100
200
300
400
図 3.15 ex17.m の実行結果(赤丸: データ点,青線: 近似直線)
路で,スイッチを入れてからの経過時間 t に対するコンデンサ C の両端電圧 v を測定したところ,表のよう
な結果が得られたとします.このデータに最小 2 乗法を適用し,v を m 次の多項式
v = a0 + a1 t + a2 t2 + · · · + am tm
(3.17)
で近似するときの係数 a0 , a1 , . . . , am を求めてみます.n 個のデータ,(t1 , v1 ), (t2 , v2 ), . . . , (tn , vn ) が得ら
れたとして,ベクトル,行列を使って表現すると,






v1
v2
..
.

 
 
∼
 
vn
t1
t2
t21
t22
1 tn
t2n
1
1
..
.

a0
· · · tm
1


· · · tm
2   a1
  ..
 .
m
· · · tn
am





(3.18)
となり,



V =

v1
v2
..
.



,




H=

vn
1
1
..
.
t1
t2
t21
t22
···
···
1
tn
t2n
···

tm
1

tm
2 
,

m
tn

a0
a1
..
.


θ=






am
とおくと,θ の最小 2 乗推定値は
θ̂ = (H T H)−1 H T V
(3.19)
100 k㱅
500uF
10V
図 3.16
時間 [秒]
電圧 [V]
0
0
20
3.3
40
5.5
60
6.9
RC 回路
80
8.0
100
8.6
64
120
9.2
140
9.4
160
9.6
180
9.7
200
9.8
で得られます.このまま MATLAB の行列演算により解を求めても良いですが,ここではもう少し計算を進
めてみます.いま,行列 H の第 j 行を hj とおくと,(3.19) 式は
θ̂ = (H T H)−1 H T V




[
hT
hT
···
=
1
2





=
n
∑
−1

hT
j hj
j=1
n
∑

hT
n
]



hT
1
hT
2
..
.
hT
n
−1


 [


hT

1





hT
2
· · · hT
n
]



v1
v2
..
.





vn
hT
i vi
(3.20)
i=1
となります.(3.19) 式を用いた場合,行列 H は n × m 行列であり,データ数が多い場合は大きな行列となり
ますが,(3.20) 式を用いると m 次の正方行列を扱うことになり,処理の上で大変有利になります.
さて,今回はデータをファイルから読み込んでみます.通常ファイルからの読み込みを行う場合は,ファイ
ルをオープンし,fscanf,fread,fgetl,fgets 等々の関数を駆使して読み込みを行い,最後にファイルをクロー
ズするという処理が必要になります.一方,データのフォーマットが単純で,
データが記録された CSV ファイル (RC.dat)
0,
20,
40,
60,
80,
100,
120,
140,
160,
180,
200,
0
3.3
5.5
6.9
8.0
8.6
9.2
9.4
9.6
9.7
9.8
上のように,「カンマ区切り」で記録されているようなデータの場合*7 は,csvread という関数が利用できま
す.使い方は大変簡単で,例えば
R=csvread(’ ファイルネーム’)
とすると,「ファイルネーム」で指定されたファイルの内容を読み取り,行列 R に格納してくれます.ファイ
ルのオープン等も必要有りません.作成したプログラムを ex18.m に示します.
*7
csv ファイルと呼ばれ,テキストエディタで作成しても良いですし,EXCEL 等でも簡単に作ることができます
65
RC 回路の過渡現象 (ex18.m)
clear all
close all
fname = input(’ データファイル名を入力して下さい:’,’s’);
M = input(’ 多項式の次数を入力して下さい:’);
R = csvread(fname);
t = R(:,1);
v = R(:,2);
L =
HtH
HtY
for
length(t);
= zeros(M+1,M+1);
= zeros(M+1,1);
i = 1 : L
h = [];
for j = 0 : M
h = [h t(i)^j];
end
HtH = HtH + h’*h;
HtY = HtY + h’*v(i);
end
a = inv(HtH)*HtY
plot(t,v,’ro’) % データ点を(赤い○,線無し)プロット
tt = [0:200]’;
VV = polyval(flipud(a),tt);
hold on
plot(tt,VV)
% 近似直線を(デフォルト表示;マーカー無し,青い線)プロット
ex18.m では,データファイル名と多項式の次数をキーボードから対話的に入力できるようにしています.
キーボードからの入力は,例えば input 関数を利用して次のように実現できます.
fname = input(’ データファイル名を入力して下さい:’,’s’);
上のセンテンスが実行されると,コマンドウィンドウに「データファイル名を入力して下さい: 」と表示して
入力待ち状態となり,キーボードから入力された内容を文字列として変数 fname に格納されます.「’s’」は,
入力された内容を文字列として扱うことを指定しています.次のセンテンス
M = input(’ 多項式の次数を入力して下さい:’);
のように「’s’」がない場合は,入力されたデータが数値として扱われます.その後,CSV ファイルからの読
み込みが行われます.
R = csvread(fname);
この場合,行列 R の第 1 列が時刻データのベクトル,第 2 列目が電圧データのベクトルとなります.データが
読み込まれた後は,(3.20) 式により最小 2 乗法の計算を行っています.
プログラムの後半部分では,データ点と 1 秒刻みで計算した近似曲線のプロットを行っています.近似
曲線の計算は数式通りまじめにプログラムしてもよいのですが,MATLAB には多項式の値を計算する関数
polyval があらかじめ用意されているので,これを活用しています.関数の仕様はヘルプを参照すればすぐに
確かめることができますが,第1引数に多項式の係数,第2引数に変数(ベクトルや行列でもよい)を与えま
す.多項式の係数は降べきの順で与える必要があるため,上の例では関数 flipud によって列ベクトル a の上
66
下を入れ換えています*8 .
多項式の次数を m = 3 とした場合の ex18.m の実行結果を以下に示します.
ex18.m の実行結果 (コマンドウィンドウの表示)
>> ex18
データファイル名を入力して下さい:rc.dat
多項式の次数を入力して下さい:3
a =
1.5385e-001
1.6793e-001
-1.0386e-003
2.2120e-006
10
8
6
4
2
0
図 3.17
0
50
100
150
200
ex18.m の実行結果(赤丸: データ点,青線: 近似直線 (m = 3))
補足 1
回路図 3.16 において,コンデンサに蓄えられる電荷 Q とコンデンサの両端電圧 VC の間には
Q = CVC
の関係があります.また,オームの法則より
R
dQ
1
+ Q=E
dt
C
なので,t = 0 において Q = 0,すなわち初期状態としてコンデンサに電荷は蓄えられていなかったとすると,
上式を解くことにより
VC = E{1 − e− CR }
t
となり,VC を t = 0 のまわりでテーラ級数展開すると
{
VC = E
*8
1
1
1
1
t−
t2 +
t3 − · · · + (−1)k−1
tk · · ·
CR
2!(CR)2
3!(CR)3
k!(CR)k
同様なはたらきをする関数として,行ベクトルの左右を入れ換える関数 fliplr 等もあります.
67
}
が得られます.この例題の場合,
E
= 0.2,
CR
E
= 2 × 10−3 ,
2!(CR)2
E
= 1.3 × 10−5 , . . . . . .
3!(CR)3
となりますから,m = 3, 4, 5, . . . と次数を増やしてみて,どの程度係数が一致するか確かめてみてください.
補足 2
この例題では,多項式の係数を最小 2 乗法を利用して求めましたが,実は MATLAB にはこれと同じ働き
をする関数 polyfit が用意されています.polyfit のヘルプを一部抜粋して掲載しておきます.
P = POLYFIT(X,Y,N) は 、デ ー タ Y を 最 小 二 乗 的 に 最 適 近 似 す る N 次 の 多 項 式 P(X) の 係 数
を 算 出 し ま す 。P は 降 順 の べ き 乗 の 多 項 式 係 数 を 含 む つ ぎ よ う な 長 さ N+1 の 行 ベ ク ト ル で す 。
P(1)*X^N + P(2)*X^(N-1) +...+ P(N)*X + P(N+1)
polyfit を実際に使ってみます.ex18.m を実行すると,変数 t に時刻,v に電圧が格納されているので,以
下のようにして多項式の係数を求めることができます.ex18.m の結果と比べてみてください.
>> polyfit(t,v,3)
ans =
2.2120e-006 -1.0386e-003
1.6793e-001
1.5385e-001
68
3.4 カルマンフィルタ
3.4.1 時系列信号を描いてみる
2
離散的な時系列信号 xt (t = 0, 1, 2, . . .) を考えます.a を定数,wt を平均 0,分散 σw
の正規性白色雑音と
し,xt が
xt+1 = axt + wt
(3.21)
と表されるとき,xt は 1 次の AR 過程(1 次のマルコフ過程)と呼ばれます.
2
a = 0.9,σw
= 1,x0 = 0 としたときの xt の一例(見本過程)をプロットしてみます.MATLAB プログ
ラムを ex19.m に,プロット例を図 3.18 に示します.
1 次のマルコフ過程を描いてみる (ex19.m)
clear all
close all
a = 0.9;
sigw2 = 1;
x = 0;
Xvec = 0;
for t = 0 : 1000
x = a*x + sqrt(sigw2)*randn(1,1);
Xvec = [Xvec; x];
end
plot(Xvec)
5
0
-5
-10
0
200
400
600
800
1000
2
図 3.18 ex19.m の実行結果(a = 0.9,σw
= 1)
(3.21) 式をそのまま計算しているだけですので,プログラム自体は特に難しくないと思います.MATLAB
を利用すると,このようなプロットも簡単に実現できるので,パラメータによって時系列がどのように変化す
るか簡単にプロットして確かめてみることができます.
69
2
分散 σw
を変化させて描いてみる
2
2
2
σw
= 1,σw
= 0.25,σw
= 0.09 の 3 つの場合についてプロットしてみます.プログラムは,ex19.m を繰
り返すだけなので各自考えてみてください.図 3.19 のような結果が得られます.
5
0
-5
0
200
400
600
800
1000
2
2
2
2
図 3.19 ex19.m で分散 σw
を変化させてプロットした結果(青: σw
= 1,赤: σw
= 0.25,緑: σw
= 0.09)
パラメータ a を変化させて描いてみる
次に,パラメータ a を変化させ,a = 0.99,a = 0.9,a = 0.3 の場合についてプロットしてみます.上と同
様に,プログラムは各自考えてみてください.結果を図 3.20 に示します.
10
0
-10
-20
-30
0
200
400
600
800
1000
図 3.20 ex19.m でパラメータ a を変化させてプロットした結果(青: a = 0.99,赤: a = 0.9,緑:
a = 0.3);a = 0 で白色雑音,a = 1 でウィーナ過程(ブラウン運動)となり,それぞれの過程に近づいて
いることがわかる.
70
3.4.2 カルマンフィルタの応用(その1)
前節(3.4.1 節)で生成した 1 次のマルコフ過程
xt+1 = axt + wt
(3.22)
に対して,xt に雑音が加わった yt が以下のように観測されたとします.
yt = xt + vt
(3.23)
ただし,vt は平均 0,分散 σv2 の正規性白色雑音で,xt ,wt とは無相関であるとします.すなわち
E[wt ] = 0,
E[vt ] = 0
2
E[wt wk ] = σw
δtk ,
E[wt xk ] = 0,
E[vt vk ] = σv2 δtk
E[vt xk ] = 0
また,初期値 x0 についての先験情報として,x0 は平均 x̄0 ,分散 σ02 の正規分布にしたがう確率変数であると
します.
x0 ∼ N (x̄0 , σ02 )
さて,上の条件の下でカルマンフィルタを利用し,観測 yt から状態 xt を推定するカルマンフィルタのアル
ゴリズムは次のようになります.
x̂t+1|t = ax̂t|t
(3.24)
x̂t|t = x̂t|t−1 + Kt [yt − x̂t|t−1 ]
Kt = Pt|t−1 [Pt|t−1 +
2
(3.25)
σv2 ]−1
(3.26)
2
σw
(3.27)
Pt|t = Pt|t−1 − Kt Pt|t−1
)
(
= (1 − Kt )2 Pt|t−1 + Kt2 σv2
{
x̂0|−1 = x̄0
初期条件:
P0|−1 = σ02
(3.28)
Pt+1|t = a Pt|t +
xt ,yt を生成し,カルマンフィルタにより xt の推定を行うシミュレーションを行ってみます.参考プログ
ラムを ex20.m に示します.
71
カルマンフィルタの応用その 1(ex20.m,1 次のマルコフ過程の推定)
clear all
close all
a = 0.99;
sigw2 = 0.25;
sigv2 = 1;
x = 0;
Xvec = 0;
% システムノイズ分散
% 観測ノイズ分散
% 状態変数を初期化
hatxp = 0;
Pp = 1;
HatXf = [];
% カルマンフィルタ初期推定値を設定
%P(0|-1) を設定(初期分散)
% 推定値を格納するベクトルの初期化
for t = 0 : 200 %1 次のマルコフ過程を生成
x = a*x + sqrt(sigw2)*randn(1,1);
Xvec = [Xvec; x];
end
Yvec = Xvec + sqrt(sigv2)*randn(size(Xvec));
% 観測値を作成
N = length(Xvec);
for i = 1 : N % カルマンフィルタ演算
K = Pp/(Pp + sigv2);
hatxf = hatxp + K*(Yvec(i)-hatxp);
Pf = Pp - K*Pp;
hatxp = a*hatxf;
Pp = a^2*Pf + sigw2;
HatXf = [HatXf; hatxf];
end
plot(Xvec, ’b-’)
hold on
plot(Yvec, ’g-’)
plot(HatXf, ’r-’)
%1 次のマルコフ過程(真の値)をプロット
% 観測値をプロット
% 推定値をプロット
ex20.m では,各種のパラメータを以下のように設定しています.
a = 0.99,
σv2
2
σw
= 0.25,
x0 = 0
=1
x̂0|−1 = 0,
P0|−1 (= σ02 ) = 1
実行結果の一例を図 3.21 に示します.図 3.21 では,状態変数 xt を青,観測値 yt を緑,推定値(フィルタ値)
x̂t|t を赤色でプロットしています.雑音に乱された観測値から xt がよく推定できていることがわかります.
√
また参考までに,図 3.22 に推定誤差 x̂t|t − xt を青色で,推定誤差の 2σ 値 (±2 Pt|t ) を赤色でプロットして
います.上記のパラメータを色々変えて,どのような変化があるか確かめてみてください.
3.4.3 カルマンフィルタの応用(その2)
もう少し(物理的に)具体的な問題設定として,一定速度でまっすぐ走行している(等速直線運動する)自
動車を考えてみます.この自動車の位置をレーダーや GPS などで測定したとし,カルマンフィルタを用いて
72
8
6
4
2
0
-2
-4
-6
図 3.21
0
50
100
150
200
ex20.m の実行結果の例(青: 状態 xt ,緑: 観測値 yt ,赤: 推定値 x̂t|t )
2
1
0
-1
-2
0
50
100
150
200
図 3.22 ex20.m の実行結果の例(青: 推定誤差 x̂t|t − xt ,赤: ±2
√
Pt|t )
自動車の位置を推定します.
時刻 t を t = k∆t (k = 0, 1, 2, . . .) のように,∆t 間隔の離散時間系で表し,時刻 k での自動車の座標を xk ,
速度を vk とすると,等速直線運動なので
xk+1 = xk + vk ∆t
(3.29)
vk+1 = vk
(3.30)
行列表現すると
[
xk+1
vk+1
]
[
=
1 ∆t
0 1
][
xk
vk
]
(3.31)
となります.一方,GPS で自動車の位置を観測したとし,GPS の観測値を z ,誤差を ε で表すと
z k = x k + εk
(3.32)
と書けます.ε は GPS の特性によってどのような誤差となるかが決まってきますが,ここでは平均 0,分散 R
の正規分布にしたがう白色雑音としておきます.(3.31) 式は状態方程式であり,自動車が(等速直線運動で)
移動するというシステムの状態を座標 x と速度 v という状態変数で表現しています.そして,(3.32) 式では,
GPS という観測器をとおして状態の一つである自動車の座標を観測しています.(3.31) 式,(3.32) 式にカル
マンフィルタを適用することで,位置および速度の推定値を得ることができます.
73
さて,(3.31) 式,(3.32) 式を 2 次元(X-Y 平面)の場合に拡張して,カルマンフィルタの動作を確認でき
る MATLAB プログラムを作成し,シミュレーションを行ってみます.状態変数ベクトル xk を

x1,k :
 x2,k :
xk = 
 x3,k :
x4,k :

X 軸座標
X 軸速度 

Y 軸座標 
Y 軸速度
とすると,状態方程式は

 
x1,k+1
1 ∆t 0
 x2,k+1   0 1 0

=
 x3,k+1   0 0 1
x4,k+1
0 0 0

0
x1,k

0 
  x2,k
∆t   x3,k
1
x4,k




(3.33)
となり,観測ベクトル,観測雑音ベクトルをそれぞれ
[
zk =
z1,k : X 軸座標
z2,k : Y 軸座標
]
[
,
εk =
ε1,k : X 軸座標観測雑音
ε2,k : Y 軸座標観測雑音
]
とすると,観測方程式は
[
z1,k
z2,k
]
[
=
1 0
0 0
0
1
0
0
]


x1,k
[
]
 x2,k 

 + ε1,k
 x3,k 
ε2,k
x4,k
となります.上式に基づいて,
1. 状態方程式を用いて,自動車の真の軌道(座標,速度)を生成し,
2. 真の軌道に対して正規性白色雑音を加えて観測値を作成し,
3. カルマンフィルタを適用して,
4. 座標,速度の推定値と,真の値を比較する
ような MATLAB プログラムを作成したものが,以下の ex21.m となります.
74
(3.34)
カルマンフィルタの応用その 2(ex21.m,自動車位置の推定)
%********************************************************************
%
Tracking of Moving Vehicle by Kalman Filter
%
%
Last Modified on Novenber 1, 1999.
%********************************************************************/
clear all
close all
NNN = 4;
% 状態変数の数
MMM = 2;
% 観測の数
Delta_Time = 1.0;
% サンプリング間隔 (sec)
sig_p = 10.0;
% 初期推定値の標準偏差 (座標)[m]
sig_v = 10.0;
% 初期推定値の標準偏差 (速度)[m/s]
sig_r = 10.0;
% 観測雑音の標準偏差 [m]
%****初期設定*******************************************************************
x = [ 0.0;
% X 座標
x1=0[m]
10.0;
% X 速度
x2=10[m/s]
0.0;
% Y 座標
x3=0[m]
10.0];
% Y 速度
x4=10[m/s]
F = eye(NNN,NNN);
% 状態遷移行列に単位行列をセット
F(1,2) = Delta_Time;
% 状態遷移行列セット
F(3,4) = Delta_Time;
H = zeros(MMM,NNN);
% 観測行列クリア
H(1,1) = 1.0;
% 観測行列セット
H(2,3) = 1.0;
Q = zeros(NNN,NNN);
% システムノイズ共分散行列セット
R = sig_r^2 * eye(MMM,MMM);
% 観測ノイズ共分散行列セット
P_p = diag([sig_p sig_v sig_p sig_v]).^2;
% 初期推定誤差共分散行列セット
Kalx_p
= [0; 0; 0; 0];
% カルマンフィルタ初期推定値セット
kekka = [];
% 演算結果格納用変数の初期化
for loop = 1 : 200
%***********観測値の生成***************************************************
z = H*x + sig_r*randn(MMM,1);
%***********Kalman Filter 演算*********************************************
K = P_p * H’ * (H*P_p*H’ + R)^(-1);
% カルマンゲイン
Kalx_f = Kalx_p + K*(z - H*Kalx_p);
% 観測更新
P_f = P_p - K*H*P_p;
% フィルタ推定誤差共分散行列・観測更新
Kalx_p = F*Kalx_f;
% 時間更新(一期先予測)
P_p = F*P_f*F’ + Q;
% 予測推定誤差共分散行列・時間更新
%***********演算結果格納**************************************************
kekka = [kekka; loop
x’
z’
Kalx_f’];
%
ループ番号
真の座標
観測値
濾波推定値
%***********真の軌道を更新************************************************
x = F*x + sqrt(diag(Q)).*randn(NNN,1);
end
plot(kekka(:,2),kekka(:,4),’b+-’)
hold on
plot(kekka(:,6),kekka(:,7),’r*-’)
plot(kekka(:,8),kekka(:,10),’g*-’)
figure
plot(kekka(:,9),’b+-’)
hold on
plot(kekka(:,11),’r*-’)
% 真の軌道をプロット
% 観測された軌道をプロット
% 推定された軌道をプロット
% X 軸速度推定値をプロット
% Y 軸速度推定値をプロット
75
プログラムが長くややこしくなってきましたが,一つ一つの文法としては今まで使ってきたものです.
ex21.m では各種パラメータを以下のように設定しています.
離散間隔: ∆t = 1[s]
システムノイズなし: Q = 04×4
観測ノイズ標準偏差: 10[m]
[
=⇒
]
R=
102
0
0
102
0
102
0
0
0
0
102
0

0
0 

0 
102
状態 x の初期値: x0 = [0 10 0 10]T
状態 x の初期推定値: x̂0|−1 = [0 0 0 0]T

初期推定誤差共分散行列: P0|−1
102
 0
=
 0
0
実行結果の一例を,図 3.23 と図 3.24 に示します.図 3.23 では真の位置を青,観測された位置を赤,カルマン
フィルタにより推定された位置を緑でプロットしています.また図 3.24 では,X 軸方向の速度推定値を青,
Y 軸方向の速度推定値を赤でプロットしています.
a
2500
2000
1350
trueaposition
observation
estimate
1250
Y[m]
1500
1000
1200
1150
1100
500
0a
0
1050
500
1000
1500
1000 a
1000
2000
1050
1100
X[m]
1150
1200
1250
X[m]
図 3.23 ex21.m の実行結果の例−位置(青: 真の位置,赤: 観測値,緑: 推定値)
12
10
Velocity[m/s]
Y[m]
a
trueaposition
observation
estimate
1300
8
6
4
X-Velocity
Y-Velocity
2
0
0
50
100
150
200
t[s]
図 3.24
ex21.m の実行結果の例−速度(青: X 軸速度の推定値,赤: Y 軸速度の推定値)
76
1300
補足
上の例では,自動車は「等速直線運動をしている」という前提で状態方程式を定式化しました.しかし,実
際の自動車を完全に一定の速度で運転できるか?と考えると,アクセルの踏み加減,エンジン出力のばらつ
き,路面の状況等々によって,速度は時々刻々と変化すると考えられます.このような状況に対しては,速度
の変化を適切に「モデル化」して取り扱う必要があります.
例えば速度の変化は小さく,ランダムに起こるものとして正規性白色雑音としてモデル化すると,状態方程
式は

 
x1,k+1
1 ∆t 0
 x2,k+1   0 1 0

 
 x3,k+1  =  0 0 1
x4,k+1
0 0 0

0
x1,k
 x2,k
0 

∆t   x3,k
1
x4,k



0
  w2,k 
+

  0 
w4,k
(3.35)
のように書くことができます.w2,k ,w4,k は各軸方向の速度変化をモデル化した正規性白色雑音です.ex21.m
では,簡単な書き換えによってシステムノイズを扱えるようにしているので,速度の変化を考慮したシミュ
レーションを各自で行ってみてください.
自動車の例に限らず,実際の運用においては,(1) 状態方程式,観測方程式を実際の物理現象に応じて適切に
記述すること,(2) システム雑音,観測雑音の統計的性質についての情報が正しいか否かが重要なファクター
となります*9 .
*9
移動体のモデルとしては,例えば速度を 1 次のマルコフ過程としてモデル化したものや,加速度を 1 次のマルコフ過程,加々速
度(躍度)を 1 次のマルコフ過程としたもの等々が提案されています.どのモデルを採用するか,パラメータの値などは,移動体
の動きの特性に依存してきます.
77
第 1 章,第2章の参考文献 (MATLAB の基本)
[A1] MATLAB 付属のヘルプ
[A2] MATLAB ユーザーズガイド,The MATH WORKS Inc.,サイバネットシステム社翻訳(1996).
[A3] サイバネットシステム社 Web ページ: http://www.cybernet.co.jp/matlab/ (技術サポートに
MATLAB ヘルプの補足日本語版あり)
[A4] 小国力: MATLAB と利用の実際,サイエンス社(1995).
[A5] 上坂吉則: MATLAB プログラミング入門,牧野書店(2000).
[A6] 青山貴伸,森口肇,蔵本一峰: 最新 使えるMATLAB,講談社(2006).
[A7] 小林一行: 最新 MATLAB ハンドブック,秀和システム(2008).
MATLAB の基本を解説した書籍はたくさん出版されています.代表的なものをいくつか挙げておきます
が,MATLAB に付属しているヘルプファイル,サイバネットシステム社 Web ページからかなりの情報を得
ることができます.書籍にはプログラミングの技法的な解説も多々ありますが,初めのうちは先輩のプログラ
ムをじっくり読む方が効果的かも知れません.
78
第3章の参考文献(応用プログラミング)
[B1] MATLAB 付属のヘルプ
[B2] 坂巻佳寿美: 見てわかる ディジタル信号処理,工業調査会(1998).
[B3] 金城繁徳,尾知博: 例題で学ぶ ディジタル信号処理,コロナ社(1997).
[B4] 尾知博: シミュレーションで学ぶディジタル信号処理,CQ 出版(2001).
[B5] 佐藤次男,中村理一郎,伊藤惇: C による理工学問題の解法,日刊工業新聞社(1994).
[B6] 杉本・久保研究室 プレ卒研資料「確率統計学とカルマンフィルタ」(2008 年 12 月).
[B7] 西山清: パソコンで解くカルマンフィルタ,丸善(1993).
[B8] A. Gelb(ed.): Applied Optimal Estimation, MIT Press, Massachusetts (1974).
[B9] R. G. Brown and P. Y. C. Hwang, Introduction to Random Signals and Applied Kalman Filtering,
Third edition, John Wiley & Sons, New York (1997).
正弦波のサンプリング等のディジタル信号の取り扱いについては [B2],[B3],[B4] を参考にしました.これ
ら 3 冊では,さまざまなディジタル信号処理について MATLAB の例題付きで解説したものです.ハレルヤ
コーラスの取り扱いについては MATLAB 付属のヘルプ [B1] に詳しく説明がされています.DTMF 信号の
仕組みについては [B2] を参考にしました.正規分布,最小 2 乗法,カルマンフィルタの理論については [B6]
および [B6] 内で紹介されている文献を参考にしてください.最小 2 乗法を用いた例題については [B5] を,カ
ルマンフィルタを用いた例題については [B7]∼[B9] を参考にしました.
79