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