Matlab - 条件差的多项式

时间:2016-05-01 08:18:27

标签: matlab plot graph quadratic cubic

我有一个问题要求我对人口数据做线性,二次和三次拟合,然后估算1915年的人口。线性和二次拟合起作用,但是立方似乎引起一个错误,告诉我多项式是条件恶劣。该图非常接近数据值,似乎非常合适。我该怎么做才能解决这个问题?代码是:

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)

2 个答案:

答案 0 :(得分:1)

发出警告信息:

  

警告:多项式条件严重。添加具有不同X的点   值,减少多项式的次数,或尝试居中和   如帮助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帮助。

答案 1 :(得分: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)