-自作4倍精度クラスでの処理時間- 34桁関数モジュール(clstaby_preci34)
ほぼ同一のプログラムで d=0.0001 t=1 の条件で処理時間を比較すると
約2125倍遅くなる。
- 結果 -
倍精度時 1分06秒
自作4倍精度クラス使用 35時間57分54秒
(ムーアの法則だと10年で1000倍なので11年分処理が遅くなる。 注意:改善余地あり。)
◆◆◆◆ ピタゴラス3体問題 ◆◆◆◆ ※別途クラスモジュール:34桁関数モジュールが必要
Option Explicit
Option Base 1
Dim m(3) As String
Public Const G As String = "1.00000000000000000000000000000000000E+0000" '万有引力定数
Sub メインルーチン()
Dim cls34 As clstaby_preci34
Set cls34 = New clstaby_preci34 ' インスタンスを作成
Dim t As String, dt As String ' 時間
Dim rr(3, 3) As String ' rr(識別番号,軸成分)
Dim vv(3, 3) As String ' vv(識別番号,軸成分)
Dim ans As Variant
Dim cnt0 As Long, cnt1 As Long
Dim sh As Worksheet
Dim 終了時刻 As String
Set sh = ThisWorkbook.Worksheets(1)
sh.Range("C10:AD65536").ClearContents ' データ消去
sh.Range("N2") = Time ' 開始時刻
'初期条件
m(1) = "3.00000000000000000000000000000000000E+0000" ' 質量1
m(2) = "4.00000000000000000000000000000000000E+0000" ' 質量2
m(3) = "5.00000000000000000000000000000000000E+0000" ' 質量3
rr(1, 1) = "1.00000000000000000000000000000000000E+0000" '(識別番号,軸成分)
rr(1, 2) = "3.00000000000000000000000000000000000E+0000" '(識別番号,軸成分)
rr(1, 3) = "0.00000000000000000000000000000000000E+0000" '(識別番号,軸成分)
rr(2, 1) = "-2.00000000000000000000000000000000000E+0000" '(識別番号,軸成分)
rr(2, 2) = "-1.00000000000000000000000000000000000E+0000" '(識別番号,軸成分)
rr(2, 3) = "0.00000000000000000000000000000000000E+0000" '(識別番号,軸成分)
rr(3, 1) = "1.00000000000000000000000000000000000E+0000" '(識別番号,軸成分)
rr(3, 2) = "-1.00000000000000000000000000000000000E+0000" '(識別番号,軸成分)
rr(3, 3) = "0.00000000000000000000000000000000000E+0000" '(識別番号,軸成分)
vv(1, 1) = "0.00000000000000000000000000000000000E+0000" '(識別番号,軸成分)
vv(1, 2) = "0.00000000000000000000000000000000000E+0000" '(識別番号,軸成分)
vv(1, 3) = "0.00000000000000000000000000000000000E+0000" '(識別番号,軸成分)
vv(2, 1) = "0.00000000000000000000000000000000000E+0000" '(識別番号,軸成分)
vv(2, 2) = "0.00000000000000000000000000000000000E+0000" '(識別番号,軸成分)
vv(2, 3) = "0.00000000000000000000000000000000000E+0000" '(識別番号,軸成分)
vv(3, 1) = "0.00000000000000000000000000000000000E+0000" '(識別番号,軸成分)
vv(3, 2) = "0.00000000000000000000000000000000000E+0000" '(識別番号,軸成分)
vv(3, 3) = "0.00000000000000000000000000000000000E+0000" '(識別番号,軸成分)
終了時刻 = "1.00000000000000000000000000000000000E+0000"
t = "0.00000000000000000000000000000000000E+0000"
dt = "0.00010000000000000000000000000000000E+0000" '0.0001
cnt0 = 0
cnt1 = 0
With sh '表記
.Cells(9, 4).Value = "t" 't
.Cells(9, 5).Value = "x1" 'x1
.Cells(9, 6).Value = "y1" 'y1
.Cells(9, 7).Value = "x2" 'x2
.Cells(9, 8).Value = "y2" 'y2
.Cells(9, 9).Value = "x3" 'x3
.Cells(9, 10).Value = "y3" 'y3
End With
Do While cls34.■34↓15(t) < cls34.■34↓15(終了時刻)
With sh
.Cells(cnt1 + 10, 4).Value = cls34.■34↓15(t) 't
.Cells(cnt1 + 10, 5).Value = cls34.■34↓15(rr(1, 1)) 'M1 x
.Cells(cnt1 + 10, 6).Value = cls34.■34↓15(rr(1, 2)) 'M1 y
.Cells(cnt1 + 10, 7).Value = cls34.■34↓15(rr(2, 1)) 'M2 x
.Cells(cnt1 + 10, 8).Value = cls34.■34↓15(rr(2, 2)) 'M2 y
.Cells(cnt1 + 10, 9).Value = cls34.■34↓15(rr(3, 1)) 'M3 x
.Cells(cnt1 + 10, 10).Value = cls34.■34↓15(rr(3, 2)) 'M3 y
cnt1 = cnt1 + 1
End With
ans = RK4(t, dt, m, rr, vv) ' ルンゲ=クッタ
rr(1, 1) = ans(1)
rr(1, 2) = ans(2)
rr(1, 3) = ans(3)
vv(1, 1) = ans(4)
vv(1, 2) = ans(5)
vv(1, 3) = ans(6)
rr(2, 1) = ans(7)
rr(2, 2) = ans(8)
rr(2, 3) = ans(9)
vv(2, 1) = ans(10)
vv(2, 2) = ans(11)
vv(2, 3) = ans(12)
rr(3, 1) = ans(13)
rr(3, 2) = ans(14)
rr(3, 3) = ans(15)
vv(3, 1) = ans(16)
vv(3, 2) = ans(17)
vv(3, 3) = ans(18)
cnt0 = cnt0 + 1
t = cls34.■加34(t, dt) ' t = t + dt
Loop
sh.Range("N3") = Time
Set cls34 = Nothing
End Sub
Function RK4(ByVal t, ByVal dt, m, ByVal r0, ByVal v0) As Variant
Dim cls34 As clstaby_preci34
Set cls34 = New clstaby_preci34 ' インスタンスを作成
'下準備--------------------------------------------------------------------------------------
Dim ret(18)
Dim r1(3, 3), r2(3, 3), r3(3, 3), r4(3, 3) ' r(識別番号,軸成分)
Dim v1(3, 3), v2(3, 3), v3(3, 3), v4(3, 3) ' v(識別番号,軸成分)
Dim k1rr(3, 3), k2rr(3, 3), k3rr(3, 3), k4rr(3, 3) ' k1rr(識別番号,軸成分)
Dim k1vv(3, 3), k2vv(3, 3), k3vv(3, 3), k4vv(3, 3) ' k1vv(識別番号,軸成分)
Dim 番号 As Integer, 軸 As Integer
Dim 数字2 As String
Dim buf01 As String
数字2 = "2.00000000000000000000000000000000000E+0000"
For 番号 = 1 To 3
For 軸 = 1 To 3
v1(番号, 軸) = v0(番号, 軸) 'v(識別番号,軸成分) (3,3) 3体×3次元 前処理
r1(番号, 軸) = r0(番号, 軸) 'r(識別番号,軸成分) (3,3) 3体×3次元 前処理
Next 軸
Next 番号
'下準備--------------------------------------------------------------------------------------
'k1
For 番号 = 1 To 3 '識別番号
For 軸 = 1 To 3 '軸成分
k1vv(番号, 軸) = cls34.■乗34(dt, 速度変位成分_func(番号, 軸, t, r1, v1)) '速度変位_総和 m/s^2
k1rr(番号, 軸) = cls34.■乗34(dt, 位置変位成分_func(番号, 軸, t, r1, v1)) '位置変位成分 m/s
Next 軸
Next 番号
'k2
For 番号 = 1 To 3
For 軸 = 1 To 3
v2(番号, 軸) = cls34.■加34(v1(番号, 軸), cls34.■除34(k1vv(番号, 軸), 数字2)) 'v(識別番号,軸成分) (3,3) 前処理
r2(番号, 軸) = cls34.■加34(r1(番号, 軸), cls34.■除34(k1rr(番号, 軸), 数字2)) 'r(識別番号,軸成分) (3,3) 前処理
Next 軸
Next 番号
For 番号 = 1 To 3 '識別番号
For 軸 = 1 To 3 '軸成分
buf01 = cls34.■除34(dt, 数字2) ' dt/2
buf01 = cls34.■加34(t, buf01) ' t+dt/2
k2vv(番号, 軸) = cls34.■乗34(dt, 速度変位成分_func(番号, 軸, buf01, r2, v2)) '速度変位_総和 m/s^2
k2rr(番号, 軸) = cls34.■乗34(dt, 位置変位成分_func(番号, 軸, buf01, r2, v2)) '位置変位成分 m/s
Next 軸
Next 番号
'k3
For 番号 = 1 To 3
For 軸 = 1 To 3
v3(番号, 軸) = cls34.■加34(v1(番号, 軸), cls34.■除34(k2vv(番号, 軸), 数字2)) 'v(識別番号,軸成分) (3,3) 前処理
r3(番号, 軸) = cls34.■加34(r1(番号, 軸), cls34.■除34(k2rr(番号, 軸), 数字2)) 'r(識別番号,軸成分) (3,3) 前処理
Next 軸
Next 番号
For 番号 = 1 To 3 '識別番号
For 軸 = 1 To 3 '軸成分
k3vv(番号, 軸) = cls34.■乗34(dt, 速度変位成分_func(番号, 軸, cls34.■加34(t, cls34.■除34(dt, 数字2)), r3, v3)) '速度変位_総和 m/s^2
k3rr(番号, 軸) = cls34.■乗34(dt, 位置変位成分_func(番号, 軸, cls34.■加34(t, cls34.■除34(dt, 数字2)), r3, v3)) '位置変位成分 m/s
Next 軸
Next 番号
'k4
For 番号 = 1 To 3
For 軸 = 1 To 3
v4(番号, 軸) = cls34.■加34(v1(番号, 軸), k3vv(番号, 軸)) 'v(識別番号,軸成分) (3,3) 前処理
r4(番号, 軸) = cls34.■加34(r1(番号, 軸), k3rr(番号, 軸)) 'r(識別番号,軸成分) (3,3) 前処理
Next 軸
Next 番号
For 番号 = 1 To 3 '識別番号
For 軸 = 1 To 3 '軸成分
k4vv(番号, 軸) = cls34.■乗34(dt, 速度変位成分_func(番号, 軸, cls34.■加34(t, dt), r4, v4)) '速度変位_総和 m/s^2
k4rr(番号, 軸) = cls34.■乗34(dt, 位置変位成分_func(番号, 軸, cls34.■加34(t, dt), r4, v4)) '位置変位成分 m/s
Next 軸
Next 番号
Dim 数字6 As String
数字6 = "6.00000000000000000000000000000000000E+0000"
Dim buf_v1 As String, buf_v1_a As String, buf_v1_b As String
Dim buf_r1 As String, buf_r1_a As String, buf_r1_b As String
For 番号 = 1 To 3
For 軸 = 1 To 3
buf_v1_a = cls34.■乗34(数字2, cls34.■加34(k3vv(番号, 軸), k2vv(番号, 軸)))
buf_v1_b = cls34.■加34(k1vv(番号, 軸), k4vv(番号, 軸))
buf_v1 = cls34.■加34(buf_v1_a, buf_v1_b)
buf_r1_a = cls34.■乗34(数字2, cls34.■加34(k2rr(番号, 軸), k3rr(番号, 軸)))
buf_r1_b = cls34.■加34(k1rr(番号, 軸), k4rr(番号, 軸))
buf_r1 = cls34.■加34(buf_r1_a, buf_r1_b)
v1(番号, 軸) = cls34.■加34(v1(番号, 軸), cls34.■除34(buf_v1, 数字6)) ' m/s
r1(番号, 軸) = cls34.■加34(r1(番号, 軸), cls34.■除34(buf_r1, 数字6)) ' m
Next 軸
Next 番号
'便宜的に戻り値を行列 ret(18)でまとめ
ret(1) = r1(1, 1)
ret(2) = r1(1, 2)
ret(3) = r1(1, 3)
ret(4) = v1(1, 1)
ret(5) = v1(1, 2)
ret(6) = v1(1, 3)
ret(7) = r1(2, 1)
ret(8) = r1(2, 2)
ret(9) = r1(2, 3)
ret(10) = v1(2, 1)
ret(11) = v1(2, 2)
ret(12) = v1(2, 3)
ret(13) = r1(3, 1)
ret(14) = r1(3, 2)
ret(15) = r1(3, 3)
ret(16) = v1(3, 1)
ret(17) = v1(3, 2)
ret(18) = v1(3, 3)
RK4 = ret
Set cls34 = Nothing
End Function
Function 速度変位成分_func(ByVal 被番号, ByVal 軸, ByVal t, ByVal R, ByVal v) As String ' (速度変位 m/s^2)を返す
Dim cls34 As clstaby_preci34
Set cls34 = New clstaby_preci34 ' インスタンスを作成
Dim sum_a As String
Dim rrr As String, rrr3 As String
Dim 差異(3) As String
Dim 基準天体 As Integer
Dim buf As String, buf2 As String
Dim 数字_1 As String
数字_1 = "-1.00000000000000000000000000000000000E+0000"
rrr = "0.00000000000000000000000000000000000E+0000" ' 初期化
sum_a = "0.00000000000000000000000000000000000E+0000" ' 初期化
' dv/dt = -G・M・(→r)/r^3 ・・・ 万有引力の法則
For 基準天体 = 1 To 3 '番号
If 被番号 <> 基準天体 Then ' 相違する場合だけ計算する
差異(1) = cls34.■減34(R(被番号, 1), R(基準天体, 1)) 'r(識別番号,軸成分) x成分
差異(2) = cls34.■減34(R(被番号, 2), R(基準天体, 2)) 'r(識別番号,軸成分) y成分
差異(3) = cls34.■減34(R(被番号, 3), R(基準天体, 3)) 'r(識別番号,軸成分) z成分
'r = √(x^2+y^2+z^2)
buf = cls34.■加34(cls34.■乗34(差異(1), 差異(1)), cls34.■乗34(差異(2), 差異(2)))
buf = cls34.■加34(buf, cls34.■乗34(差異(3), 差異(3)))
rrr = cls34.★Sqr34(buf)
' sum_a = -G * m(基準天体) * 差異(軸) / rrr / rrr / rrr + sum_a '相違し、且つ、計算する軸成分だけを積算する
buf2 = cls34.■乗34(cls34.■乗34(cls34.■乗34(数字_1, G), m(基準天体)), 差異(軸))
rrr3 = cls34.■累乗34(rrr, -3)
sum_a = cls34.■加34(cls34.■乗34(buf2, rrr3), sum_a)
End If
Next 基準天体
速度変位成分_func = sum_a '加速度 1成分のみ
Set cls34 = Nothing
End Function
Function 位置変位成分_func(ByVal 被番号, ByVal 軸, ByVal t, ByVal R, ByVal v) As String ' (位置変位 m/s)を返す
' dx/dt = v
位置変位成分_func = v(被番号, 軸) '単に速度ベクトルを返す 1成分のみ
End Function