/****************************/ /* 倒立振り子の微分方程式 */ /* coded by Y.Suganuma */ /****************************/ import java.io.*; class Test { static double a[][] = new double [2][2], b, k1; static void main(String args[]) throws IOException { double end_t = 3.0, g = 9.8, h = 0.01, I, k, l, m, pi, r, time, ut, uti, x[], dx[], wk[][]; // 領域の確保 x = new double [2]; dx = new double [2]; wk = new double [4][2]; // 微分方程式の係数の設定 pi = 4.0 * Math.atan(1.0); ut = pi / 180.0; uti = 1.0 / ut; m = 10.0; l = 1.0; r = 0.5 * l; I = l * l / 12.0; k = m; k1 = 2.0 * m * r * g; a[0][0] = 0.0; a[0][1] = 1.0; a[1][0] = m * r * g / (I + m * r * r); a[1][1] = -k / (I + m * r * r); b = -1.0 / (I + m * r * r); // 初期設定 time = 0.0; x[0] = 10.0; x[1] = 0.0; // ラジアン単位に変換 x[0] *= ut; x[1] *= ut; // 微分方程式を解く System.out.println(time + " " + x[0]*uti); Kansu kn = new Kansu(0); while (time < end_t) { time = App.rkg(time, h, x, dx, wk, 2, kn); System.out.println(time + " " + x[0]*uti); } } } /****************************/ /* 倒立振り子の運動方程式 */ /* time : 時間 */ /* x : 位置と速度 */ /* dx : xの微分 */ /****************************/ class Kansu { private int sw; // コンストラクタ Kansu (int s) {sw = s;} // void型関数 void snx(double time, double x[], double dx[]) { switch (sw) { case 0: dx[0] = Test.a[0][0] * x[0] + Test.a[0][1] * x[1]; dx[1] = Test.a[1][0] * Math.sin(x[0]) + Test.a[1][1] * x[1] + Test.b * Test.k1 * x[0]; break; } } } /************************ /* 科学技術系算用の手法 */ /************************/ class App { /*************************************************/ /* ルンゲ・クッタ法 dx/dt=f(t,x) */ /* time : 現在の時間 */ /* h : 時間刻み幅 */ /* x : 現在の状態 */ /* dx : 微係数(f(t,x):snxで計算する) */ /* g : 作業域(g[4][n]) */ /* n : 微分方程式の次数 */ /* kn : 微係数を計算するクラスオブジェクト */ /* return : time+h */ /*************************************************/ static double rkg(double time, double h, double x[], double dx[], double g[][], int n, Kansu kn) { int i1; double h2; h2 = 0.5 * h; kn.snx(time, x, dx); for (i1 = 0; i1 < n; i1++) g[0][i1] = h * dx[i1]; time += h2; for (i1 = 0; i1 < n; i1++) g[1][i1] = x[i1] + 0.5 * g[0][i1]; kn.snx(time, g[1], dx); for (i1 = 0; i1 < n; i1++) g[1][i1] = h * dx[i1]; for (i1 = 0; i1 < n; i1++) g[2][i1] = x[i1] + 0.5 * g[1][i1]; kn.snx(time, g[2], dx); for (i1 = 0; i1 < n; i1++) g[2][i1] = h * dx[i1]; time += h2; for (i1 = 0; i1 < n; i1++) g[3][i1] = x[i1] + g[2][i1]; kn.snx(time, g[3], dx); for (i1 = 0; i1 < n; i1++) g[3][i1] = h * dx[i1]; for (i1 = 0; i1 < n; i1++) x[i1] = x[i1] + (g[0][i1] + 2.0 * g[1][i1] + 2.0 * g[2][i1] + g[3][i1]) / 6.0; return time; } }