计算方法实验报告
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include<math.h>
using namespace std;
void main(){
void ColPivot(float*,int,float []);
int i;
float x[3];
float c[4][5]={1,1,0,3,4,2,1,-1,1,1,3,-1,-1,3,-3,-1,2,3,-1,4};
while(1){
x3=x2-(f(x2)/(f(x2)-f(x1)))*(x2-x1);
x1=x2;
x2=x3;
cout<<x3<<endl;
i++;
if (i>50) break;
}
}
运行窗口
实习题三
1.用列主元消去法解方程组:
1)
实验代码
#include<iostream>
#include<stdio.h>
1)
实验代码
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
double fy(double x){
return x*x-exp(x);
}
double fd(double x){
return 2*x-exp(x);
存放n个节点的值
double y[n](double *y)
存放n个节点相对应的函数值
double p
指定插值点的值
double fun()
函数返回一个双精度实型函数值,即插值点p处的近似函数值
#include<iostream>
#include<math.h>
using namespace std;
四.实验分析
显然,题二中当n=2,n=3时,k的值没有在n-1前满足各自的精度要求,所以计算失败
从题一中可以看出,插值点的个数、精度、插值点的选择都会影响实验的结果;
我们通常会选择与插值点最接近的节点,可以提高精度;
在可以计算出结果的情况下,插值点越多,结果越精确
实习题二
1.用牛顿法求下列方程的根:
函数语句与形参说明
形参与函数类型
参数意义
int n
节点的个数
float x[MAX]
存放n个节点的值(从小到大)
Float y[MAX];
存放n个节点相对应的函数值
float x0,y0
指定插值点的横纵坐标
float e
精度
程序源代码如下:
#include<iostream>
#include<math.h>
N0=N1;
y0=y0*(x0-x[k-1]);
for(i=0;i<k;i++) y[k]=(y[k]-y[i])/(x[k]-x[i]);
N1=N0+y0*y[k];
} while (fabs(N1-N0) > e && k<(n-1));
if (k==(n-1)) cout<<"计算失败!";
if (k<(n-1)) cout<<"输出结果y[x0]="<<N1<<endl;
#include <cmath>
usingΒιβλιοθήκη Baidunamespace std;
double f(double x){
return x*x-exp(x);
}
double fd(double x){
return 2*x-exp(x);
}
void main(){
int i=0;
double x1=0,x2=1,x3; //该方程在大于0上没根,exp(x)的增长速度比x*x大的多
if(fabs(*(c+j*(n+1)+i))>(fabs(*(c+k*(n+1)+i))))k=j;
using namespace std;
#define MAX 100
void main()
{ float x[MAX],y[MAX];
float x0,y0,e,N1;
float N0=0;
int i,k,n;
cout<<"输入节点的个数,n=";
cin>>n;
cout<<"请输入插值节点!"<<endl;
由线性代数知,对任何一个不高n次的多项式P(x)=b0+b1x+b2x2+…+bnxn (幂基)①
也可将其写成P(x)=a0+a1(x-x0)+a2(x-x0) (x-x1)+…+an(x-x0) …(x-xn-1)
其中ai为系数,xi为给定节点,可由①求出ai一般情况下,牛顿插值多项式Nn(x)可写成:
上式表明:n个点xi(i=0,1,…,k-1,k+1,…,n)都是lk(x)的零点。可求得lk
三.计算方法及过程:1.输入节点的个数n
2.输入各个节点的横纵坐标
3.输入插值点
4.调用函数,返回z
函数语句与形参说明
程序源代码如下:
形参与函数类型
参数意义
int n
节点的个数
double x[n](double *x)
while(k<n)
{ if(k==0)
{ for(i=1;i<n;i++)s=s*(p-x[i])/(x[0]-x[i]);
L[0]=s*y[0];
k=k+1;}
else
{s=1.0;
for(i=0;i<=k-1;i++)s=s*((p-x[i])/(x[k]-x[i]));
for(i=k+1;i<n;i++) s=s*((p-x[i])/(x[k]-x[i]));
num=num+1.0/((i+1)*(i+1));
}
cout<<"从小加到大的结果:"<<num<<endl;
num=0;
for(i=9999;i>=0;i--){
num=num+1.0/((i+1)*(i+1));
}
cout<<"从大加到小的结果:"<<num<<endl;
}
运行窗口
4.设 ,已知其精确值为1/2(3/2-1/N-1/N+1)。
for(i=0;i<n;i++)cin>>x[i];
cout<<"please input xiangliang y= "<<endl;
for(i=0;i<n;i++)cin>>y[i];
cout<<"please input LagelangrichazhiJieDian p= "<<endl;
cin>>p;
Nn(x)= a0+a1(x-x0)+a2(x-x0) (x-x1)+…+an(x-x0) …(x-xn-1))
只需求出系数ai,即可得到插值多项式。
二、计算方法及过程
1.先后输入节点个数n和节点的横纵坐标,插值点的横坐标,最后输入精度e
2.用do-while循环语句得到跳出循环时k的值
3.将k值与n-1进行比较,若在达到精度时k<n-1,则输出计算结果;若此时k=n-1,则计算失败!
n=1时,称为线性插值,L1(x)=y0(x-x1)/(x0-x1)+ y1(x-x0)/(x1-x0)=y0+(y1-x0)(x-x0)/(x1-x0)
n=2时,称为二次插值或抛物线插值,精度相对高些
L2(x)=y0(x-x1)(x-x2)/(x0-x1)/(x0-x2)+y1(x-x0)(x-x2)/(x1-x0)/(x1-x2)+y2(x-x0)(x-x1)/(x2-x0)/(x2-x1)
cout<<"The Answer= "<<fun(x,y,n,p)<<endl;
system("pause") ;}
double fun(double x[],double y[], int n,double p)
{double z=0,s=1.0;
int k=0,i=0;
double L[N];
int N;
cout<<"input N"<<endl;
cin>>N;
cout<<"从小到大加的结果:"<<suml(N)<<endl;
cout<<"从大到小加的结果:"<<sumh(N)<<endl;
}
运行窗口
实验1拉格朗日插值法
一、方法原理
n次拉格朗日插值多项式为:Ln(x)=y0l0(x)+y1l1(x)+y2l2(x)+…+ynln(x)
}
void main(){
int i=0;
double y=2.0;
for(i=0;i<50;i++){
y=y-fy(y)/fd(y);
cout<<y<<endl;
i++;
}
}
运行窗口
2)
原理同1(1),故略
2.编写一个割线法程序,求解上述个方程
编写1(1)的割线法程序
实验代码
#include <iostream>
3<n<100时,也都有相应的答案
常用的是线性插值和抛物线插值,显然,抛物线精度相对高些
n次插值多项式Ln(x)通常是次数为n的多项式,特殊情况可能次数小于n.例如:通过三点的二次插值多项式L2(x),如果三点共线,则y=L2(x)就是一条直线,而不是抛物线,这时L2(x)是一次式。
拟合曲线光顺性差
#define N 100
double fun(double *x,double *y, int n,double p);
void main()
{int i,n;
cout<<"输入节点的个数n:";
cin>>n;
double x[N], y[N],p;
cout<<"please input xiangliang x= "<<endl;
实验2牛顿插值法
一、方法原理及基本思路
在拉格朗日插值方法中,若增加一个节点数据,其插值的多项式需重新计算。现构造一个插值多项式Nn(x),只需对Nn-1(x)作简单修正(如增加某项)即可得到,这样计算方便。
利用牛顿插值公式,当增加一个节点时,只需在后面多计算一项,而前面的计算仍有用;另一方面Nn(x)的各项系数恰好又是各阶差商,而各阶差商可用差商公式来计算。
for(i=0;i<n;i++) cin>>x[i];
cout<<"请输入对应的函数值!"<<endl;
for(i=0;i<n;i++) cin>>y[i];
cout<<"请输入插值点,x0=";
cin>>x0;
cout<<"请输入精度,e=";
cin>>e;
y0=1; N1=y[0]; k=0;
do { k++;
num=0;
int j;
for(j=2;j<N+1;j++){
num=num+1.0/(j*j-1);
}
return num;
}
double sumh(int N){
num=0;
int j;
for(j=N;j>1;j--){
num=num+1.0/(j*j-1);
}
return num;
}
void main(){
system("pause");
}
三.运行结果测试:
题一:已知f(x)=sh(x)的函数表如下:计算f(0.23)的近似值
xi
0
0.20
0.30
0.50
Sh(xi)
0
0.20134
0.30452
0.52110
题二:已知根号100等于10,根号121等于11,根号144等于12;用二次插值和三次插值计算根号115的近似值。
数值分析与算法
实
验
报
告
学 院:
指导老师:
班级:
姓 名:
学 号:
实习题一
1.用两种不同的顺序计算 ,分析其误差的变化。
实验代码
#include <iostream>
#include <cmath>
using namespace std;
void main(){
float num=0;
int i;
for(i=0;i<10000;i++){
L[k]=s*y[k];
k++;}
}
for(i=0;i<n;i++)z=z+L[i];
return z;
}
四.运行结果测试:
五.实验分析
n=2时,为一次插值,即线性插值
n=3时,为二次插值,即抛物线插值
n=1,此时只有一个节点,插值点的值就是该节点的函数值
n<1时,结果都是返回0的;这里做了n=0和n=-7两种情况
1)编制按从大到小的顺序计算Sn的程序;
2)编制按从小到大的顺序计算Sn的程序;
3)按两种顺序分别计算S1000,S10000,S30000,并指出有效位数。
实验代码
#include <iostream>
#include <cmath>
using namespace std;
double num;
double suml(int N){
ColPivot(c[0],4,x);
for(i=0;i<=3;i++)printf("x[%d]=%f\n",i,x[i]);
}
void ColPivot(float*c,int n,float x[]){
int i,j,k,t;
float p;
for(i=0;i<=n-2;i++){
k=i;
for(j=i+1;j<n-1;j++)
二、主要思路
使用线性方程组求系数构造插值公式相对复杂,可改用构造方法来插值。
对节点xi(i=0,1,…,n)中任一点xk(0<=k<=n)作一n次多项式lk(xk),使它在该点上取值为1,而在其余点xi(i=0,1,…,k-1,k+1,…,n)上为0,则插值多项式为Ln(x)=y0l0(x)+y1l1(x)+y2l2(x)+…+ynln(x)
using namespace std;
void main(){
void ColPivot(float*,int,float []);
int i;
float x[3];
float c[4][5]={1,1,0,3,4,2,1,-1,1,1,3,-1,-1,3,-3,-1,2,3,-1,4};
while(1){
x3=x2-(f(x2)/(f(x2)-f(x1)))*(x2-x1);
x1=x2;
x2=x3;
cout<<x3<<endl;
i++;
if (i>50) break;
}
}
运行窗口
实习题三
1.用列主元消去法解方程组:
1)
实验代码
#include<iostream>
#include<stdio.h>
1)
实验代码
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
double fy(double x){
return x*x-exp(x);
}
double fd(double x){
return 2*x-exp(x);
存放n个节点的值
double y[n](double *y)
存放n个节点相对应的函数值
double p
指定插值点的值
double fun()
函数返回一个双精度实型函数值,即插值点p处的近似函数值
#include<iostream>
#include<math.h>
using namespace std;
四.实验分析
显然,题二中当n=2,n=3时,k的值没有在n-1前满足各自的精度要求,所以计算失败
从题一中可以看出,插值点的个数、精度、插值点的选择都会影响实验的结果;
我们通常会选择与插值点最接近的节点,可以提高精度;
在可以计算出结果的情况下,插值点越多,结果越精确
实习题二
1.用牛顿法求下列方程的根:
函数语句与形参说明
形参与函数类型
参数意义
int n
节点的个数
float x[MAX]
存放n个节点的值(从小到大)
Float y[MAX];
存放n个节点相对应的函数值
float x0,y0
指定插值点的横纵坐标
float e
精度
程序源代码如下:
#include<iostream>
#include<math.h>
N0=N1;
y0=y0*(x0-x[k-1]);
for(i=0;i<k;i++) y[k]=(y[k]-y[i])/(x[k]-x[i]);
N1=N0+y0*y[k];
} while (fabs(N1-N0) > e && k<(n-1));
if (k==(n-1)) cout<<"计算失败!";
if (k<(n-1)) cout<<"输出结果y[x0]="<<N1<<endl;
#include <cmath>
usingΒιβλιοθήκη Baidunamespace std;
double f(double x){
return x*x-exp(x);
}
double fd(double x){
return 2*x-exp(x);
}
void main(){
int i=0;
double x1=0,x2=1,x3; //该方程在大于0上没根,exp(x)的增长速度比x*x大的多
if(fabs(*(c+j*(n+1)+i))>(fabs(*(c+k*(n+1)+i))))k=j;
using namespace std;
#define MAX 100
void main()
{ float x[MAX],y[MAX];
float x0,y0,e,N1;
float N0=0;
int i,k,n;
cout<<"输入节点的个数,n=";
cin>>n;
cout<<"请输入插值节点!"<<endl;
由线性代数知,对任何一个不高n次的多项式P(x)=b0+b1x+b2x2+…+bnxn (幂基)①
也可将其写成P(x)=a0+a1(x-x0)+a2(x-x0) (x-x1)+…+an(x-x0) …(x-xn-1)
其中ai为系数,xi为给定节点,可由①求出ai一般情况下,牛顿插值多项式Nn(x)可写成:
上式表明:n个点xi(i=0,1,…,k-1,k+1,…,n)都是lk(x)的零点。可求得lk
三.计算方法及过程:1.输入节点的个数n
2.输入各个节点的横纵坐标
3.输入插值点
4.调用函数,返回z
函数语句与形参说明
程序源代码如下:
形参与函数类型
参数意义
int n
节点的个数
double x[n](double *x)
while(k<n)
{ if(k==0)
{ for(i=1;i<n;i++)s=s*(p-x[i])/(x[0]-x[i]);
L[0]=s*y[0];
k=k+1;}
else
{s=1.0;
for(i=0;i<=k-1;i++)s=s*((p-x[i])/(x[k]-x[i]));
for(i=k+1;i<n;i++) s=s*((p-x[i])/(x[k]-x[i]));
num=num+1.0/((i+1)*(i+1));
}
cout<<"从小加到大的结果:"<<num<<endl;
num=0;
for(i=9999;i>=0;i--){
num=num+1.0/((i+1)*(i+1));
}
cout<<"从大加到小的结果:"<<num<<endl;
}
运行窗口
4.设 ,已知其精确值为1/2(3/2-1/N-1/N+1)。
for(i=0;i<n;i++)cin>>x[i];
cout<<"please input xiangliang y= "<<endl;
for(i=0;i<n;i++)cin>>y[i];
cout<<"please input LagelangrichazhiJieDian p= "<<endl;
cin>>p;
Nn(x)= a0+a1(x-x0)+a2(x-x0) (x-x1)+…+an(x-x0) …(x-xn-1))
只需求出系数ai,即可得到插值多项式。
二、计算方法及过程
1.先后输入节点个数n和节点的横纵坐标,插值点的横坐标,最后输入精度e
2.用do-while循环语句得到跳出循环时k的值
3.将k值与n-1进行比较,若在达到精度时k<n-1,则输出计算结果;若此时k=n-1,则计算失败!
n=1时,称为线性插值,L1(x)=y0(x-x1)/(x0-x1)+ y1(x-x0)/(x1-x0)=y0+(y1-x0)(x-x0)/(x1-x0)
n=2时,称为二次插值或抛物线插值,精度相对高些
L2(x)=y0(x-x1)(x-x2)/(x0-x1)/(x0-x2)+y1(x-x0)(x-x2)/(x1-x0)/(x1-x2)+y2(x-x0)(x-x1)/(x2-x0)/(x2-x1)
cout<<"The Answer= "<<fun(x,y,n,p)<<endl;
system("pause") ;}
double fun(double x[],double y[], int n,double p)
{double z=0,s=1.0;
int k=0,i=0;
double L[N];
int N;
cout<<"input N"<<endl;
cin>>N;
cout<<"从小到大加的结果:"<<suml(N)<<endl;
cout<<"从大到小加的结果:"<<sumh(N)<<endl;
}
运行窗口
实验1拉格朗日插值法
一、方法原理
n次拉格朗日插值多项式为:Ln(x)=y0l0(x)+y1l1(x)+y2l2(x)+…+ynln(x)
}
void main(){
int i=0;
double y=2.0;
for(i=0;i<50;i++){
y=y-fy(y)/fd(y);
cout<<y<<endl;
i++;
}
}
运行窗口
2)
原理同1(1),故略
2.编写一个割线法程序,求解上述个方程
编写1(1)的割线法程序
实验代码
#include <iostream>
3<n<100时,也都有相应的答案
常用的是线性插值和抛物线插值,显然,抛物线精度相对高些
n次插值多项式Ln(x)通常是次数为n的多项式,特殊情况可能次数小于n.例如:通过三点的二次插值多项式L2(x),如果三点共线,则y=L2(x)就是一条直线,而不是抛物线,这时L2(x)是一次式。
拟合曲线光顺性差
#define N 100
double fun(double *x,double *y, int n,double p);
void main()
{int i,n;
cout<<"输入节点的个数n:";
cin>>n;
double x[N], y[N],p;
cout<<"please input xiangliang x= "<<endl;
实验2牛顿插值法
一、方法原理及基本思路
在拉格朗日插值方法中,若增加一个节点数据,其插值的多项式需重新计算。现构造一个插值多项式Nn(x),只需对Nn-1(x)作简单修正(如增加某项)即可得到,这样计算方便。
利用牛顿插值公式,当增加一个节点时,只需在后面多计算一项,而前面的计算仍有用;另一方面Nn(x)的各项系数恰好又是各阶差商,而各阶差商可用差商公式来计算。
for(i=0;i<n;i++) cin>>x[i];
cout<<"请输入对应的函数值!"<<endl;
for(i=0;i<n;i++) cin>>y[i];
cout<<"请输入插值点,x0=";
cin>>x0;
cout<<"请输入精度,e=";
cin>>e;
y0=1; N1=y[0]; k=0;
do { k++;
num=0;
int j;
for(j=2;j<N+1;j++){
num=num+1.0/(j*j-1);
}
return num;
}
double sumh(int N){
num=0;
int j;
for(j=N;j>1;j--){
num=num+1.0/(j*j-1);
}
return num;
}
void main(){
system("pause");
}
三.运行结果测试:
题一:已知f(x)=sh(x)的函数表如下:计算f(0.23)的近似值
xi
0
0.20
0.30
0.50
Sh(xi)
0
0.20134
0.30452
0.52110
题二:已知根号100等于10,根号121等于11,根号144等于12;用二次插值和三次插值计算根号115的近似值。
数值分析与算法
实
验
报
告
学 院:
指导老师:
班级:
姓 名:
学 号:
实习题一
1.用两种不同的顺序计算 ,分析其误差的变化。
实验代码
#include <iostream>
#include <cmath>
using namespace std;
void main(){
float num=0;
int i;
for(i=0;i<10000;i++){
L[k]=s*y[k];
k++;}
}
for(i=0;i<n;i++)z=z+L[i];
return z;
}
四.运行结果测试:
五.实验分析
n=2时,为一次插值,即线性插值
n=3时,为二次插值,即抛物线插值
n=1,此时只有一个节点,插值点的值就是该节点的函数值
n<1时,结果都是返回0的;这里做了n=0和n=-7两种情况
1)编制按从大到小的顺序计算Sn的程序;
2)编制按从小到大的顺序计算Sn的程序;
3)按两种顺序分别计算S1000,S10000,S30000,并指出有效位数。
实验代码
#include <iostream>
#include <cmath>
using namespace std;
double num;
double suml(int N){
ColPivot(c[0],4,x);
for(i=0;i<=3;i++)printf("x[%d]=%f\n",i,x[i]);
}
void ColPivot(float*c,int n,float x[]){
int i,j,k,t;
float p;
for(i=0;i<=n-2;i++){
k=i;
for(j=i+1;j<n-1;j++)
二、主要思路
使用线性方程组求系数构造插值公式相对复杂,可改用构造方法来插值。
对节点xi(i=0,1,…,n)中任一点xk(0<=k<=n)作一n次多项式lk(xk),使它在该点上取值为1,而在其余点xi(i=0,1,…,k-1,k+1,…,n)上为0,则插值多项式为Ln(x)=y0l0(x)+y1l1(x)+y2l2(x)+…+ynln(x)