一元函数的插值c语言 c语言插值函数库

C语言编写一元一次函数ax+b=0

#include iostream

创新互联公司专注于企业成都营销网站建设、网站重做改版、东胜网站定制设计、自适应品牌网站建设、H5技术商城建设、集团公司官网建设、外贸网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为东胜等各大城市提供网站开发制作服务。

int main()

{

int a = 0,b = 0;

printf("请输入一次方程的系数a和b(以逗号隔开):");

scanf("%d,%d",a,b);

double c = (double)-b / a;

printf("一次方程 %dx+%d=0 的根是:x = %lf\n",a,b,c);

system("pause");

return 0;

牛顿的插值法用C语言怎么编写怎么编啊?

#include iostream.h

#include math.h

void main()

{

char L;

do

{

double M[100][100];

double x[100],y[100];

double X=1,xx=0,w=1,N=0,P,R=1;

int n;

cout"请输入所求均差阶数:";

cinn;

for(int i=0;i=n;i++)

{

cout"请输入x"i"的值:"endl;

cinx[i];

cout"请输入y"i"的值:"endl;

ciny[i];

M[i][0]=x[i];

M[i][1]=y[i];

}

for( int j=2;j=n+1;j++)

{

for( i=1;i=n;i++)

{

M[i][j]=(M[i][j-1]-M[i-1][j-1])/(M[i][0]-M[i-j+1][0]);

}

}

for(i=1;i=n;i++)

{

cout"其"i"阶均差为:"M[i][i+1]endl;

}

cout"请输入x的值:x=";

cinxx;

for(i=0;in;i++)

{

X*=xx-x[i];

N+=M[i+1][i+2]*X;

P=M[0][1]+N;

}

cout"其函数值:y="Pendl;

for(i=0;in;i++)

{

w*=xx-x[i];

R=fabs(M[n][n+1]*w);

}

cout"其截断误差:R="Rendl;

coutendl"还想算其它插值吗?是请按'y'否则按'n'"endl;

cinL;

}while(L=='y');

}

用C语言实现拉格朗日插值、牛顿插值、等距结点插值算法

#includestdio.h

#includestdlib.h

#includeiostream.h

typedef struct data

{

float x;

float y;

}Data;//变量x和函数值y的结构

Data d[20];//最多二十组数据

float f(int s,int t)//牛顿插值法,用以返回插商

{

if(t==s+1)

return (d[t].y-d[s].y)/(d[t].x-d[s].x);

else

return (f(s+1,t)-f(s,t-1))/(d[t].x-d[s].x);

}

float Newton(float x,int count)

{

int n;

while(1)

{

cout"请输入n值(即n次插值):";//获得插值次数

cinn;

if(n=count-1)// 插值次数不得大于count-1次

break;

else

system("cls");

}

//初始化t,y,yt。

float t=1.0;

float y=d[0].y;

float yt=0.0;

//计算y值

for(int j=1;j=n;j++)

{

t=(x-d[j-1].x)*t;

yt=f(0,j)*t;

//coutf(0,j)endl;

y=y+yt;

}

return y;

}

float lagrange(float x,int count)

{

float y=0.0;

for(int k=0;kcount;k++)//这儿默认为count-1次插值

{

float p=1.0;//初始化p

for(int j=0;jcount;j++)

{//计算p的值

if(k==j)continue;//判断是否为同一个数

p=p*(x-d[j].x)/(d[k].x-d[j].x);

}

y=y+p*d[k].y;//求和

}

return y;//返回y的值

}

void main()

{

float x,y;

int count;

while(1)

{

cout"请输入x[i],y[i]的组数,不得超过20组:";//要求用户输入数据组数

cincount;

if(count=20)

break;//检查输入的是否合法

system("cls");

}

//获得各组数据

for(int i=0;icount;i++)

{

cout"请输入第"i+1"组x的值:";

cind[i].x;

cout"请输入第"i+1"组y的值:";

cind[i].y;

system("cls");

}

cout"请输入x的值:";//获得变量x的值

cinx;

while(1)

{

int choice=3;

cout"请您选择使用哪种插值法计算:"endl;

cout" (0):退出"endl;

cout" (1):Lagrange"endl;

cout" (2):Newton"endl;

cout"输入你的选择:";

cinchoice;//取得用户的选择项

if(choice==2)

{

cout"你选择了牛顿插值计算方法,其结果为:";

y=Newton(x,count);break;//调用相应的处理函数

}

if(choice==1)

{

cout"你选择了拉格朗日插值计算方法,其结果为:";

y=lagrange(x,count);break;//调用相应的处理函数

}

if(choice==0)

break;

system("cls");

cout"输入错误!!!!"endl;

}

coutx" , "yendl;//输出最终结果

}

用C语言编写一个线性插值程序

#include stdio.h

double Lerp(double x0,double y0,double x1,double y1,double x)

{

double dy = y1 - y0;

if(dy == 0){

printf("除0错误!\n");

return 0;

}

return x * (x1 - x0) / dy;

}

int main()

{

double x0,x1,y1,y0,x,y;

printf("Inptu x0 y0 x1 y1 x:");

scanf("%lf %lf %lf %lf %lf",x0,y0,x1,y1,x);

y = Lerp(x0,y0,x1,y1,x);

printf("y = %lf\n",y);

return 0;

}

C++或Basic编程

1)数据数据的概念十分广泛,它通常是对客观事物的数量、特征、性质的描述。对计算机而言,数据是计算机所能处理的一切数值、字符、图形或其他特定符号的总称,是计算机加工处理的“原料”和它所生产的“产品”(计算的结果)。2)数据元素数据元素是数据的基本单位,也称作结点和记录。在计算机程序中通常作为一个整体进行考虑和处理。一个数据元素可由若干个数据项组成。数据项是数据的不可分割的最小单位。3)数据对象数据对象是具有相同性质的数据元素的集合,是数据的子集。 1、 数据结构(Data Structure)

数据结构是指同一数据对象中个数据元素之间存在的关系(相互间存在一种或多种特定关系的数据元素的集合)。

根据数据结构的形式定义,数据结构是一个二元组:

S(Data-Structure)=(D,R)

其中:D是数据元素的有限集,R是D上关系的有限集。

逻辑结构与物理结构

数据之间的相互关系称为逻辑结构。通常分为三类基本结构:

(一)集合:结构中的数据元素除了同属于一种类型外,别无其它关系。

(二)线性结构:结构中的数据元素之间存在一对一的关系。

(三)非线性结构:

树型结构——结构中的数据元素之间存在一对多的关系。

图状结构或网状结构——结构中的数据元素之间存在多对多的关系。

数据结构在计算机中的表示称为数据的物理结构,又称为存储结构。

(一般我们将数据的逻辑结构称为是数据结构,)

存储结构可分为:顺序存储与链式存储。

顺序存储结构——借助元素在存储器中的相对位置来表示数据元素间的逻辑关系;

链式存储结构——借助指示元素存储地址的指针表示数据元素间的逻辑关系。

数据的逻辑结构与存储结构密切相关。

2.1.2 线性表

1)线性表定义

线性表(Linear List) :由n(n≧)个数据元素(结点)a1,a2, …an组成的有限序列。其中数据元素的个数n定义为表的长度。当n=0时称为空表,常常将非空的线性表(n0)记作:

L = (a1,a2,…an)

这里的数据元素ai(1≦i≦n)只是一个抽象的符号,其具体含义在不同的情况下可以不同。

2)线性表特点

线性表的逻辑结构有以下特点:

在数据元素的非空有限集中

Ø 存在唯一的一个被称作“第一个”的数据元素

Ø 存在唯一的一个被称作“最后一个”的数据元素

Ø 除第一个外,集合中的每个数据元素均只有一个前驱

Ø 除最后一个外,集合中的每个数据元素均只有一个后继

3)线性表的基本运算

线性表的主要运算有:

插入:在两个确定元素之间插入一个新元素;

删除:删除线性表中的某个元素;

查找:按某种要求查找线性表中的一个元素,需要时还可以进行更新;

排序:按给定要求对表中元素重新排序;

还有初始化、求长度等。

在不同问题的线性表中,需要进行的运算也不相同,实际应用中还可能涉及建立线性表、修改表中元素数值(编辑)等运算,但是基本上可以由上述四种运算组成。

4)顺序存储线性表

(1)顺序存储结构

把线性表的数据元素,按顺序依次存放在一组地址连续的存储单元里。用这种方法存储的线性表简称顺序表,也称为向量式存储结构。

假设线性表的每个元素需占用个存储单元,且线性表在内存中的首地址为,则线性表中第个数据元素的存储地址为:

则线性表中第个数据元素的存储位置和第个数据元素的存储位置之间满足下列关系:

这种存储结构只要知道数据元素序号,就很容易找到第个数据元素。它的主要特点有:一、各数据元素存储地址上相邻;二、无论序号为何值,找到第个元素的时间相同。

这种存储结构在高级语言中可以用一维数组的形式实现。

(2)顺序存储结构的优缺点

优点

Ø 逻辑相邻,物理相邻;

Ø 可随机存取任一元素;

Ø 存储空间使用紧凑。

缺点

Ø 插入、删除操作需要移动大量的元素;

Ø 预先分配空间需按最大空间分配,利用不充分;

Ø 表容量难以扩充。

5)线性链表

特点:

Ø 用一组任意的存储单元存储线性表的数据元素;

Ø 利用指针实现了用不相邻的存储单元存放逻辑上相邻的元素;

Ø 每个数据元素,除存储本身信息外,还需存储其直接后继的信息。

数据元素由两部分组成:

Ø 数据域:存放元素本身信息;

Ø 指针域:指示直接后继的存储地址。

线性链表一般在第一个结点之前附加一个头结点:

2.1.3 栈与队

栈和队是两种特殊的线性表,它们的运算规则较一般线性表由更多的约束和限制,因此称作限定性数据结构。

1)栈的结构和运算

(1)栈的定义

栈(Stack)是限制在表的一端进行插入和删除运算的线性表,通常称插入、删除的这一端为栈顶(Top),另一端为栈底(Bottom)。当表中没有元素时称为空栈。

假设栈,则称为栈底元素,为栈顶元素。栈中元素按的次序进栈,的顺序退栈,退栈的第一个元素应为栈顶元素。换句话说,栈的修改是按后进先出的原则进行的。因此,栈称为后进先出表(LIFO,last in first out)。

栈的存储结构也有顺序与链式两种,称为顺序栈与链栈。

(2)顺序栈

由于栈是运算受限的线性表,因此线性表的存储结构对栈也适应。

栈的顺序存储结构简称为顺序栈,它是运算受限的线性表。因此,可用数组来实现顺序栈。因为栈底位置是固定不变的,所以可以将栈底位置设置在数组的两端的任何一个端点;栈顶位置是随着进栈和退栈操作而变化的,故需用一个整型变量top来指示栈顶位置。如果用m来表示栈的最大容量,则top=0表示栈空,此时出栈,则下溢(underflow);top=m表示栈满,此时入栈,则上溢(overflow)。

(3)栈的应用

表达式求值

表达式求值步骤:首先在OS栈中放入表达式结束符“;”,

l 若为操作数,将其压入NS栈;

l 若为运算符,比较当前OS栈的栈顶元素:

ü 若当前运算符的优先数大于OS栈顶的运算符,则将当前运算符压入OS栈;

ü 若当前运算符的优先数不大于OS栈顶运算符,则从NS栈中弹出两个操作数x,y,再从OS中弹出一个运算符,,并将结果T送入NS栈。

ü 若当前运算符为“;”,且OS栈顶也为“;”,则表示表达式处理结束,此时,NS栈顶元素即为此表达式值。

过程嵌套和递归调用

过程嵌套调用如图所示:

当调用子过程时,必须把断点的信息及地址保存起来,当子过程执行完毕,返回时,取用这些信息,找到返回地址,从此断点继续执行。当程序中出现多重嵌套调用时,必须开辟一个栈,将各层断点信息依次入栈,当各层子过程返回时,又以相反的次序从栈顶取出。

递归调用

函数直接或间接地调用自身叫递归调用,这主要时用递归工作栈来实现的。下面举一个简单的例子来说明递归调用。

例 一段递归调用的C语言程序如下:

void print(int w)

{

int I;

if (w!=0)

{

print (w-1);

for (I=1; I=w; ++I)

printf(“%3d,”,w);

printf(“/n”);

}

}

在这段程序中,递归调用的执行过程如图所示:

2) 队的结构和运算

(1)队的定义

队是限定只能在表的一端进行插入,在表的另一端进行删除的线性表。

队尾(rear)——允许插入的一端

队头(front)——允许删除的一端

队的特点是:先进先出(FIFO)

(2)顺序队

存在问题:

设数组维数为M,则:

当front=-1,rear=M-1时,再有元素入队发生溢出——真溢出

l当front¹-1,rear=M-1时,再有元素入队发生溢出——假溢出

解决方案:

l 队首固定,每次出队剩余元素向下移动——浪费时间

l 循环队列

Ø 基本思想:把队列设想成环形,让sq[0]接在sq[M-1]之后,若rear+1==M,则令rear=0;

Ø 实现:利用“模”运算

入队: rear=(rear+1)%M; sq[rear]=x;

出队: front=(front+1)%M; x=sq[front];

Ø 队满、队空判定条件

front=rear

解决方案:

n 另外设一个标志以区别队空、队满

n 少用一个元素空间:

队空:front==rear

队满:(rear+1)%M==front

2.1.4 数组

1)数组的定义

(1)定义

数组可以看成是一种特殊的线性表,即线性表中数据元素本身也是一个线性表。用线性表的一般表示形式定义二维数组为:

其中,K由个结点组成:

R由以下两种关系组成:

(2)数组特点

l 数组结构固定

l 数据元素同构

(3)数组运算

数组一旦被定义,它的维数和数据元素的个数就已经固定,不能插入和删除,所以数组运算只有:

l 给定一组下标,存取相应的数据元素

l 给定一组下标,修改数据元素的值

2)数组的顺序存储结构

由于计算机的内存结构是一维的,因此用一维内存来表示多维数组,就必须按某种次序将数组元素排成一列序列,然后将这个线性序列存放在存储器中。

又由于对数组一般不做插入和删除操作,也就是说,数组一旦建立,结构中的元素个数和元素间的关系就不再发生变化。因此,一般都是采用顺序存储的方法来表示数组。

根据不同的存放形式,可以分为按行优先和按列优先顺序存放。

(1)按行优先顺序存放

按行优先顺序存放,对二维数组来说就是按行进行切分,如图所示:

假设每个数据元素只占一个单元地址,则元素的存放地址可以通过以下关系式计算:

(2)按列优先顺序存放

如果数组按列切分,就得到按列优先顺序存放方式。如图所示:

元素的存放地址可以通过以下关系式计算:

2.1.5 树与二叉树

1)树的定义及其存储结构

(1)树的定义和术语

定义:树(Tree)是n(n=0)个结点的有限集T,T为空时称为空树,否则它满足如下两个条件:

(1)有且仅有一个特定的称为根(Root)的结点;

(2)其余的结点可分为m(m=0)个互不相交的子集T1,T2,T3…Tm,其中每个子集又是一棵树,并称其为子树(Subtree)。

基本术语:

l 结点(node)——表示树中的元素,包括数据项及若干指向其子树的分支;

l 结点的度(degree)——结点拥有的子树数;

l 叶子(leaf)——度为0的结点;

l 孩子(child)——结点子树的根称为该结点的孩子;

l 双亲(parents)——孩子结点的上层结点叫该结点的双亲;

l 兄弟(sibling)——同一双亲的孩子;

l 树的度——一棵树中最大的结点度数;

l 结点的层次(level)——从根结点算起,根为第一层,它的孩子为第二层……;

l 深度(depth)——树中结点的最大层次数;

l 森林(forest)——m(m=0)棵互不相交的树的集合;

(2)树的存储结构

树的存储结构有多种形式,这里只讨论链式存储结构。因为树是多分支非线性表,因此采用多重链表结构,即每个结点设有多个指针域,其中每个指针指向一棵子树的根结点。对于每一个结点的结构类型有两种形式:结点异构型、结点同构型。

结点异构型,是根据每个结点的子树数设置相应的指针域,由于每个结点的度数不同,则同一棵树中,结点形式也不同。这种结构形式虽然能节省存储空间,但运算不方便。

结点同构型,是每个结点的指针域个数均为树的度数。这种形式运算方便,但会使链表中出现很多空链域,浪费空间。

当树的度数k=2时,空链域的比例最低,这就是要介绍的二叉树。

2)二叉树及其性质

二叉树在树结构的应用中起着非常重要的作用,因为对二叉树的许多操作算法简单,而任何树都可以与二叉树 相互转换,这样就解决了树的存储结构及其运算中存在的复杂性。

(1)二叉树定义及其存储结构

定义:二叉树是由n(n=0)个结点的有限集合构成,此集合或者为空集,或者由一个根结点及两棵互不相交的左右子树组成,并且左右子树都是二叉树。

这也是一个递归定义。二叉树可以是空集合,根可以有空的左子树或空的右子树。二叉树不是树的特殊情况,它们是两个概念。

二叉树结点的子树要区分左子树和右子树,即使只有一棵子树也要进行区分,说明它是左子树,还是右子树。这是二叉树与树的最主要的差别。

图2-8 二叉树

存储结构:通常用具有两个指针域的链表作为二叉树的存储结构,其中,每个结点由数据域(data)、左指针域(L child)和右指针域(R child)组成,如图所示:

图2-9 二叉链表

这就是二叉链表,还有三叉链表就是在这一基础上增加一个双亲结点指针。

(2)二叉树的基本性质

(1) 在二叉树的第层上,至多有个结点。

(2) 深度为h的二叉树中,至多含有个结点。

(3) 对任意一棵二叉树,若有个子结点,个度为2的结点,则必有。

(3)几种特殊形式的二叉树

l 满二叉树

一棵深度为h且有2h-1个结点的二叉树称为满二叉树。

l 完全二叉树

如果深度为h、有n个结点的二叉树中的结点能够与深度为h的顺序编号的满二叉树从1到n标号的结点相对应,则该树称为完全二叉树。

完全二叉树的特点是:

所有的叶结点都出现在第h层或h-1层。

错任一结点,如果其右子树的最大层次为1,则其左子树的最大层次为1或l+1。

满二叉树是完全二叉树的特例。

(1) 平衡二叉树

所有结点的平衡因子为-1、0、1。

(4)一般树转换为二叉树

为了使一般树也能象二叉树一样用二叉树链表表示,必须找出树与二叉树之间的对应关系。将一般树转换为二叉树的方法为:

(1) 在兄弟结点之间加一连线;

(2) 对每个结点,除了与它的第一个孩子保持联系外,去除与其它孩子的联系;

(3) 以树根为轴心将整棵树顺时针旋转45度。

任何一棵树转换为二叉树,其根结点的右子树必为空。

3)二叉树的遍历

遍历——按一定规律走遍树的各个结点,每一结点仅被访问一次,即找一个完整而有规律的走法,以得到树中所有结点的一个线性排列。

常用方法

先序遍历(DLR):先访问根结点,然后分别先序遍历左子树、右子树

中序遍历(LDR):先中序遍历左子树,然后访问根结点,最后中序遍历右子树

后序遍历(LRD):先后序遍历左、右子树,然后访问根结点

2.2 工程手册的数据处理

基本要求:

(1)熟悉工程手册的数据处理方法;(2)掌握数表的程序化方法;(3)了解线图的程序化方法;(4)掌握最小二乘法拟合方法及其应用;(4)能用高级程序设计语言(如C语言)编写前述相应数据处理方法的基本程序并上机通过。

教学内容:

(1)数表的程序化;(2)线图的程序化;(3)建立经验公式的方法。

重点与难点:

重点:(1)查表程序设计;(2)一元函数的插值;(3)最小二乘法拟合。

难点:(1)抛物线插值中结点的选取;(2)插值程序设计及上机调试;(3)最小二乘法拟合程序设计及上机调试。

学时安排:

讲课4学时,课外上机练习不少于2学时。

在机械设计过程中,往往需要从有关的工程手册或设计规范中查找各种设计数据(资料)。这些数据在手册或规范中一般是以数表和线图的形式存放(记录)的。在进行机械CAD时,首先要把这些数表、线图形式的数据计算机化,即把它们存入计算机外、内存储器中,并设计相应的自动检索程序。

从总体上说,这些设计资料的计算机处理有以下三种方法:

(1)程序化:在应用程序内部对这些数表和线图进行处理,包括数组法和拟合公式法。

(2)数据文件法:将数表或线图中得数据编成一个独立的数据文件,存入外存,供设计解题时调用。高级程序设计语言本身一般均具备相应的数据文件处理功能。

(3)数据库法:将数表或线图中的数据暗数据库中的规定进行文件结构化,即建成数据库。

本章重点讨论程序化方法,补充介绍有关数据文件法的基本内容,数据库存储方法在后面第5章中介绍。

2.2.1 数表的程序化

l 数表的形式:

从函数角度看有:

单变量表:e.g. T.3-1~T.3-3

双变量表:e.g. T.3-4~T.3-5 单值表:e.g. T.3-3~T.3-6

多变量表:e.g. T.3-6 多值表:e.g. T.3-1~T.3-2

无变量表:e.g. 齿轮标准模数(m)系列值。

l 数表数据的形成(来源)及处理原则:

(1)有些本来就有精确的计算公式,为了便于手工设计使用,才制成表格供设计时查用(如各种数学用表)——力求找到原来的理论计算公式或经验公式→编入应用程序。(最简单的方法)。

(2)对大多数数表而言,或本来就无法表达成公式,或一时难以找到原来公式——程序化处理。

l 数表程序化方法:

1) 数组法:适于只需要用数表中所列数据(离散点、型值点或结点数据),

2) 插值法(拟合公式法):对于需要用到数表中各离散点中间的数据。

1)数组法实例

本教材共介绍了六个实例,这里选取二个重点介绍,其余四个自己分析。

例1 平键和键槽的剖面尺寸,见图2-10和表2-1(摘引自GB/T 1095-1979)

它是单变量多值表。查表时,设计计算出的轴径dgiven→D(范围) →b,h,t,t1。可使用一维数组,D的范围可用其上限表示。变量及数组的定义:

int i;

float dgiven,b,h,t,t1;

float D[12]={10.0,12.0,…,85.0};

float kb[12]=…

.

.

.

float kt[12]=…

图2-10 平键和键槽的剖面图

表2-1 平键和键槽的尺寸表

图2-11平键和键槽的剖面尺寸查询流程

尺寸查取流程图见图2-11。

要求:用C(Turbo C or Visual C++等均可)语言编程实现该数表数据存储及查询。

例2 齿轮传动工况系数KA,见表2-2。

表2-2 齿轮传动工况系数KA

图2-12 齿轮传动工况系数KA查询流程

根据原动机机、工作机的工况→KA,使用二维数组:KK[i][j],i=0~2:表示原动机工况,j=0~2:表示工作机工况。

变量及数组定义:

float KA;

int i,j;

float;

KK[3][3]={{1.0,1.25,1.75},{1.25,1.5,2.0},{1.5,1.75,2.25}};

查表程序流程图见图2-12。

要求:用C(Turbo C or Visual C++等均可)语言编程实现该数表数据存储及查询。

例3 说明:多变量单值表

① P1值需用三维数组NN(4,4,14),可以将P1值→数据文件→NN数组。

② 降维处理:三维→二个二维。

2) 一元函数的插值

设有一用数据表格给出的列表函数y=f(x),如下表2-3:

表2-3 列表函数y=f(x)

表中只有几个离散点(或型值点、结点)的数据,当自变量为结点间的中间值时,就要用到插值法求取其函数值。

基本思想:在插值点附近选取几个合适的结点,过这些点构造一个简单函数g(x),在此小段上用g(x)代替原来函数f(x),这样插值点的函数值就用g(x)的值来代替,如图2-13。

图2-13 一元函数插值

插值的实质问题:如何构造一个既简单又具有足够精度的函数f(x)。

插值方法类型:线性插值、抛物线插值。

(1)线性插值

方法步骤:(1)选xi,xi+1,满足xix xi+1;(2)过(xi,yi)及(xi+1,yi+1)两点构造直线g(x)→f(x)。

误差问题:存在误差,当自变量间隔较小,而插值精度不要很高时,可以满足要求。

x(n),y(n)——一维数值,n——结点数。C语言下标从0开始。xgiven,ygiven——已知的x 插入值及求出的函数值。

图2-14 线性插值流程

(2)抛物线插值

在f(x)上选取三点(xi-1,yi-1),(xi,yi),(xi+1,yi+1),构造抛物线g(x)→f(x)。比线性插值精度好。

关键问题:根据插值点x选取合适的三个点。选取方法归纳为(“靠近原则”):

设插值点为x,且xi-1x≤xi,i=3,4,…,n-1,

(1)若|x-xi-1|≤|x-xi|,即x靠近xi-1点或居于xi-1与 xi之中点,则选xi-2,xi-1,xi三个点,上式中i=i-1;

(2)若|x-xi-1||x-xi|,即x靠近xi点,则选xi-1,xi,xi+1三个点,上式中i=I;

(3)若x1≤x≤x2,即x靠近表头,则选x1,x2,x3三个点,上式中i=2;

(4)若x n-1≤x≤xn,即x靠近表尾,则选xn-2,xn-1,xn三个点,上式中i=n-1。

程序流程图见下图2-15。

图2-15 抛物线插值流程

要求:将线性插值与抛物线插值统一编程。

3)二元函数的插值

有二元列表函数f(xi,yi),i=1,2,…,n,如下表2-4。

表2-4 二元列表函数

插值几何意义:在3D空间中选定几个点,通过这些点构造一块曲面g(x,y),用它近似地表示在这区间内原有的曲面f (x,y),从而得到插值后的函数值Zk=g(xk,yk) , 如图2-15所示。

插值方式类型,在一元函数插值方法的基础上延伸,有以下几种:

(1)直线-直线插值

最最基本、最简单、精度最低。

如图所示,g(x,y)形成:以AB、CD为导线,作//yoz平面的直母线(EF)直线的运动→柱状面。

插值步骤:

图2-15 二元函数插值

图2-16 抛物线插值流程

(a)根据k点的(xk,yk)→周围四点a,b,c,d,满足xa=xc,xb=xd,ya=yb,yc=yd,xaxkxb,yaykyb;

(b)A,B,C,D,过A,B用线性插值→E,过C,D用线性插值→F;

(c)过E,F用线性插值→K点。

(2)抛物线-直线插值

将导线AB、CD→抛物线ABE,CDF。插值步骤:

(1)据k点的(xk,yk)→a,b,c,d+e,f;

(2)据a,b,c,d,e,f→A,B,C,D,E,F,过A,B,E 用抛物线插值→U点,过C,D,F用抛物线插值→V点;

(3)U,V用线性插值→K点。

(3)抛物线-抛物线插值

(1)据k点的(xk,yk)→a,b,c,d+e,f+r,s,t;

(2)据a,b,c,d, e,f,r,s,t→A,B,C,D,E,F,R,S,T,

过A,B,E用抛物线插值→U点,过C,D,F用抛物线插值→V点,过R,S,T用抛物线插值→W点;

(3) 过U,V,W用抛物线插值→K点。

上述三种插值方法统一的程序流程图见P44图3-10,三种方法由变量II控制。

要求:读懂该流程图,有余力的学生编程上机。

2.2.2 数表的公式拟合

工程实际中常需要用一定的数学方法将一系列测试数据或统计数据拟合成近似的经验公式——曲线拟合。

插值法的实质是在几何上用严格通过各结点的曲线或曲面来近似代替列表函数曲线或曲面。但通过试(实)验所得的数据离散性很大,误差比较大,因此,插值法建立的公式必然保留了所有误差,此外,要构造这样的函数的复杂度或难度比较大。有鉴于此,采用构造近似曲线、曲面,此曲线、曲面并不严格通过所有结点,而是尽可能反映所给数据的趋势,这种利用所给数据建立拟合或近似曲线或曲面经验公式的过程称为曲线、曲面拟合或公式拟合。

本节介绍最常用最基本的单变量曲线拟合方法——最小二乘法。(其他常用的还有Bezier法、三次参数样条法、B样条法等)。

1)最小二乘法拟合的基本思想

根据离散点的大致分布规律,先确定拟合函数的类型,如多项式函数、指数函数、对数函数等,计算出各数据点横坐标处的函数值与纵坐标之间的偏差的平方,求其和并使之为最小值,从而解出函数的待定系数。

已知由线图或实验所得m个点的值为:(x1,y1),(x1,y1),……,(xm,ym),设拟合函数公式为:y=f(x),则每一结点处的偏差为: (i=1,2,…,m),偏差的平方和为:

求 min 函数f(x)的待定系数→ f(x)

拟合函数的类型,常选取初等函数,如对数函数、指数函数、代数多项式等。一般是根据数据曲线形态判断所采用的函数类型。最常用的是代数多项式拟合。本节只讨论在选定函数类型的情况下如何确定各系数值的问题。

2)最小二乘法的(代数)多项式拟合

设拟合公式为: (n次多项式)

已知m个点的值(x1,y1),(x1,y1),……,(xm,ym),且mn,结点偏差的平方和为:

为使 j=0,1,2,…,n

其中:(k=1,2,…,2m+1)

这是一个关于的n+1个线性方程组,求解该方程组→→f(x)

常用二次三项式拟合公式:

例1 介绍

程序流程图,见P.44图3-13

要求:看懂该流程图,该流程图中采用了高斯消去法解联立方法(详见3.3.4节),有余力的学生编程上机。


网站栏目:一元函数的插值c语言 c语言插值函数库
文章出自:http://azwzsj.com/article/doojodh.html