サンプル・プログラム集
(1) for〜end文を用いて,あるものの和;即ち合計を求めるときの
ワン・パターンの記述
s=0; for ii=1:n s=s+________________; end |
上記においては,合計を求める変数名をsと置き,for文の繰り返し回数nはあらかじめ
プログラムの前段で既に与えられているものと仮定している。
ポイントは,
・合計を求める変数名sをfor〜end文のループの外で,0と置く
・ループの中で,s=s+________________ と置く
ただし,・下線部には個々の加算されるべき値(問題により定数,
変数,式の値などとなる)がiiの変化に応じて順に入れ
替わるように配慮する。
・問題によってはfor〜end文が2重,3重になる場合,また
このような多重ループのときs=0;が外側と内側のループ
の間に挟まる場合がある。
(注) もちろん,Matlab関数sum()を用いることもできる。上記のようにfor〜end
文を用いて合計を求める場合には,sは1×1のサイズ;スカラー変数で
あるが,sum()を使用するときは()内にくる変数はベクトルやマトリックス
であり,それを記憶するためのメモリーを多く必要とする。以上の特徴を
考慮して,適宜使い分けすればよい。
(2) 演習問題2に関する好ましくないプログラム例
・好ましくない例 その1
s=0; for ii=1:100 a=10; d=5; s=s+____; end |
このようにプログラムを記述すると,a=10;,d=5;の文(ステートメント)が,ループ
が繰り返される都度実行される。結果として(100-1)=99回無駄な計算をする
ことになる。
対応策→ a=10;,d=5;の文(ステートメント)をfor〜end文の前,具体的にはs=0;
の前にずらす。
s=0;はfor〜end文の直前に置く方がループ内のs=s+____;と
離れないので,すぐに何かの合計を求めていることが分かり易い。
・好ましくない例 その2
a=10; d=5; s=0; for ii=1:100 s=____+s; end |
s=____+s;のようにすると,下線部が長い式の場合,何かの合計を求めて
いるプログラムであることを瞬時に理解することが困難である。
・好ましくない例 その3
a=10; d=5; n=100; s=0; for ii=a:d:a+(n-1)*d s=s+ii; end |
s=s+ii;としたいがためにfor
ii=a:d:a+(n-1)*dとするのは,避けよう。iiは繰り
返しを制御する変数なので,できるだけシンプルに記述したい。このように記述
すると,__に該当する式が複雑で長くなる場合,for文が非常に見づらくなる。
これを避ける記述は,必ずある。例えば,上記に対しては下記のプログラムを
参照のこと。
参考プログラム
a=10; d=5; n=100; s=0; for ii=1:n s=s+a+(ii-1)*d; end |
(3) 演習問題5に関する好ましくないプログラム例
・好ましくない例 その1
x=0; for ii=1:6 jj=1:2; if mean(f(ii,jj),2)>=210 x=ii end end |
・ 先頭にあるx=0;は,無意味。理由は,これより下の文で変数xが式の右辺にきて
いないので。
・ jj=1:2;はループ内にあるので,5回無駄な計算をしていることになる。
・ x=iiのようにして新たな変数xを持ち出す必然性は無い。
参考プログラム1
(関数mean( )を用いた場合)
% case a % case b q=mean(f,2); for ii=1:6 for ii=1:6 if mean(f(ii,:),2)>=210 if q(ii)>=210 または ii ii end end end end |
上記の例のようにfが2次元の配列変数の場合,関数mean(
)は次のように用いる。
mean(f,1) : 列毎の平均値を求める
mean(f,2) : 行毎の平均値を求める
参考プログラム2
for ii=1:6 if (f(ii,1)+f(ii,2))/2>=210 ii end end |
出力の体裁をきちんとするならば,例えばiiの代わりに以下のようにする。
disp(sprintf('Group
name of mean>=210 %d',ii))
(4) 演習問題6に関するコメント
a)行ベクトル,列ベクトル,マトリックスの作成
行ベクトル→
h=[173 171 165 165 173 175 174 167
163 165 160 167 170 180 170]; 空白で区切り
または
h=[173,171,165,165,173,175,174,167,163,165,160,167,170,180,170]; カンマで区切り
または
h=[173 171 165
165 173 ...
175 174 167
163 165 ...
160 167 170
180 170]; 継続行の印 ... を用いた例
即ち,列と列の要素間の区切りは「空白」または「カンマ」
ステートメントの長さが長くなりすぎる場合には,継続行の印 ... を
用いることで複数行に記述できる。
列ベクトル→ h=[173;171;165;165;173;175;174;167;163;165;160;167;170;180;170];
または h=[173
171
165
:
:
170」;
即ち,行と行の区切りは「セミコロン」または改行
マトリックス→ h=[173 171 165
165 173;
175 174 167
163 165;
160 167 170
180 170];
または h=[173,171,165,165,173;
175,174,167,163,165;
160,167,170,180,170];
(注意) 以上については,テキストpp.18,19参照のこと
行ベクトル,列ベクトルは1次元の配列変数として h(ii) と記述できる。
行ベクトルを h(1,ii),列ベクトルを
h(ii,1) と記述する必要はない。
b)好ましくない例
c=0; for ii=1:15 c=c+h(ii)*w(ii)/15; end r=(c-haver*waver)/hsd*wsd; |
・for〜end文の中で15で割り算をしているが,これはループの外で
1回割り算すればよい。即ち,14回無駄な割り算をしている。
・r=(c-haver*waver)/hsd*wsd; と記述すると最後のwsdは分母にこない。
分母にかかるようにするには,r=(c-haver*waver)/(hsd*wsd); とする。
サンプル・プログラム集の先頭へ戻る
プログラミングのトップページへ戻る