1. 程式人生 > >Matlab 曲線擬合之 polyfit 、polyval、poly2str 函式

Matlab 曲線擬合之 polyfit 、polyval、poly2str 函式

原文出處(僅供參考)

ttps://www.cnblogs.com/farewell-farewell/p/7227516.html

https://www.cnblogs.com/clairvoyant/p/4710015.html

1  Matlab 曲線擬合之polyfit與polyval函式

p=polyfit(x,y,n)

[p,s]= polyfit(x,y,n)

說明:x,y為資料點,n為多項式階數,返回p為冪次從高到低的多項式係數向量p。x必須是單調的。矩陣s用於生成預測值的誤差估計。

 

多項式曲線求值函式:polyval( )

呼叫格式: y=polyval(p,x)

[y,DELTA]=polyval(p,x,s)

說明:y=polyval(p,x)為返回對應自變數x在給定係數P的多項式的值。

[y,DELTA]=polyval(p,x,s) 使用polyfit函式的選項輸出s得出誤差估計Y DELTA。它假設polyfit函式資料輸入的誤差是獨立正態的,並且方差為常數。則Y DELTA將至少包含50%的預測值。

 

有如下資料

時間t

1900

1910

1920

1930

1940

1950

1960

1970

1980

1990

2000

人口y

76

92

106

123

132

151

179

203

227

250

281

1. y與t的經驗公式為 y = at^2 + bt + c

複製程式碼

clear;
clf;                                                      %清除當前視窗
clc;
t = 1900:10:2000;                                         %時間t
y = [76 92 106 123 132 151 179 203 227 250 281];          %人口y

plot(t,y,'k*');
hold on;
% figure;                                 %重新開一個圖
p1 = polyfit(t,y,2);
plot(t, polyval(p1, t));
axis([1900 2000 0 300]);                                  %影象xy軸範圍

disp(char(['y=',poly2str(p1,'t')],['a=',num2str(p1(1)),'   b=',...
    num2str(p1(2)),'   c=',num2str(p1(3))]));

複製程式碼

結果如下:

y=   0.0094289 t^2 - 34.7482 t + 32061.5711
a=0.0094289   b=-34.7482   c=32061.5711

 2. y與t的經驗公式為y = a e^(bt)

複製程式碼

clear;
clf;                                                      %清除當前視窗
clc;
t = 1900:10:2000;                                         %時間t
y = [76 92 106 123 132 151 179 203 227 250 281];          %人口y
yy = log(y);                                              %指數基尼必需的線性化變形
p2 = polyfit(t,yy,1);
b = p2(1);
a = exp(p2(2));
y2 = a * exp(b*t);                                       %指數擬合函式式
plot(t,y,'rp',t,y2,'k-');
grid off;
xlabel('時間t');
ylabel('人口數(百萬)');
title('人口資料');

複製程式碼

 

2  str2poly()和poly2str()

                               多項式表示法

  MATLAB中採用行向量來表示多項式,將多項式的係數按降次冪次序存放於行向量中。即多項式P(x)=a0xn+a1xn-1+ ... +an-1x+an的係數行向量為P=[a0 a1 ... an],順序為高次冪到低次冪。舉個例子,x5-7x3+2x+4,可以用係數行向量[1 0 -7 0 2 4]來表示,多項式中缺少的次冪要用“0”補齊。

  1、str2poly():

  下面為str2poly()函式,實現從多項式的字串表示轉換為多項式的行向量表示,輸入不必降冪排列,程式碼如下:

複製程式碼

 1 %sr2poly.m
 2 %把多項式的字串表示轉換為行向量
 3 function Y=str2poly(X)
 4 %X是字串形式的多項式
 5 %Y是行向量形式的多項式
 6 %輸入格式檢查
 7 if(ischar(X)==0),
 8     disp('輸入錯誤:輸入X必須是一個字串');
 9 end;
10 %用正則表示式尋找'+'或者'-'的下標位置
11 index=regexp(X,'\+|\-');
12 %多形式的項數
13 L=length(index);
14 %用於儲存多項式的每一項資訊的單元字串矩陣
15 term=cell(1,L+1);
16 term(1)=cellstr(X(1:(index(1)-1)));
17 for i=1:L-1,
18     term(i+1)=cellstr(X(index(i):(index(i+1)-1)));
19 end;
20 term(L+1)=cellstr(X(index(L):end));
21 %如果第一項為空則刪除第一項
22 if(isempty(char(term(1)))),
23     term(1)=[];
24     %多項式的項數減一
25     L=L-1;
26 end;
27 %多項式係數矩陣
28 coefficient=[];
29 %多項式冪次矩陣,它與多項式係數矩陣一一對應
30 power=[];
31 for i=1:L+1,
32     %單項多項式字串表示式
33     substring=char(term(i));
34     %用正則表示式,尋找字串'x^',由於'^'是正則表示式中特殊字元,多以用'\^'
35     index2=regexp(substring,'x\^');
36     if(isempty(index2)==0),
37         %如果匹配上
38         if((index2(1)==1))
39             %單項多項式字串為'x^*'形式
40             coefficient=[coefficient 1];
41             power=[power str2num(substring((index2(1)+2):end))];
42         elseif(index2(1)==2)
43             %單項多項式字串為'+x^*'或者'-x^*','3x^*'形式
44             if(substring(1)=='+'),
45                 coefficient=[coefficient 1];
46                 power=[power str2num(substring((index2(1)+2):end))];
47             elseif(substring(1)=='-'),
48                 cofficient=[coefficient -1];
49                 power=[power str2num(substring(index2(1)+2:end))];
50             else                  51                 coefficient=[coefficient str2num(substring(1:(index2(1)-1)))];
52                 power=[power str2num(substring((index2+2):end))];
53             end;
54         else
55             %單項多項式字串為'2.2x^'
56             coefficient=[coefficient str2num(substring(1:(index2(1)-1)))];
57             power=[power str2num(substring((index2+2):end))];
58         end;
59     else
60             %單項多項式字串不含'x^'
61             %用正則表示式,尋找字串'x'
62             index2=regexp(substring,'x');
63             if(isempty(index2)==0),
64                 %如果匹配上'x'
65                  if(index2(1)==1),
66                      %單項多項式字串為'x*'形式
67                      coefficient=[coefficient 1];
68                      power=[power 1];
69                  elseif(index2(1)==2),
70                      %單項多項式字串為'+x'或者'-x','3x*'形式
71                      if((substring(1)=='+')==1),
72                          coefficient=[coefficient 1];
73                          power=[power 1];
74                      elseif(substring(1)=='-'),
75                          coefficient=[coefficient -1];
76                          power=[power 1];
77                      else
78                          %單項多項式字串為'2.2x*'
79                          coefficient=[coefficient str2num(substring(1:(index2-1)))];
80                          power=[power 1];
81                      end;
82                  else
83                      coefficient=[coefficient str2num(substring(1:(index2-1)))];
84                      power=[power 1];
85                  end;
86             else
87                 %單項多項式字串不含'x^','x',則斷定他是常數項
88                 coefficient=[coefficient str2num(substring)];
89                 power=[power 0];
90             end;
91         end;
92     end;
93     %合併同類項
94     N=max(power)+1;
95     Y=zeros(1,N);
96     for i=1:N,
97         index3=power==(N-i);
98         Y(i)=sum(coefficient(index3));
99      end;

複製程式碼

  在命令列輸入以下程式碼:(輸入時為字串形式)

 1 >> str2poly('x^7-2x^6+3x^5-5x^4+x^2-1') 

  輸出程式碼如下:

1 ans =
2 
3      1    -2     3    -5     0     1     0    -1

  2、poly2str():

  接下來是poly2str()函式,實現了把一個行向量表示的多項式轉換為常見的字串表示的多項式,程式碼如下:

複製程式碼

 1 %poly2str.m
 2 %把多項式的行向量表示轉換為字串表示
 3 function Y=poly2str(X)
 4 %X是表示一個多項式的向量
 5 %Y多項式的字串表示
 6 %輸入檢查,如果X不是一個向量則退出
 7 if isvector(X)==0,
 8     disp('輸入錯誤:輸入X不是一個向量,請輸入一個代表多項式的向量!');
 9     return; 
10 end;
11 Y='';    %輸入字串
12 n=length(X);
13 for i=1:n,                  %把多項式的每一次冪轉換成字串
14     if(i~=1&&X(i)>0)         
15         Y=[Y '+'];          %若為正係數,必須新增‘+'
16     end;
17                              %輸出係數
18     if(X(i)==0),             %如果該次冪係數為零,則不輸出字串
19         continue;
20     elseif(X(i)==1&&i~=n),   %如果該次冪係數為1,可以不輸出係數,只輸出想x^n
21         Y=Y;
22     else
23         Y=[Y num2str(X(i))];      %其他輸入情況
24     end;
25     
26     if(i==n-1),               %輸入x^n   1次冪輸入字串'x'
27         Y=[Y 'x'];
28     elseif(i==n),               %0次冪不輸出x^n
29         Y=Y;
30     else
31         Y=[Y 'x^' num2str(n-i)];   %其他情況輸出x^n
32     end;
33                                   %如果不是最後一項,輸出'+'
34 end;
35 if(Y(1)=='+'),                    %修正如果0次冪為0時,造成末尾有多餘的字串‘+’
36     Y(1)=[];
37 end;

複製程式碼

  在命令列輸入以下程式碼:(輸入時為矩陣行向量形式)

 1 >> poly2str([1 -2 3 -5 0 1 0 -1]) 

  輸出程式碼如下:

ans = 

        x^7-2x^6+3x^5-5x^4+x^2-1