論理インデックスとデータの抽出
あるデータ配列から、特定の条件を満たすデータを抽出したいとき、MATLABでは論理インデックスの機能を使います。
まず適当なデータを定義します。ここでは魔方陣を作成します。魔方陣とは行方向、列方向、対角方向の和が等しくなる行列のことです。
>> A = magic(5)
A =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
データをイメージとして可視化してみましょう。
>> imagesc(A,[1 25])
>> colorbar
条件A > 20を満たす論理配列を作成します。
>> B = A > 20
B =
0 1 0 0 0
1 0 0 0 0
0 0 0 0 1
0 0 0 1 0
0 0 1 0 0
上の条件が真のデータ(論理配列がTrue(=1))のみ抽出します。
>> A(B)
ans =
23
24
25
21
22
条件が真のデータのみ置換することもできます。
>> A(B) = 0
A =
17 0 1 8 15
0 5 7 14 16
4 6 13 20 0
10 12 19 0 3
11 18 0 2 9
変更後のデータも可視化して、変換前と比較してみましょう。20以上の値が無くなったため、濃い赤色の表示が青色に変わっています。
>> imagesc(A,[1 25])
>> colorbar
データ解析を行うためには、可視化機能は非常に重要です。演算だけでなく可視化機能も豊富に提供されている点もMATLABの特長です。
MATLABはインタープリタ型? コンパイル型?
MATLABユーザの多くは、MATLABがインタープリタ型のプログラミング環境なので実行速度が遅いと誤解しています。本当にそうでしょうか? MATLABで提供されている多くの関数は、確かにMATLAB言語で書かれており、それがインタープリタ型で処理、実行されています。インタープリタ型環境では、実行時にソースプログラムを解釈しながら逐次実行していくため、処理速度は遅いのですが、プログラムを書き換えたらすぐに実行できのるので、アイデアの確認、デバッグ、試行錯誤が容易というメリットがあります。
また、インタープリタ型の環境ゆえに、MATLAB関数の内容をユーザ側で見て確認したり、プログラミングの勉強をしたりするのに役立てられるというメリットもあります。例えば魔方陣を計算する関数 magic を edit の引数として与えますと
>> edit magic
処理内容が書かれたMATLABのプログラムを見ることが出来ます。このプログラムのアルゴリズムを確認したり、予め適用されている関数を場合によってはカスタマイズして使ったりすることが出来るようになっているのです。
このようにインタープリタ型の実行環境となっている一方、実は多くの関数はBuilt-in関数として、予めコンパイルされた実行ファイルが提供されています。
- eig:固有値と固有ベクトル計算
- fft:FFT, DFTを計算
- filter:1次元デジタルフィルタリングを行う
- conv/conv2:コンボリューション(畳み込み演算)
これらBuilt-in関数のメリットとは、プリコンパイルというだけでなく、マルチスレッド化されている点です。自分でマルチスレッド対応のプログラムを作ろうと思うと大変な労力が要されると思いますが、MATLABがあれば関数を叩くだけでマルチコアCPUの能力を十分に引き出せるのです。
全部の関数がインタープリタだと遅く、逆にコンパイルされているとカスタマイズ性に欠けてしまうので、その良いとこ取りをしているのがMATLABなのです。
豊富な関数ライブラリとグラフィック機能
MATLAB基本機能から、行列演算とインタープリタ/プリコンパイルという2つの特徴を紹介しましたが、もう1つ、作業効率に大きく影響する機能があります。それは豊富に提供されている関数ライブラリとデータを可視化する時に役立つグラフィックス機能です。
MATLABの包括的な開発環境は、MATLAB基本機能と分野別の機能やライブラリを纏めたオプションで構成されています。オプションは制御、信号処理、ファイナンス、バイオ、C/HDLコード生成/検証など多岐にわたるので、必要な機能を持ったオプションを必要に応じて購入して利用します。MATLABだけでも1,000以上の関数が利用できるのですが、オプションを追加するとさらに使用可能な関数は増加します。例えばMATLABの基本機能の中に離散フーリエ変換を行う関数「fft」が提供されていますが、オプションの「Signal Processing Toolbox」を使うとピリオドグラム「periodogram」やスペクトログラム「spectrogram」などプラスアルファの機能を備えた関数が提供されており、これらの機能を使いたい人にとってはプログラミングの省力化ができるのです。
関数fftを使ってピリオドグラムの計算を行う例とSignal Processing Toolboxの関数を使った例を比較してみましょう。
信号生成
Fs = 1000; % サンプリング周波数
t = (0:1023)/Fs; % 時間軸ベクトル
A = [1 2]; % Sin波の振幅(行ベクトル)
f = [150;140]; % Sin波周波数 (列ベクトル)
xn = A*sin(2*pi*f*t) + 0.1*randn(size(t)); % 2トーンのSin波とノイズを加算
MATLAB基本機能を使ったピリオドグラムの計算
win = hamming(1024)'; % ハミングウィンドウを生成して転地
xnwin = xn.*win; % 信号にハミングウィンドウを適用
Pwin = win*win'; % ピリオドグラム計算のための係数
Xn = fft(xnwin,1024); % フーリエ変換
Pxx = 2*(abs(Xn).^2)/(Pwin)/Fs; % ピリオドグラムの計算
f0 = (0:length(Xn)-1)/length(Xn)*Fs; % 周波数軸の計算
plot(f0, 10*log10(Pxx), ’r'),grid on % XYプロット
xlim([0 Fs/2]) % X軸の表示範囲を0~ナイキスト周波数に設定
ylim([-70 10]) % Y軸の表示範囲設定
Signal Processing Toolbox機能を使ったピリオドグラムの計算
figure
periodogram(xn,hamming(1024),'onesided',1024,Fs)
ylim([-70 10]) % Y軸の表示範囲設定
ただでさえ簡潔にプログラミングできるMATLABのプログラムが、オプションで提供される関数を使うことでさらに簡潔に記述できました。プログラムの記述量が少ないということは、デバッグの手間も比例して少なくなります。また、バグを混入する可能性は、プログラム記述量に比例して大きくなります。バグを混入させないためには何もプログラムしなければ良いのですが、より良い機能や目的とする結果を実現するためにはそうもいきません。
上記の例にもあるように、演算結果を確認・把握するには可視化をすることが必要不可欠です。数値配列を見て現象を把握できる人はなかなかいないと思いますので、人間はデータを図式化して表示することで現象を把握しようとします。他のグラフィックス表示の例を見てみましょう。
以下はMathWorksのロゴにもなっている、L型の膜の固有関数を表示する関数を使った例です。
>> M = membrane(1, 100);
計算されたデータは201x201の行列データとなっていますので、これを3次元メッシュを表示する関数に代入してみます。
>> mesh(M)
著者紹介
松本 充史(まつもと あつし)
MathWorks Japan
アプリケーションエンジニアリング部
シニアアプリケーションエンジニア
Mathworks JapanではMATLABの中でも特に信号処理やコード生成に関する機能を担当している