链接:https://zhuanlan.zhihu.com/p/36103034
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
1) polyfit
代码例子如下,拟合一个3次曲线,并画图。
x = 0:1:9;
y = [0 2 4 6 8 20 12 14 16 18]
A=polyfit(x,y,3);
z=polyval(A,x);
plot(x,y,\'r*\',x,z,\'b\')
1) lsqcurvefit nlinfit
使用lsqcurvefit(最小二乘拟合)或nlinfit。下面的例子,是拟合一个3次曲线。这两个函数还可以拟合指数函数、三角函数等。
x=[0 1 2 3 4 5 6 7 8 9];
y=[0 1 2 3 4 5+10 6 7 8 9]; %这里,有一个噪音
w=[1 1 1 1 1 0.1 1 1 1 1]; %我们知道噪音的权重很低
a0=[1 1 1 1];
f=@(a,x)a(1)+a(2)*x+a(3)*x.*x+a(4)*x.*x.*x;
f1 = lsqcurvefit(f,a,x,y)
f2 = nlinfit(x,y,f,a0)
y1=f(f1,x)
y2=f(f2,x)
plot(x,y,\'r*\',x,y1,\'b\',x,y2,\'g\')
2)cftool
注意,上述拟合,是无权重拟合。w没有起作用,会发现拟合的曲线被噪音影响较大。下面将采用cftool拟合来降低噪音:
命令行中输入:cftool,回车,就打开了cftool窗口。
在窗口中,将X data选为x,将Y data选为y,此时就自动拟合为一个直线。注意,重要的地方来了:将Weights选择为w,会发现直线更加贴近正常点!
下列参考文章中有所有拟合类型的解释 matlab cftool用法及其菜单 [李园7舍_404]
3)使用fit 注意,这才是最重要的拟合!cftool能实现的,这里全能实现。
x=[0;1;2;3;4;5;6;7;8;9];
y=[0;1;2;3;4;5+10;6;7;8;9]; %这里,有一个噪音
w=[1;1;1;1;1;0.1;1;1;1;1]; %我们知道噪音的权重很低
a0=[1 1];
plot(x,y,\'o\')
fo = fitoptions(\'Method\',\'NonlinearLeastSquares\',...
\'StartPoint\',a0);
ft = fittype(\'a+x*b\',\'options\',fo);
[curve,gof] = fit(x,y,ft,\'Weights\',w)
hold on
plot(curve,\'m\')
legend(\'Data\',\'curve\')
hold off
参见:
Fit type for curve and surface fitting
Create or modify fit options object
4) fit使用SmoothingSpline
x=[0;1;2;3;4;5;6;7;8;9];
y=[0;1;2;3;4;5+10;6;7;8;9]; %这里,有一个噪音
w=[1;1;1;1;1;0.2;1;1;1;1]; %我们知道噪音的权重很低
a0=[1 1];
plot(x,y,\'o\')
fo = fitoptions(\'method\',\'SmoothingSpline\',\'SmoothingParam\',0.07,\'Weights\',w);
ft = fittype(\'smoothingspline\');
f = fit(x,y,ft,fo)
y1= f(x)
hold on
plot(x,y1,\'r\')
legend(\'Data\',\'f\')
hold off
可惜,拟合代码不能转C++
1)写一个文件 fixSmoothingSpline.m,内容如下,是做一个加权样条拟合的,
function y1 = fixSmoothingSpline(x, y, w)%#codegen
f = fit(x,y,\'SmoothingSpline\',\'SmoothingParam\',0.07,\'Weights\',w);
y1= f(x);
2)在命令行中输入coder,调出coder窗口,
3)可是,因为上述文件中带有fit字样,不支持转C。