我有一个问题要求我对人口数据做线性,二次和三次拟合,然后估算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)
答案 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')
结果表明,在这种情况下,两个立方体拟合实际上是相同的。
有关该问题的详细信息,请参阅polyfit
帮助。
答案 1 :(得分:0)
在较新版本的MATLAB中,警告还说你应该read the help。
特别是,您需要重新调整数据以避免数字问题。幸运的是,这是polyfit
和polyval
可以为您做的事情。
你需要这样做的原因是拟合多项式是非常恶劣的。在幕后,它构建了一个矩阵,其中包含了多项式中每个幂的年数。因此,您有一个矩阵,其中包含1815
和1815^3 = 6e9
等条目,这不是理想的条件。缩放确保您不会在矩阵中获得大数字,因此条件数会得到改善。
实际上,您必须稍微改变一下polyfit
和polyval
:
[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)