第 9 章 多項式について
13.3 do 文による反復処理
do文は反復処理で利用します.
このdo文には三種類の変種があり,各々は終了条件が異なります.
¶ ³
1. forh変数i:h初期値isteph増分i thruh境界値idoh本体i
2. forh変数i:h初期値isteph増分i whileh終了条件idoh本体i 3. forh変数i:h初期値isteph増分i
unlessh終了条件idoh本体i
(stepは終了条件や境界の後に置いても構いません.)
µ ´
do文の実行は最初に初期値をh変数iに割当てます.このh変数iの事を制御変数と呼びます.こ の制御変数は局所的なもので,do文の中だけで効力を持ちます.
do文は初期値を制御変数に割当てると,以下の手順で反復処理を行います.
1. do文が終了するのは以下の場合です.
(a) 制御変数がthruによって指定された境界値を越えた場合.
(b) unless条件がtrueになった場合.
(c) while条件がfalseになった場合.
2. 本体が評価されます.
3. 増分が制御変数に加えられます.
h終了条件iが満される迄,(1)から(3)までの処理が繰返し実行されます. h終了条件iは幾つも 与えても良く,その場合,それらの内のどれか一つが条件を満した時点でdo文が終了します.
do文のh初期値i,h増分i,h境界値iは,終了条件さえthru,unless,whileで判別出来るのであれ ば,どの様な式でも構いません.更に,h増分iが1の場合は,step 1を省略しても構いません.又,h本 体iにも特に制約はありません.
その為,以下の例は全て同じ結果となります.
1. for i:1 step 2 thru 10 do
print("sin(%pi/6*",i,")=",float(sin(i*%pi/6)));
2. for i:1 step 2 while i<10 do
print("sin(%pi/6*",i,")=",float(sin(i*%pi/6)));
3. for i:1 step 2 unless i>=10 do
print("sin(%pi/6*",i,")=",float(sin(i*%pi/6)));
h境界値i,h増分iとh終了条件iはdo文の各時点で評価される事に注意して下さい.これらの処 理を行うだけで膨大な計算を引き起すものや,結果がh本体iの実行中に変化しないものならば,do 文に対してより効果的な値を制御変数に設定して,do文で用いるのがより効率的です.
通常のdo文によって返される値はアトムのdoneです.函数returnを用いると, 本体の中でdo から早目に抜けて必要な値を与える事に使えます. blockにあるdo文中のreturnはdo文を出るだ けで,block全体から出る訳ではありません.同様にgo函数もblock中のdo文から抜ける為に使っ てはなりません.
13.3.1 do 文の追加形式
制御変数に対して何時も加える量の代りに,各々の反復で別の手法に代えたい事もあるかもしれ ません.この場合,next式をstepの代りに使えます. これで制御変数にはループを通して各時点で 式を評価した値が設定されます.
(c1) for count:2 next 3*count thru 20 do display(count)$
count = 2 count = 6 count = 18
forh変数i:h値i · · · do · · ·構文の代りに, forh変数if romh値i · · · do · · ·が使える. from h値iをstepやnextの値や終了条件の後に置く事も出来ます. fromh値iが省略されると1が初 期値として用いられます.
時には反復処理の実行で,制御変数が実際に使われていないものに興味を持つかもしれません.そ こで,終了条件のみに情報の初期化と更新を, 次の貧弱な初期推定値を用いて5の平方根を計算す る次の例の様に省略する事も出来ます.
(c1) x:1000
(c2) thru 10 while x#0.0 do x:.5*(x+5.0/x)$
(c3) x;
(d3) 2.236068
終了条件でさえもすっかり省略し,不定値のまま本体を評価し続けるdo本体を与えても構いま せん.この場合,return函数をdo文の実行を中断する為に使う必要があります.
(c1) newton(f,guess):=
142 第13章 プログラム block([numer,y],
local(df), numer:true,
define(df(x),diff(f(x),x)), do (y:df(guess),
if y=0.0 then error("derivative at:",guess," is zero."), guess:guess-f(guess)/y,
if abs(f(guess))<5.0e-6 then return(guess)))$
(c2) sqr(x):=x^2-5.0$
(c3) newton(sqr,1000);
(d3) 2.236068
returnが実行された時,guessの現行の値がdo文の値として返される事に注意して下さい.block
から抜けるとdo文の値はblockの値として返されます.何故なら, doはblockの中で最後の文だか らです.
do文のもう一方の形式がMaximaで利用出来ます.
¶構文は ³
forh変数iinhリストi[h終了条件判定i] doh本体i
µ ´
リストの成分は任意の式であり,本体の各反復では変数に続けて割り当てられます. オプション のh終了条件判定iはdo文の実行を終了させる為に用いる式で,このh終了条件判定iに当て嵌ま らない場合は,hリストiを消耗した場合,h本体iでreturnが実行された場合に終了します.
尚,hリストiは任意のアトムでない式や列でも構いません.
(%i8) for f in [sin,cos,tan] do print(f(1),"=",float(f(1)));
sin(1) = .8414709848078965 cos(1) = .5403023058681398 tan(1) = 1.557407724654902
(%o8) done