這裡用到的還是最小二乘方法,和上一次這篇文章原理差不多。
就是首先構造最小二乘函式,然後對每乙個係數計算偏導,構造矩陣乘法形式,最後解方程組。
比如有乙個二次曲面:z=ax^2+by^2+cxy+dx+ey+f
首先構造最小二乘函式,然後計算係數偏導(我直接手寫了):
解方程組(下圖中a矩陣後面求和符號我就沒寫了啊),然後計算c:
**如下:
clear all;結果如下,深色曲面是原模型,淺色曲面是用雜訊資料擬合的模型:close all;
clc;
a=2;b=2;c=-3;d=1;e=2;f=30
; %係數
n=1:0.2:20
;x=repmat(n,96,1
);y=repmat(n'
,1,96);
z=a*x.^2+b*y.^2+c*x.*y+d*x+e*y +f; %原始模型
surf(x,y,z)
n=100
;ind=int8(rand(n,2)*95+1
);x=x(sub2ind(size(x),ind(:,1),ind(:,2
)));
y=y(sub2ind(size(y),ind(:,1),ind(:,2
)));
z=z(sub2ind(size(z),ind(:,1),ind(:,2)))+rand(n,1)*20
; %生成待擬合點,加個雜訊
hold on;
plot3(x,y,z,'o
');a=[n sum(y) sum(x) sum(x.*y) sum(y.^2) sum(x.^2
); sum(y) sum(y.^
2) sum(x.*y) sum(x.*y.^2) sum(y.^3) sum(x.^2.*y);
sum(x) sum(x.*y) sum(x.^2) sum(x.^2.*y) sum(x.*y.^2) sum(x.^3
); sum(x.*y) sum(x.*y.^2) sum(x.^2.*y) sum(x.^2.*y.^2) sum(x.*y.^3) sum(x.^3.*y);
sum(y.^
2) sum(y.^3) sum(x.*y.^2) sum(x.*y.^3) sum(y.^4) sum(x.^2.*y.^2
); sum(x.^
2) sum(x.^2.*y) sum(x.^3) sum(x.^3.*y) sum(x.^2.*y.^2) sum(x.^4
)];b=[sum(z) sum(z.*y) sum(z.*x) sum(z.*x.*y) sum(z.*y.^2) sum(z.*x.^2)]'
;c=inv(a)*b;
z=c(6)*x.^2+c(5)*y.^2+c(4)*x.*y+c(3)*x+c(2)*y +c(1
); %擬合結果
mesh(x,y,z)
注:加權最小二乘可以參考我後來的這篇文章。
Matlab曲面擬合和插值
插值和擬合都是資料優化的一種方法,當實驗資料不夠多時經常需要用到這種方法來畫圖。在matlab中都有特定的函式來完成這些功能。這兩種方法的確別在於 當測量值是準確的,沒有誤差時,一般用插值 當測量值與真實值有誤差時,一般用資料擬合。插值 對於一維曲線的插值,一般用到的函式yi interp1 x,y...
Matlab曲面擬合和插值
插值和擬合都是資料優化的一種方法,當實驗資料不夠多時經常需要用到這種方法來畫圖。在matlab中都有特定的函式來完成這些功能。這兩種方法的確別在於 當測量值是準確的,沒有誤差時,一般用插值 當測量值與真實值有誤差時,一般用資料擬合。插值 對於一維曲線的插值,一般用到的函式yi interp1 x,y...
matlab練習程式(修正指數曲線擬合)
對於一般的指數曲線如 y a e k t 可以先對兩邊求對數得到 log y log a k t 這樣的曲線,然後用最小二乘來計算係數。但是對於修正指數曲線如 y k a b t 這樣的函式,沒法直接求對數然後用最小二乘,因為有乙個常數項k,這裡可以利用三和法來計算係數。對於曲線 y k a b t...