2013-05-27 10 views
7

Ich habe ein Array von Daten, die, wenn geplottet, so aussieht.MATLAB-Kurvenanpassung, exponentiell gegenüber linear

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

Ich brauche den polyfit Befehl verwenden, um die am besten passende exponentielle für die Zeit etwa zwischen 1.7 und 2.3 zu bestimmen. Ich muss auch diese exponentiellen passen zu einem einfachen linear passen.

ich die Gleichung Temp(t) = Temp0 * exp(-(t-t0)/tau) gegeben habe, wo t0 die Zeit, um entsprechende Temperatur ist Temp0 (Ich kann wählen, wo meine Kurvenanpassung beginnen, aber es muss in etwa zwischen 1,7 und 2,3 auf den Bereich beschränkt werden). Hier ist mein Versuch.

% 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) 

Meine Exponentialfit endet wie exponential fit suchen. Meine lineare Passform sieht wie linear fit aus. (praktisch identisch). Was mache ich falsch? Sollten die beiden Passungen so ähnlich sein? Mir wurde gesagt, dass circshift helfen kann, aber ich konnte die Anwendbarkeit des Befehls nach dem Lesen der Hilfedatei nicht erfassen.

+0

Link von @Amro scheint von The MathWorks beschädigt worden zu sein. Aktualisierte Version ist [hier] (http://www.mathworks.com/help/stats/examples/curve-fitting-and-distribution-fitting.html). – horchler

+1

Danke @horchler, hier ist der aktualisierte Link zu dem Beispiel, das ich zuvor erwähnt habe: [Probleme bei der Anpassung nichtlinearer Modelle durch Transformation an die Linearität] (http://www.mathworks.com/help/stats/examples/pitfalls-in- fitting-nonlinear-models-by-transformation-to-linearity.html) – Amro

Antwort

4

Dinge verhalten sich so wie Sie erwarten. Das Problem ist, dass die Funktion, die Sie anpassen möchten, keine sehr gute Annäherung der Daten ist. Bei Betrachtung der Kurve scheint der exponentielle Teil der Kurve asymptotisch auf einen Wert um 16 zu tendieren; aber die Funktion, die Sie verwenden, wird schließlich zu einer Temperatur von 0 neigen. Wenn Sie also zu einem Teil passen, der von 22 zu 16 geht, werden Sie eine fast lineare Beziehung haben. Um dies zu illustrieren, habe ich ein paar Codezeilen geschrieben, die ungefähr mit den Datenpunkten übereinstimmen, die Sie haben - und die zeigen, wie verschiedene Funktionen (eine, die zu 0 neigt, und eine andere, die zu 16 tendiert) Ihnen eine ganz andere Form der Kurve geben. Die erste (Ihre ursprüngliche Funktion) ist fast linear zwischen T-Werten von 22 und 16 - so wird es wie die lineare Anpassung aussehen.

Ich schlage vor, dass Sie über die "richtige" Form der Funktion nachdenken - was ist die zugrunde liegende Physik, die Sie eine bestimmte Form wählen lässt? Das richtig zu machen ist essentiell ...Hier

ist der Code:

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') 

Die in der folgenden Handlung führt:

enter image description here

ich daraus schließen, dass der Hauptgrund, Ihre Plots so ähnlich aussehen, dass die Funktion, die Sie versuchen zu passen ist fast linear über die Domäne, die Sie wählen - eine andere Wahl der Funktion wird eine bessere Übereinstimmung sein.

+1

Vielen Dank, Floris. Ich schätze Ihre Antwort. Mir wurde gesagt, dass ich die beiden Formen der Kurvenanpassung vergleichen und diejenige identifizieren sollte, die den Daten "besser" entspricht. Ich hatte angenommen, dass die Formulare deutlicher würden und wenn sie es nicht waren, begann ich an meinem Code zu zweifeln. Ihre Antwort ist sehr klar und informativ, und ich danke Ihnen. – scimaks

2

Wenn ich richtig verstehe, enthalten die Variablen Zeit und Temp, die Sie in der Polyfit verwenden, den gesamten Wert (von 1,5 bis 2,5). Vielleicht möchten Sie den Wert für Zeit und Temp auf 1,71 bis 2,3 begrenzen, bevor Sie das Polyfit berechnen (im Moment wird das Polyfit von 1,5 auf 2,5 berechnet, weshalb die Linie nicht mit den Datenpunkten ausgerichtet ist).

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

Du hast recht m_power! Vielen Dank. Ich habe die neuen Passungen hochgeladen. Sollte die exponentielle und die lineare Anpassung so ähnlich aussehen? Danke nochmal! – scimaks

4

Wie ich in den Kommentaren erwähnt, gibt es einen Unterschied zwischen einem linearen Modell in log-Raum Einpassen eines nicht-linearen Modells gegenüber Beschlages (sowohl im Sinne der kleinsten Quadrate).

Dort eine nette demo in der Toolbox Statistik, die die Situation erklärt. Ich Anpassung der Code unten:

%# 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

Verwenden

polyfit(x,y,n) 

Funktion in Matlab Toolbox-Kurvenanpassung.