一、線性擬合
? 線性擬合
我隨便設定一個函數(shù)然后通過解方程計算出對應的系數(shù)
假設我的函數(shù)原型是
y=a*sin(0.1*x.^2+x)+b* squre(x+1)+c*x+d
clc;
clear;
x=0:0.2:10;
% 我們這里假設 a=3.2 b=0.7 c=5.0 d是一個隨機
y=3.2*sin(0.1*x.^2+x)+0.7*sqrt(x+1)+5*x +rand(size(x));
plot(x,y,'*');
hold on ;
y1=sin(0.1*x.^2+x);
y2=sqrt(x+1);
y3=x;
y4=rand(size(x));
X=[y1;y2;y3;y4];%將各自的倆帶入
P=X'\y' % 通過解方程計算出4個系數(shù)
yn=P(1)*y1+P(2)*y2+P(3)*y3+P(4)*y4; % 得到一個新的函數(shù) 計算得出的擬合Y的值
plot(x,yn,'r');
legend('原始數(shù)據(jù)點','紅色曲線擬合值','Location','southoutside','Orientation','horizontal')
?擬合系數(shù):
?
clear;
clc;
close all
t=0:0.001:2*pi;%原函數(shù)
YS=sin(t);%基函數(shù)
N=21;
Yo=[];
for k=1:N
Yn=sawtooth(k*(t+pi/2),0.5);
Yo=[Yo,Yn'];
end
YS=YS';%擬合
a = Yo\YS;
%繪圖
figure()
for k=1:N
clf
plot(t,Yo(:,1:k)*a(1:k,:),t,YS,'LineWidth',1)
ylim([-1.3,1.3])
xlim([0,6.3])
pause(0.1)
end
二、非線性擬合
利用matlab實現(xiàn)非線性擬合(三維、高維、參數(shù)方程)_matlab多元非線性擬合_hyhhyh21的博客-CSDN博客
上面的這位是真正的大佬,我們都是照貓畫虎的學習。
1、一維
簡單的一維的擬合:
思路: 將非線性-》線性:
eg:
?將其兩邊都取對數(shù)
用線性的方式計算出a b?
逆變換 ,畫出曲線:
clear
clc
close all
% 假設函數(shù) 為 y=a* exp(-bx)
x=0:0.1:5;
% 我們這里假設 a=2.4 b=1.2
a=2.4;
b=1.2;
y=a*exp(-b*x);%
y=y+1.3*y.*rand(size(y)); % 增加噪聲
plot(x,y,'.');
hold on;
%Lg_y=Lg_a+b*(-x) 變成了ax+b 的形式 ,然而我們的最終的目的是通過x 來計算出a 和 b
% 對等式的兩邊取對數(shù)
lg_y=log(y);
y1=ones(size(x));
y2=-x;
% 同理和上面計算線性的一楊
X=[y1;y2];
P =X'\lg_y'
% 畫出擬合后的曲線
a_fit=exp(P(1));
b_fit=P(2);
x2=0:0.01:10;
plot(x2,a_fit*exp(-b_fit*x2),'-','linewidth',1.5,'color','r')
Matlab 中的非線性擬合方法
1、fit 方法
fit是最常用,最經(jīng)典的方法
?
ft = fittype( 'a*x+b*sin(c*x).*exp(d*x)+e', 'independent', 'x', 'dependent', 'y' );; %函數(shù)的表達式,
OP1 = fitoptions( 'Method', 'NonlinearLeastSquares' );% 非線性擬合方法
OP1.StartPoint = 5*rand(1,5);%初始值,越靠近真實值越好
OP1.Lower = [-2, 0, 2, 0, 0];%參數(shù)的最小邊界
OP1.Upper = [1, 3, 5, 2, 3];%參數(shù)的最大邊界
% 開始擬合
fitobject = fit(x',y',ft,OP1);
Fit_P=ones(size(P));
Fit_P(1)=fitobject.a;
Fit_P(2)=fitobject.b;
Fit_P(3)=fitobject.c;
Fit_P(4)=fitobject.d;
Fit_P(5)=fitobject.e;
2、nlinfit()函數(shù) Levenberg-Marquard
L-M 非線性迭代
?
% 2 用nlinfit()函數(shù) Levenberg-Marquardt?
% 定義一個函數(shù)
Func=@(P,x)( P(1)*x+P(2)*sin(P(3)*x).*exp(P(4)*x)+P(5));% 也就是說定義一個函數(shù)模型
OP2 = statset('nlinfit');%?
% ?x,y ?modelfun是函數(shù)模型 ?beta表示的是初始值 ,我這里寫成最進行的那個參數(shù) ? OP2 ?擬合的方法
beta=[-0.17 2.1 ?3.0 ?0.25 ?2.0];% 初始值
Fit_P2 = nlinfit(x,y,Func,beta,OP2);
%擬合
fit_y2 = Fit_P2(1)*x1+Fit_P2(2)*sin(Fit_P2(3)*x1).*exp(Fit_P2(4)*x1)+Fit_P2(5);;
subplot(3,2,2)
hold on;
plot(x,y,'LineStyle','none','MarkerSize',15,'Marker','.','color','k')
plot(x1,fit_y2,'-','linewidth',1.5,'color','r');
box on
%ylim(y_lim)
title('nlinfit函數(shù)')
3、信賴域法(trust region reflective)
信賴域法(trust region reflective)是通過Hessian 矩陣,逐步試探鄰域內的最小化,來求解問題的。相比較之前的那些雅克比相關的方法,信賴域法會占用更多內存和速度,所以適用于中小規(guī)模的矩陣。
% 3 信賴區(qū)間 IsqNonLin()
func2=@(P)(P(1)*x+P(2)*sin(P(3)*x).*exp(P(4)*x)+P(5) -y);
% lsqnonlin方法
% 'Algorithm','trust-region-reflective' 算法是trust-region-reflective
% MaxFunctionEvaluations MaxFunctionEvaluations可以理解為試探的次數(shù),
% 比如算法在一個點的四周試探了三個鄰近點的值,然后確定下一步要往其中的某個點走,
% 這個時候FunctionEvaluations對應3次,即試探了3次,而Iteration是一次,即走了一步,完成了一步迭代
% MaxIterations 最大迭代次數(shù)
OP3=optimoptions(@lsqnonlin,'Algorithm','trust-region-reflective','MaxFunctionEvaluations',1e4,'MaxIterations',1e3);
%[-2, 0, 2, 0, 0];%參數(shù)的最小邊界
%[1, 3, 5, 2, 3];%參數(shù)的最大邊界
lower=[-2, 0, 2, 0, 0];
up=[1, 3, 5, 2, 3];
% 計算出系數(shù)
[Fit_P3,~]=lsqnonlin(func2,beta,lower,up,OP3);
fit_y3=Fit_P3(1)*x1+Fit_P3(2)*sin(Fit_P3(3)*x1).*exp(Fit_P3(4)*x1)+Fit_P3(5);
subplot(3,2,3);
hold on
plot(x,y,'LineStyle','none','MarkerSize',15,'Marker','.','color','k')
plot(x1,fit_y3,'-','linewidth',1.5,'color','r')
hold off
box on
%ylim(y_lim)
title('lsqnonlin函數(shù)');
%4 lsqcurvefit()函數(shù) trust-region-reflective
modelfun2 = @(p,x)(p(1)*x+p(2)*sin(p(3)*x).*exp(p(4)*x)+p(5)) ;
OP4=optimoptions('lsqcurvefit','Algorithm','trust-region-reflective','MaxFunctionEvaluations',1e4,'MaxIterations',1e3);
%[-2, 0, 2, 0, 0];%參數(shù)的最小邊界
%[1, 3, 5, 2, 3];%參數(shù)的最大邊界
lower=[-2, 0, 2, 0, 0];
up=[1, 3, 5, 2, 3];
% 計算出系數(shù)
%[p,~] = lsqcurvefit(modelfun,p0,x,y,[-2,0,2,0,0],[1,3,5,3,3],OP4);
[Fit_P4,~]=lsqcurvefit(modelfun2,beta,x,y,lower,up,OP4);
fit_y4=Fit_P4(1)*x1+Fit_P4(2)*sin(Fit_P4(3)*x1).*exp(Fit_P4(4)*x1)+Fit_P4(5);
subplot(3,2,4);
hold on
plot(x,y,'LineStyle','none','MarkerSize',15,'Marker','.','color','k')
plot(x1,fit_y4,'-','linewidth',1.5,'color','r')
hold off
box on
%ylim(y_lim)
title('lsqcurvefit函數(shù)');
4、fsolve()函數(shù)
默認的算法為trust-region-dogleg,屬于信賴域法。
5、粒子群法
?所有代碼:
clear;
close all;
clc;
% 自定義一個非線性的函數(shù) y=a*x+b*sin(c*x).*exp(d*x)+e 那將函數(shù)
x = 0:0.05:10;
P=[-0.2 2.4 3.4 0.3 1.7];
y = P(1)*x+P(2)*sin(P(3)*x).*exp(P(4)*x)+P(5);
y=y+0.5*randn(size(x)); % 添加噪聲
figure();
% 1 .fit 函數(shù)開始擬合
ft = fittype( 'a*x+b*sin(c*x).*exp(d*x)+e', 'independent', 'x', 'dependent', 'y' );; %函數(shù)的表達式,
OP1 = fitoptions( 'Method', 'NonlinearLeastSquares' );% 非線性擬合方法
%OP1.StartPoint = 5*rand(1,5);%初始值,越靠近真實值越好
OP1.StartPoint = [-0.17 2.1 3.0 0.25 2.0];
OP1.Lower = [-2, 0, 2, 0, 0];%參數(shù)的最小邊界
OP1.Upper = [1, 3, 5, 2, 3];%參數(shù)的最大邊界
% 開始擬合
fitobject = fit(x',y',ft,OP1);
Fit_P=ones(size(P));
Fit_P(1)=fitobject.a;
Fit_P(2)=fitobject.b;
Fit_P(3)=fitobject.c;
Fit_P(4)=fitobject.d;
Fit_P(5)=fitobject.e;
%plot(x,y,'.');
% 開始計算擬合后的y
x1 = 0:0.01:10;
fit_y1 = Fit_P(1)*x1+Fit_P(2)*sin(Fit_P(3)*x1).*exp(Fit_P(4)*x1)+Fit_P(5);
subplot(3,2,1)
hold on
plot(x,y,'LineStyle','none','MarkerSize',10,'Marker','.','color','k');
plot(x1,fit_y1,'-','linewidth',1.5,'color','r');
% 開始計算擬合后的y
fit_y1 = Fit_P(1)*x+Fit_P(2)*sin(Fit_P(3)*x).*exp(Fit_P(4)*x)+Fit_P(5);
subplot(3,2,1)
plot(x,y,'LineStyle','none','MarkerSize',15,'Marker','.','color','k')
plot(x,fit_y1,'-','linewidth',1.5,'color','r');
hold on;
title('經(jīng)典fit函數(shù)');
box on;
% 2 用nlinfit()函數(shù) Levenberg-Marquardt
% 定義一個函數(shù)
Func=@(P,x)( P(1)*x+P(2)*sin(P(3)*x).*exp(P(4)*x)+P(5));% 也就是說定義一個函數(shù)模型
OP2 = statset('nlinfit');%
% x,y modelfun是函數(shù)模型 beta表示的是初始值 ,我這里寫成最進行的那個參數(shù) OP2 擬合的方法
beta=[-0.17 2.1 3.0 0.25 2.0];% 初始值
Fit_P2 = nlinfit(x,y,Func,beta,OP2);
%擬合
fit_y2 = Fit_P2(1)*x1+Fit_P2(2)*sin(Fit_P2(3)*x1).*exp(Fit_P2(4)*x1)+Fit_P2(5);
subplot(3,2,2)
hold on;
plot(x,y,'LineStyle','none','MarkerSize',15,'Marker','.','color','k')
plot(x1,fit_y2,'-','linewidth',1.5,'color','r');
box on
%ylim(y_lim)
title('nlinfit函數(shù)')
% 3 信賴區(qū)間 IsqNonLin()
func2=@(P)(P(1)*x+P(2)*sin(P(3)*x).*exp(P(4)*x)+P(5) -y);
% lsqnonlin方法
% 'Algorithm','trust-region-reflective' 算法是trust-region-reflective
% MaxFunctionEvaluations MaxFunctionEvaluations可以理解為試探的次數(shù),
% 比如算法在一個點的四周試探了三個鄰近點的值,然后確定下一步要往其中的某個點走,
% 這個時候FunctionEvaluations對應3次,即試探了3次,而Iteration是一次,即走了一步,完成了一步迭代
% MaxIterations 最大迭代次數(shù)
OP3=optimoptions(@lsqnonlin,'Algorithm','trust-region-reflective','MaxFunctionEvaluations',1e4,'MaxIterations',1e3);
%[-2, 0, 2, 0, 0];%參數(shù)的最小邊界
%[1, 3, 5, 2, 3];%參數(shù)的最大邊界
lower=[-2, 0, 2, 0, 0];
up=[1, 3, 5, 2, 3];
% 計算出系數(shù)
[Fit_P3,~]=lsqnonlin(func2,beta,lower,up,OP3);
fit_y3=Fit_P3(1)*x1+Fit_P3(2)*sin(Fit_P3(3)*x1).*exp(Fit_P3(4)*x1)+Fit_P3(5);
subplot(3,2,3);
hold on
plot(x,y,'LineStyle','none','MarkerSize',15,'Marker','.','color','k')
plot(x1,fit_y3,'-','linewidth',1.5,'color','r')
hold off
box on
%ylim(y_lim)
title('lsqnonlin函數(shù)');
%4 lsqcurvefit()函數(shù) trust-region-reflective
modelfun2 = @(p,x)(p(1)*x+p(2)*sin(p(3)*x).*exp(p(4)*x)+p(5)) ;
OP4=optimoptions('lsqcurvefit','Algorithm','trust-region-reflective','MaxFunctionEvaluations',1e4,'MaxIterations',1e3);
%[-2, 0, 2, 0, 0];%參數(shù)的最小邊界
%[1, 3, 5, 2, 3];%參數(shù)的最大邊界
lower=[-2, 0, 2, 0, 0];
up=[1, 3, 5, 2, 3];
% 計算出系數(shù)
%[p,~] = lsqcurvefit(modelfun,p0,x,y,[-2,0,2,0,0],[1,3,5,3,3],OP4);
[Fit_P4,~]=lsqcurvefit(modelfun2,beta,x,y,lower,up,OP4);
fit_y4=Fit_P4(1)*x1+Fit_P4(2)*sin(Fit_P4(3)*x1).*exp(Fit_P4(4)*x1)+Fit_P4(5);
subplot(3,2,4);
hold on
plot(x,y,'LineStyle','none','MarkerSize',15,'Marker','.','color','k')
plot(x1,fit_y4,'-','linewidth',1.5,'color','r')
hold off
box on
%ylim(y_lim)
title('lsqcurvefit函數(shù)');
%% 5 fsolve()函數(shù) %默認算法trust-region-dogleg
modelfun3 = @(p)(p(1)*x+p(2)*sin(p(3)*x).*exp(p(4)*x)+p(5) -y);
p0 = 5*rand(1,5);
OP5 = optimoptions('fsolve','Display','off');
Fit_P = fsolve(modelfun3,beta,OP5);
fit_y5 = Fit_P(1)*x1+Fit_P(2)*sin(Fit_P(3)*x1).*exp(Fit_P(4)*x1)+Fit_P(5);
subplot(3,2,5)
hold on
plot(x,y,'LineStyle','none','MarkerSize',15,'Marker','.','color','k')
plot(x1,fit_y5,'-','linewidth',1.5,'color','r')
hold off
box on
title('fsolve函數(shù)')
%% 6 粒子群PSO算法
fun6 = @(p) ( norm(p(1)*x+p(2)*sin(p(3)*x).*exp(p(4)*x)+p(5) -y) );%這里需要計算誤差的平方和
OP6 = optimoptions('particleswarm','InertiaRange',[0.4,1.2],'SwarmSize',100);
[p,~,~,~] = particleswarm(fun6,5,[-5,-5,-5,-5],[5,5,5,5],OP6);%區(qū)間可以稍微放大一些,不怕
y6 = p(1)*x+p(2)*sin(p(3)*x).*exp(p(4)*x)+p(5);
subplot(3,2,6)
hold on
plot(x,y,'LineStyle','none','MarkerSize',15,'Marker','.','color','k')
plot(x,y6,'-','linewidth',1.5,'color','r')
hold off
box on
ylim(y_lim)
title('PSO算法')
三、多項式曲線
?Matlab:
>> x=linspace(0,4*pi,150);
y=cos(x)+10*rand(1);
plot(x,y,'.');
hold on;
[p,s]=polyfit(x,y,9);% 擬合為7階的函數(shù)
x1=linspace(0,4*pi,150);
y1=polyval(p,x1);
plot(x1,y1,'color','r');
p
p =
0.0000 0.0000 -0.0004 0.0081 -0.0783 0.3753 -0.7660 0.3815 -0.4104 10.6154
% 方程變換
>> x=linspace(0,4*pi,150);
y=2*exp(-(x-1).^2/1.^2)+0.1*rand(1);
plot(x,y,'.')
>> x=linspace(0,4*pi,50);
y=2*exp(-(x-1).^2/1.^2)+0.1*rand(1);
plot(x,y,'.')
>> x=linspace(0,4*pi,50);
y=2*exp(-(x-1).^2/1.^2)+0.1*rand(1);
plot(x,y,'.');
hold on;
[p,s]=polyfit(x,y,9);% 擬合為7階的函數(shù)
x1=linspace(0,4*pi,50);
y1=polyval(p,x1);
plot(x1,y1,'color','r')
?從上圖我們可以看出9階的擬合效果要比7階的好很多,那么我們用c++實現(xiàn)的時候也就按照9階的來。文章來源:http://www.zghlxwxcb.cn/news/detail-523888.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-523888.html
到了這里,關于Matlab 線性擬合、一維、多維度非線性擬合、多項式擬合的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!