(1)「電気・電子工学のための数値計算法入門」橋本修著 総合電子出版社
(2)「ディジタル信号処理技術」玉井徳みち、長島厚、藤田泰弘、若井修造著 日経BP社
(3)「よくわかる有限要素法」福森栄次著 Ohmsha
http://szksrv.isc.chubu.ac.jp/java/physics/rlc/rlc0.html
http://www.asahi-net.or.jp/~jk2m-mrt/kiso_RLC.htm
http://ja.wikipedia.org/wiki/%E4%B8%89%E8%A7%92%E9%96%A2%E6%95%B0
http://www.cmplx.cse.nagoya-u.ac.jp/~furuhashi/education/CircuitMaker/chap1.pdf
http://www.akita-nct.ac.jp/~yamamoto/lecture/2003/5E/lecture_5E/diff_eq/node2.html
http://chemeng.on.coocan.jp/cemath/cemath08.html
http://homepage3.nifty.com/skomo/f6/hp6_3.htm
http://homepage1.nifty.com/gfk/rungekutta.htm
(a) 微分の説明
微分方程式の解を求める
(b) 微分方程式の解を数値計算で求める
(c) 積分の説明
(d) 関数が微分の形の形で表されているときの積分値を求める
(一般的に数値積分をする意味は、関数自体が変化の式(例えば速度の関数)などで表されているとき
ある時刻から時刻までの距離を求めたいときなどで使用される。
もちろんその変化の式が、手計算によって計算可能ならば積分によって時間と距離の関係を導出し
その時間を入れることで直接距離を導いたほうが早い。
しかし、一般的に時間と距離の関係のような式自体が導出することが不可能な場合が世の中には多く
時間と速度の関係のような変化の式を見つけ出すことの方が容易なのだが、これを手計算で積分すること
は非常に難しいため数値積分が提案された)
常微分方程式を解く前に、近似とテーラー展開を復習する
今、のときの関数値
が求められるとするとき、
変数がからわずかに違う
になったときの
は?
(1-1)
が分かっているとき
と
を結ぶ直線を
aにおける曲線の接線と等しいとみなす。
一辺をxとし、体積をyとすると
とし、
から
離れた点を考える。
(1-1)
ある点における関数
が決まるとき、
ある曲線は、近似を1次(直線),2次(曲線),3次...というように
無限個の近似曲線の集合によって、もとの曲線に近づけることができる。
これをテーラー展開という。
微分方程式の初期解を求める方法として、テイラー展開法を説明する。
1階の常微分方程式は、一般に
という形で表すことができる(微分が が、
と同じ意味になるのだが、
違和感があるが仕方がない!)。
これを初期条件
いま、の点から
離れた点
(は整数で、
とする)
の曲線の方程式を求める。
(2-1)
ここで、
なので
同じように
(2-2)
(2-2)の第一項は、
(2-2)の第二項は、 (2-3)
(2-3)の第一項は
(2-3)の第二項は
ゆえに
([再考] この計算あってるかな??)
このようにを順次計算し、初期条件
のときの結果を
(2-1)に代入するとの点から
の範囲の
を求めることができる。
が
になってしまったら、
超える直前のを
とし
再度1を超えないように計算をすればよい。
[条件]
厳密解
初期値を代入すると
いま、とすると
(2-1)
解は5項までもとめた。テイラー法の項数を増やせばより厳密解に近くなる。
以下のプログラムの結果、テイラー法の項数は10ぐらいあれば厳密解とほぼ等しくなる
#include "stdafx.h" #include<iostream> #include<fstream> #include<io.h> #include<math.h> double f(double x); double kai(int in); int _tmain(int argc, _TCHAR* argv[]) { errno_t err; FILE *fp_output; double n = 0; double h =1/40.; double x0 =0; double y2=0,y5=0,y10=0,x=0,correcty=0; double yy[10]; yy[0]= 1; //0階微分 x=0のときのy(x) yy[1]= -sin(3*x) - 3*yy[0]; //1階微分 x=0のときのy'(x) yy[2]= -3*cos(3*x)-3*yy[1]; //2階微分 x=0のときのy''(x) yy[3]= pow(3.,2.)*sin(3*x)-3*yy[2]; yy[4]= pow(3.,3.)*cos(3*x)-3*yy[3]; yy[5]= -pow(3.,4.)*sin(3*x)-3*yy[4]; yy[6]= -pow(3.,5.)*cos(3*x)-3*yy[5]; yy[7]= pow(3.,6.)*sin(3*x)-3*yy[6]; yy[8]= pow(3.,7.)*cos(3*x)-3*yy[7]; yy[9]= -pow(3.,8.)*sin(3*x)-3*yy[8]; if( err = fopen_s(&fp_output,"data.txt","w") != 0){ exit(2);} for(float n=1; (n*h) < 1;n++){ x=x0+n*h; y2 = yy[0] + (1./kai(1))*yy[1]*pow((n*h),1) + (1./kai(2))*yy[2]*pow((n*h),2); y5 = yy[0] + (1./kai(1))*yy[1]*pow((n*h),1) + (1./kai(2))*yy[2]*pow((n*h),2) + (1./kai(3))*yy[3]*pow((n*h),3) + (1./kai(4))*yy[4]*pow((n*h),4) + (1./kai(5))*yy[5]*pow((n*h),5); y10 = yy[0] + (1./kai(1))*yy[1]*pow((n*h),1) + (1./kai(2))*yy[2]*pow((n*h),2) + (1./kai(3))*yy[3]*pow((n*h),3) + (1./kai(4))*yy[4]*pow((n*h),4) + (1./kai(5))*yy[5]*pow((n*h),5) + (1./kai(6))*yy[6]*pow((n*h),6) + (1./kai(7))*yy[7]*pow((n*h),7) + (1./kai(8))*yy[8]*pow((n*h),8) + (1./kai(9))*yy[9]*pow((n*h),9) ; correcty=f(x); printf("x = %f cy = %f y2 = %f y5 = %f y10 = %f\n",x,correcty,y2,y5,y10); fprintf_s(fp_output,"%f %f %f %f %f\n",x,correcty,y2,y5,y10); } if(fp_output != NULL) fclose(fp_output); getchar(); return 0; } double kai(int in){ double ans=1; for(int n=in;n > 0;n--){ ans=ans*(double)n; } return ans; } double f(double x){ double y; y=(1./6.) * (cos(3*x)-sin(3*x)+5*exp(-3*x)); return y; }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 5.1 テイラー法 % written by embedded.samurai %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% echo off clear all close all load 'data.txt' x=data(:,1); cy=data(:,2); y2=data(:,3); y5=data(:,4); y10=data(:,5); plot(x,cy,'r-','linewidth',6); hold on plot(x,y2,'b+-','linewidth',2); hold on plot(x,y5,'g+-','linewidth',2); hold on plot(x,y10,'m+-','linewidth',2); hold on grid on xlabel('x','Fontsize',18) ylabel('y','Fontsize',18) h=legend('厳密解',..., 'テイラー法(第2項まで)',..., 'テイラー法(第5項まで)',..., 'テイラー法(第10項まで)',..., 3); set(h,'FontSize',15) axis([0 1.0 -Inf 1.2]); h=gca get(h) set(h,'LineWidth',2,..., 'FontSize',18) print -djpeg telor_method.jpg