方程式の解法
方程式(f(x))の解を求めるということはf(x)=0を意味し、グラフ上では y=f(x)で X 軸との交点を求めることである。ここではエクセルを用いて方程式 の解を求める方法を3つ紹介する。もちろん、前回教わったニュートンラフソン 法も行う。 1. グラフを確認しながら求める方法 エクセルの便利な点は数値を簡単にグラフ化できる点である。中学校の数 学でも教わったように方程式の解はX 軸と交差する点である。これをグラフを確 認しながら決定してみる。次の方程式を解いてみる。 この方程式を解くためにy
x
log
ex
1
のyの値の変化を見てみる。 A1-A18 に X 軸の値として 0.1 から 16 までの値を入れてみる。B1 に “=A1*LN(A1)-1”を入力することでyの値を計算する。B1 を B2 から B18 にコピーする。A1:B18 を選択して、グラフ作成のアイコンを押し、散布0
1
log
x
x
e 図 1図を選択し完了にするとグラフを作成することができる。 できた図1のグラフからわかるようにf(x)の値は2付近で X 軸と交差している ことがわかる。実際の値を見てみるとx=1 の時には負の値であるが、x=2 では正の値になっている。すなわち、1と2の間にX 軸と交差していることが わかる。X の値を1と2の間で変化させて同様に計算しグラフを作成してみ る。 図2 では X 軸との交点は丁度 1.7 と 1.8 の間であることがわかる。 1.763222 -1.3E-06 1.763223 0 1.763224 1.83E-06 これを繰り返すと上の表のように0になるX を求めることができる。この場合に はx=1.763223 が解である。 2. ニュートンラフソン法で求める(表計算) 次にニュートンラフソン法を用いて、セル中で計算させて求めることを考える。 その例が図4である。 図 2
この例ではA 列は計算回数である。A2 には 0 が代入してあり、A3 は”=A2+1 として計算回数を表示するようにしてある。B2 が初期値である。この場合は 1 を 初期値としている。B3 はニュートンラフソン法の公式を代入してある。 上式に基づいて B3 には”=B2-(B2*LN(B2)-1)/(LN(B2)+1)”としてある。 xi=B2 であるので B2 を用いて B3=xi+1を計算している。これを繰り返すため に B4 以降にコピーすると繰り返し計算ができる。C 列には|xi+1-xi|が表 示されている。この結果を見ると5回目で誤差が10-6以下になっている。そのと きの解はグラフを見ながら求めた結果とよく一致している。 1 ln 1 ln ) ( ' ) ( 1 i i i i i i i i x x x x x f x f x x
3. ニュートンラフソン法で求める(VBA) まず、新しいワークシートへ移動します。そして、コマンドボタンを作成し、名前 をニュートンラフソン法に変更しましょう。また,シートの名前を方程式の開放に 変更します. マクロの登録のウィンドウが開くので新規作成を押し,起動したエディタで次の このボタンを押した状態でコマ ンドボタンを作成する。 作成したコマンドボタンの名前をニ ュートンラフソン法に変更する。 シートの名称を方程式の解法と する。
プログラムを入力する。 次に VBA エディターで挿入-ユーザーフォームで新しいユーザーフォームを 作成し、ラベル、テキストボックス、コマンドボタンを利用して条件の入力画面を 作成する。 さらに、このユーザーフォームのオブジェクト名を“非線形方程式”とする。こ のオブジェクト名の変更はエクセルの表中に作成したコマンドボタンで呼び出 すプログラムに“非線形方程式.show”と記述したが、ここで作成したユーザー フォームを呼び出すためである。 次に計算実行のボタンをダブルクリックして、コード画面を表示し、コードを入 力する。コード入力の際にテキストボックスの値を参照する。この場合、テキスト ボックスの番号が重要である。この例では以下のように対応している。 初期値= : テキストボックス1 閾値(しきいち)= : テキストボックス2 最大反復回数= : テキストボックス3 計算実行 : コマンドボタン1 終了 : コマンドボタン2
Private Sub CommandButton1_Click() 非線形方程式.Show
End Sub
ラベル
テキストボックス
もし各自のテキストボックスの番号が異なる場合にはそれに対応してプログラム を読み直してほしい。コード画面が現れたら次のプログラムを入力する。
Private Sub CommandButton1_Click() Dim X1 As Double
Dim eps As Double Dim ff As Double Dim df As Double Dim x As Double Dim max As Integer
Dim No As Integer Worksheets("方程式の解法").Activate Set WS = Worksheets("方程式の解法").Application WS.Cells(34, 2) = "初期値 X1=" WS.Cells(34, 3) = TextBox1.Text X1 = CDbl(TextBox1.Text) WS.Cells(35, 2) = "閾値=" WS.Cells(35, 3) = TextBox2.Text eps = CDbl(TextBox2.Text) WS.Cells(36, 2) = "最大反復回数=" WS.Cells(36, 3) = TextBox3.Text max = CDbl(TextBox3.Text) No = 0 Do
If No >= max Then Exit Do x = X1 No = No + 1 ff = x * Log(x) - 1 df = Log(x) + 1 X1 = x - (ff / df) WS.Cells(39 + No, 2) = "X1=" WS.Cells(39 + No, 3) = X1 WS.Cells(39 + No, 5) = No WS.Cells(39 + No, 7) = x - X1 Loop While (Abs(x - X1) > eps) WS.Cells(37, 2) = "方程式の解=" WS.Cells(37, 3) = X1 End Sub
①
③
④
⑤
⑥
②
プログラムを解説する前にプログラムの流れを解説しておく。ニュートンラフソン 法での解の計算は下記のような流れにより計算する。 変数定義 初期値設定 (x0、閾値、最大反復回数など) 反復回数(No)≧ 最大反復回数(max) xi+1の計算 閾値(eps)≧|xi+1-xi| xi+1の表示 No No Yes Yes 解の表示 終了
①
②,③,④
⑤
⑥
プログラムの解説 ① 変数の定義 プログラム中で用いる変数(数値を入れておくメモリ)は必ず定義されな ければならない。ここでは2種類の変数が定義されている。 Dim X1 As Double ア イ エ オ 変数の定義は上記のように記述される。 ア : 変数の定義を行いますという宣言 イ : 定義する変数名 変数名は自由につけることができるがアルファベットと数字およ び_(アンダーライン)でその変数が何を意味するかを考えてつける ようにすると良い。ただし、頭文字に数字やアンダーバーは使うこ とができない。漢字やひらがなカタカナなども使うことができるが 別のコンピュータに持って行った場合にエラーを起こす可能性が あるので使うべきではない エ : イの変数をどの様な変数として定義するかという意味 オ : 変数の種類 変数の種類には次のようなものがある。 データの型 データの特徴 データの例 Integer 整数(小数点のつかな い数値) 0,5, 100 Long 桁数の大きい整数 (Integer も含む) -24534, 100000000 Single 実数(小数点を含む数 値) -2.0, 12.8 Double 桁数がかなり大きい実 数(Single も含む) -2.5×1050, 3.5× 10-100 String 文字 カレーうどん、大学 変数の型としては上記のもの以外にもDate, Byte 等がある。ここでは必要な いので割愛する。 プログラムで定義する変数は常にプログラムの一番最初で定義する。そし て、この変数の有効範囲は定義した部分からEnd Sub まである。すなわち、 Private・・・・End Sub がその変数が有効な範囲である。プログラムではそ れぞれのコマンドボタンやテキストボックスなどにそれぞれプログラムを記述する ことができる。その単位をプロシージャと呼ぶが、通常、変数は各プロシージャ 内でのみ有効であるということである。つまり、別のプロシージャで同じ変数を定
義してもかまわないということである。 ② 利用するワークシートの定義 Worksheets("方程式の解法").Activate このコマンドは利用するワークシートを定義しています。すなわち、実際の操 作で考えるとワークシートのタグをマウスでクリックすることです。上記の例では 方程式の解法と名付けたワークシートが選択されています。 さらに、選択したワークシートの名前を WS というな変数に代入しています。 この変数は①では定義されていませんが、実際にはオブジェクト変数というもの で代入することで定義されていると考えてください。 ③ 初期値の代入 ここでは初期値、閾値、最大反復回数を各セルおよび変数に代入していま す。 WS.Cells(34, 2) = "初期値 X1=" 先頭のWS は用いるワークシートを示しています。この命令では34行目の2 列目のセルに"初期値 X1="という文字列を代入しています。前の授業で はRange という命令を使いました。Range の場合にはセルの位置の指定 に“A1”や”B2”等の表現を用いました。しかし、プログラムで行の位置や列 の位置を変化させたい場合にはこれでは不便です。Cells のセル指定では Cells(行位置を示す数値、列位置を示す数値)という指定の仕方をします。 セル位置をすべて数値で表すことができるのでプログラム中でも扱いやすく なります。具体的には⑤の中で出てくる39+No のように演算形式で表現 することもできます。 WS.Cells(34, 3) = TextBox1.Text この命令では34行目3列目のセルに TextBox1.Text の内容を代入して います。つまり前の命令の右横のセルに TextBox1.Text の内容つまり初 期値の値を代入しています。 X1 =CDbl(TextBox1.Text) さらに次の命令では X1 という変数に初期値を代入しています。CDbl()は 文字を数値(倍精度)に変換する関数です。テキストボックスに入力された 数字は文字として認識されます。変数に文字を代入する場合には必ず数 値に変換してください。同様に、35,36行目に閾値と最大反復回数を代 入し、eps と max にも代入しています。
④ 反復回数の初期化 No = 0 この命令では No という整数変数に0を代入しています。この変数は⑤で反 復回数を数えるために使います。計算が始まる前には必ず0でなければならな いのでここで0にしています。 ⑤ ニュートンラフソン法の計算 この部分が計算の本体です。計算のフローチャートを見てください。ここに相 当する部分は動作が複雑です。反復回数が最大反復回数より大きいか小さ いかの判断をする部分があり、さらに計算値と前回の計算値の差が閾値より 大きいかどうかの判断をする部分があります。さらに、同じ計算を繰り返し行う動 作をしなければなりません。 条件判断 条件判断には次の命令を使います。 If 条件式1 Then ElseIf 条件式2 Then ElseIf 条件式3 Then Else End IF 判断文は条件式が満足されている場合(真)にすぐ次の実行文を実行し、そ れ以外は実行せずにEndIf に飛び、If 文を終了します。 実行文群1 実行文群2 実行文群2 実行文群n
具体的には次のようになります。 If x<0 Then MsgBox “x は負の数です。“ ElseIf x<10 Then MsgBox “x は0以上10未満の数です。“ ElseIf x<20 Then MsgBox “x は10以上20未満の数です。“ Else MsgBox “x は20以上の数です。” End If このプログラムで MsgBox というのが出ていますがこれはこの命令に続く文章 を画面に表示する命令です。 x=-1の場合 この場合には最初の文の条件式(x<0)が満足されます。そのため、画面に “xは負の数です”と表示して終了します。 x=12 の場合 この場合にはx<0 は満足しませんからその次の実行文(MsgBox “x は負の 数です。“は実行しません。その次の条件式(x<10)も満足しません。そして、3 番目の条件式(x<20)は満足しますので画面に” x は10以上20未満の数で す。“と表示して終了します。 x=35 の場合 この場合には3つの条件式(x<0, x<10, x<20)のどれも満足しません。その ため、一番最後のElse の実行文(“x は20以上の数です。”を表示)を実行し ます。
条件式に用いられる演算記号は次のようなものがあります。 記号 意味 = 左辺と右辺が等しい > 左辺が右辺より大きい < 左辺が右辺未満 >= 左辺が右辺以上 <= 左辺が右辺以下 <> 左辺と右辺が等しくない
また、条件式を複数つなぐ論理演算子(And, Or, Not 等)も使うことができま
す。 繰り返し 今回行うニュートンラフソン法では xi+1=xi-f(xi)/f’(xi)を求めることにより数 値解を求めます。たとえば初期値x0=1 から x1を求めます。さらにx1を元にx2 を求めます。さらに x2→x3→x4→x5・・・のように漸化式として一つ前の値から 次の値を求めます。このような計算に対してプログラムする際にはどの様にする のでしょう。x0→x1に対刷るプログラムを書き、x1→x2に対するプログラムを書き、 さらに・・・・。ではどこまでプログラムを書けばよいのでしょう。方程式によっては かなりの回数計算しなければならない場合があるはずですし、簡単に解を得ら れる場合もあります。これまで考慮してプログラムをするには最初に自分で計算 してみてプログラムを書く必要があり、個々の方程式について別々のプログラ ムになってしまい、効率が良くありません。はっきり言ってそんなことならプログラ ムを書く必要はないはずです。 あらゆるプログラム言語には繰り返し命令というのがあります。VBAでも同じで す。コンピュータにとってあるルール(プログラム)に沿って繰り返しを行うことは得 意なことです。VBAでは3種類の繰り返し命令があります。 Do….Loop ステートメント Do….Loop ステートメントは Do と Loop で囲まれた範囲の命令をある条件の 間繰り返し実行するための命令です。その構文には4種類あります。 Do While 条件式 ① 繰り返したい命令文 Loop Do Until 条件式 ③ 繰り返したい命令文 Loop Do ② 繰り返したい命令文 Loop While 条件式 Do ④ 繰り返したい命令文 Loop Until 条件式
①~④の違いは2種類あります。ひとつは条件式の位置です。条件式が Do の部分に記述されているもの(①と③)と Loop の部分に記述されているもの (②と④)です。この2つの違いは条件判定をする位置です。Do…Loop ステ ートメントでは条件判定が行われ、その判定が True(真)の場合には繰り返しを 行い、偽(False)の場合には Do…Loop ステートメントを終了します。そのため、 下のように Do の部分に条件判定がある場合には最初から判定が偽の場合 には1回もその繰り返しが実行されません。 x=-1 Do While x>0 x=x-1 Loop Debug.Print x これに対して、Loop の部分に条件判定がある場合には最低でも1回はその繰 り返しが実行されます。 x=-1 Do x=x-1 Loop While x>0 Debug.Print x もう一つの違いは条件判定の部分の While〔①、②〕と Until〔③、④〕で す。これは英語の意味と同じです。 While : 条件式が真の間繰り返しを実行する。 Untile : 条件式が真になったら繰り返しを終了する。 条件式以外でこの繰り返しを終了するにはExit Do という命令があり、しばし ばif 文と併せて用いられます。 For…Next ステートメント For…Nest ステートメントも Do…Loop ステートメントと同様に繰り返しの命 令です。記述例を示します。 For カウンタ変数名= 初期値 To 最終値 Step 増分 繰り返すべき命令群 Next カウンタ変数名 For…Next ステートメントでは繰り返し回数がわかっている場合に用います。 カウンタ変数名というのは何回繰り返したかを判定するために用いる変数です ① ② x=-1 が表示される。 ① ② x=-2 が表示される。 判定が偽のため Do…Loop は実行されな い 最低でも1回は実行さ れる。
(必ずしも繰り返し回数とは一致しない)。 上の命令文の意味はカウンタ変数を初 期値から初めて、増分ずつ増加させ、最 終値になるまで繰り返せということを意味 しています。例を下に示します。 x=0
For i=1 to 10 step 1 x=x+I next I MsgBox x この例ではi の値が 1 から1ずつ増加させ、10 になるまで繰り返しなさい。とい うことを示しています。すなわち、10 回繰り返すということです。 x=0
For i=1 to 10 step 2 x=x+I next I MsgBox x この例は増分が 2 です。そのため、カウ ンタ変数i は 2 づつ増加します。もちろん カウンタ変数には明確な数値でなくても初期値と最終値に変数を指定すること ができます。For…Next ステートメントでも繰り返しの回数の途中であっても抜 け出すことができます。その命令はExit For です。 While…Wend ステートメント 3つめの繰り返し命令はWhile…Wend ステートメントです。記述方法を示し ます。 While 条件式 繰り返すべき命令群 Wend この命令では条件式が成り立っている間は繰り返し続けます。逆に条件式が 成立しなくなったら繰り返しの実行が終了します。例で見てみましょう。 i x(①) x(②) 1 0 1 2 1 3 3 3 6 4 6 10 5 10 15 6 15 21 7 21 28 8 28 36 9 36 45 10 45 55 ① ② ② ① i x(①) x(②) 1 0 1 3 1 4 5 4 9 7 9 16 9 16 25
intVal=0 intAdd=0 While intAdd<=100 intVal=intVal+intAdd intAdd=intAdd+1 Wend MsgBox intVal こ の プ ロ グ ラ ム で は 最 初 の 2 行 で 変 数 を 0 に 初 期 化 し て い ま す 。 While…Wend の条件式は intAdd<=100 なので intAdd という変数が 100
以下の時は繰り返します。繰り返し命令では単に intAdd の足し算を行ってい るだけです。この繰り返しの中ではカウンタ変数として intAdd が用いられてい ます。そして、intAdd=intAdd+1 でカウンタを1つずつ増加させています。そし て、intAdd が 100 まで繰り返しを行い、101 になったときに終了します。 While…Wend ステートメントではこれを終了する命令がありません。そのため、 条件式および条件の変化をきちんと行わないと無限ループ(いつまでたっても 終わらないプログラム)になってしまいがちです。 以上で基礎知識の説明は終わりましたので⑤の部分の説明を行います。 ① Do
② If No >= max Then Exit Do ③ x = X1 ④ No = No + 1 ⑤ ff = x * Log(x) - 1 ⑥ df = Log(x) + 1 ⑦ X1 = x - (ff / df) ⑧ WS.Cells(39 + No, 2) = "X1=" ⑨ WS.Cells(39 + No, 3) = X1 ⑩ WS.Cells(39 + No, 5) = No ⑪ WS.Cells(39 + No, 7) = x - X1 ⑫ Loop While (Abs(x - X1) > eps)
①⑫ この間を繰り返す。 ②If No >= max Then Exit Do
No:Do…Loop の間を何回実行したかを示すカウンタ変数 Max:入力した最大反復回数 この判断文では繰り返しが最大反復回数を超えたら、繰り返し操作を終了す る(Exit Do)。 ③x=X1 x : 一つ前の方程式の数値解 X1 : x を用いて計算する新しい数値解 この命令で新たに計算するにあたって、x に前回計算した X1 の値を代入し ている。 ④No=No+1 カウンタ変数を1つ増やしている。(何回計算したか確認のため) ⑥ ff = x * Log(x) – 1 ・・・・・・
y
x
log
ex
1
⑦ df = Log(x) + 1 ・・・・・・・y’ (y の導関数)
⑧ X1 = x - (ff / df) ・・・・・ (ニュートンラフソン法) ⑧ WS.Cells(39 + No, 2) = "X1="
⑨ WS.Cells(39 + No, 3) = X1 ⑩ WS.Cells(39 + No, 5) = No ⑪ WS.Cells(39 + No, 7) = x - X1
⑧~⑪では Cells の行の指定が 39+No となっています。No は繰り返し
変数です。つまり、何行目に出力するかが繰り返し回数によって変わることを意 味します。1回目は40行目、2回目は41行目です。これにより、計算過程を記 録することができます。
⑫ Loop While (Abs(x - X1) > eps)
条件式はAbs(x - X1) > eps です。eps は閾値です。さらに、Abs は絶対
値を取る関数です。つまり、前回と今回の計算結果の差が eps 以上であった ら繰り返しを実行し続けることを意味しています。 プログラムの一番最後(6ページ目の⑥)は最終結果の出力です。 X1=○○○ 回数 前回との差 の形式での結果の出力 ) ( ' ) ( 1 i i i i x f x f x x