㈠ 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的長度相同吧?