Scilab 勉強会(第 3 回)
高橋 一馬,十文字 俊裕,柏倉 守
平成
17 年 11 月 15 日
関数
ファイルはエディタを用いて作成する.Scilab にはエディタ SciPad が附属している.SciPad では なく他のエディタを利用してもよい.作成した関数は Scilab にロードすることで(関数に誤りがなけ れば) Scilab 標準関数と同じように使用することができる.
1. 関数の構造
関数の構造は以下の形式に従わなければならない. function [y1,...,yn]=foo(x1,...,xm) . . . endfunction ここで foo は関数名で,x1,...xm は関数の 個の入力引数, y1,...yn は関数からの 個の出 力引数である.縦のドットは関数で実行されるコマンドのリストを表している.出力引数がひとつの 場合は function y=foo(x1,...,xm) . . . endfunction と書ける.2. SciPad
メインウィンドウの Editor を選択するか,コマンドラインで-->scipad と入力すると Scilab 附属エディタ SciPad が起動する. つぎの を計算する関数を入力してみる. function [x]=fact(k) k=int(k) if k<1 then k=1,end x=1; for j=1:k,x=x*j;end endfunction SciPad のカーソル移動はコマンドラインの場合と同じである. プログラムを間違いなく入力できたらファイルにセーブする.メニューバーの File の Save を選択 するか Ctrl-s とするとファイルセーブの画面が現われる.ファイルの新規作成の場合,関数名と 同じファイル名がデフォルトとなる.ファイル名は関数名と同じである必要はないが,同じであるほ うが間違いが少なくなる.
ファイルの拡張子 sci が自動的に設定されている.Scilab 関数の拡張子は sci でなければなら ない.したがって,SciPad 以外のエディタを利用する場合,拡張子を sci にすることを忘れてはな らない. SciPad は通常必要となるファイル操作機能を提供している.
3. 関数のロード
作成した関数を Scilab で利用するには関数を Scilab にロードしなければならない. 関数が fact.sci と言う名前のファイルにあるとする.この関数をロードするには次のようにすれ ばよい.SciPad での関数のロードはメニューバーの Execute の Load into Scilab を指定するか,Ctrl-l とする.ファイルを変更しその変更を Scilab に反映するには,ファイルをセーブし再度関数をロー ドしなければならない. (同じ関数名を持つ関数をロードすると最新の関数が有効となる.)
関数はコマンドラインからもロードできる.コマンドラインからのロードは,主に,SciPad 以外のエ ディタを利用しているときに使用する.コマンドラインからのロードの書式は
exec('ファイルへのパス/ファイル名.sci',-1) あるいは getf('ファイルへのパス/ファイル名.sci') である.ここでファイルが Scilab を起動したディレクトリにある場合や適切に設定された Scilab の パス変数に含まれるディレクトリにある場合は, ファイルへのパス/ は省略できる. 以下に関数のロード例を示す.ここで exists('名前') はその名前の変数や関数が存在すれば 1,存在しなければ 0 を返す関数である. --> exists('fact') ans = 0. --> exec('../macros/fact.sci',-1); --> exists('fact') ans = 1. --> x=fact(5) x = 120.
上の Scilab セッションのはじめのコマンド exists で fact がないということがわかる.相対パ ス ../macros/ にあるファイル fact.sci が関数が exec によりロードされる.つぎに,exists に より fact がロードされていることを確認し,関数 fact を実行している.
4. グローバル変数とローカル変数
関数では関数を呼び出す環境と同じ変数名を持つ変数を定義することができる.同じ変数名であ っても,関数内の変数と関数を呼び出す環境の変数は異なる実体を持つ.そのため,関数内の変 数を変更しても関数を呼び出す環境の変数は変化しない.
関数内で入力パラメータにない変数が定義されておらず,呼び出した環境で同じ名前をもつ変数 がある場合の値をとる.(resume を使用しない場合)関数内での変数の変更は呼び出した環境の 変数を変更しないという意味でローカルを保つ.この特徴から,関数は入力や出力パラメータなし でも使用できる.例を用いてこの性質を説明する. function [y1,y2]=f(x1,x2) y1=x1+x2 y2=x1-x2 endfunction この関数に入力引数,出力引数を与えると以下のようになる. -->[y1,y2]=f(1,1) y2 = 0. y1 = 2. 関数の出力引数は 2 個あるがそれを指定しない場合,はじめの引数のみが出力される. -->f(1,1) ans = 2. 入力引数をひとつだけ指定,呼出し環境で x2 が定義されていない場合つぎのようにエラーとな る. -->f(1) y1=x1+x2; !--error 4 undefined variable : x2 at line 2 of function f 呼出し環境で x2 を定義すると以下のように実行できる. -->x2=1; -->[y1,y2]=f(1) y2 = 0. y1 = 2.
-->f(1) ans =
1.プログラミング 1.1 比較演算子と論理演算子 Scilab では比較演算子、論理演算子として表1,2で示した記号が使われます。 表1: 比較演算子 == 等しい < より小さい > より大きい <= 以上 >= 以下 <> or ‾= 等しくない 表 2: 論理演算子 & 論理積 │ 論理和 ‾ 論理否定 論理式が成立するとき値を真(True)、成立しないとき偽(False)となり、このように真偽の 2 値 をとる型を Boolean 型といいます。 Scilab では真の値は %t、 偽の値は %f となります。 次 のように、画面にはそれぞれ T、F と表示されます。 -->1 < 2 ans = T -->1 > 2 ans = F コマンドへの入力は%t(あるいは%T)と%f (あるいは%F)を用います。 -->a=%t a =
T また、数値としては%t は 1 と%f は0 になります。 -->2*%t ans = 2. -->3*%f ans = 0. 論理演算子 を用いるとより複雑な 論理式を書くことができます。 & は論理積であり a&b にお いて a と b が T のときのみ T でそれ以外は F になります。 │は論理和で a│ b において a と b のいずれかが T とき T で、両方 F のとき F になります。 ‾ は論理否定で、‾a において a が T なら F, a が F なら T になります。 -->(1 < 2) & (3 > 4) ans = F -->(1 < 2) | (3 > 4) ans = T -->~(1==1) ans = F 比較演算子は論理演算子より優先順位が高いので (1 < 2) & (3 > 4) は 1 < 2 & 3 > 4 と等価 です。また、^,*,/,¥,+,-といった算術演算子 は比較演算子、論理演算子より優先順位が 高くなります。 論理演算子の優先順位は高い順に論理否定、論理積、論理和となっています。
-->1|1&0 ans = T (1&0 が先に評価され 0, つぎに 1│0 が評価され 0 となる) -->~ 1 & 0 ans = F -->~ (1 & 0) ans = T 表3 に主な演算子の優先順序を示します。 表 3: 優先順位 ^ 高 *,/,¥ +,- 比較演算子 ‾ & │ = 低
1.2 ループ
Scilab では for ループと while ループが利用できます。 1.2.1 for ループ for ループの書式は以下の通りです。 for 制御変数 = 制御変数に値を代入するベクトル コマンド end for ループは、ベクトルのはじめ要素を制御変数に代入し、コマンドを実行します。次に、ベク トルの 2 番目の要素を制御変数に代入し、コマンドを実行します。この操作をベクトルの値の 最後の要素まで繰り返します。 for ループの例 --> x=1;for k=1:4,x=x*k,end x = 1. x = 2. x = 6. x = 24. -->x=1;for k=[-1 3 0],x=x+k,end x = 0. x = 3. x =
3. 1.2.2 while ループ while ループは以下の書式を持ち条件式を満たす限りコマンドを繰り返し実行します。 while 条件式 コマンド end while ループの例 --> x=1; while x<14,x=2*x,end x = 2. x = 4. x = 8. x = 16. 1.2.3 break と continue
for ループや while ループからは break コマンドで抜け出せます。 break の例
-->x=1; while x<14,x=2*x,if x>3 then break,end; end x = 2. x = 4. 複数のループがあるとき break は一番外側のループから抜け、次のループに制御を移します。 continue は continue 以降のループ内のコマンドをスキップしそのループの始めに制御を戻し
ます。 次の例ではループのなかの条件式が成立したとき、k の表示を スキップしループの始め に実行が移動しています。
-->for k=1:5;if k>2&k<=4 then disp('hello'),continue,end,k=x,end k = 1. k = 2. hello hello k = 5. 1.3 条件文
Scilab には二つの形式の条件文、if-then-else と select-case が存在します。
1.2.1 if-then-else 文 if-then-else には 3 つの書式があります。 次の書式の場合、式を評価し、もし真なら then と end の間のコマンドを実行します。 if 式 then コマンド end コマンドは複数行でも可能です。
次の書式であれば、式が真であれば then と else の間のコマンドを実行し、偽なら else と end の間のコマンドを実行します。
if 式 then コマンド else
end 次の書式は elseif 以外は上の書式と同じです。 elseif の後にある式を評価し、もし真なら つ ぎの elseif(または else)までのコマンドを実行します。 if 式 then コマンド elseif 式 then コマンド elseif 式 then コマンド : else コマンド end if 文の例 --> x=1; --> if x>0 then,y=-x,else,y=x,end y = - 1. --> x=-1; --> if x>0 then,y=-x,else,y=x,end y = - 1. 1.3.2 select-case 文 select-case 文には次の書式があります。 select 式 case 値 コマンド
コマンド else コマンド end 式を case の後ろにある値と比較し、等しくなる最初の場合の命令を実行します。 どの条件に も当てはまらない場合は else 以下の命令を実行します。 次の例は変数 n の値を用いて処理の場合分けを行っています。 -->x=7;
-->select x,case 1,y=x+1,case 3,y=x+3,else y=x,end y =
7.
1.4 deff による関数定義
Scilab では deff を用いて関数を定義できます。deff の書式は次の通りです。 deff('[出力変数の並び]=関数名(入力変数の並び)','コマンド') 複数行コマンドを書きたい場合は deff('[出力変数の並び]=関数名(入力変数の並び)',['コマンド';'コマンド']) のように,複数のコマンド'(文字列)からなる行列(配列)を使用する. 例えばy=x+10はつぎのように定義できる. -->deff('y=myfunc(x)','y=x+10') -->myfunc(5) ans = 15 また、変数やコマンドが複数ある場合は -->deff('[x,y]=f(z)',['x=z^2','y=z^3']) -->[x,y]=f(3)
y =
27. x =
9.
1
多項式あれこれ
1.1
多項式、多項式行列
Scilab では、多項式は簡単に作成し操作することができます。多項式の操作は、本質的 に定数行列の操作と同様です。Scilab では、基関数として poly が用意されています。 基関数poly は、多項式の係数または根を指定するために使用されます。基関数
poly の使い方
poly(多項式の根からなるベクトル, '記号変数') poly(多項式の係数からなるベクトル, '記号変数', 'coeff') *poly の第三引数はフラグオプションで、根または係数を指定するときに使います。 指定しないと根を指定したことになります。 フラグオプション roots:根 coeff、c:係数 -->p=poly([1 2],'s') p = 2 2 - 3s + s -->q=poly([1 2],'s','c') q = 1 + 2s 多項式は通常の演算と同様に、四則演算が可能です。しかし、同じ変数で表現される多項 式の間でのみ可能です。 -->(p+q)/(q*p) ans = 2 3 - s + s --- 2 3 2 + s - 5s + 2spoly の最初の係数が正方行列で、かつ、根のオプションが有効である場合、結果は行列の 多項式の係数になります。 -->poly([1 2;3 4],'s') ans = 2 - 2 - 5s + s 実数や複素数の定数のように多項式は、行列の要素として使用することができます。これ はシステム理論に関してScilab の非常に便利な機能の一つです。 -->s=poly(0,'s') s = s -->a=[1/s 1/(1+s);1/(1+s) 1/s^2] a = ! 1 1 ! ! - --- ! ! s 1 + s ! ! ! ! 1 1 ! ! --- - ! ! 2 ! ! 1 + s s ! 上の例から行列を多項式と分数から構築することが可能であることがわかります。
1.2
多項式に関係する関数
1.2.1 分母分子の取り出し 多項式の分母分子の取り出しはdenom、numer で取り出すことができます。-->R=q/p R = 1 + 2s --- 2 2 - 3s + s -->denom(R) ans = 2 2 - 3s + s -->numer(R) ans = 1 + 2s 1.2.2 多項式の微分 derivat は多項式の導関数を返します。 -->p p = 2 2 - 3s + s -->derivat(p) ans = - 3 + 2s 1.2.3 多項式の評価 horner は、多項式に数値あるいは多項式代入した結果を求めます。
-->horner(p,3) ans = 2. -->x=poly(0,'x'); -->horner(p,x-1) ans = 2 6 - 5x + x 1.2.4 その他の多項式の関数