题目:
给出以下数据:
xi | -1 | -0.75 | -0.5 | -0.25 | 0 | 0.25 | 0.5 0 | 0.75 | 1.00 |
---|---|---|---|---|---|---|---|---|---|
yi | -0.2209 | 0.3295 | 0.8826 | 1.4392 | 2.0003 | 2.5645 | 3.1334 | 3.7061 | 4.2836 |
利用最小二乘法,求他们的一次、二次拟合多项式,写出正规方程组并求出最小平方逼近多项式。
(注意:连续时称为逼近,离散时称为拟合,最佳逼近和小二乘拟合思路近似)
首先给出求一次拟合多项式的代码:
%最小二乘拟合-一次多项式
clear;
clc;
x0=[-1 -0.75 -0.5 -0.25 0 0.25 0.5 0.75 1];%m=9
y0=[-0.2209 0.3295 0.8826 1.4392 2.0003 2.5645 3.1334 3.7061 4.2836];
syms x;
%生成法方程系数矩阵-一次函数
z1=[0 0];
z2=[0 0];
b=[0 0];
for i=1:9
z1(1)=9;
z1(2)=x0(i)+z1(2);
z2(1)=z1(2);
z2(2)=x0(i)*x0(i)+z2(2);
b(1)=y0(i)+b(1);
b(2)=x0(i)*y0(i)+b(2);
end
fprintf('法方程组系数矩阵z和结果向量b分别为:\n')
z=[z1;z2]
b
a=vpa(inv(z)*b',8);
fprintf('最小二乘拟合一次多项式为:\n')
f(x)=a(1)+a(2)*x %最小二乘拟合一次多项式
plot(x0,y0,'b*'); %原始离散点
hold on
plot(x0,f(x0),'r') %最小二乘拟合一次多项式曲线图,红色线段
% 与8次多项式拟合曲线对比---系统自带函数
fprintf('8次多项式拟合由高到低系数为:\n')
p=polyfit(x0,y0,8)
y(x)=p(1)*x^8+p(2)*x^7+p(3)*x^6+p(4)*x^5+p(5)*x^4+p(6)*x^3+p(7)*x^2+p(8)*x+p(9);
plot(x0,y(x0),'g') %8次多项式拟合,绿色点
运行结果:
拟合函数图形:
放大一个离散点的局部区域,如下图所示:
可以思考一下为什么一次多项式拟合存在误差,而8次多项式直接经过离散点?
我们构建的是逼近拟合,而polyfit函数是插值拟合
求二次多项式拟合的代码:
%最小二乘法拟合
clear;
clc;
x0=[-1 -0.75 -0.5 -0.25 0 0.25 0.5 0.75 1];%m=9
y0=[-0.2209 0.3295 0.8826 1.4392 2.0003 2.5645 3.1334 3.7061 4.2836];
syms x;
%生成法方程系数矩阵-二次函数
z1=[0 0 0];
z2=[0 0 0];
z3=[0 0 0];
b=[0 0 0];
for i=1:9
z1(1)=9;
z1(2)=x0(i)+z1(2);
z1(3)=x0(i)*x0(i)+z1(3);
z2(1)=z1(2);
z2(2)=x0(i)*x0(i)+z2(2);
z2(3)=x0(i)^3+z2(3);
z3(1)=z1(3);z3(2)=z2(3);
z3(3)=x0(i)^4+z3(3);
b(1)=y0(i)+b(1);
b(2)=x0(i)*y0(i)+b(2);
b(3)=x0(i)^2*y0(i)+b(3);
end
fprintf('法方程组系数矩阵z和结果向量b分别为:\n')
z=[z1;z2;z3]
b
a=vpa(inv(z)*b',4);
fprintf('最小二乘法拟合二次多项式为:\n')
f(x)=a(1)+a(2)*x-a(3)*x^2
plot(x0,y0,'b*');
hold on
plot(x0,f(x0),'r')
fprintf('8次多项式拟合由高到低系数为:\n')
p=polyfit(x0,y0,8)
y(x)=p(1)*x^8+p(2)*x^7+p(3)*x^6+p(4)*x^5+p(5)*x^4+p(6)*x^3+p(7)*x^2+p(8)*x+p(9);
plot(x0,y(x0),'g')
运行结果:
拟合函数图形:
代码的不足之处:所用的方法就是简单粗暴的把书上的计算方法用代码实现了而已,理想情况下应该时自己输入xi和yi的数据,然后输入需要几次多项式拟合,输入完成后即可输出结果,或者自定义一个polyfit1函数,实现系统自带的polyfit函数的功能。
这是这学期恰烂钱的时候帮别人写的,以后有时间再改进吧~