当前位置:文档之家› 计算方法上机作业插值与拟合实验报告

计算方法上机作业插值与拟合实验报告

计算方法实验题目:班级:学号:姓名:目录计算方法实验 (1)1 实验目的 (3)2 实验步骤 (3)2.1环境配置: (3)2.2添加头文件 (3)2.3主要模块 (3)3 代码 (4)3.1主程序部分 (4)3.2多项式方程部分 (4)3.3核心算法部分 (8)3.4数据结构部分 (13)4运行结果 (19)4.1拉格朗日插值法运行结果 (19)4.2牛顿插值法运行结果 (20)4.3多项式拟合运行结果 (20)5总结 (21)拉格朗日插值法 (21)牛顿插值法 (21)多项式拟合 (21)6参考资料 (22)1 实验目的1.通过编程对拉格朗日插值法、牛顿插值法以及多项式拟合数据的理解2.观察上述方法的计算稳定性和求解精度并比较各种方法利弊2 实验步骤2.1环境配置:VS2013,C++控制台程序2.2添加头文件#include "stdio.h"#include "stdlib.h"#include "stdafx.h"2.3主要模块程序一共分成三层,最底层是数据结构部分,负责存储数据,第二层是交互部分,即多项式方程部分,负责输入输出获得数据,最上层是核心的算法部分,负责处理已获得的数据。

具体功能如下:●数据结构部分数据结构部分是整个程序的最底层,负责存储部分。

因方程系数作为数据元素插入和删除操作较少,而顺序表空间利用率大且查看方便,故此程序选用顺序表保存系数。

数据结构文件中写的是有关顺序表的所有基本操作以供其他文件调用。

本次实验使用列主元高斯消元法作为求解方程组的方法,所以也用了二维顺序表存储数组。

综上,数据结构部分文件是前两个试验的文件内容和,稍作修改。

●常系数微分方程部分多项式方程部分是程序的第二层,内容主要是常系数微分方程导数的计算和显示菜单部分。

●算法部分算法部分分为两个文件,一个是插值部分,一个是拟合部分。

插值部分文件负责有关插值的核心算法,处于整个程序最上层部分,负责拉格朗日插值法和牛顿插值法的具体实现过程。

调用方程文件的函数,将获得的数据进行处理运算,将结果返回给方程主函数和输出的第二层。

每种方法有两个函数,一个为仅仅实现一次插值的算法,另一个是和方程部分联系的函数,负责交互中想实现的整体的算法。

拟合部分文件主要负责多项式拟合的算法实现,因为要用到列主元高斯消去法所以也将此部分算法移入其中。

主函数负责获取方程系数并显示,算法和方程作为后台程序,顺序表作为存储手段。

3 代码3.1主程序部分// Interpolationandfitting.cpp : 定义控制台应用程序的入口点。

//#include "stdafx.h"#include"equation.h"#include "stdafx.h"int _tmain(int argc, _TCHAR* argv[]){GetEquation();while (Exflag){ShowMenu();}return 0;}3.2多项式方程部分方程部分头文件#ifndef _EQUATION_H#define _EQUATION_H#include "squencelist.h"#include "stdio.h"#include "stdlib.h"extern int Numberx;extern int Exflag;extern sequenlist *B;extern sequenlist *D;extern sequenlist *L;void GetEquation(void);void ShowMenu(void);void printres(sequenlist *A);void printfunction2(datacoa *A);void printfunctionf(datacoa *A);void Tip(void);#endif方程部分CPP文件#include "stdafx.h"#include "equation.h"#include "math.h"#include "alfitting.h"#include "alinterpolation.h"#include "squencelist.h"#include "stdio.h"#include<iostream>#include <iomanip>//全局变量int Numberx=0;int Exflag = 1;sequenlist *B;sequenlist *D;sequenlist *L;////////////////////////获得给定数据///////////////////////// void GetEquation(void){int j = 0;datatype x = 0;B = InitList();D = InitList();cout << "输入给定数据的个数:" << endl;cin >> Numberx;cout << "从小到大输入x,输入00结束(如y=x^2+2x+1输入1 2 1 00):" << endl;cin >> x;while (x != 00){for (j = 1; j <= Numberx; j++){if (!Insert(B, x, j))exit(0);cin >> x;}}cin.clear();cout << "输入f(x),输入00结束(如y=x^2+2x+1输入1 2 1 00):" << endl;cin >> x;while (x != 00){for (j = 1; j <= Numberx; j++){if (!Insert(D, x, j))exit(0);cin >> x;}}printres(B);printres(D);}//////////////////////////显示交互/////////////////////////////void ShowMenu(void){int c1, c2;cout << "选择插值的方法:" << endl;cout << "1.拉格朗日插值法" << endl;cout << "2.牛顿插值法" << endl;cout << "3.直接拟合" << endl;cout << "0.退出" << endl;cin >> c1;switch (c1){case 0:Tip();break;case 1:Langmethod();break;case 2:Newtonmethod();break;case 3:break;default:break;}cout << "选择拟合方式:" << endl;cout << "1.多项式拟合" << endl;cout << "2.返回插值" << endl;cout << "0.退出" << endl;cin >> c2;switch (c2){case 0:Tip();break;case 1:Fpolynomial();Tip();break;case 2:break;default:break;}}////////////////////////打印结果/////////////////////////// void printres(sequenlist *A){int i;for (i = 1; i <= A->last; i++){cout << setw(12) << A->data[i];}cout << endl;}////////////////////////打印输出矩阵/////////////////////////// void printfunction2(datacoa *A){int i, j;cout << "矩阵=" << endl;for (i = 1; i <= A->m; i++){for (j = 1; j <= A->n; j++){cout << setw(12) << A->data[i][j];}cout << endl;}}////////////////////////打印输出函数/////////////////////////// void printfunctionf(datacoa *A){int i = 1;cout << "f=";cout << A->data[i][A->n];for (i = 2; i <= A->m; i++){if (A->data[i][A->n]< 0)cout << A->data[i][A->n] << "*" << "x^" << i - 1;else cout << "+" << A->data[i][A->n] << "*" << "x^" << i - 1;}cout << endl;}////////////////////////返回提示///////////////////////////void Tip(void){int flag;cout << "输入000退出,其余返回:" << endl;cin >> flag;if (flag == 000)Exflag = 0;}3.3核心算法部分插值部分头文件#ifndef _ALINTERPOLATION_H#define _ALINTERPOLATION_H#include "stdio.h"#include "stdlib.h"void Langmethod(void);datatype Langarange(sequenlist *X, sequenlist *F, datatype x);datatype Newtoninterpolation(sequenlist *X, sequenlist *F, datatype x);void Newtonmethod(void);#endif插值部分CPP文件#include "alinterpolation.h"#include "stdafx.h"#include "squencelist.h"#include "equation.h"#include "math.h"//////////////////////////拉格朗日插值//////////////////////////// datatype Langarange(sequenlist *X, sequenlist *F, datatype x){int i, j;datatype temp = 0;L = InitList();for (i = 1; i <= Numberx; i++){Insert(L, F->data[i], i);for (j = 1; j <= Numberx; j++){if (j == i)continue;L->data[i] = L->data[i] * ((x - X->data[j]) / (X->data[i] - X->data[j]));}temp = temp + L->data[i];}return temp;}void Langmethod(void){int i;datatype x, f;cout << "请输入插值点:" << "\t";cin >> x;f = Langarange(B, D, x);i = Findi(B, x);Insert(B, x, i);Insert(D, f, i);printres(B);printres(D);}//////////////////////////牛顿多项式插值//////////////////////////// datatype Newtoninterpolation(sequenlist *X, sequenlist *F, datatype x) {int i, j, k;datacoa *FX;datatype temp1 = 0, temp2 = 0, Nn = 0;double temp = 1;FX = InitStruct();for (i = 1; i <= Numberx; i++){InsertA2(FX, X->data[i], i, 1);InsertA2(FX, F->data[i], i, 2);}for (j = 3; j <= Numberx + 1; j++){for (i = 1; i <= Numberx - j + 2; i++){temp1 = FX->data[i + 1][j - 1] - FX->data[i][j - 1];temp2 = FX->data[i + j - 2][1] - FX->data[i][1];InsertA2(FX, temp1 / temp2, i, j);}}Nn = FX->data[1][2];for (j = 3; j <= Numberx + 1; j++){for (k = 1; k <= j - 2; k++)temp = temp*(x - FX->data[k][1]);Nn = Nn + temp*FX->data[1][j];temp = 1;}return Nn;}void Newtonmethod(void){int i;datatype x, f;cout << "请输入插值点:" << "\t";cin >> x;f = Newtoninterpolation(B, D, x);i = Findi(B, x);Insert(B, x, i);Insert(D, f, i);printres(B);printres(D);}●拟合部分头文件#ifndef _ALFITTING_H#define _ALFITTING_H#include "stdio.h"#include "stdlib.h"void ColumnGaussmethod(datacoa *A, int Xnumbers);void Fpolynomial(void);#endif●拟合部分CPP文件#include "alfitting.h"#include "stdafx.h"#include "squencelist.h"#include "equation.h"#include "math.h"//////////////////////////列主元高斯消元法//////////////////////////// void ColumnGaussmethod(datacoa *A, int Xnumbers){int i, j, i2, flagc, k, j2;int Fnumber = Xnumbers - 1;datatype temp, res;for (i = 1; i < Fnumber; i++){flagc = i;for (i2 = i + 1; i2 <= Fnumber; i2++)if ((fabs(A->data[i2][i]))>(fabs(A->data[flagc][i])))flagc = i2;if (flagc != i)for (k = i; k <= Xnumbers; k++){temp = A->data[i][k];A->data[i][k] = A->data[flagc][k];A->data[flagc][k] = temp;}for (i2 = i + 1; i2 <= Fnumber; i2++){temp = A->data[i2][i] / A->data[i][i];for (j2 = i; j2 <= Xnumbers; j2++)A->data[i2][j2] = A->data[i2][j2] - temp*A->data[i][j2];}}for (i = Fnumber; i >= 1; i--){for (j = Fnumber; j >= i + 1; j--)A->data[i][Xnumbers] = A->data[i][Xnumbers] - A->data[i][j] * A->data[j][Xnumbers + 1];res = A->data[i][Xnumbers] / A->data[i][i];InsertA2(A, res, i, Xnumbers + 1);}}//////////////////////////多项式拟合////////////////////////////void Fpolynomial(void){int Xnumbers;int i, j, k;datatype s = 0, t = 0;datacoa *A;A = InitStruct();cout << "请输入拟合次数:" << "\t";cin >> Xnumbers;for (i = 1; i <= Xnumbers + 1; i++){for (j = 1; j <= Xnumbers + 1; j++){for (k = 1; k <= B->last; k++)s = s + pow(B->data[k], j + i - 2);InsertA2(A, s, i, j);s = 0;}for (k = 1; k <= B->last; k++)t = t + pow(B->data[k], i - 1)*D->data[k];InsertA2(A, t, i, Xnumbers + 2);t = 0;}ColumnGaussmethod(A, A->n);printfunctionf(A);}3.4数据结构部分数据结构头文件#ifndef _SQUENCELIST_H#define _SQUENCELIST_H#include "stdio.h"#include "stdlib.h"#include "stdafx.h"#include<iostream>using namespace std;#define maxsize 1024/***sequenlist*/typedef double datatype;typedef struct{datatype data[maxsize][maxsize];int m, n;}datacoa;typedef struct{datatype data[maxsize];int last;}sequenlist;sequenlist *InitList();int Length(sequenlist*);int Insert(sequenlist*, datatype, int);int Delete(sequenlist*, int);int Locate(sequenlist*, datatype);void del_node(sequenlist*, datatype); void PrintList(sequenlist*);int Compare_L(sequenlist*, sequenlist*); int Findi(sequenlist*L, datatype x);void Invert(sequenlist*);datacoa *InitStruct();int InsertA2(datacoa*, datatype, int, int);void DeleteLie(datacoa*L, int j);void DeleteLine(datacoa*L, int i);/***linklist*/typedef char linkdatatype;typedef struct node{linkdatatype data;struct node*next;}linklist;linklist* CreateListF();#endif数据结构CPP文件#include "stdafx.h"#include "squencelist.h"///////////////////////////////////数据结构部分//////////////////////////////////////////////////////////////////////////////sequenlist/////////////////////////////////////////// sequenlist *InitList(){sequenlist*L = (sequenlist*)malloc(sizeof(sequenlist));L->last = 0;return L;// sequenlist*L = new sequenlist;}int Length(sequenlist*L){return L->last;}int Insert(sequenlist*L, datatype x, int i){int j;if (L->last >= maxsize - 1)cout << "表已满" << endl;return 0;}for (j = L->last; j >= i; j--)L->data[j + 1] = L->data[j];L->data[i] = x;L->last++;return 1;}int Delete(sequenlist*L, int i){int j;if ((i<1) || (i>L->last)){cout << "非法删除位置" << endl;return 0;}for (j = i; j <= L->last; j++)L->data[j] = L->data[j + 1];L->last--;return 1;}int Locate(sequenlist*L, datatype x){int i = 1;while (i <= L->last){if (L->data[i] != x)i++;else return i;}return 0;}/*顺序表中删除所有元素为x的结点*/ void del_node(sequenlist*L, datatype x) {int i = Locate(L, x);while (i != 0)if (!Delete(L, i))break;i = Locate(L, x);}}void PrintList(sequenlist*L){int i = 1;for (i = 1; i <= L->last; i++)cout << L->data[i] << ' ';cout << endl;}int Compare_L(sequenlist*A, sequenlist*B) {int j = 1;int i = 0;int n, m;n = A->last;m = B->last;while ((j <= n) && (j <= m)){if (A->data[j] == B->data[j])i = 0;if (A->data[j] < B->data[j]){i = -1;break;}if (A->data[j] > B->data[j]){i = 1;break;}j++;}if (i != 0)return i;else{if (m < n)i = 1;if (n < m)i = -1;if (m == n)i = 0;return i;}int Findi(sequenlist*L,datatype x){int i;for (i = 1; i < L->last; i++)if (L->data[i]>x)break;return i;}void Invert(sequenlist*L){int i;datatype temp;for (i = 1; i <= L->last / 2; i++){temp = L->data[i];L->data[i] = L->data[L->last + 1 - i];L->data[L->last + 1 - i] = temp;}}///////////////////////////////////ARRAY[][]/////////////////////////////////////////// datacoa *InitStruct(){datacoa*L = (datacoa*)malloc(sizeof(datacoa));L->m = 0;L->n = 0;return L;// datacoa*L = new datacoa;}int InsertA2(datacoa*L, datatype x, int i, int j){int k;if ((L->m >= maxsize - 1) || (L->n >= maxsize - 1)){cout << "表已满" << endl;return 0;for (k = L->n; k >= j; k--)L->data[i][k + 1] = L->data[i][k];L->data[i][j] = x;if (i > L->m)L->m++;if (j > L->n)L->n++;return 1;}void DeleteLie(datacoa*L, int j){int k, i;if ((j<1) || (j>L->n)){cout << "非法删除位置" << endl;}for (i = 1; i <= L->m; i++){for (k = j; k <= L->n; k++)L->data[i][j] = L->data[i][j + 1];}L->n--;}void DeleteLine(datacoa*L, int i){int k, j;if ((i<1) || (i>L->m)){cout << "非法删除位置" << endl;}for (j = 1; j <= L->n; j++){for (k = i; k <= L->m; k++)L->data[i][j] = L->data[i + 1][j];}L->m--;}///////////////////////////////////linklist/////////////////////////////////////////// linklist* CreateListF(){linklist *head, *p;char ch;head = (linklist*)malloc(sizeof(linklist));head->next = NULL;cin >> ch;while (ch != '\n'){p = (linklist*)malloc(sizeof(linklist));p->data = ch;p->next = head->next;head->next = p;}return head;}4运行结果4.1拉格朗日插值法运行结果4.2牛顿插值法运行结果4.3多项式拟合运行结果5总结拉格朗日插值法拉格朗日插值法和牛顿算法比起来比较简单,注意迭代的次序。

相关主题