| 例1) |
|
| 硫酸水素ナトリウム |
|
|
|
 |
|
| 電離度1として、完全解離とする |
|
|
|
 |
|
| 平衡定数をk=1.2*10^-2とする |
|
|
|
| 水の解離定数kw=10^-14 |
|
|
|
硫酸水素ナトリウムの濃度をCとすると、物質収支と、電荷収支をとり、式を整理すると、以下のような式になる。
|
|
 |
|
この方程式の解が水素イオン濃度になります。
この方程式を二分法と、ニュートン方で、計算してみます。
|
|
|
|
ここで、エクセルのクラスモジュールの使い方に、説明を移したいと思います。
二分法と、ニュートン方の数値計算に関する説明は割愛します。
まず、クラスモジュールを二つ追加します。一つを二分法のプログラムを貼り付け、もう一つに、ニュートン法を貼り付けます。
そのあと、クラス名を変更します。クラス名は、私は、cnibunとcnewtonと付けました。
|
 |
|
|
| ****************cnibunのソースプログラムです********************* |
|
Option Explicit
Public Function nibun(ByVal a As Double, ByVal b As Double, ByVal of As Object) As Variant
Dim c As Double
Dim seid As Double
Dim change As Double
seid = 0.0000000001
If of.f(a) * of.f(b) > 0 Then
nibun = "解ないかも"
Exit Function
End If
If a = b Then
nibun = "解ないよ"
Exit Function
End If
If a = 0 Then
change = b
b = a
a = change
End If
Do While gosa(a, b) > seid
c = (a + b) / 2#
If of.f(a) = 0 Then
nibun = a
Exit Function
End If
If of.f(b) = 0 Then
nibun = b
Exit Function
End If
If of.f(a) * of.f(c) < 0 Then
b = c
Else
a = c
End If
Loop
nibun = (a + b) / 2
End Function
Public Function gosa(a As Double, b As Double) As Double
gosa = Abs((a - b) / a)
End Function
|
|
|
|
|
|
| ******************cnewtonのプログラムです。******************************** |
|
Public Function newton(ByVal x As Double, f4 As Object) As Double
Dim xx As Double
Do While True
xx = x - f4.f(x) / f4.df(x)
If Abs((xx - x) / x) < 0.000000000001 Then Exit Do
x = xx
Loop
newton = xx
End Function
|
|
|
|
|
|
ここで、二分法もニュートン法でも利用する方程式は、新たにクラスモジュールを作り、
そこに作るのが、数値計算のプログラムを汎用性にし、新たな方程式にも、柔軟に対応できるように、なります。
|
|
|
|
| ***************方程式のクラスモジュールです************************************* |
|
Option Explicit
Dim CNaHSO4 As Double
'求める解の方程式
Public Function f(h As Double) As Double
Dim k As Double
Dim kw As Double
k = 1.2 * 10 ^ -2
kw = 10 ^ -14
f = h ^ 3 + k * h ^ 2 - (k * CNaHSO4 + kw) * h - k * kw
End Function
'ニュートン法用の一次微分の式
Public Function df(h As Double) As Double
Dim k As Double
Dim kw As Double
k = 1.2 * 10 ^ -2
kw = 10 ^ -14
df = 3 * h ^ 2 + 2 * k * h - (k * CNaHSO4 + kw)
End Function
'硫酸水素ナトリウムの濃度設定
Public Property Get c() As Double
c = CNaHSO4
End Property
Public Property Let c(ByVal vNewValue As Double)
CNaHSO4 = vNewValue
End Property
|
|
|
|
|
|
|
**********ここまで作ると、後標準モジュールでの利用です。*******************
|
|
Option Explicit
Public Sub NaHSO4nibun()
Dim a As New cnibun
Dim b As New NaHSO4
Dim c As New cnewton
'硫酸水素ナトリウムの濃度
b.c = 0.2
Debug.Print a.nibun(1, 10 ^ -14, b), c.newton(1, b)
End Sub
|
|
| ***********計算結果******************************** |
|
 |
|
|
|
|
|
上記の標準モジュールのプログラムを見ても解るように、二分法と、ニュートン法のオブジェクトを作り、
また、方程式のオブジェクトを作り、数値計算のオブジェクトに方程式のオブジェクトを渡し、計算結果を出しています。
すっきりしたプログラムになっていると思います。
また、プログラムに、細工をして、計算回数を見ると、二分法の方が計算回数に関して多いことがわかります。
では、二分法は、いらないのでは、と言う方もいるかと思います。
ニュートン法の欠点として、一次微分形が、容易に求まらないと、面倒になります。
式が、複雑だと、二分法を使ったほうが便利だなと思う時があります。
次に、硫酸を例に取り、式を複雑なままで、二分法で計算して見ました。
|
|
|
|
| 例2) |
|
 |
|
| 完全解離の電離度を1とする |
|
|
|
 |
|
| あと条件は、例1と同じです。 |
|
|
|
| 例一と同様に、物質収支と電荷収支をとって、式を作ると |
|
 |
|
 |
|
| 整理すれば、良いのですが、今回は、ワザと整理しませんでした。 |
|
|
|
| *****************方程式のクラスモジュールを作ります***************************** |
|
Option Explicit
Dim CH2SO4 As Double
Public Function f(h As Double) As Double
Dim k As Double
Dim kw As Double
Dim w As Double
k = 1.2 * 10 ^ -2
kw = 10 ^ -14
w = h / (k + h)
f = h ^ 2 - (2# - w) * CH2SO4 * h - kw
End Function
Public Property Get c() As Double
c = CH2SO4
End Property
Public Property Let c(ByVal vNewValue As Double)
CH2SO4 = vNewValue
End Property
|
|
|
|
|
|
| ****************よって、標準モジュールは、以下のようになりました。****************** |
|
Public Sub H2SO4()
Dim a As New cnibun
Dim b As New H2SO4
'硫酸濃度
b.c = 0.01
Debug.Print a.nibun(1, 10 ^ -14, b)
End Sub
|
|
|
|
| 計算結果は |
|
 |
|
|
|
よって、クラスモジュールを利用すると、プログラミングに汎用性ができます。
便利とは、思いませんか。
|
|
|
|