|
楼主 |
发表于 2005-8-21 14:51
|
显示全部楼层
正餐第三道:四阶runge-kutta法程序<br>function fun_ode_runge_kutta_4<br>%建立三阶runge-kutta公式,使用其中的一个特例<br>xn=0:.1:1;<br>y0=1; <br>y_n=[];<br>for i=1:length(xn)-1<br> K1=y0-2*xn(i)/y0;<br> K2=y0+.5*diff(xn([1:2]))*K1-2*(xn(i)+.5*diff(xn([1:2])))/(y0+.5*diff(xn([1:2]))*K1);<br> K3=y0+.5*diff(xn([1:2]))*K2-2*(xn(i)+.5*diff(xn([1:2])))/(y0+.5*diff(xn([1:2]))*K2);<br> K4=y0+diff(xn([1:2]))*K3-(2*xn(i)+2*diff(xn([1:2])))/(y0+diff(xn([1:2]))*K3);<br> y_n=[y_n;y0+1/6*diff(xn([1:2]))*(K1+2*K2+2*K3+K4)];<br> y0=y_n(end);<br>end<br>%精确的解析解<br>dy=dsolve('Dy=y-2*x/y','y(0)=1','x');<br>y_exact=subs(dy,'x',{.1:.1:1});<br>% 精度比较<br>y_compare=[y_n';y_exact];<br>y_compare_minor=[y_compare(2,:)-y_compare(1,:)];<br>var_y=var(y_compare_minor');<br>=================================================================================<br>var_y=2.8864e-012<br>精
度再往上走两个量级,runge-kutta法是最常用的单步高精度微分方程的解法,ode45的基本思想即来自于此,由于lyrock对这个方法的基本
问题已经总结的比较全面,因此,我在这里只是简单介绍一下我自己学习的感受,同样,未必全面,未必精确,甚至未必正确,只是作为前面我所参与内容的一点心
得,一家之言而已:<br>runge-kutta法的基本内涵是来自于函数的taylor展开的,我们知道taylor展开是函数逼近的有效方法.但由
于展开过程中求导的机时代价过高,因此采用了在一个步长范围内再做内插节点序列,求数值差分得到内插节点序列的差分值,然后将这些斜率平均之,由此来形成
runge-kutta法的迭代格式,显然从基本思路中可以看出,runge-kutta法这样一种高精度的单步方法仅仅可用于微分方程的初值问题,不能
解决边值问题,而所谓的二阶,三阶,四阶的runge-kutta法只是在等步长中内插入不同数量的序列节点而已,我们知道,内插点越多,平均值就越接近
真实步长经过点的导数值,只是我们在实际操作过程中多了一个机时和精确度两者之间的权衡而已.而正是因为这个权衡引出了另外一个问题:如何能保证在一定机
时的情况下精确度的最理想化?即转化为处理两个问题:<br>1.怎样衡量和检验计算结果的精度?<br>2.如何依据所获得的精度处理步长?<br>这样引出了变步长的runge-kutta法,我并不清楚ode45是怎样的一种变步长的runge-kutta法,但数值分析书中对这个问题的描述是:<br>先从节点xn出发,以h为步长求得近似值,记做y_n+1_(h),由于公式局部阶段误差为o(h^5)则有:<br>y(x_n+1)-y_n+1_(h)≈ch^5<br>再将步长折半,跨两步到x_n+1求得近似值y_n+1_(h/2),每跨一步截断误差为o((h/2)^5),所以有<br>y(x_n+1)-y_n+1_(h)≈2c(h/2)^5<br>这样步长折半误差可以减少到1/16,对于最后我们所设定的精度ε,如果折半两次计算结果的偏差Δ>ε,则再折半,直到Δ<ε为止<br>反之,如果如果折半两次计算结果的偏差Δ<ε,则加倍步长,直到Δ>ε为止,这时再将步长折半一次,得到所要的结果.<br>这
样做的目的无非是得到合理的步长值使得计算速度在给定精度下最为合理,因此我们在ode45中事前并不能知道(除非你很有经验,那是另外一个故事了
^_^)步长确切等于多少(我个人的理解是这样,不知道正确与否,请大家给予指正)由于变步长的原因,我上面的工作的目的也就显现出来了,即定步长只能够
使精度达到1e-12的量级,而同样的问题,用ode45变步长方法则能够得到1e-18的精度量级,所以总体上讲虽然计算量增加,但是是合算的.其他的
问题我也等待lyrock给出更加全面的解答,他的工作应该还有最后一个部分,很期待...^_^我最近在做论文的前期编程工作,很忙,只能这样凭借记
忆,写些很粗糙的东西,上面不对的地方还请lyrock和bzzz见谅...
<br>
|
|