2016-05-01 84 views
1

我有一個問題,要求我爲人口數據做線性,二次和三次擬合,然後估計1915年的人口。線性和二次擬合的工作,但立方似乎會產生一個錯誤告訴我多項式條件不好。該圖非常接近數據值,似乎很適合。我能做些什麼來彌補這一點?該代碼是:Matlab - 條件很差的多項式

clear; 
clc; 
close all; 

year = [1815,1845,1875,1905,1935,1965]; 
population = [8.3,19.7,44.4,83.2,127.1,190.9]; 

rlinear = polyfit(year,population,1); 
rquadratic = polyfit(year,population,2); 
rcubic = polyfit(year,population,3); 

newTime = linspace(1815,1965,100); 
vrlinear = polyval(rlinear,newTime); 
vrquadratic = polyval(rquadratic,newTime); 
vrcubic = polyval(rcubic,newTime); 

subplot(2,2,1) 
plot(year,population,'ob',newTime,vrlinear) 
xlabel('Year') 
ylabel('Population (millions)') 
title('Year vs. US population') 

subplot(2,2,2) 
plot(year,population,'ob',newTime,vrquadratic) 
xlabel('Year') 
ylabel('Population (millions)') 
title('Year vs. US population') 

subplot(2,2,3) 
plot(year,population,'ob',newTime,vrcubic) 
xlabel('Year') 
ylabel('Population (millions)') 
title('Year vs. US population') 

estimate = polyval(rquadratic,1915); 
fprintf('The estimated population in the year 1915 is %d million. \r',estimate) 

回答

1

繼警告消息:

警告:多項式受到嚴重製約。添加具有不同X 值的點,降低多項式的程度,或嘗試集中和按照HELP POLYFIT中的描述縮放。

中心和縮放解決了這個問題:

[rcubic2,~,mu] = polyfit(year,population,3); 
vrcubic2 = polyval(rcubic2,newTime,[],mu); 

subplot(2,2,3) 
plot(year,population,'ob',newTime,vrcubic1) 
hold on 
plot(newTime,vrcubic2,'--r') 
xlabel('Year') 
ylabel('Population (millions)') 
title('Year vs. US population') 

enter image description here

結果表明,在這種情況下,兩個立方擬合幾乎是相同的。 有關該問題的更多詳細信息,請參閱polyfit幫助。

0

在較新版本的MATLAB中,警告還說你應該read the help。 特別是,您需要重新調整數據以避免數值問題。幸運的是,這是polyfitpolyval可以爲你做的事情。

你需要這樣做的原因是擬合一個多項式是相當不適應的。在幕後,它構建了一個矩陣,其中包含您在多項式中對每個權力產生的年數。所以你有一個像18151815^3 = 6e9這樣的條目的矩陣,這對於調節是不理想的。縮放比例確保您不會在矩陣中獲得大量數字,因此條件數量會得到改善。

實際上,你必須調用polyfitpolyval有點不同:

[p,s,m] = polyfit(year, population, order) 
[populationAtOtherYears] = polyval(p, otherYears, s, m) 

所以你的腳本看起來是這樣的:

clear; 
clc; 
close all; 

year  = [1815,1845,1875,1905,1935,1965]; 
population = [8.3,19.7,44.4,83.2,127.1,190.9]; 

[linear.poly, linear.sigma, linear.mu] = polyfit(year,population,1); 
[quadratic.poly, quadratic.sigma, quadratic.mu] = polyfit(year,population,2); 
[cubic.poly, cubic.sigma, cubic.mu] = polyfit(year,population,3); 

newTime = linspace(1815,1965,100); 
% next line is to make a function for easier calling 
evaluatePolynomial = @(fit, t) polyval(fit.poly, t, fit.sigma, fit.mu); 
linear.evaluated = evaluatePolynomial(linear, newTime); 
quadratic.evaluated = evaluatePolynomial(quadratic, newTime); 
cubic.evaluated  = evaluatePolynomial(cubic, newTime); 

subplot(2,2,1) 
plot(year,population,'ob',newTime,linear.evaluated) 
xlabel('Year') 
ylabel('Population (millions)') 
title('Year vs. US population') 

subplot(2,2,2) 
plot(year,population,'ob',newTime,quadratic.evaluated) 
xlabel('Year') 
ylabel('Population (millions)') 
title('Year vs. US population') 

subplot(2,2,3) 
plot(year,population,'ob',newTime,cubic.evaluated) 
xlabel('Year') 
ylabel('Population (millions)') 
title('Year vs. US population') 

estimate = evaluatePolynomial(quadratic,1915); 
fprintf('The estimated population in the year 1915 is %d million. \r',estimate)