1

我有一个问题要求我对人口数据进行线性、二次和三次拟合,然后估计 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)
4

2 回答 2

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')

在此处输入图像描述

结果表明,在这种情况下,两个三次拟合实际上是相同的。有关该问题的更多详细信息,请参阅polyfit帮助。

于 2016-05-01T09:00:37.277 回答
0

在较新版本的 MATLAB 中,警告还说您应该阅读帮助。特别是,您需要重新调整数据以避免数字问题。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)
于 2016-05-01T09:04:30.167 回答