计算方法上机作业
计算方法上机报告_董晓壮

计算方法A上机报告学院(系):电气工程学院学生姓名:陶然学号:授课老师:完成日期:2019年12月03日西安交通大学Xi'an Jiaotong University目录1 QR分解法求解线性方程组 (2)1.1 算法原理 (2)1.1.1 基于吉文斯变换的QR分解 (2)1.1.2 基于豪斯霍尔德变换的QR分解 (3)1.2 程序流程图 (4)1.2.1 基于吉文斯变换的QR分解流程图 (4)1.2.2 基于豪斯霍尔德变换的QR分解流程图 (5)1.3 程序使用说明 (5)1.3.1 基于吉文斯变换的QR分解程序说明 (5)1.3.2 基于豪斯霍尔德变换的QR分解程序说明 (7)1.4 算例计算结果 (8)2 共轭梯度法求解线性方程组 (10)2.1 算法原理 (10)2.2 程序流程图 (10)2.3 程序使用说明 (11)2.4 算例计算结果 (12)3 三次样条插值 (14)3.1 算法原理 (14)3.2 程序流程图 (16)3.3 程序使用说明 (17)3.4 算例计算结果 (19)4 龙贝格积分 (21)4.1 算法原理 (21)4.2 程序流程图 (22)4.3 程序使用说明 (23)4.4 算例计算结果 (24)结论 (26)1 QR 分解法求解线性方程组1.1 算法原理矩阵的QR 分解是指,可以将矩阵A 分解为一个正交矩阵Q 和一个上三角矩阵R 的乘积,实际中,QR 分解经常被用来解决线性最小二乘问题,分解情况如图1.1所示。
=⨯图1.1 QR 分解示意图本次上机学习主要进行了两个最基本的正交变换—吉文斯(Givens )变换和豪斯霍尔德(Householder )变换,并由此导出矩阵的QR 分解以及求解线性方程组的的方法。
1.1.1 基于吉文斯变换的QR 分解吉文斯矩阵也称初等旋转阵,如式(1.1)所示,它把n 阶单位矩阵I 的第,i j 行的对角元改为c ,将第i 行第j 列的元素改为s ,第j 行第i 列的元素改为s −后形成的矩阵。
计算方法大作业——龙贝格积分

3 龙贝格积分3.1 算法原理及程序框图龙贝格积分法是在复化梯形求积公式、复化辛普森求积公式和复化科茨求积公式关系的基础上,构造出的一种精度更高的数值积分方法。
对于复化梯形求积公式而言,近似积分为()2221[]41n n n n I f T T T T ≈+-=-.(11) 对于复化辛普森求积公式和复化科茨求积公式而言,也有类似的关系,如公式(12)和公式(13)。
()22221[]41n n n n I f S S S S ≈+-=- (12)()22231[]41n n n n I f C C C C ≈+-=- (13)通过对公式(11)~(13)做进一步分析,可得到公式(14)和公式(15)。
()22141n n n n S T T T =+--(14)()222141n n n n C S S S =+-- (15)根据公式(14)和公式(15)表现出来的规律,令龙贝格积分为()223141n n n n R C C C =+-- (16)其截断误差为c R h 8f (8)(η),已经具有很高的精度。
龙贝格积分法是将区间[a , b ]逐次分半进行计算,因此,对已知函数f (x )在区间[a , b ]上的龙贝格积分法的计算公式的算法如下,程序框图如图13所示。
(1) 计算T 1:[]1()()2b aT f a f b -=+;(2) 逐次计算T 2k +1:()1211221121,0,1,2222kk k k k i b a b a T T f a i k +++=--⎛⎫=++-= ⎪⎝⎭∑;(3) 逐次计算S 2k 、C 2k 和R 2k :()()()11111122222222232222141141141kk k k k k k k k k k k S T T T C S S S R C C C ++++++⎧=+-⎪-⎪⎪=+-⎨-⎪⎪=+-⎪-⎩;(4) 若122k k R R ε+-<,则取[]12k I f R +≈;否则,继续计算,直到满足精度为止。
计算方法上机作业——龙格库塔法

计算方法上机作业——龙格库塔法龙格库塔法(Runge-Kutta method)是一种常用于求解常微分方程(Ordinary Differential Equation,ODE)的数值解法。
它是由德国数学家卡尔·龙格(Carl Runge)和马丁·威尔海姆·库塔(Martin Wilhelm Kutta)在20世纪初提出的。
龙格库塔法的基本思想是通过数值逼近来计算微分方程的近似解。
在讲解龙格库塔法之前,我们先来简单回顾一下ODE的一阶常微分方程的基本形式:y′(y)=y(y,y)其中,y(y,y)是已知函数。
龙格库塔法的核心是使用差分逼近计算函数的斜率。
假设我们要求解的方程为:y′(y)=y(y,y),y(y)=y₀所需计算的点为y₀,y₁,...,yy,对应的函数值为y₀,y₁,...,yy,其中y是步长的个数。
龙格库塔法通过递推关系式来计算估计值,并不断更新当前点的函数值。
接下来以龙格库塔法的经典四阶形式为例进行说明。
该方法的基本方程如下:yy+1=yy+(y₁+2y₂+2y₃+y₄)/6y₁=ℎy(yy,yy)y₂=ℎy(yy+ℎ/2,yy+y₁/2)y₃=ℎy(yy+ℎ/2,yy+y₂/2)y₄=ℎy(yy+ℎ,yy+y₃)其中y表示当前步骤,ℎ表示步长,yy表示当前点的函数值,y₁,y₂,y₃和y₄则表示对应的斜率。
使用龙格库塔法,我们可以通过不断递归计算来求得指定区间(例如[y,y])上的函数值。
具体步骤如下:1.确定求解区间[y,y]和初始点(y₀,y₀)以及步长ℎ。
2.初始化:设置yy=y₀,yy=y₀。
3.对所有y=0,...,y−1:计算y₁,y₂,y₃和y₄,根据上述递推关系式。
根据递推关系式计算yy+1更新当前点的函数值,即yy+1=y(yy+1)。
更新当前点的y值,即yy+1=yy+ℎ。
4.返回结果:最终求得的函数值。
需要注意的是,选择适当的步长对最终结果的精度和计算效率都有重要影响。
数值计算方法上机实验报告

数值计算方法上机实验报告
一、实验目的
本次实验的主要目的是熟悉和掌握数值计算方法,学习梯度下降法的
原理和实际应用,熟悉Python语言的编程基础知识,掌握Python语言的
基本语法。
二、设计思路
本次实验主要使用的python语言,利用python下的numpy,matplotlib这两个工具,来实现数值计算和可视化的任务。
1. 首先了解numpy的基本使用方法,学习numpy的矩阵操作,以及numpy提供的常见算法,如矩阵分解、特征值分解等。
2. 在了解numpy的基本操作后,可以学习matplotlib库中的可视化
技术,掌握如何将生成的数据以图表的形式展示出来。
3. 接下来就是要学习梯度下降法,首先了解梯度下降法的主要原理,以及具体的实际应用,用python实现梯度下降法给出的算法框架,最终
可以达到所期望的优化结果。
三、实验步骤
1. 熟悉Python语言的基本语法。
首先是熟悉Python语言的基本语法,学习如何使用Python实现变量
定义,控制语句,函数定义,类使用,以及面向对象编程的基本概念。
2. 学习numpy库的使用方法。
其次是学习numpy库的使用方法,学习如何使用numpy库构建矩阵,学习numpy库的向量,矩阵操作,以及numpy库提供的常见算法,如矩阵分解,特征值分解等。
3. 学习matplotlib库的使用方法。
西安电子科技大学出版社计算方法上机答案

西安电子科技大学出版社《计算方法》任传祥等编著第九章计算方法上机参考答案实验一,算法一#include <stdio.h>#include <math.h>double I0=log(6)/log(5),I1;int n=1;main (){while(1){I1=1.0/(n)-I0*5.0;printf("%d %lf\n", n,I1);if(n>=20)break;elseI0=I1;n++;}}实验一,算法二#include <stdio.h>#include <math.h>double I0=(1/105.0+1/126.0)/2,I1;int n=20;main (){printf("%d %lf\n", n,I0);while(1){I1=1.0/(5.0*n)-I0/5.0;printf("%d %lf\n", n-1,I1);if(n<2)break;elseI0=I1;n--;}}实验二,二分法#include <stdio.h>#include <math.h>#define esp 1e-3double f(double x);main (){double a=1,b=2,x;while(fabs(b-a)>esp){x=(a+b)/2;printf("x=%lf\n",x);if(f(x)==0)break;elseif(f(x)*f(a)<0)b=x;elsea=x;}}double f(double x){return pow(x,3)-x-1;}实验二,牛顿迭代法#include<stdio.h>#include<math.h>double f(double x);double f1(double x);#define esp 1e-3void main(){double x0 = 1.5, x1;x1 = x0 - f(x0) / f1(x0);printf("x=%lf\n", x1);x0 = x1;x1 = x0 - f(x0) / f1(x0);printf("x=%lf\n", x1);while (fabs(x1 - x0)>esp){x0 = x1;x1 = x0 - f(x0) / f1(x0);printf("x=%lf\n", x1);} }double f(double x){return pow(x, 3) - x - 1;} double f1(double x){return 3 * x*x - 1;}弦割法#include<stdio.h>#include<math.h>double f(double x);#define esp 1e-3void main(){double x0 = 1.5, x1=2.0,x2;do{ x2=x1 - (x1-x0)*f(x1) /(f(x1)-f(x0));x0=x1;x1=x2;printf("x=%lf\n", x1);}while (fabs(x1 - x0)>esp);{printf("x=%lf\n", x1);}}double f(double x){return pow(x, 3) - x - 1;}实验3#include <stdio.h>/*列主元高斯消去法*/#include <math.h>float x[3],temp,max;float A[3][4]={10,-2,-1,3,-2,10,-1,15,-1,-2,5,10},c[3][4]={10,-2,-1,3,-2,10,-1,15,-1,-2,5,10}; int n=3,i,k,j,m;void main(){for(i=0;i<n;i++){max=A[i][i];k=i;for(j=j+1;j<n;j++){{max=fabs(A[j][i]);k=j;}}if(k!=i){for(j=i+1;j<=n;j++){temp=A[i][j];A[i][j]=A[k][j];A[k][j]=temp;}}for(j=i+1;j<n;j++)for(m=i+1;m<=n;m++){c[j][m]=c[j][m]+(-c[j][i]/c[i][i])*c[i][m];}}for(i=n-1;i>=0;i--){temp=0.0;for(j=n-1;j>=i+1;j--)temp=temp+c[i][j]*x[j];x[i]=(c[i][n]-temp)/c[i][i];}printf("x[1]=%f\nx[2]=%f\nx[3]=%f\n",x[0],x[1],x[2]);实验四,拉格朗日插值#include<stdio.h>int n=5,i,j;double l,L=0,X=0.5;main(){double x[5]={0.4,0.55,0.65,0.8,0.9};doubley[5]={0.41075,0.57815,0.69675,0.88811,1.02652}; for(i=0;i<n;i++){l=y[i];for(j=0;j<n;j++){if(j!=i)l=l*(X-x[j])/(x[i]-x[j]); } L=L+l;}printf("%lf\n",L);return 0;} X=0.5 X=0.7 X=0.85牛顿插值法#include<stdio.h>#include<math.h>main(){double x[5]={0.4,0.55,0.65,0.8,0.9};doubley[5]={0.41075,0.57815,0.69675,0.88811,1.02652};int n=5,i,j;double z;printf("input z\n");scanf("%lf",&z);double a[5][5];for(i=0;i<5;i++)a[i][0]=y[i];for(i=1;i<5;i++)for(j=i;j<5;j++)a[j][i]=(a[j][i-1]-a[j-1][i-1])/(x[j]-x[j-i]);double N=a[0][0],temp=1.0;for(i=1;i<n;i++){temp=temp*(z-x[i-1]);N=N+a[i][i]*temp;}printf("N=%lf\n",N);return 0;}实验五曲线拟合#include <stdio.h>#include <math.h>float x[5]={1,2,3,4,5};float y[5]={7,11,17,27,40};float A[2][3],c[2][3];float z[2],temp,max;int i,j,k,m;int n=2;void main(){for(i=0;i<5;i++){c[0][0]=A[0][0]+=1;c[0][1]=A[0][1]+=x[i];c[0][2]=A[0][2]+=y[i];c[1][0]=A[1][0]+=x[i];c[1][1]=A[1][1]+=x[i]*x[i];c[1][2]=A[1][2]+=x[i]*y[i];}/* for(i=0;i<2;i++){printf(" %lf %lf %lf\n",A[i][0],A[i][1],A[i ][2]);}*/for(i=0;i<n;i++){max=A[i][i];k=i;for(j=j+1;j<n;j++){if(fabs(A[j][i])>max){max=fabs(A[j][i]);k=j;}} if(k!=i){for(j=i+1;j<=n;j++){temp=A[i][j];A[i][j]=A[k][j];A[k][j]=temp;}}for(j=i+1;j<n;j++)for(m=i+1;m<=n;m++){c[j][m]=c[j][m]+(-c[j][i]/c[i][i])*c[i][m];}}for(i=n-1;i>=0;i--){temp=0.0;for(j=n-1;j>=i+1;j--)temp=temp+c[i][j]*z[j];z[i]=(c[i][n]-temp)/c[i][i];}printf("a=%f\nxb=%f\n",z[0],z[1]); }实验六数值积分/*梯形*/#include<stdio.h>#include<math.h> double f(double x); main(){double x[10],y[10];double h,b=1,a=0,I;int n,i;printf("n\n");scanf("%d",&n);h=(b-a)/n;for(i=0;i<=n;i++){x[i]=a+(i*h);y[i]=f(x[i]);}I=f(a)+f(b);for(i=1;i<=n-1;i++){I=I+2*y[i];}I=(h/2)*I;printf("%lf",I);}double f(double x){double f;f=1.0/(1.0+(x*x));return(f);}/*辛普森*/#include<stdio.h>#include<math.h>double f(double x);main(){double x[30],y[30];double h,b=1,a=0,I;int n,i;printf("n\n");scanf("%d",&n);//点乘2扩展h=(b-a)/n;x[10]=1;y[10]=f(x[10]);for(i=0;i<n;i++){x[2*i]=a+(i*h);y[2*i]=f(x[2*i]);x[2*i+1]=a+(i+(1.0/2.0))*h;y[(2*i)+1]=f(x[(2*i)+1]);}I=f(a)+f(b);for(i=0;i<n;i++){I=I+4*y[(2*i)+1];}for(i=1;i<n;i++){I=I+2*y[2*i];}I=(h/6)*I;printf("%lf\n",I);}double f(double x){double f;f=1.0/(1.0+(x*x));return(f);}/*梯形*//*辛普森*/。
东南大学计算方法与实习上机实验一

东南大学计算方法与实习实验报告学院:电子科学与工程学院学号:06A*****姓名:***指导老师:***实习题14、设S N=Σ(1)编制按从大到小的顺序计算S N的程序;(2)编制按从小到大的顺序计算S N的程序;(3)按两种顺序分别计算S1000,S10000,S30000,并指出有效位数。
解析:从大到小时,将S N分解成S N-1=S N-,在计算时根据想要得到的值取合适的最大的值作为首项;同理从小到大时,将S N=S N-1+ ,则取S2=1/3。
则所得式子即为该算法的通项公式。
(1)从大到小算法的C++程序如下:/*从大到小的算法*/#include<iostream>#include<iomanip>#include<cmath>using namespace std;const int max=34000; //根据第(3)问的问题,我选择了最大数为34000作为初值void main(){int num;char jus;double cor,sub;A: cout<<"请输入你想计算的值"<<'\t';cin>>num;double smax=1.0/2.0*(3.0/2.0-1.0/max-1.0/(max+1)),temps;double S[max];// cout<<"s["<<max<<"]="<<setprecision(20)<<smax<<'\n';for(int n=max;n>num;){temps=smax;S[n]=temps;n--;smax=smax-1.0/((n+1)*(n+1)-1.0);}cor=1.0/2.0*(3.0/2.0-1.0/num-1.0/(num+1.0)); //利用已知精确值公式计算精确值sub=fabs(cor-smax); //double型取误差的绝对值cout<<"用递推公式算出来的s["<<n<<"]="<<setprecision(20)<<smax<<'\n';cout<<"实际精确值为"<<setprecision(20)<<cor<<'\n';cout<<"则误差为"<<setprecision(20)<<sub<<'\n';cout<<"是否继续计算S[N],是请输入Y,否则输入N!"<<endl;cin>>jus;if ((int)jus==89||(int)jus==121) goto A;}(2)从小到大算法的C++程序如下:/*从小到大的算法*/#include<iostream>#include<iomanip>#include<cmath>using namespace std;void main(){int max;A: cout<<"请输入你想计算的数,注意不要小于2"<<'\t';cin>>max;double s2=1.0/3.0,temps,cor,sub;char jus;double S[100000];for(int j=2;j<max;){temps=s2;S[j]=temps;j++;s2+=1.0/(j*j-1.0);}cor=1.0/2.0*(3.0/2.0-1.0/j-1.0/(j+1.0)); //利用已知精确值公式计算精确值sub=fabs(cor-s2); //double型取误差的绝对值cout<<"用递推公式算出来的s["<<j<<"]="<<setprecision(20)<<s2<<'\n';cout<<"实际精确值为"<<setprecision(20)<<cor<<'\n';cout<<"则误差为"<<setprecision(20)<<sub<<'\n';cout<<"是否继续计算S[N],是请输入Y,否则输入N!"<<endl;cin>>jus;if ((int)jus==89||(int)jus==121) goto A;}(3)(注:因为程序中setprecision(20)表示输出数值小数位数20,则程序运行时所得到的有效数字在17位左右)ii.选择从小到大的顺序计算S1000、S10000、S30000的值需要计算的项S1000S10000S30000计算值0.74900049950049996 0.74966672220370571 0.74996666722220728实际精确值0.74900049950049952 0.74990000499950005 0.74996666722220373误差 4.4408920985006262*10-16 5.6621374255882984*10-15 3.5527136788005009*10-15有效数字17 17 17附上部分程序运行图:iii.实验分析通过C++程序进行计算验证采用从大到小或者从小到大的递推公式算法得到的数值基本稳定且误差不大。
东南大学计算方法上机报告实验报告完整版

实习题11. 用两种不同的顺序计算644834.11000012≈∑=-n n,试分析其误差的变化解:从n=1开始累加,n 逐步增大,直到n=10000;从n=10000开始累加,n 逐步减小,直至1。
算法1的C 语言程序如下: #include<stdio.h> #include<math.h> void main() { float n=0.0; int i; for(i=1;i<=10000;i++) { n=n+1.0/(i*i); } printf("%-100f",n); printf("\n"); float m=0.0; int j; for(j=10000;j>=1;j--) { m=m+1.0/(j*j); } printf("%-7f",m); printf("\n"); }运行后结果如下:结论: 4.设∑=-=Nj N j S 2211,已知其精确值为)11123(21+--N N 。
1)编制按从大到小的顺序计算N S 的程序; 2)编制按从小到大的顺序计算N S 的程序;3)按2种顺序分别计算30000100001000,,S S S ,并指出有效位数。
解:1)从大到小的C语言算法如下:#include<stdio.h>#include<math.h>#include<iostream>using namespace std;void main(){float n=0.0;int i;int N;cout<<"Please input N"<<endl;cin>>N;for(i=N;i>1;i--){n=n+1.0/(i*i-1);N=N-1;}printf("%-100f",n);printf("\n");}执行后结果为:N=2时,运行结果为:N=3时,运行结果为:N=100时,运行结果为:N=4000时,运行结果为:2)从小到大的C语言算法如下:#include<stdio.h>#include<math.h>#include<iostream>using namespace std;void main(){float n=0.0;int i;int N;cout<<"Please input N"<<endl;cin>>N;for(i=2;i<=N;i++){n=n+1.0/(i*i-1);}printf("%-100f",n);printf("\n");}执行后结果为:N=2时,运行结果为:N=3时,运行结果为:N=100时,运行结果为:N=4000时,运行结果为:结论:通过比较可知:N 的值较小时两种算法的运算结果相差不大,但随着N 的逐渐增大,两种算法的运行结果相差越来越大。
应用计算方法

结果分析:比较发现,经过两种改进迭代法,求重根时迭代速度明显加快。
3-4 试验目的体验 Steffensen’s method 加速技巧 试验内容:先用 Newton 法求解方程 x-tanx=0 再用 Steffensen 法求解,比较迭代步数。精确到 10-4。 迭代公式: P(k+1)=P(k)-(P(k)-tan(P(k)))/(1-(sec(P(k)))^2) 初值 P0=1 Newton 法: function [ p,k ]=fnewton( p0,max,tol ) for k=1:max p=p0-(p0-tan(p0))/(1-(sec(p0))^2); if abs(p-p0)<tol break; end p0=p; end disp(p); disp(k) % fnewton( 1,100,10^(-4) ) Steffensen 法: function [ p1,k ]=steffensen( p0,max,tol ) n=1; p(1)=p0; while n<=max for k=1:2 p(k+1)=p(k)-(p(k)-tan(p(k)))/(1-(sec(p(k)))^2); end p1=p(1)-(p(2)-p(1))^2/(p(3)-2*p(2)+p(1)); f0=p1-(p1-tan(p1))/(1-(sec(p1))^2); if abs(f0)<tol break; end n=n+1; p(1)=p1; end disp(p1); disp(n) % steffensen( 1,100,10^(-4) ) >> steffensen( 1,100,10^(-4) ) -1.3387e-07 3
3-2 试验目的:考察 Newton 法求单根的收敛速度 应用 Newton 迭代法求 3-1 中的方程,并与 3-1 中的迭代法相比较,考察收敛速度。精确到时 10-4 迭代公式: P(k+1)= P(k)-(2P(k)-eP(k)+3)/(2- eP(k)) 初值 P0=1 和-1。 Newton 法: function [ p,k ] = fnewton( p0,max,tol ) for k=1:max p=p0-(2*p0-exp(p0)+3)/(2-exp(p0)); if abs(p-p0)<tol break; end
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
计算方法第四次上机报告
2.用欧拉方法解初值
y’=10x(1-y) 0<=x<=1
Y(0)=0
取步长h=0.1,保留5位有效数字,并与准确解相比较
分析:该题目考察欧拉方法解初值问题
程序如下:
function Heun(a,b,y0,n)
h=(b-a)/n;x=a:h:b;
y=y0*ones(1,n+1);
for j=2:n+1
yp=y(j-1)+h*f(x(j-1),y(j-1));
yc=y(j-1)+h*f(x(j),yp);
y(j)=1/2*(yp+yc);
end
for k=1:n+1
fprintf('x[%d]=%f\ty[%d]=%f\n',k-1,x(k),k-1,y(k)); end
function z=f(xx,yy)
z=10*xx*(1-yy);
运行结果:
>> Heun(0,1,0,10)
x[0]=0.000000 y[0]=0.000000
x[1]=0.100000 y[1]=0.050000
x[2]=0.200000 y[2]=0.183000
x[3]=0.300000 y[3]=0.362740
x[4]=0.400000 y[4]=0.547545
x[5]=0.500000 y[5]=0.705905
x[6]=0.600000 y[6]=0.823543
x[7]=0.700000 y[7]=0.901184
x[8]=0.800000 y[8]=0.947627
x[9]=0.900000 y[9]=0.973290
x[10]=1.000000 y[10]=0.986645
>>
分析:
该结果与准确结果相比比较接近,但是有一定的误差。
6.用四阶龙格—库塔公式解第三题中的初值问题,取步长h=0.2,保留五位有效数字。
题目目的分析:
该题考查四阶龙格-库塔方法和改进欧拉方法求解精确度问题。
程序:
改进欧拉法:
function Heun(a,b,y0,n)
h=(b-a)/n;x=a:h:b;
y=y0*ones(1,n+1);
for j=2:n+1
yp=y(j-1)+h*f(x(j-1),y(j-1));
yc=y(j-1)+h*f(x(j),yp);
y(j)=1/2*(yp+yc);
end
for k=1:n+1
fprintf('x[%d]=%f\ty[%d]=%f\n',k-1,x(k),k-1,y(k));
end
四阶龙格-库塔方法:
function odeRK4(a,b,y0,n)
h=(b-a)/n;x=a:h:b;
y=y0*ones(1,n+1);
for j=2:n+1
k1=f(x(j-1),y(j-1));
k2=f(x(j-1)+h/2,y(j-1)+h/2*k1);
k3=f(x(j-1)+h/2,y(j-1)+h/2*k2);
k4=f(x(j-1)+h,y(j-1)+h*k3);
y(j)=y(j-1)+h/6*(k1+k4)+h/3*(k2+k3);
end
for k=1:n+1
fprintf('x[%d]=%f\ty[%d]=%f\n',k-1,x(k),k-1,y(k)); end
function z=f(xx,yy)
z=-yy;
结果:
>> Heun(0,1.0,1,10)
x[0]=0.000000 y[0]=1.000000
x[1]=0.100000 y[1]=0.905000
x[2]=0.200000 y[2]=0.819025
x[3]=0.300000 y[3]=0.741218
x[4]=0.400000 y[4]=0.670802
x[5]=0.500000 y[5]=0.607076
x[6]=0.600000 y[6]=0.549404
x[7]=0.700000 y[7]=0.497210
x[8]=0.800000 y[8]=0.449975
x[9]=0.900000 y[9]=0.407228
x[10]=1.000000 y[10]=0.368541
>>
>> odeRK4(0,1.0,1,5)
x[0]=0.000000 y[0]=1.000000
x[1]=0.200000 y[1]=0.818733
x[2]=0.400000 y[2]=0.670324
x[3]=0.600000 y[3]=0.548817
x[4]=0.800000 y[4]=0.449335
x[5]=1.000000 y[5]=0.367885
>>
结果分析:
由程序结果得改进欧拉法和四阶龙格-库塔法运行结果上在小数第二位后才开始有所不同,但结果相差不大,精确度都是挺高的
12.将二阶方程
化为一阶方程组,取h=0.1,用四阶龙格-库塔法求有y(0.2)的近似值,保留5位有效数字。
解:
目的分析:
该题目是要将二阶方程化为一解方程组,并用四阶龙格-库塔法求近似值。
程序如下:
公式部分:
function z=f1(xx,yy)
z=5*xx-6*yy;
四阶龙格-库塔法:
function odeRK4_1(a,b,y0,n)
h=(b-a)/n;x=a:h:b;
y=y0*ones(1,n+1);
z=-ones(1,n+1);
for j=2:n+1
k1=z(j-1);
l1=f1(z(j-1),y(j-1));
k2=z(j-1)+h/2*l1;
l2=f1(z(j-1)+h/2*l1,y(j-1)+h/2*k1);
k3=z(j-1)+h/2*l2;
l3=f1(z(j-1)+h*l2/2,y(j-1)+h/2*k2);
k4=z(j-1)+h*l3;
l4=f1(z(j-1)+h*l3,y(j-1)+h*k3);
y(j)=y(j-1)+h*(k1+2*k2+2*k3+k4)/6;
z(j)=z(j-1)+h*(l1+2*l2+2*l3+l4)/6;
end
for k=1:n+1
fprintf('x[%d]=%f\ty[%d]=%f\n',k-1,x(k),k-1,y(k));
end
end
结果图:
结果分析:
由程序结果得四阶龙格-库塔法所得y(0.2)=0.501088
所给初值问题精确解为,y(0.2)=0.5009424.两结果在数值上相差不大,精确度高。