サンプル・プログラム集

(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); とする。
                
サンプル・プログラム集の先頭へ戻る
プログラミングのトップページへ戻る