今流行りのLLMによるプログラミングに挑戦。
今回試したやつでは、Googleのbardではちゃんとしたものが作れませんでしたが、bingのchatではFortranのそれっぽいコードを生成してくれました。
モジュールの本体だけが出力されていたので、fpmのサブルーチンに組み込んで作ってしまいました。
まずは準備。
$ fpm new rk
$ cd rk/src
fpmを実行すると app/main.f90 と src/rk.f90 が生成されるので、rk.f90 の方にbingの出力を張りつけます。
module rk
implicit none
private
public :: say_hello
contains
subroutine say_hello
! パラメータの設定
real :: m = 1.0 ! 質量
real :: k = 0.1 ! 空気抵抗係数
real :: g = 9.8 ! 重力加速度
real :: dt = 0.01 ! 時間刻み
real :: tmax = 10.0 ! 最大時間
! 変数の宣言
real :: x, y, z ! 座標
real :: vx, vy, vz ! 速度
real :: t ! 時間
real :: k1_x, k2_x, k3_x, k4_x ! x方向のルンゲクッタ係数
real :: k1_y, k2_y, k3_y, k4_y ! y方向のルンゲクッタ係数
real :: k1_z, k2_z, k3_z, k4_z ! z方向のルンゲクッタ係数
! 初期値の設定
x = 0.0
y = 0.0
z = 100.0
vx = 10.0
vy = 10.0
vz = 0.0
t = 0.0
! ループの開始
do while (z > 0 .and. t < tmax)
! x方向のルンゲクッタ係数の計算
k1_x = vx * dt
k2_x = (vx - k * vx / m * dt / 2) * dt
k3_x = (vx - k * vx / m * dt / 2) * dt
k4_x = (vx - k * vx / m * dt) * dt
! y方向のルンゲクッタ係数の計算
k1_y = vy * dt
k2_y = (vy - k * vy / m * dt / 2) * dt
k3_y = (vy - k * vy / m * dt / 2) * dt
k4_y = (vy - k * vy / m * dt) * dt
! z方向のルンゲクッタ係数の計算
k1_z = vz * dt
k2_z = (vz - g - k * vz / m * dt / 2) * dt
k3_z = (vz - g - k * vz / m * dt / 2) * dt
k4_z = (vz - g - k * vz / m * dt) * dt
! x方向の速度と位置の更新
vx = vx - k * vx / m * dt
x = x + (k1_x + 2*k2_x + 2*k3_x + k4_x) / 6
! y方向の速度と位置の更新
vy = vy - k * vy / m * dt
y = y + (k1_y + 2*k2_y + 2*k3_y + k4_y) / 6
! z方向の速度と位置の更新
vz = vz - g - k * vz / m * dt
z = z + (k1_z + 2*k2_z + 2*k3_z + k4_z) / 6
! 時間の更新
t = t + dt
! 時系列データの表示(小数点以下3桁まで)
print "(F10.3,x,F10.3,x,F10.3,x,F10.3)", t, x, y, z
end do
! プログラムの終了
end subroutine say_hello
end module rk
サブルーチン名のsay_helloというのはデフォルトで作られるもので、変更していませんが、通常はらしい名前に変更します。
メインルーチンは生成されたやつをそのまま使います。
program main
use rk, only: say_hello
implicit none
call say_hello()
end program main
あとはfpmでビルドして実行するだけ。
$ cd ..
$ fpm run
これで、時系列のXYZ座標値が画面にずらっと出力されるのでした。
メモしてなかったのですが、bingに喰わせたプロンプトは大体次みたいのだったかと。
空力を考慮した落下時の時々刻々の位置をルンゲクッタ方を用いてFortran2000で書いてください。
もしかしたら、他にも色々と付け加えていたかもしれないです。
言語を指定しなかったら、デフォでPythonの結果を出していました。LISPで出力しようとしましたが、sbclではうまく動かせませんでした。
まぁ、部品を作るのには役に立つのかもしれませんね。それをうまく組み合わせてやると。
だんだん馬鹿にな~る。