2015-05-04 28 views
0

我有一組三維數據(300點),創建一個看起來像兩個錐體或橢圓體相互連接的表面。我想要一種方法來找到這個數據集的最佳擬合橢球或圓錐的方程。迴歸方法並不重要,越容易越好。我基本上需要一種方法,一個代碼或一個matlab函數來計算這些數據的橢圓方程的常量。如何將橢圓錐體擬合成一組數據?

回答

0

你也可以嘗試fminsearch,但爲了避免落在局部最小值上,考慮到係數的數量(試圖消除其中一些),你將需要一個好的起點。

這裏是一個2D橢圓的例子:

% implicit equation 
fxyc = @(x, y, c_) c_(1)*x.^2 + c_(2).*y.^2 + c_(3)*x.*y + c_(4)*x + c_(5).*y - 1; % free term locked to -1 

% solution (ellipse) 
c_ = [1, 2, 1, 0, 0]; % x^2, y^2, x*y, x, y (free term is locked to -1) 

[X,Y] = meshgrid(-2:0.01:2); 
figure(1); 
fxy = @(x, y) fxyc(x, y, c_); 
c = contour(X, Y, fxy(X, Y), [0, 0], 'b'); 
axis equal; 
grid on; 
xlabel('x'); 
ylabel('y');   
title('solution');   

% we sample the solution to have some data to fit 
N = 100; % samples 
sample = unique(2 + floor((length(c) - 2)*rand(1, N))); 
x = c(1, sample).'; 
y = c(2, sample).'; 

x = x + 5e-2*rand(size(x)); % add some noise 
y = y + 5e-2*rand(size(y)); 

fc = @(c_) fxyc(x, y, c_); % function in terms of the coefficients 
e = @(c) fc(c).' * fc(c); % squared error function 

% we start with a circle 
c0 = [1, 1, 0, 0, 0]; 

copt = fminsearch(e, c0) 

figure(2); 
plot(x, y, 'rx'); 
hold on 
fxy = @(x, y) fxyc(x, y, copt); 
contour(X, Y, fxy(X, Y), [0, 0], 'b'); 
hold off; 
axis equal; 
grid on; 
legend('data', 'fit'); 
xlabel('x');     %# Add an x label 
ylabel('y');   
title('fitted solution'); 

enter image description here

0

該matlab函數fit可以採取任意適合的表達式。它需要弄清楚參數,但可以完成。

您將首先創建一個fittype對象,該對象具有代表您的預期形式的字符串。你需要鍛鍊自己的表達是最適合你期待什麼,我要帶a cone expression from the Mathworld site爲例,並重新安排它針對z

ft = fittype('sqrt((x^2 + y^2)/c^2) + z_0', ... 
    'independent', {'x', 'y'}, 'coeff', {'c', 'z_0'}); 

如果它是一個簡單的表格MATLAB可以計算出哪些是變量,哪些是係數,但是有些更復雜的因素,您可能需要幫助。

的「fitoptions」對象持有的方法配置:根據您的數據集,你可能需要花費一些時間,指定的上限和下限,起始值等

fo = fitoptions('Upper', [one, for, each, of, your, coeffs, in, the, order, they, appear, in, the, string], ... 
    'Lower', [...], `StartPoint', [...]); 

然後得到輸出

[fitted, gof] = fit([xvals, yvals], zvals, ft, fo); 

警告:我已經用2D數據集完成了這麼多工作,並且docs狀態可以工作三次,但是我自己沒有這樣做,所以上面的代碼可能無法工作,請檢查文檔以確保您已經得到你的語法正確。

這可能值得從一個簡單的擬合表達式開始,這是線性的,以便您可以使您的代碼正常工作。然後將表達式換成圓錐體並玩耍,直到你得到看起來像你期望的東西。

當你合適的時候,一個好的訣竅是你可以在你的fit中使用的字符串表達式上使用eval函數來評估字符串的內容,就好像它是一個matlab表達式一樣。這意味着您需要使用與您的字符串表達式中的變量和係數名稱相同的工作空間變量。