. Cプログラミング (2014) . 第 11 回 – 宿題2の解説,演習2 – 松田七美男 2014 年 12 月 18 日 . 宿題 2:概要 . 強制振動の過渡応答 . 一次元の強制振動の初期値問題 1 1 x ¨ = −x − x˙ + cos t, x(0) = 0, x(0) ˙ = v0 4 2 を,4 次のルンゲ-クッタ法で数値解析し変位 x(t) の絶対値 |x| の 最大値を数値的に求めなさい. . . 初期速度 v0 を「学籍番号÷ 10」,としなさい. 例)1Y13B078 ⇒ v0 = 78/10 = 7.8 1 . 刻み幅 h は始め 0.01 とし,|x| が最大となる時間 t1 を 0.01 の精度で見つける.続いて t1 − 0.01 から,刻み幅を細かく h = 1 × 10−6 に変えて再計算して |x| が最大になる時間を 1 × 10−6 の精度で見つける. 2 . 解析する時間の最大値 Tmax は,30 程度としなさい. 3 . 宿題 2:振動の様子 v0 = 1, 2, 5, 10 とした場合の振動の様子を図に示します.変位の 絶対値が最も大きくなるのは t = 2, 5 付近の初めの 2 つピークの どちらかであることが一目瞭然です. 10 v0 = 1 2 5 10 8 6 x(t) 4 2 0 -2 -4 -6 -8 0 5 10 15 t . 20 25 30 . 宿題 2:振動の様子 v0 = 1, 2, 5, 10 とした場合の振動の様子を図に示します.変位の 絶対値が最も大きくなるのは t = 2, 5 付近の初めの 2 つピークの どちらかであることが一目瞭然です. 10 v0 = 1 2 5 10 8 6 x(t) 4 2 0 -2 -4 -6 -8 0 5 10 15 t . 20 25 30 . 解答例 #include #include #include #include #define #define #define #define <stdio.h> <stdlib.h> <math.h> "rk4fix.h" Tmax H HH V0 while (t < Tmax){ xtmp = r[0]; vtmp = r[3]; rk4fixv6(mov, t, r, h); t += h; if (fabs(r[0]) > xmax) { xmax = fabs(r[0]); t1 = t; xm1 = xtmp; vm1 = vtmp; } } 30 0.01 1e-6 7.8 vec6 mov(double t, double r[6]) { vec6 ret; ret.f[0] ret.f[1] ret.f[2] ret.f[3] ret.f[4] ret.f[5] = = = = = = h = HH; tm = t1; t = t1 - H; r[0] = xm1; r[3] = vm1; r[3]; 0; 0; -r[0] - 0.25*r[3] + cos(0.5*t); 0; 0; while (t <= t1 + 2*H){ rk4fixv6(mov, t, r, h); t += h; if (fabs(r[0]) > xmax) { xmax = fabs(r[0]); tm = t; } } printf("xmax = %.8f at tm = %.7f\n", xmax, tm); return ret; } int main(int argc, char **argv) { double t = 0, h = H, t1 = 0, tm = 0, xtmp, xm1, vtmp, vm1, xmax = 0, r[6] = {0, 0, 0, V0, 0, 0}; return 0; . } . 解答例 #include #include #include #include #define #define #define #define <stdio.h> <stdlib.h> <math.h> "rk4fix.h" Tmax H HH V0 30 0.01 1e-6 7.8 while (t < Tmax){ xtmp = r[0]; vtmp = r[3]; rk4fixv6(mov, t, r, h); t += h; if (fabs(r[0]) > xmax) { xmax = fabs(r[0]); t1 = t; xm1 = xtmp; vm1 = vtmp; } } 定数の定義 vec6 mov(double t, double r[6]) { vec6 ret; ret.f[0] ret.f[1] ret.f[2] ret.f[3] ret.f[4] ret.f[5] = = = = = = h = HH; tm = t1; t = t1 - H; r[0] = xm1; r[3] = vm1; r[3]; 0; 0; -r[0] - 0.25*r[3] + cos(0.5*t); 0; 0; while (t <= t1 + 2*H){ rk4fixv6(mov, t, r, h); t += h; if (fabs(r[0]) > xmax) { xmax = fabs(r[0]); tm = t; } } printf("xmax = %.8f at tm = %.7f\n", xmax, tm); return ret; } int main(int argc, char **argv) { double t = 0, h = H, t1 = 0, tm = 0, xtmp, xm1, vtmp, vm1, xmax = 0, r[6] = {0, 0, 0, V0, 0, 0}; return 0; . } . 解答例 #include #include #include #include #define #define #define #define <stdio.h> <stdlib.h> <math.h> "rk4fix.h" Tmax H HH V0 30 0.01 1e-6 7.8 while (t < Tmax){ xtmp = r[0]; vtmp = r[3]; rk4fixv6(mov, t, r, h); t += h; if (fabs(r[0]) > xmax) { xmax = fabs(r[0]); t1 = t; xm1 = xtmp; vm1 = vtmp; } } 定数の定義 vec6 mov(double t, double r[6]) { vec6 ret; ret.f[0] ret.f[1] ret.f[2] ret.f[3] ret.f[4] ret.f[5] = = = = = = h = HH; tm = t1; t = t1 - H; r[0] = xm1; r[3] = vm1; r[3]; 微分方程式の記述 0; 0; -r[0] - 0.25*r[3] + cos(0.5*t); 0; 0; while (t <= t1 + 2*H){ rk4fixv6(mov, t, r, h); t += h; if (fabs(r[0]) > xmax) { xmax = fabs(r[0]); tm = t; } } printf("xmax = %.8f at tm = %.7f\n", xmax, tm); return ret; } int main(int argc, char **argv) { double t = 0, h = H, t1 = 0, tm = 0, xtmp, xm1, vtmp, vm1, xmax = 0, r[6] = {0, 0, 0, V0, 0, 0}; return 0; . } . 解答例 #include #include #include #include #define #define #define #define <stdio.h> <stdlib.h> <math.h> "rk4fix.h" Tmax H HH V0 30 0.01 1e-6 7.8 while (t < Tmax){ xtmp = r[0]; 前の値の保存 vtmp = r[3]; rk4fixv6(mov, t, r, h); t += h; if (fabs(r[0]) > xmax) { xmax = fabs(r[0]); t1 = t; xm1 = xtmp; vm1 = vtmp; } } 定数の定義 vec6 mov(double t, double r[6]) { vec6 ret; ret.f[0] ret.f[1] ret.f[2] ret.f[3] ret.f[4] ret.f[5] = = = = = = h = HH; tm = t1; t = t1 - H; r[0] = xm1; r[3] = vm1; r[3]; 微分方程式の記述 0; 0; -r[0] - 0.25*r[3] + cos(0.5*t); 0; 0; while (t <= t1 + 2*H){ rk4fixv6(mov, t, r, h); t += h; if (fabs(r[0]) > xmax) { xmax = fabs(r[0]); tm = t; } } printf("xmax = %.8f at tm = %.7f\n", xmax, tm); return ret; } int main(int argc, char **argv) { double t = 0, h = H, t1 = 0, tm = 0, xtmp, xm1, vtmp, vm1, xmax = 0, r[6] = {0, 0, 0, V0, 0, 0}; return 0; . } . 解答例 #include #include #include #include #define #define #define #define <stdio.h> <stdlib.h> <math.h> "rk4fix.h" Tmax H HH V0 30 0.01 1e-6 7.8 while (t < Tmax){ xtmp = r[0]; 前の値の保存 vtmp = r[3]; rk4fixv6(mov, t, r, h); t += h; if (fabs(r[0]) > xmax) { xmax = fabs(r[0]); t1 = t; xm1 = xtmp; 最大値の探索と vm1 = vtmp; 相応する値の保存 } } 定数の定義 vec6 mov(double t, double r[6]) { vec6 ret; ret.f[0] ret.f[1] ret.f[2] ret.f[3] ret.f[4] ret.f[5] = = = = = = h = HH; tm = t1; t = t1 - H; r[0] = xm1; r[3] = vm1; r[3]; 微分方程式の記述 0; 0; -r[0] - 0.25*r[3] + cos(0.5*t); 0; 0; while (t <= t1 + 2*H){ rk4fixv6(mov, t, r, h); t += h; if (fabs(r[0]) > xmax) { xmax = fabs(r[0]); tm = t; } } printf("xmax = %.8f at tm = %.7f\n", xmax, tm); return ret; } int main(int argc, char **argv) { double t = 0, h = H, t1 = 0, tm = 0, xtmp, xm1, vtmp, vm1, xmax = 0, r[6] = {0, 0, 0, V0, 0, 0}; return 0; . } . 解答例 #include #include #include #include #define #define #define #define <stdio.h> <stdlib.h> <math.h> "rk4fix.h" Tmax H HH V0 30 0.01 1e-6 7.8 while (t < Tmax){ xtmp = r[0]; 前の値の保存 vtmp = r[3]; rk4fixv6(mov, t, r, h); t += h; if (fabs(r[0]) > xmax) { xmax = fabs(r[0]); t1 = t; xm1 = xtmp; 最大値の探索と vm1 = vtmp; 相応する値の保存 } } 定数の定義 vec6 mov(double t, double r[6]) { vec6 ret; ret.f[0] ret.f[1] ret.f[2] ret.f[3] ret.f[4] ret.f[5] = = = = = = h = HH; tm = t1; t = t1 - H; r[0] = xm1; r[3] = vm1; r[3]; 微分方程式の記述 0; 0; -r[0] - 0.25*r[3] + cos(0.5*t); 0; 0; while (t <= t1 + 2*H){ rk4fixv6(mov, t, r, h); t += h; if (fabs(r[0]) > xmax) { xmax = fabs(r[0]); tm = t; } } printf("xmax = %.8f at tm = %.7f\n", xmax, tm); return ret; } int main(int argc, char **argv) { double t = 0, h = H, t1 = 0, tm = 0, xtmp, xm1, vtmp, vm1, xmax = 0, r[6] = {0, 0, 0, V0, 0, 0}; return 0; . 時間を戻して値設定 } . 解答例 #include #include #include #include #define #define #define #define <stdio.h> <stdlib.h> <math.h> "rk4fix.h" Tmax H HH V0 30 0.01 1e-6 7.8 while (t < Tmax){ xtmp = r[0]; 前の値の保存 vtmp = r[3]; rk4fixv6(mov, t, r, h); t += h; if (fabs(r[0]) > xmax) { xmax = fabs(r[0]); t1 = t; xm1 = xtmp; 最大値の探索と vm1 = vtmp; 相応する値の保存 } } 定数の定義 vec6 mov(double t, double r[6]) { vec6 ret; ret.f[0] ret.f[1] ret.f[2] ret.f[3] ret.f[4] ret.f[5] = = = = = = h = HH; tm = t1; t = t1 - H; r[0] = xm1; r[3] = vm1; r[3]; 微分方程式の記述 0; 0; -r[0] - 0.25*r[3] + cos(0.5*t); 0; 0; t1 時間を戻して値設定 H H while (t <= t1 + 2*H){ 2H の範囲にある rk4fixv6(mov, t, r, h); t += h; if (fabs(r[0]) > xmax) { xmax = fabs(r[0]); tm = t; } } printf("xmax = %.8f at tm = %.7f\n", xmax, tm); return ret; } int main(int argc, char **argv) { double t = 0, h = H, t1 = 0, tm = 0, xtmp, xm1, vtmp, vm1, xmax = 0, r[6] = {0, 0, 0, V0, 0, 0}; return 0; . max } . 解答例 #include #include #include #include #define #define #define #define <stdio.h> <stdlib.h> <math.h> "rk4fix.h" Tmax H HH V0 30 0.01 1e-6 7.8 while (t < Tmax){ xtmp = r[0]; 前の値の保存 vtmp = r[3]; rk4fixv6(mov, t, r, h); t += h; if (fabs(r[0]) > xmax) { xmax = fabs(r[0]); t1 = t; xm1 = xtmp; 最大値の探索と vm1 = vtmp; 相応する値の保存 } } 定数の定義 vec6 mov(double t, double r[6]) { vec6 ret; ret.f[0] ret.f[1] ret.f[2] ret.f[3] ret.f[4] ret.f[5] = = = = = = h = HH; tm = t1; t = t1 - H; r[0] = xm1; r[3] = vm1; r[3]; 微分方程式の記述 0; 0; -r[0] - 0.25*r[3] + cos(0.5*t); 0; 0; t1 時間を戻して値設定 H H while (t <= t1 + 2*H){ 2H の範囲にある rk4fixv6(mov, t, r, h); t += h; if (fabs(r[0]) > xmax) { xmax = fabs(r[0]); tm = t; 10−6 の精度で最大値の探索 } } printf("xmax = %.8f at tm = %.7f\n", xmax, tm); return ret; } int main(int argc, char **argv) { double t = 0, h = H, t1 = 0, tm = 0, xtmp, xm1, vtmp, vm1, xmax = 0, r[6] = {0, 0, 0, V0, 0, 0}; return 0; . max } . 演習 2 . 平方根関数の自作 . √ 平方根 x を計算する関数 double mysqrt( double x) を作成しなさい. ただし,x の値に応じて以下の場合分けを行って算出するものと します. . . 0.01 ≤ x ≤ 100 の値に対しては,方程式 f (ξ) = ξ 2 − x = 0 の解を ニュートン法 (試行回数 8) で求めなさい.これは,次の漸化式を 計算することになります. ( ) 1 x ξ0 = x, ξk+1 = ξk + 2 ξk 1 √ . 上記範囲外については x × (10)2n = 10n √x と変換することに より算出しなさい. .3 引数 x の平方根を,自作 mysqrt() と数学関数ライブラリの sqrt() について比較するプログラムを作成し,自分の学籍番号を X とし て,X, X × 10−4 , X × 105 に対して実行しなさい. 2 . 演習 2 提出に関する注意 Waseda-net Web メールサービスを用いて提 出しなさい. 宛先は [email protected] 件名には,学生番号(英数半角),名前,演習 2 をこの 順に記述しなさい. 例)1Y13B999,△○ ×□,演習 2 〆切は,12 月 18 日 10:30 送信控えの保存を忘れずに ソース(inv mat.c と lineq invmat.c)と実行 結果の両方が必要.添付不可. ソースには空白を挿入したり,字下げをほど こすなど読みやすくなる工夫をしなさい.
© Copyright 2024 ExpyDoc