第7章 MATLAB のプログラミングⅡ
7.1 実験目的
前章では Command Window から直ちに実行できる Matlab コマンドや複数のコマンドを記述した m-ファイルの作成を述べた。本章では、Script M-ファイルだけでなく、FunctionM-ファイルの作成方法や、言語構成、またはプログラミングの動作原理などの更なる基本的事項について習得することを目的としている。

7.2 実験内容
M-ファイル種類は①Script M-ファイル、②Function M-ファイルの 2 種類の形式に分けられる。これらのファイルの具体的な作成方法は後述するが、まず両者の特徴を次表にまとめる。
Script M-ファイル

Function M-ファイル

実行したいコマンド・関数を順に記 function で始まる宣言文が必要で述するのみ。

ある。

入力引数および出力引数がない。
記述と実行の特徴

入力引数のみ、または入出力両方の引数の定義が必要である。

一連のコマンド・関数をまとめて処 定義したい関数を作成し後に実行理することができる。

することができる。

コメント： 実際のプログラミングでは、一般的にスクリプトM-ファイ
ルでプログラムを最初に作成し、アルゴリズムの検証等を済ませたらそのプログラムをファンクションM-ファイルに移行させることが多い。
ファイル内の変数は、全てグローバ ファイル内の変数は、ローカル変数
Workspaceの使用有効性

ル変数として Workspace に一括して として Workspace に管理され、各独管理され、同一の変数名が使用され 立した関数中で同一の変数名が使た場合にはその内容も変化してし用されている場合でも、それらの内まう。

容は互いに干渉されない。

何度も繰り返して試行させるよう

MATLAB 言語を拡張するのに極めてな一連の処理の記述に向いている。 有効である。

7−1

7.2.1 スクリプト M-ファイルのプログラミングスクリプト M-ファイル自体の作り方は前述したように非常に簡単である。つまり、実行したいコマンド、関数を順に並べて一つのスクリプト M-ファイルの中に記述することである。しかし実際に、どの関数をどのようにして使用したら良いのかというのは Matlab の関数を事前にある程度熟知しておく必要がある。本節では、まず、script M-ファイルによく使われているコマンド・関数の一覧を示し、特にプログラミング言語でよく使用される制御文について詳しく説明する。その後、応用例題を通して Matlab プログラムの動作原理について説明する。
1. M-ファイルの常用コマンド・関数
M-ファイルは一連のコマンド・関数で構成される。以下良く用いられるコマンド・関数を種類別に纏めたものを次表に示す。
コマンド・関数の種類よく使用されるコマンド・関数の名とその説明
clear - ワークスペース変数を削除する。

一般的なコマンドload- ファイルから保存された変数を読み込む。

save- ワークスペース変数をファイルに保存する。

数値演算子は例題 4̲7 を参照すること
比較演算子:

数値演算子、比較演算子、論理演算子

eq - 等しい==

ne - 等しくない~=

lt - より小さい<

gt - より大きい>le - より小さいまたは等しい<=

ge - より大きいまたは等しい>=

論理演算子:

制御コマンド基本行列と行列操作
初等数学関数and - 要素ごとの論理積&or - 要素ごとの論理和|

not - 否定~制御文は例題 5̲2 を参照すること
第 5 章を参照すること。
三角関数：
sin - 正弦値

7−2sinh - 双曲線正弦値

asin - 逆正弦値

asinh - 逆双曲線正弦値

指数関数：
exp - 指数関数

log - 自然対数

log10 - 常用対数(底が 10) sqrt - 行列の平方根
複素数：
abs - 絶対値

angle - 位相角

imag - 複素数の虚部

real - 複素数の実部

丸めと剰余：
round - 最も近い整数への丸め
rem - 除算の剰余 sign - 符号関数
特殊数学関数

gamma - ガンマ関数
行列解析：
norm - 行列やベクトルのノルム行列関数(線形数値代数)

rank - 行列のランク

det - 行列式 trace - 対角要素の和線形方程式：
inv - 逆行列

lu - LU 分解

qr - 直交三角分解

固有値と特異値：
eig - 固有値と固有ベクトル svd - 特異値分解
基本演算：
max - 配列の最大要素

min - 配列の最小要素

mean - 配列の平均値 median - 配列の中央値
std- 標準偏差var- 分散sort- 要素の昇順に並べ替え hist - ヒストグラム

sum - 配列要素の和 prod - 配列要素の積
データ解析とフーリエ変換に用いられる関数

相関：
corrcoef - 相関係数

cov - 共分散行列

フィルタリングとコンボリューション（畳み込み演算）：
filter- 1 次元デジタルフィルタリング

conv -

コンボリューションと多項式の乗算

deconv - デコンボリューションと多項式の除算
detrend - 線形トレンド除去
フーリエ変換：fft - 1 次元高速フーリエ変換
ifft - 1 次元逆高速フーリエ変換

7−3

オーディオハードウェアデバイス：
sound - ベクトルを音声として再生オーディオサポート関数

soundsc - 音声としてのオートスケーリングと再生
オーディオファイルのインポート/エクスポート：
wavread - (".wav")サウンドファイルの読み込み
wavwrite - (".wav")サウンドファイルの書き出し
データ補間：

補間と多項式interp1 - 1 次元補間(table lookup)
多項式：roots - 多項式の根

polyval - 多項式の計算

数値積分(求積法) ：quad - 低次の数値積分関数を引数とする関数と ODE ソルバ

quadl - 高次の数値積分

常微分方程式の解：
ode45 - ノンスティッフな微分方程式の中次の解法
1 次元偏微分方程式ソルバ例：
pdepe - 双曲線-楕円 PDEs の初期境界値問題の解法

グラフィックス

第 6 章を参照すること。
文字列、数値の変換：

キャラクタと文字列

num2str - 数値を文字列に変換
str2num - 文字行列を数値に変換
ファイルのオープンとクローズ：
fopen - オープン fclose - クローズ

ファイルの入出力

バイナリファイルの入出力例：
fread- ファイルからバイナリデータを読み込む。

fwrite - バイナリデータをファイルに書き出す。
現在の日付と時間：now - 日付番号での現在の日付と時間
date - 日付文字列での現在の日付
時間と日付

時間関数：
tic - ストップウオッチタイマの開始
toc - ストップウオッチタイマの停止
pause - 秒単位での待機

これらのコマンドや関数に関する詳細は、 >> helpwin で参照してください。

7−4

2. 制御文
一般的にプログラミング作業においては、同じような計算パターンが重複しないように、反復や分岐制御文などを用いたりしてプログラミングの効率化を図る場合が多い。MATLAB
でも反復、分岐、条件と言った制御文が用意されている。また MATLAB の制御文の文法はC 言語等とほぼ同じであるので容易に理解できるであろう。しかし、MATLAB はインタープリタ言語であるため、普通コンパイラ言語と違い、プログラム中に反復文を使い過ぎてしまうと演算速度がかなり落ちてしまう。このような理由から、MATLAB では制御文の使用を極力控え、出来るだけ MATLAB に備えられている行列演算の特性をうまく利用してプログラミングを行うことが望ましい。
例題 7̲1：典型的な制御文を次表のように示す。また、制御文ごとに作成したプログラム例題を実行してみよう。
プログラムの例題：
制御文の書式

次の制御文を用いて整数 1〜100 までの奇数和と偶数和、総和をそれぞれ求めよ。

1. 指定回数の反復文 :for … end
for … for …… end … end%ファイル名：forloop.m
clear all
odd=0;even=0;
for i=1:2:100

書式例：for 繰返し回数
実行文
End
2. 不定回数の反復文:

odd=odd+i; even=even+(i+1);
end
total=odd+even;%ファイル名：whileloop.m

while … end

clear allwhile … while …… end … end

odd=0;even=0;i=0;j=0;I=100;
while i<=I;

書式例：

odd=odd+j; j=i+1;

while 繰返し終了条件
実行文
End
3. 条件分岐文:

even=even+i; i=i+2;
end
total=odd+even;%ファイル名：forif.m

if … end

clear allif … else … end

odd=0;even=0;

7−5

if…elseif…else…end

for i=1:100;
if rem(i,2) ~=0

書式例：

odd=odd+i;

if 判別条件１

else

実行文１

even=even+i;

elseif 判別条件２

end

実行文２
else

end

判別条件３

total=odd+even;

実行文３
End
4. 分岐文:switch … case …… end
switch … case … othercase … end%ファイル名：switchcase.mclear all
odd=0;even=0;
for i=1:100;

書式例：

switch rem(i,2)

switch 分岐点（数値、数式）
case

case 1分岐路１odd=odd+i;

実行文１
case

case 0分岐路２even=even+i;

実行文２

end

othercase

end

実行文３

total=odd+even;end

例題7̲2：第6章にある例題6̲5（p.6-8）の計算プログラムに対して、制御文を利用したものに書き直してみよう。
プログラム Samp7̲2.m% The generalized Gaussian distributions% filename: Samp7̲2.m% Jianting Cao, Feb. 11, 2003
% Workspace 変数をすべて削除
clear all% 係数 lambda, x, alpha, p の定義

7−6

lambda = 1/sqrt(2); x = -5:0.1:5; alpha = [1 2 3];p=[];% ループ計算for i=1:3;p(:,i)=alpha(i)*lambda/(2*gamma(1/alpha(i)))*exp(-abs(lambda*x).^alpha(i));
end;% プロットと修飾
plot(x,p(:,1),'k*-',x, p(:,2),'ro-',x, p(:,3),'b.-');
title('The generalized Gaussian distributions ','FontSize',14);xlabel('x','FontSize',16);ylabel('p(x)','FontSize',16);
legend('super-Gaussian', 'Gaussian', 'sub-Gaussian');axis([-5 5 0 0.5]);grid;

7.2.2 ファクション M-ファイルのプログラミング
前述したように、MATLAB ではファンクション M-ファイルを使うことで任意の関数の作成ができ、MATLAB 言語そのものさえも拡張することができる。具体的に Function M-ファイルの記述は以下のようになる。
1) 第一行目の Function 定義部の一般書式はfunction [出力引数] = 関数名(入力引数)であるが、出力の引数がない場合の形式は、function

関数名(入力引数)となる。この定義部を実行すると、入力引数が Local Workspace へ引き渡される。
2) 第二行目以降のコメント部は定義した関数に関する情報(目的、入力と出力の引数の使用法など)を記述しておけば、後に help 関数名でその使用法をチェックすることができる。なお、コメント文は記号<%>で始まる。
3) Function 本体：
普通 Local Workspace で計算を行い、最後に関数の計算した値をあらかじめ出力引数に割り当ててから Workspace に戻り、後の操作に用いられるようにする。
例題7̲3：平均値と分散を一度に計算する関数を作成してみよう。
プログラム名：my̲mv.m

Function [mean,var]=my̲mv(x)% ベクトルの平均値,分散を計算する関数

7−7

%x- 行，または列ベクトル% mean - 平均値 （スカラ）% var -

分散（スカラ）% 埼工大＿電子工学科＿専門実験＿第 5 章; Feb. 15, 2003; by 曹 建庭
[m,n] = size(x);if (~((m==1) | (n==1)) | (m==1 & n==1)) % ベクトルの判別
error('Input must be a vector!') % エラーメッセージの表示
end
if m>n% 列ベクトルである場合の計算

mean = sum(x)/m;
var = sum(x.^2)/m;
elseif m<=n

% 行ベクトル、またはスカラである場合の計算

mean = sum(x)/n;var = sum(x.^2)/n;end
上記で作成した関数をファイル my̲mv.m に保存する。（一般的にファイルの名前はfunction の名前(my̲mv)と同じものをつけることが多い。）
第 1 行目の Function 定義部の記述から判るように、my̲mv 関数は 1 入力・2 出力の関数である。すなわち、1 個のベクトルを入力引数として与えれば、関数内で計算された平均値と分散値がそれぞれ出力引数から得られる。
上述したように、第 2 行目から始まるのコメント部は関数(my̲mv)の目的・使用法などが記述されており、Command Window で help を実行すると次のように表示される。このようにコメントを残しておけば、その目的・使用法を後に忘れたとしても役に立つ。
>> help my̲mv
ベクトルの平均値,分散を計算する関数
x- 行，または列ベクトル

mean - 平均値 （スカラ）var -分散（スカラ）

埼工大＿電子工学科＿専門実験＿第 5 章; Feb. 15, 2003; by 曹 建庭

上記で実際に作成した関数 my̲mv をコマンドラインから実行してみると、

7−8

>> a=[1 2];>> [u v]=my̲mv(a)u =1.5000v =2.5000のようになり、関数 my̲mv は正しく動作していることが判る。また、列ベクトル a=[12]ʼ

を入力すると、下記のような結果が得られる。しかし、行列 a=[1 2;1 2]; を入力して実行するとこの関数は正しく機能せず、次のエラーを返して動作が中断される。

>> a=[1 2;1 2];[u v]=my̲mv(a)??? エラー: ==> my̲mv
Input must be a vector!

また、この例題を実行することで以下のようなことが分かる：
1) Command Window で定義した変数名(a u v)は必ずしも第 1 行目の Function 定義部で定義された引数名(x, mean, var)と同じである必要がない。
2) 例題 5̲4 を実行した後に Workspace で使われている変数を確認すると、変数(a u v)のみが表示されるが、ファンクション M-ファイル my̲mv.m に記述されている、関数
my̲mv で使用されたローカル変数(x, m, n, mean, var)であるので表示されない。
例題7̲4：例題7̲2のプログラムを関数の形で作成してみよう。
プログラム名： my̲pdf.mfunction p=my̲pdf(x,alpha)% ベクトルの平均値,分散を計算する関数%%

x- 確率変数のベクトル，例えば，x=-5:0.1:5% alpha - 分布を制御する変数ベクトルまたはスカラで与えられる正の値である。
% p -確率密度関数の値、サイズは x と同じベクトル%% 埼工大＿電子工学科＿専門実験＿第 5 章; Feb. 15, 2003; by 曹 建庭

7−9

% 入力引数の個数の判別
if nargin <= 1, error('Not enough input arguments.');end% x, alpha 各変数のサイズの判断[m n] = size(x);[u v]=size(alpha);if (~((m == 1) | (n == 1)) | (m == 1 & n == 1))
error('Input must be a vector!')% ベクトルの判別% エラーメッセージの表示

elseif (u>1 & v>1) | (u==0 | v==0)% ベクトルとスカラの判別

error('Input must be a vector or a scale !')% エラーメッセージの表示

end% alpha が正の値であることを判別
if any(le(alpha,zeros(u,v)))==1% alpha のすべての要素 <= zeros(u,v)

error('Input must be a positive value!') % エラーメッセージの表示
end% 変数 lambda, p の定義
lambda = 1/sqrt(2);p=[];% loop の計算とプロットfor i=1:max([u v])
p(i,:)=alpha(i)*lambda/(2*gamma(1/alpha(i)))*exp(-abs(lambda*x).^alpha(i));
plot(x,p(i,:));hold on;end% プロットの修飾
title('The generalized Gaussian distributions ','FontSize',14);ylabel('p(x)','FontSize',16);xlabel('x','FontSize',16);axis([min(x) max(x) 0 0.5]);grid;
hold off
実行例

7−10

>> x=-5:0.1:5;>> alpha=0.1:0.2:4;>> p=my̲pdf(x,alpha);

7.3 実験課題
1. 反復文（for … end）及び関数 sum をそれぞれ利用し、次の課題に対して Script M-ファイル形式のプログラム、計算結果と演算時間を示せ。なお、プログラムの演算時間を計るために、ストップウオッチタイマ関数（tic, toc）を利用せよ。
(1) 整数 1〜10000 までの和。
(2) 整数 1〜10000 までの自乗の和。
2. ある数値列の平均値及び分散をそれぞれ計算するFunction M-ファイル形式のプログラ
ムを作成せよ。また、正規分布の乱数関数randn(1,n)で生成したデータに対して作成したプログラムを利用して①n=10、②n=200、③n=10000の場合、乱数の平均値及び分散の値を考察せよ。
3. 一元二次方程式 ax 2 + bx + c = 0 の解を求めるFunction M-ファイル形式のプログ
ラムを作成せよ。また、種々の適当な係数を与えて作成した関数プログラムを検証せよ。

7−11