トップに戻る

クラスモジュールの便利な使い方U


使い方Tを、改造してみます。
改造の方針は、まず、クラスモジュールのsinpsonの引数に定数sa,sb,scが、存在した場合。
引数の数が、増えたり、減ったりして、積分する式が別な式等の、変わった場合、
クラスモジュールのsinpsonを書き換えないといけなくなります。
そこで、sinpsonの定数の無い、クラスモジュールsinp1に、csinp関数を作り、sinpson関数をを少し書き換えました。
赤い部分が変更された箇所です。

sinp1のクラスモジュールを作り以下の関数を作りました。
Function csinp(x1 As Double, x2 As Double, ff As fun1) As Double

       Dim dd As Integer
       Dim i As Integer
       Dim dd2 As Integer
       Dim h As Double
       Dim an As Double
       Dim an1 As Double
       Dim y As Double
       Dim j As Integer
       Dim x As Double
      csinp = 0
       If x1 = x2 Then
           Exit Function
       End If

       i = 2
       dd2 = 2
       h = (x2 - x1) / 2
      an = ff.f(x1) + 4 * ff.f(x1 + h) + ff.f(x2) * h / 2
       an1 = an * 0.9
       Do While (Abs(an1 - an) / an * 100 > 0.0000001)
           an = an1
           dd = dd2 * i
           h = (x2 - x1) / dd
          y = ff.f(x1)
           x = x1
          For j = 1 To i

             x = x + h
            y = y + 4 * ff.f(x)
             x = x + h
            y = y + 2 * ff.f(x)

         Next j

        y = y - ff.f(x2)
         an1 = y * h / 3
         i = i + 1
      Loop

     csinp = an1

End Function

csinpを見ると、sinpson関数とほとんどコードは変わりません。
積分する関数とその関数の引数が、f(sa, sb, sc, x)からff.f(x)
変わっただけです。
sinp1のモジュールを見ても解るように、
ここからは、積分する方程式が、消えて、
新たなクラスモジュールfun1に積分するf( )が、定義されています。

積分する関数をfun1クラスモジュールに、下のように作りました。
定数 a,b,cをプロパティで、代入して、 が、独立変数Xだけの関数にしました。
Dim a As Double
Dim b As Double
Dim c As Double


Public Function f(x As Double) As Double

f = a + b * 10 ^ -3 * x + (c * 10 ^ 5 / x ^ 2)

End Function

Public Property Get aa() As Variant

aa = a

End Property

Public Property Let aa(ByVal vNewValue As Variant)

a = vNewValue

End Property

Public Property Get bb() As Variant

bb = b

End Property

Public Property Let bb(ByVal vNewValue As Variant)

b = vNewValue

End Property

Public Property Get cc() As Variant

cc = c

End Property

Public Property Let cc(ByVal vNewValue As Variant)

c = vNewValue

End Property



また、以上のコードを実行する標準モジュールは、
以下のようになります。
Public Function sinp11(sa As Double, sb As Double, sc As Double, x1 As Double, x2 As Double) As Double
Dim oa As New sinp1
Dim ob As New fun1

Application.Volatile

ob.aa = sa
ob.bb = sb
ob.cc = sc

sinp11 = oa.csinp(x1, x2, ob)

End Function


結論として、この様に、コードを改良すると、数値計算するシンプソンのコードの再利用度が上がっていることに気が付くと思います。
Tで、紹介したコードでは、積分する関数が、変わると、シンプソンのコード自体を少し変えないといけない
積分する式をどの様に変えても、Uで、改良したコードは、基本的な、シンプソンのコードを変えなくても良いことが解ります。
しかし、積分する関数名には、f という名前で定義しないと、いけないという制限はあります。

また、シンプソンの引数のクラスをfun1でしか、定義できないという不便さがあります。

これを、解決するのに、便利な使い方Vで紹介します。
注意 Application.Volatileは、ユーザー 関数を作った時に再計算するための、メッソドです。