環境システム科学演習− MATLABを用いた海洋情報処理・作図演習 


目次    授業ホーム    ホーム


1) MATLAB導入

Matlabとは科学研究ソフトウェアの一つで1970年代にアメリカの大学で開発された。 Matrix Laboratoryの略で行列演算を直接行うことが出来る。また、汎用性が高く大気や海洋など地球惑星物理分野をはじめとした多くの分野で利用されている。


1-1 MATLBの起動


目次    授業ホーム    ホーム

上のようなアイコンをダブルクリックすればMATLABを起動することができる。起動すると以下のような画面が現れる。

コマンドウィンドー:   ウィンドー右側。コマンドを直接入力し計算させる事ができる。

ワークスペースウィンドー:ウィンドー左上。現在計算に直接使用できる変数の情報を確認できる。

ディレクトリーウィンドー:ウィンドー左上。現在ワークスペースを置くコンピュータディスク内のディレクトリー情報を確認できる

コマンド履歴ウィンドー:ウィンドー左下。これまで実行した命令文の履歴を確認、選択による再実行ができる。

ワークスペース:現在計算や処理に用いている記憶領域(例えば机の上)

Matlabを用いた作業は、ワークスペースと呼ばれる、作業に直接かかわるいわば机のようなスペースを、ある任意のコンピュータ内のディレクトリーにおき、必要であればそれを移動して他のファイルを読み込んだりしながら行う。


1-2 基本的なコマンドの入力と実行


目次    授業ホーム    ホーム

pwdは現在ワークスペースが何処にあるかを出力します。pwdを実行してみよう。

   実行例

        >> pwd

        ans =

       C:\MATLAB6p5\work

というような出力を得られる。ansは出力先を指定しなかった為に自動的にMATLABが作成した変数である。ansの内容は実際のディレクトリ構成によるため必ずしも上記と同じであるとは限らない。

cdはchange directoryの略で、ワークスペースを他のディレクトリーに移したい時に用いる。cdを使ってディレクトリを移動してみよう。

        >> cd ..
        >> pwd
        ans =
        C:\MATLAB6p5

cd ..は、以前ワークスペースを置いていたディレクトリーの一つ上の階層へディレクトリーを移動する。このため、次の命令pwdの出力ansは、C:\MATLAB6p5\workからC:\MATLAB6p5に変化しているのがわかる。このようなディレクトリーの移動の仕方を相対パスを用いた移動と呼ぶ。相対パスとは、相対的な位置関係(例えばこの場合一つ上の階層を示す..)を使ったコンピュータ内のアドレスである。それに対して絶対パスは、絶対的な位置(アドレスを最初から最後まで書く)を用いたアドレスである。

今、CドライブのResearchディレクトリーにいるとして、その中にあるdata1フォルダの、そのまた中のdataフォルダのアドレスは相対パス、絶対パスを用いて以下のように書ける。

相対パス:.\data1\data (.は現在位置を表す)

絶対パス:C:\Research\data1\data

ls は現在ワークスペースを置くディレクトリーにどんなファイルが存在するかをリストにして示してくれる。実際にコマンドウィンドーにlsと入力して結果を調べてみよう。

        >> ls
        
        . extern license.txt work 
        .. help notebook 
        MATLAB 6.5.lnk ja sys 
        bin java toolbox 
        demos jhelp uninstall 

のようなワークスペースを置いたディレクトリー内のファイルやフォルダ名の一覧が見られるはずである。

whoはワークスペースに存在する変数名の一覧を出力するコマンドである。実行してみよう。

        >> who
        Your variables are:
        ans 

上の例では、ワークスペース上に先ほどpwdで出力された結果ansが一覧表示された。

whosはwhoと類似したコマンドであるが、さらに詳細な変数情報を出力する。

        >> whos
        Name Size Bytes Class
        ans 1x12 24 char array
        Grand total is 12 elements using 24 bytes

whosによって、ansという変数が1行12列のchar array(文字列)であることがわかった。


1-3 MATLABの変数


目次    授業ホーム    ホーム

MATLABには主に以下の4つの変数型が存在する。

実数は全て基本的に倍精度実数で虚数も倍精度で表される。

        >> a=88
        a =
        88

虚数はiおよびjを用いて表す。

        >> b=88+3i
        b =
       88.0000 + 3.0000i

文字列は、'  'で囲った内側に書き定義できる。

        >> c='Tokyo University of Marine Science and Technology'
        c =       
        Tokyo University of Marine Science and Technology

構造体とは、上記の異なる変数を全て含めることが出来る変数型でデータベースのような情報をまとめるのに有用である。

        >> d.name='Nagai Takeyoshi'
        d = 
        name: 'Nagai Takeyoshi'
        
        >> d.age=35
        d = 
        name: 'Nagai Takeyoshi'
        age: 35
        
        >> d.blood='A'
        d = 
        name: 'Nagai Takeyoshi'
        age: 35
        blood: 'A'

以上を実行後whosを実行すると、

        >> whos
        Name Size Bytes Class
        
        a 1x1 8 double array
        b 1x1 16 double array (complex)
        c 1x49 98 char array
        d 1x1 412 struct array
        
        Grand total is 71 elements using 534 bytes

と表示され、aが実数、bが虚数、cが文字列、dが構造体と確認できる。このようにコマンドウィンドーで直接数を定義したりすることが可能であるが、行列やベクトルの内容が大きくなると結果の画面への表示に時間を取られてしまう。そこで、以下のように;をコマンドの最後につければ結果の表示はしない約束になっており、多くの場合コマンド行の最後は;で終了させる。

        >>a=[1:1:20];

 


1-4 ベクトルや行列の定義、四則演算


目次    授業ホーム    ホーム

FORTRANやBASICでは、複数の値をもつ変数を配列と呼んだが、MATLABでは1行や1列のデータとして一つの変数に格納される複数の値をベクトルと呼ぶ。例えば、1から20まで1ずつ増加する行ベクトルを生成してみよう。

        >> e=1:1:20
        
        e =
        Columns 1 through 10 
        
        1 2 3 4 5 6 7 8 9 10
        
        Columns 11 through 20 
        
        11 12 13 14 15 16 17 18 19 20

1:1:20の中央の1は、1ずつ増えることを表す。これを任意の整数に置き換えてベクトルや行列を任意数ずつ増加(減少)するように定義できる。eの定義の仕方について上記と同様なことは以下のようにも出来る。ベクトルや行列の定義の際には[]を用いて値を囲む。

        >> e=[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20]

この行ベクトルを列ベクトルとして定義するには、;で数字を区切る。

        >> f=[1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20]

        f =

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20

あるいは、元の行ベクトルeをTranspose(転置)して列ベクトルに変換することも出来る。

        >> f=e'

結果は上記fの内容と同一となる。

同様に、行列は以下のように定義することが出来る。

        >> g=[92 4 6;1 2 3;8 -3 4]

        g =

        92  4   6
         1   2   3
         8 -3  4

上の例では、3行3列の正方行列がgとして定義されている。ベクトルと同様に'を使って転置行列を求めてみよう。

        >> h=g'

        h =

        92  1   8
        4   2  -3
        6   3   4

となったはずである。hはgの転置行列であり、h=gTと教科書などには書かれる。次に、行列の一部を別の行列として抽出する。hの1から2行、1から2列目を抜き出してmとするには以下のようにする。

        >> m=h(1:2,1:2)

        m =

        92 1
        4 2

ここで、h(1:2,1:2)は行範囲を、h(1:2,1:2)は列範囲を指定する事に注意を要する。もし、hの2列目を取り出しh2という列ベクトルとして定義したい場合は以下のようになる。

        >> h2=h( : , 2)

        m =

        1
        2 
        3

あるいはhの1行目を取り出したい場合は以下になる。

        >> h1=h( 1, : )

        h1 = 91    1  8
        

つまり、行列の全ての列や全ての行を指定するとき、:だけで指定できると言うことである。また、hの2行目から最終行までを取り出すときは以下のようにも書ける。

        >> m2=h(2:end,:)

        m =2

        4   2  -3
        6   3   4
endによって最終行や最終列を指定できることを意味し、膨大な行、列数をもつ行列の行列数を調べることなくendを用いればよい。

これらベクトルや行列が同じ次元を持つとき、MatlabベクトルやMatlab行列同士の四則演算は、"行列"としての計算を行わせる場合と、そうでない場合に分けられる。例えばg×hを行う場合、以下に示す二種類の掛算は同一ではない。

(2)式は、行列AとBの行列の積を計算したものである。

(3)は、行列A,Bの各要素毎の掛算である。MATLABでは、(2)と(3)を以下のように書き分ける。

>>A*B

>>A.*B

それぞれの実行例は以下のとおりである。

        >> a=[1 2 3;4 5 6;7 8 9]
        
        a =
        
        1 2 3
        4 5 6
        7 8 9
        
        >> b=[2 4 6;8 10 12;14 16 18;]
        
        b =
        
        2 4 6
        8 10 12
        14 16 18
        
        >> a*b
        
        ans =
        
        60 72 84
        132 162 192
        204 252 300

        >> a.*b
        
        ans =
        
        2 8 18
        32 50 72
        98 128 162
 

このことは、割算についても同様である。

他の演算関数

足し算 +  
引き算 -  
掛算 *  
割算 /  
割算の余り mod(a,b)  
べき乗 ^  
平方根 sqrt(a)  
最大値 max(a)  
最小値 min(a)  
平均値 mean(a)  

1-5 基本的な作図用の関数


目次    授業ホーム    ホーム

 基本的な作図関数plotは、一つあるいは二つのベクトルで指定した位置をx,y座標として線や点で作図する。例えば以下のようなsin関数を作図してみよう。sinはMATLABでsin()関数を使って計算できる。piはMATLAB内では円周率πとして直接扱うことが出来る。

>> x=[0:0.1:2*pi]; %0から0.1ずつ2πまでのベクトル。
>> y=sin(x); %セミコロンを付けると計算結果を表示しない
>> plot(x,y)

*プログラム中で%を使うとそれ以降の同じ行に書かれたことはコメントとなる。

上記のコマンドを実行すると、下図のようなsin関数を線で描くことが出来たはずだ。

また、以下のようにplot文にオプションでマークや色を指定することも出来る。

>> plot(x,y,'rx')

この例では、赤の×印でデータ点を示せと命令した。以下のような種類の色やマークを指定できる(もっと詳細な設定も可能である)。

 

例えば,緯度と経度データをplotを使って線で結べば地図を書くことが出来る。まず、下記のリンクからデータをダウンロードし自分の好きな場所に保存しよう。

日本地図データ

次にMATLABのワークスペースを先ほどファイルを保存したところに移動し、以下のようなコマンドを打つ。

>> load japanmap
>> whos
Name Size Bytes Class

lat 307798x1 2462384 double array
lon 307798x1 2462384 double array

Grand total is 615596 elements using 4924768 bytes

whosの結果は、ワークスペースにlon, latという変数が存在していることを示す。load コマンドは*.matファイルをワークスペース内に読み込むときに使う。変数lon中身を調べると、

NaN
144.4239
144.4239
144.4239
NaN
144.0003
144.0000
144.0000
144.0000
144.0000
NaN
127.4892
127.4892
NaN
140.5007
140.5006
NaN

というふうに一列のベクトルで経度の値(度)とNaNという文字が入っていることがわかる。NaNはNot A Numberの略で、”数ではないが空の数の値”として実数行列、ベクトルに含めることが出来る。上記で学んだplotは、lon, latで緯度-経度空間に定義される点を線で結ぶが、島から島へ線を結んでしまうと地図として非常に見づらい。そこでこのNaNを島と島の間に入れてやって島と島を切り離すことが出来る。

>> plot(lon,lat,'k')

というコマンドで、黒い実線で日本地図が書けたはずだ。

というコマンドで、黒い実線で日本地図が書けたはずだ。

ワークスペース内の変数を*.matファイルに保存するには、

>> save('testdata','lon','lat')


とすればよい。ここではlonとlatがtestdata.matというファイルに書き込まれた


1-6 MATLAB m-Editorを用いたプログラムの編集


目次    授業ホーム    ホーム

上記演習内容では、命令を直接コマンドウィンドーに打ち込んだが、MATLABは一行ずつしかコマンドを実行できず、大規模な解析を行う際などには、面倒だ。そこで通常は、Matlabに付属しているM-Editorを用いてまとまったプログラムとして名前を付けて保存し、コマンドウィンドーでそれを呼び出して実行する。

Matlabメニューの新規作成からM-Fileを選択するかMatlabの上部にある白いボタンを押すと新しいプログラムファイルを作成することが出来る。MatlabでのこのようなプログラムはM-Fileとよばれ、拡張子は*.mである。

たとえば以下のプログラムを作成し、好きな名前で保存してみよう。次に以下のリンクから水温と水深のデータをダウンロードしプログラムと同じ場所に保存しよう。

水温-水深データ

作成したプログラムをコマンドウィンドーにその名前を書いてEnterを押し呼び出そう。

>>plottemp


1-7 for を用いた繰り返し


目次    授業ホーム    ホーム

MATLABを用いて計算を繰り返すには、凡そ for を用いる。forはBasicでも使われたが、Matlabではforはendと対にして用いる。即ち、

for i=1:1:1000

   命令文

end

この例では、引数iを1から1000まで1ずつ増加させながら、命令文を1000回繰り返す。引数は任意の英字を用いることが出来る。


1-8 if 文を用いた条件文


目次    授業ホーム    ホーム

Matlabで条件を課すには、ifを用いる場合が多い。ifも必ずendと対にしなければならない。即ち、

if 条件

 命令文

end

上記例では、条件を満たすときに命令文を実行する。

次に下記のプログラムを書いて保存し実行してみよう。

a==b aはbと等しい
a~=b aはbと等しくない
a>b aはbより大きい
a<b aはbより小さい
a>=b aはb以上
a<=b aはb以下

複数の条件

if 条件1

    命令1

elseif 条件2

    命令2

elseif 条件3

    命令3

else

    命令4

end

上記例では、順に条件1が満たされれば命令1のみを実行、条件1を満たさず条件2を満たせば命令2を実行、条件1、2を満たさず、条件3を満たせば命令3を実行、条件1、2、3全てを満たさなければ命令4を実行、というふうに条件が課される。