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

合集下载

(完整word版)计算方法A上机实验报告

(完整word版)计算方法A上机实验报告

计算方法A上机实验报告姓名:苏福班级:硕4020 学号:3114161019一、上机练习目的1)复习和巩固数值计算方法的基本数学模型,全面掌握运用计算机进行数值计算的具体过程及相关问题。

2)利用计算机语言独立编写、调试数值计算方法程序,培养学生利用计算机和所学理论知识分析解决实际问题的能力。

二、上机练习任务1)利用计算机语言编写并调试一系列数值方法计算通用程序,并能正确计算给定题目,掌握调试技能。

2)掌握文件使用编程技能,如文件的各类操作,数据格式设计、通用程序运行过程中文件输入输出运行方式设计等。

3)写出上机练习报告。

三、上机题目1. 共轭梯度法求解线性方程组。

(第三章)2. 三次样条插值(第四章)3. 龙贝格积分(第六章)4. 四阶龙格-库塔法求解常微分方程的初值问题四、上机报告题目1:共轭梯度法求解线性方程组1.算法原理共轭梯度法是把求解线性方程组的问题转化为求解一个与之等价的二次函数极小值的问题。

从任意给定的初始点出发,沿一组关于矩阵A共轭的方向进行线性搜索,在无舍入误差的假定下,最多迭代n 次(其中n 为矩阵A 的阶数),就可求得二次函数的极小值,也就求得了线性方程组Ax b =的解。

定理:设A 是n 阶对称正定矩阵,则x *是方程组Ax b =的解得充分必要条件是x *是二次函数1()2TT f x x Ax b x =-的极小点,即 ()()min nx R Ax b f x f x **∈=⇔=共轭梯度法的计算公式:(0)(0)(0)()()()()(1)()()(1)(1)(1)()()()(1)(1)()k T k k k T k k k k k k k k T k k k T k k k k k d r b Ax r d d Ad xx d r b Ax r Ad d Ad d r d ααββ++++++⎧==-⎪⎪=⎪⎪=+⎪⎨=-⎪⎪⎪=-⎪⎪=+⎩2. 程序框图(1)编写共轭梯度法求解对称正定矩阵的线性方程组见附录(myge.m):function x=myge(A,b)输入对称正定矩阵及对应的列向量,初始向量设为0,精度取为810 。

计算方法上机实验

计算方法上机实验

1.拉格朗日插值多项式,用于离散数据的拟合#include <stdio.h>#include <conio.h>#include <alloc.h>float lagrange(float *x,float *y,float xx,int n) /*拉格朗日插值算法*/{ int i,j;float *a,yy=0.0; /*a作为临时变量,记录拉格朗日插值多项式*/a=(float *)malloc(n*sizeof(float));for(i=0;i<=n-1;i++){ a[i]=y[i];for(j=0;j<=n-1;j++)if(j!=i) a[i]*=(xx-x[j])/(x[i]-x[j]);yy+=a[i];}free(a);return yy;}main(){ int i,n;float x[20],y[20],xx,yy;printf("Input n:");scanf("%d",&n);if(n>=20) {printf("Error!The value of n must in (0,20)."); getch();return 1;} if(n<=0) {printf("Error! The value of n must in (0,20)."); getch(); return 1;} for(i=0;i<=n-1;i++){ printf("x[%d]:",i);scanf("%f",&x[i]);}printf("\n");for(i=0;i<=n-1;i++){ printf("y[%d]:",i);scanf("%f",&y[i]);}printf("\n");printf("Input xx:");scanf("%f",&xx);yy=lagrange(x,y,xx,n);printf("x=%f,y=%f\n",xx,yy);getch();}2.牛顿插值多项式,用于离散数据的拟合#include <stdio.h>#include <conio.h>#include <alloc.h>void difference(float *x,float *y,int n){ float *f;int k,i;f=(float *)malloc(n*sizeof(float));for(k=1;k<=n;k++){ f[0]=y[k];for(i=0;i<k;i++)f[i+1]=(f[i]-y[i])/(x[k]-x[i]);y[k]=f[k];}return;}main(){ int i,n;float x[20],y[20],xx,yy;printf("Input n:");scanf("%d",&n);if(n>=20) {printf("Error! The value of n must in (0,20)."); getch(); return 1;} if(n<=0) {printf("Error! The value of n must in (0,20).");getch(); return 1;} for(i=0;i<=n-1;i++){ printf("x[%d]:",i);scanf("%f",&x[i]);}printf("\n");for(i=0;i<=n-1;i++){ printf("y[%d]:",i);scanf("%f",&y[i]);}printf("\n");difference(x,(float *)y,n);printf("Input xx:");scanf("%f",&xx);yy=y[20];for(i=n-1;i>=0;i--) yy=yy*(xx-x[i])+y[i];printf("NewtonInter(%f)=%f",xx,yy);getch();}3.高斯列主元消去法,求解其次线性方程组第一种#include<stdio.h>#include <math.h>#define N 20int main(){ int n,i,j,k;int mi,tmp,mx;float a[N][N],b[N],x[N];printf("\nInput n:");scanf("%d",&n);if(n>N){ printf("The input n should in(0,N)!\n");getch();return 1;}if(n<=0){ printf("The input n should in(0,N)!\n");getch();return 1;}printf("Now input a(i,j),i,j=0...%d:\n",n-1); for(i=0;i<n;i++){ for(j=0;j<n;j++)scanf("%f",&a[i][j]);}printf("Now input b(i),i,j=0...%d:\n",n-1);for(i=0;i<n;i++)scanf("%f",&b[i]);for(i=0;i<n-2;i++){ for(j=i+1,mi=i,mx=fabs(a[i][j]);j<n-1;j++) if(fabs(a[j][i])>mx){ mi=j;mx=fabs(a[j][i]);}if(i<mi){ tmp=b[i];b[i]=b[mi];b[mi]=tmp;for(j=i;j<n;j++){ tmp=a[i][j];a[i][j]=a[mi][j];a[mi][j]=tmp;}}for(j=i+1;j<n;j++){ tmp=-a[j][i]/a[i][i];b[j]+=b[i]*tmp;for(k=i;k<n;k++)a[j][k]+=a[i][k]*tmp;}}x[n-1]=b[n-1]/a[n-1][n-1];for(i=n-2;i>=0;i--){ x[i]=b[i];for(j=i+1;j<n;j++)x[i]-=a[i][j]*x[j];x[i]/=a[i][i];}for(i=0;i<n;i++)printf("Answer:\n x[%d]=%f\n",i,x[i]); getch();return 0;}第二种#include<math.h>#include<stdio.h>#define NUMBER 20#define Esc 0x1b#define Enter 0x0dfloat A[NUMBER][NUMBER+1] ,ark;int flag,n;exchange(int r,int k);float max(int k);message();main(){float x[NUMBER];int r,k,i,j;char celect;clrscr();printf("\n\nUse Gauss.");printf("\n\n1.Jie please press Enter."); printf("\n\n2.Exit press Esc.");celect=getch();if(celect==Esc)exit(0);printf("\n\n input n=");scanf("%d",&n);printf(" \n\nInput matrix A and B:"); for(i=1;i<=n;i++){printf("\n\nInput a%d1--a%d%d and b%d:",i,i,n,i);for(j=1;j<=n+1;j++) scanf("%f",&A[i][j]);}for(k=1;k<=n-1;k++){ark=max(k);if(ark==0){printf("\n\nIt's wrong!");message();}else if(flag!=k)exchange(flag,k);for(i=k+1;i<=n;i++)for(j=k+1;j<=n+1;j++)A[i][j]=A[i][j]-A[k][j]*A[i][k]/A[k][k];}x[n]=A[n][n+1]/A[n][n];for( k=n-1;k>=1;k--){float me=0;for(j=k+1;j<=n;j++){me=me+A[k][j]*x[j];}x[k]=(A[k][n+1]-me)/A[k][k];}for(i=1;i<=n;i++){printf(" \n\nx%d=%f",i,x[i]);}message();}exchange(int r,int k){int i;for(i=1;i<=n+1;i++)A[0][i]=A[r][i];for(i=1;i<=n+1;i++)A[r][i]=A[k][i];for(i=1;i<=n+1;i++)A[k][i]=A[0][i];}float max(int k){int i;float temp=0;for(i=k;i<=n;i++)if(fabs(A[i][k])>temp){temp=fabs(A[i][k]);flag=i;}return temp;}message(){printf("\n\n Go on Enter ,Exit press Esc!");switch(getch()){case Enter: main();case Esc: exit(0);default:{printf("\n\nInput error!");message();} }}4.龙贝格求积公式,求解定积分#include<stdio.h>#include<math.h>#define f(x) (sin(x)/x)#define N 20#define MAX 20#define a 2#define b 4#define e 0.00001float LBG(float p,float q,int n){ int i;float sum=0,h=(q-p)/n;for (i=1;i<n;i++)sum+=f(p+i*h);sum+=(f(p)+f(q))/2;return(h*sum);}void main(){ int i;int n=N,m=0;float T[MAX+1][2];T[0][1]=LBG(a,b,n);n*=2;for(m=1;m<MAX;m++){ for(i=0;i<m;i++)T[i][0]=T[i][1];T[0][1]=LBG(a,b,n);n*=2;for(i=1;i<=m;i++)T[i][1]=T[i-1][1]+(T[i-1][1]-T[i-1][0])/(pow(2,2*m)-1);if((T[m-1][1]<T[m][1]+e)&&(T[m-1][1]>T[m][1]-e)){ printf("Answer=%f\n",T[m][1]); getch();return ;}}}5.牛顿迭代公式,求方程的近似解#include<stdio.h>#include<math.h>#include<conio.h>#define N 100#define PS 1e-5#define TA 1e-5float Newton(float (*f)(float),float(*f1)(float),float x0 ) { float x1,d=0;int k=0;do{ x1= x0-f(x0)/f1(x0);if((k++>N)||(fabs(f1(x1))<PS)){ printf("\nFailed!");getch();exit();}d=(fabs(x1)<1?x1-x0:(x1-x0)/x1);x0=x1;printf("x(%d)=%f\n",k,x0);}while((fabs(d))>PS&&fabs(f(x1))>TA) ;return x1;}float f(float x){ return x*x*x+x*x-3*x-3; }float f1(float x){ return 3.0*x*x+2*x-3; }void main(){ float f(float);float f1(float);float x0,y0;printf("Input x0: ");scanf("%f",&x0);printf("x(0)=%f\n",x0);y0=Newton(f,f1,x0);printf("\nThe root is x=%f\n",y0); getch();}。

数值计算方法上机实验报告

数值计算方法上机实验报告

数值计算方法上机实验报告
一、实验目的
本次实验的主要目的是熟悉和掌握数值计算方法,学习梯度下降法的
原理和实际应用,熟悉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库的使用方法。

计算方法上上机实习报告

计算方法上上机实习报告

计算方法上上机实习报告在本次计算方法的上机实习中,我深入体验了数值计算的魅力和挑战,通过实际操作和实践,对计算方法有了更深刻的理解和认识。

实习的目的在于将课堂上学到的理论知识运用到实际的计算中,熟悉各种数值算法的实现过程,提高编程能力和解决实际问题的能力。

我们使用了具体编程语言和软件名称进行编程和计算。

在实习过程中,我首先接触到的是数值逼近的相关内容。

通过多项式插值和曲线拟合的练习,我明白了如何用简单的函数去近似复杂的曲线。

例如,拉格朗日插值法和牛顿插值法让我能够根据给定的离散数据点构建出一个连续的函数,从而对未知点进行预测。

在实际操作中,我需要仔细处理数据的输入和输出,以及算法中的细节,如边界条件和误差控制。

数值积分是另一个重要的部分。

通过梯形公式和辛普森公式,我学会了如何对给定的函数进行数值积分。

在编程实现时,要合理地选择积分区间和步长,以达到所需的精度。

同时,我也了解到了数值积分方法的误差来源和误差估计方法,这对于评估计算结果的可靠性非常重要。

线性方程组的求解是计算方法中的核心内容之一。

我分别使用了高斯消元法和迭代法(如雅克比迭代法和高斯赛德尔迭代法)来求解线性方程组。

在实际编程中,我深刻体会到了算法的效率和稳定性的重要性。

对于大规模的线性方程组,选择合适的算法可以大大提高计算速度和精度。

在非线性方程求根方面,我运用了二分法、牛顿法和割线法等方法。

这些方法各有特点,二分法简单但收敛速度较慢,牛顿法收敛速度快但需要计算导数。

在实际应用中,需要根据方程的特点和求解的要求选择合适的方法。

在实习中,我也遇到了不少问题和挑战。

首先是编程中的错误,如语法错误、逻辑错误等,这需要我耐心地调试和修改代码。

其次,对于一些复杂的算法,理解其原理和实现细节并不容易,需要反复查阅资料和思考。

还有就是数值计算中的误差问题,有时候由于误差的积累,导致计算结果与预期相差较大,需要通过调整算法参数或者采用更精确的算法来解决。

《数值计算方法》上机实验报告

《数值计算方法》上机实验报告

《数值计算方法》上机实验报告华北电力大学实验名称数值il•算方法》上机实验课程名称数值计算方法专业班级:电力实08学生姓名:李超然学号:200801001008 成绩: 指导教师:郝育黔老师实验日期:2010年04月华北电力大学实验报告数值计算方法上机实验报吿一.各算法的算法原理及计算机程序框图1、牛顿法求解非线性方程*对于非线性方程,若已知根的一个近似值,将在处展开成一阶xxfx ()0, fx ()xkk泰勒公式"f 0 / 2 八八,fxfxfxxxxx 0 0 0 0 0 kkkk2!忽略高次项,有,fxfxfxxx 0 ()()(),,, kkk右端是直线方程,用这个直线方程来近似非线性方程。

将非线性方程的**根代入,即fx ()0, X ,* fxfxxx 0 0 0 0, ,, kkkfx 0 fx 0 0,解出fX 0 *k XX,, k' fx 0 k水将右端取为,则是比更接近于的近似值,即xxxxk, Ik, Ikfx ()k 八XX, Ikk* fx()k这就是牛顿迭代公式。

,2,计算机程序框图:,见,,3,输入变量、输出变量说明:X输入变量:迭代初值,迭代精度,迭代最大次数,\0输出变量:当前迭代次数,当前迭代值xkl,4,具体算例及求解结果:2/16华北电力大学实验报吿开始读入l>k/fx()0?,0fx 0 Oxx,,01* fx ()0XX,,,?10kk, ,1,kN, ?xx, 10输出迭代输出X输出奇异标志1失败标志,3,输入变量、输出变量说明: 结束例:导出计算的牛顿迭代公式,并il •算。

(课本P39例2-16) 115cc (0), 求解结果:10. 75000010.72383710. 72380510. 7238052、列主元素消去法求解线性方程组,1,算法原理:高斯消去法是利用现行方程组初等变换中的一种变换,即用一个不为零的数乘 -个 方程后加只另一个方程,使方程组变成同解的上三角方程组,然后再自下而上 对上三角3/16华北电力大学实验报告方程组求解。

计算方法与实习上机实验报告

计算方法与实习上机实验报告

计算方法与实习上机实验报告一、引言本文旨在介绍和展示我们在“计算方法”课程中的实习上机实验环节所完成的一些关键任务和所取得的成果。

该实验课程的目标是让我们更深入地理解和应用各种计算方法,并在实际操作中提高我们的编程和问题解决能力。

二、实验内容与目标实验的主要内容是利用各种计算方法解决实际数学问题。

我们被要求使用编程语言(如Python或Java)来实现和解决这些问题。

这些问题包括使用牛顿法求解平方根,使用蒙特卡洛方法计算圆周率,以及使用最优化方法求解函数的最小值等。

实验的目标不仅是让我们掌握计算方法的基本理论,更是要让我们能够在实际操作中运用这些方法。

我们需要在实习过程中,通过与同伴们合作,共同解决问题,提高我们的团队合作能力和问题解决能力。

三、实验过程与问题解决策略在实验过程中,我们遇到了许多问题,如编程错误、理解困难和时间压力等。

我们通过相互讨论、查阅资料和寻求教师帮助等方式,成功地解决了这些问题。

例如,在实现牛顿法求解平方根时,我们一开始对导数的计算和理解出现了一些错误。

但我们通过查阅相关资料和讨论,最终理解了导数的正确计算方法,并成功地实现了牛顿法。

四、实验结果与结论通过这次实习上机实验,我们不仅深入理解了计算方法的基本理论,还在实际操作中提高了我们的编程和问题解决能力。

我们的成果包括编写出了能有效求解平方根、计算圆周率和求解函数最小值的程序。

这次实习上机实验非常成功。

我们的团队不仅在理论学习和实践操作上取得了显著的进步,还在团队合作和问题解决方面积累了宝贵的经验。

这次实验使我们对计算方法有了更深的理解和认识,也提高了我们的编程技能和解决问题的能力。

五、反思与展望回顾这次实验,我们意识到在实验过程中,我们需要更好地管理我们的时间和压力。

在解决问题时,我们需要更有效地利用我们的知识和资源。

在未来,我们希望能够更加熟练地运用计算方法,并能够更有效地解决问题。

我们也希望能够将所学的计算方法应用到更广泛的领域中,如数据分析、科学研究和工业生产等。

计算方法与实习上机报告

计算方法与实习上机报告

计算方法与实习——上机报告学院:电子工程学院学号:姓名:刘波2015.1.4计算方法与实习上机报告习题一:1 舍入误差及稳定性一、实验目的(1)通过上机编程,复习巩固以前所学程序设计语言及上机操作指令;(2)通过上机计算,了解舍入误差所引起的数值不稳定性二、实验内容1、用两种不同的顺序计算1000021n n -=∑,分析其误差的变化 2、已知连分数()101223//(.../)n n a f b b a b a a b =++++,利用下面的算法计算f : 11,i n n i i i a d b d b d ++==+(1,2,...,0)i n n =-- 0f d = 写一程序,读入011,,,...,,,...,,n n n b b b a a 计算并打印f 3、给出一个有效的算法和一个无效的算法计算积分1041nn x y dx x =+⎰ (0,1,...,10)n = 4、设2211N N j S j ==-∑,已知其精确值为1311221N N ⎛⎫-- ⎪+⎝⎭ (1)编制按从大到小的顺序计算N S 的程序 (2)编制按从小到大的顺序计算N S 的程序(3)按两种顺序分别计算10001000030000,,,S S S 并指出有效位数三、实验步骤、程序设计、实验结果及分析1、用两种不同的顺序计算1000021n n -=∑,分析其误差的变化 (1)实验步骤:分别从1~10000和从10000~1两种顺序进行计算,应包含的头文件有stdio.h 和math.h(2)程序设计:a.顺序计算#include<stdio.h>#include<math.h>void main(){double sum=0;int n=1;while(1){sum=sum+(1/pow(n,2));if(n%1000==0)printf("sun[%d]=%-30f",n,sum);if(n>=10000)break;n++;}printf("sum[%d]=%f\n",n,sum);}b.逆序计算#include<stdio.h>#include<math.h>void main(){double sum=0;int n=10000;while(n!=0){sum=sum+(1/pow(n,2));if(n%200==0)printf("sum[%d]=%-10f",n,sum);if(n<1)break;n--;}printf("sum[%d]=%f\n",n,sum);}(3)实验结果及分析:程序运行结果:a.顺序计算b.逆序计算结果分析:两种不同顺序计算结果是一样的,顺序计算误差从一开始就很小,而逆序计算误差最开始十分大,后来结果正确。

计算机上机报告

计算机上机报告

计算方法上机实验报告上课时间: 2014-2015学年秋学期, 6~14周一. 拉格朗日插值------------------------------------------------------1二. 牛顿插值------------------------------------------------------------3三. 改进欧拉法---------------------------------------------------------5四. 四阶龙格-库塔-----------------------------------------------------7五. 牛顿迭代------------------------------------------------------------9 六.复化Simpson公式------------------------------------------------11七. Romberg算法------------------------------------------------------14八. Seidel迭代法------------------------------------------------------17九. Gauss列主元消去法----------------------------------------------20一.拉格朗日插值1.程序代码#include<iostream.h>void Lagrange(){int i=0;double a[10],b[10],L,L1,L2,L3,L4,x;cout<<"x=";for(i=0;i<4;i++){cin>>a[i];}cout<<"y=";for(i=0;i<4;i++){cin>>b[i];}cout<<"x=";cin>>x;L1=(x-a[1])*(x-a[2])*(x-a[3])*b[0]/(a[0]-a[1])/(a[0]-a[2])/(a[0]-a[3]);L2=(x-a[0])*(x-a[2])*(x-a[3])*b[1]/(a[1]-a[0])/(a[1]-a[2])/(a[1]-a[3]);L3=(x-a[0])*(x-a[1])*(x-a[3])*b[2]/(a[2]-a[0])/(a[2]-a[1])/(a[2]-a[3]);L4=(x-a[0])*(x-a[1])*(x-a[2])*b[3]/(a[3]-a[0])/(a[3]-a[1])/(a[3]-a[2]);L=L1+L2+L3+L4;cout<<"L="<<L;}void main(){Lagrange();cout<<endl;}2.例子3.运行结果二. 牛顿插值1.程序代码#include <iostream.h>#include<conio.h>void main(){int n,i,j;double A[50][50],*x,*y;cout<<"请输入插值节点数: ";cin>>n;x=new double[n];y=new double[n];cout<<"请输入这"<<n<<"个插值节点(xi,yi): "<<endl;for(i=0;i<=n-1;i++)cin>>x[i]>>y[i];double K=1,xx,N=0,P;for(i=0;i<=n-1;i++){A[i][0]=x[i];A[i][1]=y[i];}for(j=2;j<=n;j++)for(i=1;i<=n-1;i++){A[i][j]=(A[i][j-1]-A[i-1][j-1])/(A[i][0]-A[i-j+1][0]);}for(i=0;i<=n-1;i++)cout<<"输出第"<<i+1<<"阶差商为: "<<A[i][i+1]<<endl;cout<<"请输入预求值x=";cin>>xx;for(i=0;i<n-1;i++){K*=xx-x[i];N+=A[i+1][i+2]*K;P=A[0][1]+N;}cout<<"Newton插值结果为: y="<<P<<endl;getch();}2.例子3.运行结果三. 改进欧拉法1.程序代码#include<iostream.h>#include<conio.h>double fun(double x,double y){return(-0.9*y/(1+2*x));}void main(){double a,b,*y,h,*x,yp,yc;int n,k;cout<<"常微分方程为y'=-0.9*y/(1+2*x)"<<endl;cout<<"其中0<=x<=1"<<endl;cout<<"初值为y(0)=1"<<endl;cout<<"请输入计算区间(a,b): ";cin>>a>>b;cout<<"请输入步长h: ";cin>>h;cout<<"请输入计算次数: ";cin>>n;y=new double[n];x=new double[n];cout<<"请输入初值y(0)=";cin>>y[0];x[0]=a;for(k=0;k<=n;k++){yp=y[k]+h*fun(x[k],y[k]);yc=y[k]+h*fun(x[k]+h,yp);y[k+1]=0.5*(yp+yc);x[k+1]=x[k]+h;}cout<<"迭代结果为: "<<endl;for(k=0;k<=n;k++)cout<<"x"<<k<<"="<<x[k]<<'\t'<<"y"<<k<<"="<<y[k]<<endl;getch();}2.例子3.运行结果四. 四阶龙格-库塔1.程序代码#include<iostream.h>#include<conio.h>double fun(double x,double y){return(x-y);}void main(){double a,b,*y,h,x,k1,k2,k3,k4;int n,k;cout<<"常微分方程为y'=x-y"<<endl;cout<<"其中0<=x<=1"<<endl;cout<<"初值为y(0)=0"<<endl;cout<<"请输入计算区间(a,b): ";cin>>a>>b;cout<<"请输入步长h: ";cin>>h;cout<<"请输入计算次数: ";cin>>n;y=new double[n];cout<<"请输入初值y(0): ";cin>>y[0];x=a;cout<<"Runge-Kutta迭代法结果为: "<<endl;cout<<"x0="<<x<<'\t'<<"y0="<<y[0]<<endl;for(k=0;k<=n-1;k++){k1=fun(x,y[k]);k2=fun(x+h/2,y[k]+k1*h/2);k3=fun(x+h/2,y[k]+k2*h/2);k4=fun(x+h,y[k]+k3*h);y[k+1]=y[k]+(h/6)*(k1+2*(k2+k3)+k4);cout<<"x"<<k+1<<"="<<x+h<<'\t'<<"y"<<k+1<<"="<<y[k+1]<<endl;x=x+h;}getch();}2.例子3.运行结果五. 牛顿迭代法1.程序代码(C++代码)#include<iostream>#include<cmath>using namespace std;double newtondiedai(double a,double b,double c,double d,double x); int main(){double a,b,c,d;double x=1.5;cout<<"请依次输入方程四个系数: ";cin>>a>>b>>c>>d;x=newtondiedai(a,b,c,d,x);cout<<x<<endl;return 0;}double newtondiedai(double a,double b,double c,double d,double x) {while(abs(a*x*x*x+b*x*x+c*x+d)>0.000001){x=x-(a*x*x*x+b*x*x+c*x+d)/(3*a*x*x+2*b*x+c);}return x;}2.例子3.运行结果六. 复化Simpson公式1.程序代码(C++代码)#include<iostream.h>#include<math.h>double function1(double x)//被积函数{double s;s=x/(4+x*x);return s;}double function2(double x)//被积函数{double s;s=sqrt(x);return s;}double ReiterationOfSimpson(double a,double b,double n,double f(double x))//复化Simpson公式{double h,fa,fb,xk,xj;h=(b-a)/n;fa=f(a);fb=f(b);double s1=0.0;double s2=0.0;for(int k=1;k<n;k++){xk=a+k*h;s1=s1+f(xk);}for(int j=0;j<n;j++){xj=a+(j+0.5)*h;s2=s2+f(xj);}double sn;//和sn=h/6*(fa+fb+2*s1+4*s2);//复化Simpson公式return sn;}main(){double a,b,Result,n;cout<<"请输入积分下限:"<<endl;cin>>a;cout<<"请输入积分上限:"<<endl;cin>>b;cout<<"请输入分割区间数n:"<<endl;cin>>n;cout<<"复化Simpson 公式计算结果:";Result=ReiterationOfSimpson(a, b, n,function1); cout<<Result<<endl;}2.例子 (620(n 3)4x I dx x ==+⎰)3.运行结果七. Romberg算法1.程序代码(C++代码)#include<iostream>#include<cmath>using namespace std;#define f(x) (4/(1+x*x))#define epsilon 0.0001#define MAXREPT 10double Romberg(double aa,double bb) { int m,n;double h,x;double s,q;double ep;double *y =new double[MAXREPT]; double p;h=bb-aa;y[0]=h*(f(aa)+f(bb))/2.0;m=1;n=1;ep=epsilon+1.0;while((ep>=epsilon)&&(m<MAXREPT)) { p =0.0;for(int i=0;i<n;i++){ x=aa+(i+0.5)*h;p=p+f(x);}p=(y[0] + h*p)/2.0;s=1.0;for(int k=1;k<=m;k++){ s=4.0*s;q=(s*p-y[k-1])/(s-1.0); y[k-1]=p;p=q;}p=fabs(q-y[m-1]);m=m+1;y[m-1]=q;n=n+n;h=h/2.0;}return (q);}int main(){double a,b;cout<<"Romberg积分,请输入积分范围a,b:"<<endl; cin>>a>>b;cout<<"积分结果:"<<Romberg(a,b)<<endl;system("pause");return 0;}2.例子(1241I dxx=+⎰)3.运行结果八. Seidel迭代法1.程序代码(C++代码)# include <math.h># include <stdio.h># define max 100# define EPS 1e-6float a[3][3]={{10,-1,-2},{-1,10,-2},{-1,-1,5}}; float b[3]={7.2,8.3,4.2};float x[3]={0,0,0};float y[3];float S(int m){int n;float S=0;float y;for(n=0;n<3;n++){if(m==n){}else{S+=a[m][n]*x[n];}}y=(b[m]-S)/a[m][m];return y;}void main(){int i;int F,T=1,k=1;do{F=0;if(T){T=0;}else{k++;for(i=0;i<3;i++){x[i]=y[i];}}for(i=0;i<3;i++){y[i]=S(i);}for(i=0;i<3;i++){if(fabs(x[i]-y[i])>EPS){F=1;}}printf("%d\n",k);}while(((F==1)&&k!=max));printf("迭代次数:%d\n",k);for(i=0;i<3;i++){printf("x[%d]=%1.6f\n",i,y[i]); }}2.例子(1012237.21102238.31253 4.2x x xx x xx x x--=⎧⎪-+-=⎨⎪--+=⎩)3.运行结果九. Gauss列主元消去法1.程序代码(C++代码)#include <stdio.h>#include<conio.h>#include <math.h>#define max_dimension 20int n;static float a[max_dimension][max_dimension]; static float b[max_dimension];static float x[max_dimension];void main(){int i;int j;int d;int row;float temp;float known_items;float l[max_dimension][max_dimension];printf("请输入阶数:");scanf("%d",&n);printf("\n");printf("请输入系数矩阵的值: ");printf("\n");for(i=0; i<n; i++){ printf("输入第%d行的值:",i+1);for (j=0; j<n; j++){scanf("%f",&a[i][j]);}printf("\n");}printf("请输入常数项的值: ");for(i=0; i<n; i++)scanf("%f",&b[i]);printf("\n");for(d=0; d<n-1; d++){row=d;for(i=d+1; i<n; i++){if(fabs(a[i][d])>fabs(a[row][d]))row=i;}if(row!=d){for(j=d; j<n; j++){temp=a[row][j];a[row][j]=a[d][j];a[d][j]=temp;}temp=b[row];b[row]=b[d];b[d]=temp;}for(i=d+1; i<n; i++){l[i][d]=-a[i][d]/a[d][d];for (j=d; j<n; j++){a[i][j]=a[i][j]+a[d][j]*l[i][d];}b[i]=b[i]+b[d]*l[i][d];}}printf("\n");for (i=n-1; i>-1; i--){known_items=0;for(j=1; j<n-i; j++){known_items=known_items+a[i][i+j]*x[i+j]; }x[i]=(b[i]-known_items)/a[i][i];}printf("方程组的根为:\n\n");for(i=0; i<n; i++)printf("%.5f ",x[i]);printf("\n\n");getch();}2.例子3.运行结果。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

计算方法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 −后形成的矩阵。

吉文斯变换矩阵具有以下性质:(1) (),,P i j θ是正交矩阵,()()1T,,,,P i j P i j θθ−=;(2) 仅改变向量的第,i j 个元素; (3) 仅改变矩阵的第,i j 行元素;(4) 可以使用有限个吉文斯矩阵乘积P ,使得12Px x e =。

()111,,111n ncsP i j sc θ⨯⎛⎫ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪⎪=⎪ ⎪ ⎪− ⎪ ⎪ ⎪ ⎪ ⎪⎝⎭i j i j(1.1)矩阵A 按列分块表示为:()12,,,n a a a ,利用性质1,2,4,可以对每一列的各个元素进行计算消去,最终可以得到图1.1的QR 矩阵。

1.1.2 基于豪斯霍尔德变换的QR 分解给定一个n 阶的向量u ,满足21u=,矩阵T 2H I uu =−就是所说的豪斯霍尔德变换矩阵,也称为初等反射阵。

该矩阵存在一定的几何意义,当3n =时,如图1.2所示,对于空间给定的向量x 可以分解为12x x x =+,其中,u 为垂直于π平面的单位法向量,于是有:120x u x ku ==, (1.2)x 1x 2x uHx2x −图1.2 空间向量分解图将空间给定的向量x 和豪斯霍尔德矩阵相乘,有:()()()T 11T T22222Hx I uu x Hx I uu x Hx I uu x ⎧=−⎪=−⇒⎨=−⎪⎩ (1.3)结合式(1.2)可以进行化简,得到:1122Hx x Hx x =⎧⎨=−⎩ (1.4) 得到的向量关于平面对称,因此也称为初等反射矩阵。

豪斯霍尔德矩阵同样存在着优良的性质: (1) 矩阵H 为对称正交矩阵T 1H H H −==;(2) 对于任意给定的单位向量u ,存在初等反射矩阵H ,使得Hx u σ=; 矩阵A 按列分块表示为:()12,,,n a a a ,利用上述性质,可以对每一列进行变换,最终可以得到图1.1的QR 矩阵。

1.2 程序流程图1.2.1 基于吉文斯变换的QR 分解流程图1.2.2 基于豪斯霍尔德变换的QR 分解流程图计算中间参数计算中间参数()()()()2TTsgn (,):,=,,+1:,R i i R i n i R i i R i n i σωσ=−⎡⎤+⎣⎦T 2,2100u H I uu H H ωω==−⎡⎤=⎢⎥⎣⎦图1.3 基于豪斯霍尔德变换的QR 分解流程图由上述流程图也可以明显的看出来,吉文斯变换的QR 分解需要的循环步骤大于豪斯霍尔德的步骤,与理论分析的一致。

1.3 程序使用说明1.3.1 基于吉文斯变换的QR 分解程序说明基于吉文斯变换的QR 分解程序主要有两个函数构成,主函数如下所示,包含相应的注释,主函数主要就是进行QR 求解,以及方程组的求解。

function [Q,R,x]=Givens(A,b)%基于吉文斯变换的QR分解与方程组求解%输入参数说明:A:参数矩阵% b:列向量m=size(A,1); %矩阵的行数n=size(A,2); %矩阵的列数R=A; %给定QR分解矩阵的初始矩阵RQ=eye(m); %给定QR分解矩阵的初始正交矩阵Qfor i=1:n-1 %分别循环对每一列[a1,a2...an] 求解[P1,P2..Pn] for j=i+1:m %对aij元素消0,求解PijAi=R(:,i); %读取第i列的所有元素Pij=Pij_cal(Ai,i,j); %调用Pij矩阵计算函数Q=Q*Pij'; %求解正交矩阵QR=Pij*R; %求解Rendend%根据QR分解结果求解方程组b=Q'*b; %方程组两边同时左乘正交矩阵Q的逆x(n)=b(n)/R(n,n); %计算初值;for i=n:-1:1 %循环求解x的值sum=0; %每次对求和变量进行初始化for j=i+1:nsum=sum+R(i,j)*x(j);endx(i)=(b(i)-sum)/R(i,i);endend子函数的主要是进行每一个元素的消去的矩阵参数计算,具体如下所示:function [Pij]=Pij_cal(Ai,i,j)%计算每个元素的正交矩阵%输入参数说明:Ai:第i行的列向量% i,j:需要消零元素的编号ai=Ai(i); %需要消元行的首元素赋值;aj=Ai(j); %消元的元素赋值;c=sqrt(ai^2+aj^2); %用于计算角度值;cos_theta=ai/c; %计算cos值sin_theta=aj/c; %计算sin值Pij=eye(length(Ai)); %给定m*m的初始单位矩阵;Pij(i,i)=cos_theta;Pij(i,j)=sin_theta;Pij(j,i)=-sin_theta;Pij(j,j)=cos_theta;end1.3.2 基于豪斯霍尔德变换的QR分解程序说明在进行豪斯霍尔德变换的编程时,我们所需奥解决的主要问题是进行QR矩阵的求解,而对于矩阵的相乘以及矩阵基本的运算和求解向量的范数而言,在进行编程的时候并没有使用自己编写的函数,而是调用了MATLAB中相应的算法。

具体的程序及相应的注释如下所示:function [Q,R,x]=householder(A,b)%基于豪斯霍尔德的QR求解与方程组求解m=size(A,1); %矩阵的行数n=size(A,2); %矩阵的列数R=A; %给定QR分解矩阵的初始矩阵RQ=eye(m); %给定QR分解矩阵的初始正交矩阵Qfor i=1:n-1if R(i,i)>=0 %对zgama符号进行判断sigma=-norm(R(i:n,i));elsesigma=norm(R(i:n,i));endw=[R(i,i)-sigma,R(i+1:n,i)']'; %求解中间计算参数wu=w/norm(w,2);H=eye(m-i+1)-2*u*u'; %求解矩阵HiH=blkdiag(eye(i-1),H); %将矩阵扩展为m*m 的矩阵 Q=Q*H'; %求解Q 矩阵 R=H*R; %求解R 矩阵 end%根据QR 分解结果求解方程组b=Q'*b; %方程组两边同时左乘正交矩阵Q 的逆 x(m)=b(m)/R(m,m); %计算初值;for i=n:-1:1 %循环求解x 的值sum=0; %每次对求和变量进行初始化 for j=i+1:nsum=sum+R(i,j)*x(j); endx(i)=(b(i)-sum)/R(i,i); end end1.4 算例计算结果为了验证所编写的程序是否正确,采用了作业题中第74页的计算实习2.4进行验证,该题具体的数据如式(1.5)所示。

54756753941287886537810987556 , 5791197553688910189587877810105756759101052A b ⎡⎤⎡⎤⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥==⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎣⎦⎣⎦(1.5)将相应的数据输入到MATLAB 中,分别运行基于吉文斯变换的QR 分解程序“[Q,R,x]=Givens(A,b)”和豪斯霍尔德程序“[Q,R,x]=householder(A,b)”可以得到相应的方程组的解如式(1.6)所示:[]T1111111x = (1.6)经过比较发现,采用两种算法得到的QR 分解矩阵,如式(1.7)所示,经过比较发现两者得到的结果在正负号方面存在差异,主要是豪斯霍尔德算法中对于σ取值确定上存在正负的情况,因此略有不同。

0.33330.33720.28770.43670.09820.22220.66530.26670.91200.01360.24620.11810.07060.13190.46670.14980.19610.14070.57040.44460.42250.33330.06570.56920.60350.05840.42360.11660.40000.0251givensQ −−−−−−−−−−−=−0.13600.37780.38150.62130.38290.46670.14980.72940.15600.15470.42000.05500.33330.06860.06400.44450.69150.07780.44520.33330.33720.28770.43670.09820.22220.6householderQ ⎡⎤⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥−−⎢⎥−−−−⎢⎥⎢⎥−−−⎣⎦−−−=6530.26670.91200.01360.24620.11810.07060.13190.46670.14980.19610.14070.57040.44460.42250.33330.06570.56920.60350.05840.42360.11660.40000.02510.13600.37780.38150.62130.38290.46670.149−−−−−−−−−−−−−−−−−−80.72940.15600.15470.42000.05500.33330.06860.06400.44450.69150.07780.4452⎡⎤⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥−⎢⎥⎢⎥−−−⎣⎦得到的上三角R 矩阵的结果如下所示15.000019.533320.933319.933321.600021.266719.80000.00007.4464 2.6996 2.90553.0995 2.3624 1.10660.00000.0000 3.2416 3.3580 1.68830.4811 2.30360.00000.00000.0000 3.73420.7405 1.6506 1.11390.00000.givensR −−−−−=−−−−householder00000.00000.0000 3.2303 3.2048 3.90190.00000.00000.00000.00000.0000 1.98010.07380.00000.00000.00000.00000.00000.00000.978615.000019.533320.933319.93321.60R ⎡⎤⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥−−⎢⎥−−−−⎢⎥⎢⎥−−−−⎣⎦−−−−−=0021.266719.80000.00007.4464 2.6996 2.9055 3.0995 2.3624 1.10660.00000.0000 3.2416 3.3580 1.68830.4811 2.30360.00000.00000.0000 3.73420.7405 1.6506 1.11390.00000.00000.00000.0000 3.2303 3.2048 3.−−−−−−−−−−−−−−−−−−−−90190.00000.00000.00000.00000.0000 1.98010.07380.00000.00000.00000.00000.00000.00000.9786⎡⎤⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥−−−⎢⎥⎢⎥⎣⎦为了验证所计算结果是否正确,采用MATLAB 中关于QR 分解的库算法,在命令栏中输入“[Q,R]=qr(A)”得到的结果与采用豪斯霍尔德的计算结果相同,在命令栏中输入“[x]=inv(A)*b ”得到的方程组的解与计算结果相同,验证了算法的正确性。

相关文档
最新文档