2013-05-27 184 views
7

我有一個數據數組,當繪製時,看起來像這樣。MATLAB曲線擬合,指數與線性

http://s12.postimg.org/7ja47a6b1/temp.jpg

我需要使用polyfit命令來大致確定1.72.3之間的最佳擬合指數的時間。我還必須比較這個指數擬合到一個簡單的線性擬合。

我給出的等式Temp(t) = Temp0 * exp(-(t-t0)/tau),其中t0是對應於溫度Temp0時間(I可以選擇在何處開始我的曲線擬合,但是它必須大致1.7和2.3之間被限制的區域)。這是我的嘗試。

% Arbitrarily defined starting point 
t0 = 1.71; 

%Exponential fit 
p = polyfit(time, log(Temp), 1) 
tau = -1./p(1) 
Temp0 = exp(p(2)) 

tm = 1.8:0.01:2.3; 
Temp_t = Temp0*exp(-(tm)/tau); 
plot(time, Temp, tm, Temp_t) 

figure(2) 

%Linear fit 
p2 = polyfit(time, Temp, 1); 
Temp_p = p2(1)*tm + p2(2); 
plot(time, Temp, tm, Temp_p) 

我的指數擬合最終看起來像exponential fit。我的線性適合看起來像linear fit。 (幾乎相同)。我做錯了什麼?如果兩者適合如此相似?我聽說circshift可能會有所幫助,但在閱讀幫助文件後,我無法掌握該命令的適用性。

+0

來自@Amro的鏈接似乎已被The MathWorks打破。更新版本是[here](http://www.mathworks.com/help/stats/examples/curve-fitting-and-distribution-fitting.html)。 – horchler

+1

Thanks @horchler,這裏是我前面提到的示例的更新鏈接:[通過轉換爲線性擬合非線性模型的陷阱](http://www.mathworks.com/help/stats/examples/pitfalls-in- fitting-nonlinear-models-by-transforming-to-linearity.html) – Amro

回答

4

事情表現就像你期待。問題是你試圖適合的函數不是一個很好的數據近似值。目光看起來曲線,似乎曲線的指數部分漸近地趨於約16的值;但是你使用的函數最終會趨向於0的溫度。因此,擬合一個從22到16的部分將會給你一個幾乎線性的關係。爲了說明這一點,我寫了幾行代碼,這些代碼大致與您擁有的數據點匹配 - 並顯示不同的函數(傾向於0,傾向於16的另一個函數)會爲您提供截然不同的曲線形狀。第一個(你的原始函數)在22和16的T值之間幾乎是線性的 - 所以它看起來像線性擬合。

我建議您考慮適合的函數的「正確」形狀 - 使您選擇特定形式的底層物理是什麼?獲得這種權利至關重要......

下面是代碼:

time = linspace(1.5, 2.5, 200); 
t0 = 1.7; 
t1 = 2.3; 
tau = 2.0; 

% define three sections of the function: 
s1 = find(time < t0); 
s2 = find(time >= t0 & time < t1); 
s3 = find(time > 2.3); 

% compute a shape for the function in each section: 
tData(s1) = 28 - 50*(time(s1)-1.5).^2; 
tData(s2) = 22*exp(-(time(s2)-t0)/tau); 
tData(s3) = tData(s2(end)) + (s3 - s3(1))*12/numel(s3); 

figure 
plot(time, tData) 

% modify the equation slightly: assume equilibrium temperature is 16 
% with a bit of effort one could fit for this as a second parameter 
Teq = 16; 
tData2 = tData; 
tau2 = tau/8; % decay more strongly to get down to approx the same value by t1 
tData2(s2) = (22 - Teq) * exp(- (time(s2) - t0)/tau2) + Teq; 
tData2(s3) = tData2(s2(end)) + (s3 - s3(1))*12/numel(s3); 

hold on; 
plot(time, tData2, 'r') 

這將導致以下情節:

enter image description here

我由此得出結論,主要的原因,你的情節看起來非常類似的是,該功能你試圖擬合幾乎是線性的,你選擇的領域 - 功能的不同選擇將是更好的匹配。

+1

非常感謝Floris。我感謝你的迴應。我被告知要比較兩種形式的曲線擬合,並確定符合數據「更好」的那種。我認爲這些表格會更加清晰,如果沒有,我開始懷疑我的代碼。你的回答非常明確和信息豐富,我感謝你。 – scimaks

2

如果我理解正確,您在polyfit中使用的變量time和temp包含所有值(從1.5到2.5)。因此,在計算polyfit之前,您可能需要將時間和Temp的值限制爲1.71至2.3(現在它正在計算從1.5到2.5的polyfit,因此爲什麼該線不與數據點對齊)。

p = polyfit(time, log(Temp), 1) 
+0

你是對的m_power!謝謝。我已經上傳了新版本。指數和線性擬合看起來應該如此相似嗎?再次感謝你! – scimaks

4

正如我在評論所提到的,有相對於擬合的非線性模型(無論是在最小二乘意義上的)擬合在對數空間中的線性模型之間的差。

統計工具箱中有一個不錯的demo解釋情況。我適應下面的代碼:

%# sample data 
x = [5.72 4.22 5.72 3.59 5.04 2.66 5.02 3.11 0.13 2.26 ... 
    5.39 2.57 1.20 1.82 3.23 5.46 3.15 1.84 0.21 4.29 ... 
    4.61 0.36 3.76 1.59 1.87 3.14 2.45 5.36 3.44 3.41]'; 
y = [2.66 2.91 0.94 4.28 1.76 4.08 1.11 4.33 8.94 5.25 ... 
    0.02 3.88 6.43 4.08 4.90 1.33 3.63 5.49 7.23 0.88 ... 
    3.08 8.12 1.22 4.24 6.21 5.48 4.89 2.30 4.13 2.17]'; 

xx = linspace(min(x), max(x), 100); 

%# linear regression in log-space 
%#   y = p2 * exp(p1*x) 
%# => log(y) = log(p2) + p1*x 
p_exp = polyfit(x, log(y), 1); 
yy1 = exp(p_exp(2)) .* exp(xx .* p_exp(1)); 

%# linear regression 
p_lin = polyfit(x, y, 1); 
yy2 = polyval(p_lin, xx); 

%# non-linear regression (using previous result as initial coeff) 
f = @(p,x) p(2)*exp(p(1)*x); 
p_nonlin = nlinfit(x, y, f, [p_exp(1) exp(p_exp(2))]); 
yy3 = f(p_nonlin, xx); 

plot(x,y,'o', xx,yy1,'-', xx,yy2,'-', xx,yy3,'-') 
legend({'data points','linear in log-space','linear','non-linear'}) 

regression

0

使用

polyfit(x,y,n) 

功能在Matlab曲線擬合工具箱。