2016-05-01 85 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)