㈠ c语言如何对若干离散点进行m阶多项式拟合
m阶多项式拟合,是算法问题,不是计算机语言问题。你先要有你的具体计算策略和方法,数值计算时,用计算机语言写出程序,算出结果。用 c 语言 或 fortran 语言 或别的语言,大同小异,没有原则差别。
你先要定出你的方程形式,例如
y = a1*x^m+a2*x^(m-1)+...am
a1,a2,...,am 是 m 个待定系数
把你的离散点[xi,yi] 代入方程,你可以得到 线性方程式 yi = a1*xi^m+a2*xi^(m-1)+...am
若你有 n 个点,就得到 n 个 方程式。若 n<m 有无穷解,若 n=m 有一解。
通常 离散点的个数 远超过 方程阶数,也就是方程个数超出要解的未知数的个数,n>m,这时,
通常 用 最小二乘法 求解 这个线性方程组。也就是所谓的拟合。
最小二乘法 求解 这个线性方程组 的程序 网上(这里不敢写,写了,你就看不到我的贴子了)可以找到,自己写也不复杂。
曲线拟合文章估计网络文库里也有。
㈡ 如何用EXCEL拟合回归多项式公式
手头比方说有如下的数据,如果我们要对未来收入进行预测,该怎么做呢,当然是要找合适的回归模型!这个可以利用差分法或者散点图来判别,不过还是散点图比较方便,还可以自动出拟合回归方程。
插入散点图如下,我们首先看一下散点的波动情况,如果对趋势线比较熟悉的话,应该知道这是二次曲线,不知道也不要紧,我们可以一个个试!
右击散点图中的数据标记,找到“添加趋势线”进入“趋势线选项”界面。
经过一个个试之后,来到多项式,顺序为2,代表二阶多项式模型,即,还要勾选下方的显示公式和R平方值。R方代表着回归方程的拟合程度,越靠近1越好,我们已经看到R方是0.999了,已经拟合的很好了!
以上是一种方法,不过系数还要自己抄多麻烦,况且常数项被简写了到底是多少啊??要自己去求得的话也特别简单,使用Linest函数即可,大家不知道吧,我也是刚刚知道,太好用了!!!!
LINEST函数简介:
LINEST(known_y's, [known_x's], [const], [stats])
LINEST 函数语法具有以下参数 (参数:为操作、事件、方法、属性、函数或过程提供信息的值。):
Known_y's 必需。关系表达式 y = mx + b 中已知的 y 值集合。
如果 known_y's 对应的单元格区域在单独一列中,则 known_x's 的每一列被视为一个独立的变量。
如果 known_y's 对应的单元格区域在单独一行中,则 known_x's 的每一行被视为一个独立的变量。
Known_x's 可选。关系表达式 y = mx + b 中已知的 x 值集合。
known_x's 对应的单元格区域可以包含一组或多组变量。如果仅使用一个变量,那么只要 known_y's 和 known_x's 具有相同的维数,则它们可以是任何形状的区域。如果使用多个变量,则 known_y's 必须为向量(即必须为一行或一列)。
如果省略 known_x's,则假设该数组为 {1,2,3,...},其大小与 known_y's 相同。
const
可选。一个逻辑值,用于指定是否将常量 b 强制设为 0。
如果 const 为 TRUE 或被省略,b 将按通常方式计算。
如果 const 为 FALSE,b 将被设为 0,并同时调整 m 值使 y = mx。
stats
可选。一个逻辑值,用于指定是否返回附加回归统计值。
如果 stats 为 TRUE,则 LINEST 函数返回附加回归统计值,这时返回的数组为 {mn,mn-1,...,m1,b;sen,sen-1,...,se1,seb;r2,sey;F,df;ssreg,ssresid}。
如果 stats 为 FALSE 或被省略,LINEST 函数只返回系数 m 和常量 b。
如何就这个例子应用函数呢?因为我们要产生3个数分别是常数项,回归系数2项,因此,我们要选中3个单元格以便输出3个数字即A14:C14。
然后按F2,输入{=LINEST(C3:C11,B3:B11^COLUMN($A:$B),TRUE,FALSE) }公式,再按Ctrl+Shift+Enter返回数组。(必须按数组模式输入公式,输入成功的话会看见“{}”这两个符号),看见了吧,已经产生了3个数字!!!
跟散点图的公式去核对一下是不是一模一样?这样我们就可以预测2006年的收入!!!后面不再写了吧。。略过。
公式说明,C3:C11选择了Y数据,B3:B11选择了X数据,^COLUMN($A:$B),后面COLUMN其实返回的是数据所在列号即(1,2)代表1次方和2次方,也就是产生了这样的公式,后面的TRUE代表输出常数项,最后一个FALSE只返回系数和常量,不返回附加回归统计值。
㈢ 求一个n阶多项式二乘拟合的算法,最好是C语言
//函数功能有,求多项式的和,差,积
/*
输入函数的输入操作:1,先输入多项式的成员的个数n:(如 x+1,的n=2);
2,输入多项式(x+1),格式如下:
coef expn
1 1
1 0
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct {
float coef;
int expn;
}Elemtype;
typedef struct node{
Elemtype data;
node *next;
}LNode,*Linklist;
Linklist creat(int n); //创建n各节点,并初始化
void print(Linklist head);//输出
Linklist Add(Linklist f1,Linklist f2); //f1+f2
Linklist sub(Linklist f1,Linklist f2); //f1-f2
Linklist mult(Linklist f1,Linklist f2); //f1*f2
Linklist turn(Linklist head); //排序,合并同类项
int len(Linklist head); //求多项式的长度
void main()
{
Linklist f1,f2,f4,f3;
printf(" Polyn + - *\n");
printf("Input polyn \nPolyn f1 input data n:");
int n;scanf("%d",&n);
f1=creat(n);
printf("Polyn f2 input data n:");
scanf("%d",&n);
f2=creat(n);
printf("\nOUT Polyn;\n");
printf("polyn1:"); print(f1);
printf("polyn2:"); print(f2);
f3=Add(f1,f2); printf("polyn Add f1+f2:"); print(f3);
f4=sub(f1,f2); printf("polyn sub f1-f2"); print(f4);
printf("polyn mult f1*f2:"); print(mult(f1,f2));
}
Linklist turn(Linklist head)
{
Linklist p, q;
if(!head->next) return head;
Elemtype temp;
for (q=head;q->next;q=q->next)
{
for (p=q->next;p;p=p->next)
{
if(p->data.expn>q->data.expn)
{
temp=p->data;p->data=q->data;q->data=temp;
}
else if(p->data.expn==q->data.expn) {
q->data.coef=q->data.coef+p->data.coef;p=p->next;
q->next=p; if(!p||!p->next) break;
}
}
if((q==NULL)||(q->next==NULL)) break;
}
return head;
}
Linklist creat(int n)
{
Linklist head,p,pf;
printf("input %d data :\n coef expn\n",n);
for(int i=0;i<n;i++)
{
pf=(Linklist)malloc(sizeof(LNode));
if(i==0)
head=p=pf;
printf("NO %d : ",i+1);
scanf("%f%d",&pf->data.coef,&pf->data.expn);
if(pf->data.coef) {p->next=pf;
p=p->next;}
}
p->next=NULL;
head=turn(head);
return head;
}
void print(Linklist head)
{
Linklist p;
p=head;
printf("\n coef expn\n");
while(p){
printf(" %6.2f %4d\n",p->data.coef,p->data.expn);
p=p->next;
}
printf("\n");
}
int len(Linklist head)
{
Linklist p;
p=head;
int n;
for(n=0;p;p=p->next,n++);
return n;
}
Linklist Add(Linklist f1,Linklist f2) //f1+f2
{
Linklist p1,p2,f;
Linklist p,pf;
p1=f1; p2=f2;
p=f=(Linklist)malloc(sizeof(LNode));f->next=NULL;
while (p1||p2)
{
pf=(Linklist)malloc(sizeof(LNode));
if(p1&&(p2==NULL))
{
pf->data=p1->data;
p1=p1->next;
}
else if(p2&&(p1==NULL)){
pf->data=p2->data;
p2=p2->next;
}
else if(p1->data.expn-p2->data.expn==0)
{
pf->data.coef=p1->data.coef+p2->data.coef;
pf->data.expn=p1->data.expn;
p1=p1->next;p2=p2->next;
}
else if(p1->data.expn>p2->data.expn)
{
pf->data=p1->data;
p1=p1->next;
}
else if(p1->data.expn<p2->data.expn){
pf->data=p2->data;
p2=p2->next;
}
if(pf->data.coef) //如果系数coef==0 则删除该项成员
{p->next=pf;
p=p->next;}
}
p->next=NULL;f=f->next; f=turn(f);
return f;
}
Linklist sub(Linklist f1,Linklist f2) //f1-f2
{
Linklist p1,p2,f;
Linklist p,pf;
p1=f1; p2=f2;
p=f=(Linklist)malloc(sizeof(LNode));f->next=NULL;
while (p1||p2)
{
pf=(Linklist)malloc(sizeof(LNode));
if(p1&&(p2==NULL))
{
pf->data=p1->data;
p1=p1->next;
}
else if(p2&&(p1==NULL)){
pf->data.expn=p2->data.expn;
pf->data.coef=-p2->data.coef;
p2=p2->next;
}
else if(p1->data.expn-p2->data.expn==0)
{
pf->data.coef=p1->data.coef-p2->data.coef;
pf->data.expn=p1->data.expn;
p1=p1->next;p2=p2->next;
}
else if(p1->data.expn>p2->data.expn)
{
pf->data=p1->data;
p1=p1->next;
}
else if(p1->data.expn<p2->data.expn){
pf->data.expn=p2->data.expn;
pf->data.coef=-(p2->data.coef);
p2=p2->next;
}
if(pf->data.coef)
{p->next=pf;
p=p->next;}
}
p->next=NULL;f=f->next; f=turn(f);
return f;
}
Linklist mult(Linklist f1,Linklist f2) //f1*f2
{
Linklist p1,p2,f;
Linklist pf;f=NULL;
for(p1=f1;p1;p1=p1->next)
{
for(p2=f2;p2;p2=p2->next)
{
pf=(Linklist)malloc(sizeof(LNode));
pf->data.expn=p1->data.expn+p2->data.expn;
pf->data.coef=p1->data.coef*p2->data.coef;
pf->next=NULL;
f=Add(f,pf);
pf=NULL;
}
}
f=turn(f);
return f;
}
㈣ 最小二乘法三次多项式曲线拟合 算法 C++ 实现,该怎么处理
//最小二乘法
//x[n] y[n] 已知输入
//n输入点个数
//a[m] 返回m-1次拟合多项式的m个系数
//m 拟合多项式的项数,即拟合多项式的最高次为m-1
//dt[3] dt[0]返回拟合多项式与各数据点误差的平方和,
dt[1]返回拟合多项式与各数据点误差的绝对值之和
dt[2]返回拟合多项式与各数据点误差的绝对值的最大值
//
//拟合多项式的输出
//Y(x) = a0 + a1(x-X) + a2(x-X)^2 + …… am(x-X)^m
// 其中X为已知点x的平均值
******************************************/
#include "math.h"
void pir1(x,y,n,a,m,dt)
int n,m;
double x[],y[],a[],dt[];
{
int i,j,k;
double z,p,c,g,q,d1,d2,s[20],t[20],b[20];
for (i=0; i<=m-1; i++) a[i]=0.0;
if (m>n) m=n;
if (m>20) m=20;
z=0.0;
for (i=0; i<=n-1; i++) z=z+x[i]/(1.0*n);
b[0]=1.0; d1=1.0*n; p=0.0; c=0.0;
for (i=0; i<=n-1; i++)
{ p=p+(x[i]-z); c=c+y[i];}
c=c/d1; p=p/d1;
a[0]=c*b[0];
if (m>1)
{ t[1]=1.0; t[0]=-p;
d2=0.0; c=0.0; g=0.0;
for (i=0; i<=n-1; i++)
{ q=x[i]-z-p; d2=d2+q*q;
c=c+y[i]*q;
g=g+(x[i]-z)*q*q;
}
c=c/d2; p=g/d2; q=d2/d1;
d1=d2;
a[1]=c*t[1]; a[0]=c*t[0]+a[0];
}
for (j=2; j<=m-1; j++)
{ s[j]=t[j-1];
s[j-1]=-p*t[j-1]+t[j-2];
if (j>=3)
for (k=j-2; k>=1; k--)
s[k]=-p*t[k]+t[k-1]-q*b[k];
s[0]=-p*t[0]-q*b[0];
d2=0.0; c=0.0; g=0.0;
for (i=0; i<=n-1; i++)
{ q=s[j];
for (k=j-1; k>=0; k--)
q=q*(x[i]-z)+s[k];
d2=d2+q*q; c=c+y[i]*q;
g=g+(x[i]-z)*q*q;
}
c=c/d2; p=g/d2; q=d2/d1;
d1=d2;
a[j]=c*s[j]; t[j]=s[j];
for (k=j-1; k>=0; k--)
{ a[k]=c*s[k]+a[k];
b[k]=t[k]; t[k]=s[k];
}
}
dt[0]=0.0; dt[1]=0.0; dt[2]=0.0;
for (i=0; i<=n-1; i++)
{ q=a[m-1];
for (k=m-2; k>=0; k--)
q=a[k]+q*(x[i]-z);
p=q-y[i];
if (fabs(p)>dt[2]) dt[2]=fabs(p);
dt[0]=dt[0]+p*p;
dt[1]=dt[1]+fabs(p);
}
return;
}
㈤ 怎么用matlab进行非线性的多元函数拟合
方法一:
1、最常用的是多项式拟合,采用polyfit函数,在命令窗口输入自变量x和因变量y。
㈥ 怎么用MATLAB进行多元多项式拟合
实例
1
先看一个具体的例子,通过构造一系列离散的二维点集,然后用不同阶次的多项式来拟合,比较哪个效果更好。最后说明多项式拟合在matlab中的用法。
2
首先启动matlab,选择编辑器,再新建一个命令文件。
3
然后,在编辑器窗口中输入本题的代码。如下图所示。并保存,此处命名为dxsnh。
4
需要注意的是,保存文件的位置要与当前搜索路径的位置保持一致。这可以通过右键编辑窗口的文件,在弹出的下拉框中选择。
5
最后再命令行窗口处输入dxsnh,并敲入键盘上的enter建。可以看出阶数越高,曲线与拟合点拟合得越好。
END
命令解释
1
通过上面的例子知道,matlab实现多项式拟合的关键命令是polyfit。
2
该命令的格式如下
[p,s]=polyfit(x,y,n)
功能介绍:对于已知的数据x、y进行多项式拟合,拟合的多项式的阶数为n,其中p为多项式的系数矩阵,s为预测误差估计值的矩阵。
㈦ 如何使用MATLAB进行多项式拟合的计算
方法/步骤
在进行曲线拟合之前需要对数据进行绘图,通过图形来对数据的基本趋势进行一个大概的判断,便于进一步拟合。
%绘制图形:
x=1:1:9;
y=[9 7 6 3 -1 2 5 7 20];
plot(x,y,'r*');
5
确定了模型的参数后,揭下来的模型检验与修正我们不再进行,有兴趣的网友可以自行尝试,也可以关注我几天后更新下一篇经验:如何使用matlab建立人口预测模型。最后对最后一段代码中出现的两个函数进行说明:
P=polyfit(x,y,N); %N多项式拟合函数,返回降幂排列的多项式系数
yi=polyval(P,xi); %计算以P向量为系数的多项式在xi处的值
㈧ 最小二乘法三次多项式曲线拟合 算法 C++ 实现,该怎么处理
/******************************************
//参考《常用算法程序集(C语言描述第三版)》
//最小二乘法
//x[n]y[n]已知输入
//n输入点个数
//a[m]返回m-1次拟合多项式的m个系数
//m拟合多项式的项数,即拟合多项式的最高次为m-1
//dt[3]dt[0]返回拟合多项式与各数据点误差的平方和,
dt[1]返回拟合多项式与各数据点误差的绝对值之和
dt[2]返回拟合多项式与各数据点误差的绝对值的最大值
//
//拟合多项式的输出
//Y(x)=a0+a1(x-X)+a2(x-X)^2+……am(x-X)^m
//其中X为已知点x的平均值
******************************************/
#include"math.h"
voidpir1(x,y,n,a,m,dt)
intn,m;
doublex[],y[],a[],dt[];
{
inti,j,k;
doublez,p,c,g,q,d1,d2,s[20],t[20],b[20];
for(i=0;i<=m-1;i++)a[i]=0.0;
if(m>n)m=n;
if(m>20)m=20;
z=0.0;
for(i=0;i<=n-1;i++)z=z+x[i]/(1.0*n);
b[0]=1.0;d1=1.0*n;p=0.0;c=0.0;
for(i=0;i<=n-1;i++)
{p=p+(x[i]-z);c=c+y[i];}
c=c/d1;p=p/d1;
a[0]=c*b[0];
if(m>1)
{t[1]=1.0;t[0]=-p;
d2=0.0;c=0.0;g=0.0;
for(i=0;i<=n-1;i++)
{q=x[i]-z-p;d2=d2+q*q;
c=c+y[i]*q;
g=g+(x[i]-z)*q*q;
}
c=c/d2;p=g/d2;q=d2/d1;
d1=d2;
a[1]=c*t[1];a[0]=c*t[0]+a[0];
}
for(j=2;j<=m-1;j++)
{s[j]=t[j-1];
s[j-1]=-p*t[j-1]+t[j-2];
if(j>=3)
for(k=j-2;k>=1;k--)
s[k]=-p*t[k]+t[k-1]-q*b[k];
s[0]=-p*t[0]-q*b[0];
d2=0.0;c=0.0;g=0.0;
for(i=0;i<=n-1;i++)
{q=s[j];
for(k=j-1;k>=0;k--)
q=q*(x[i]-z)+s[k];
d2=d2+q*q;c=c+y[i]*q;
g=g+(x[i]-z)*q*q;
}
c=c/d2;p=g/d2;q=d2/d1;
d1=d2;
a[j]=c*s[j];t[j]=s[j];
for(k=j-1;k>=0;k--)
{a[k]=c*s[k]+a[k];
b[k]=t[k];t[k]=s[k];
}
}
dt[0]=0.0;dt[1]=0.0;dt[2]=0.0;
for(i=0;i<=n-1;i++)
{q=a[m-1];
for(k=m-2;k>=0;k--)
q=a[k]+q*(x[i]-z);
p=q-y[i];
if(fabs(p)>dt[2])dt[2]=fabs(p);
dt[0]=dt[0]+p*p;
dt[1]=dt[1]+fabs(p);
}
return;
}
㈨ 怎样用MATLAB进行多项式拟合
x=[0.0000 0.3532 0.6576 0.6843 0.6659 0.6148 0.5845 0.5686 0.5385 0.5276 0.5459 0.6775 0.7928 0.8755 0.9759 1.0000 0.9825 0.7542 0.6532 0.5025];
n=1:length(x);
n1=n.^2;
p=polyfit(n,x,2);
p0=p(3)
a2=sqrt(p(2))
a4=p(1)^0.5
plot(n,x,'*');
由于不知道你的横坐标是什么,就拿自然数列了,可能不对!
你只给了一组数据是横坐标还是纵坐标啊?如果问题又补充的话,给我发个消息,我再帮你看看那!
㈩ 用MatLab进行多项式3次方拟合
多项式拟合很简单,用polyfit函数很容易做,但是题主,你至少要保证x和y的长度相同吧?