meine Frage Sehen und here beantworten. Ich habe auch ein minimales Arbeitsbeispiel gezeigt, das zeigt, wie es für Ihre Anwendung gemacht werden kann. Ich behaupte nicht, dass dies der beste Weg ist - ich durchwühle alles selbst, also werden alle Kritiken oder Vereinfachungen geschätzt.
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as pl
def wrapper(x, *args): #take a list of arguments and break it down into two lists for the fit function to understand
N = len(args)/2
amplitudes = list(args[0:N])
timeconstants = list(args[N:2*N])
return fit_func(x, amplitudes, timeconstants)
def fit_func(x, amplitudes, timeconstants): #the actual fit function
fit = np.zeros(len(x))
for m,t in zip(amplitudes, timeconstants):
fit += m*(1.0-np.exp(-t*x))
return fit
def gen_data(x, amplitudes, timeconstants, noise=0.1): #generate some fake data
y = np.zeros(len(x))
for m,t in zip(amplitudes, timeconstants):
y += m*(1.0-np.exp(-t*x))
if noise:
y += np.random.normal(0, noise, size=len(x))
return y
def main():
x = np.arange(0,100)
amplitudes = [1, 2, 3]
timeconstants = [0.5, 0.2, 0.1]
y = gen_data(x, amplitudes, timeconstants, noise=0.01)
p0 = [1, 2, 3, 0.5, 0.2, 0.1]
popt, pcov = curve_fit(lambda x, *p0: wrapper(x, *p0), x, y, p0=p0) #call with lambda function
yfit = gen_data(x, popt[0:3], popt[3:6], noise=0)
pl.plot(x,y,x,yfit)
pl.show()
print popt
print pcov
if __name__=="__main__":
main()
Ein Wort der Warnung, obwohl. Eine lineare Summe von Exponentialen macht die Anpassung EXTREM empfindlich für jegliches Rauschen, insbesondere für eine große Anzahl von Parametern. Sie können dies testen, indem Sie den im Skript erzeugten Daten sogar eine kleine Menge Rauschen hinzufügen - selbst kleine Abweichungen führen dazu, dass sie die falsche Antwort vollständig erhalten, während die Anpassung immer noch mit dem Auge einwandfrei aussieht (Test mit Rauschen = 0, 0.01 und 0,1). Seien Sie sehr vorsichtig bei der Interpretation Ihrer Ergebnisse, auch wenn die Passform gut aussieht. Es ist auch eine Form, die Variablenwechsel ermöglicht: Die am besten geeignete Lösung ist dieselbe, auch wenn Sie Paare von (m_i, t_i) gegen (m_j, t_j) tauschen, was bedeutet, dass Ihr Chi-Quadrat mehrere identische lokale Minima hat Variablen werden während der Anpassung abhängig von Ihren Anfangsbedingungen ausgetauscht. Dies ist wahrscheinlich kein numerisch robuster Weg, um diese Parameter zu extrahieren.
Um Ihre zweite Frage, ja, können Sie durch die Definition Ihrer Exponentialgrößen wie so:
m_0**2*(1.0-np.exp(-t_0**2*x)+...
Grundsätzlich quadrieren sie alle in Ihrer aktuellen Anpassungsfunktion, passen sie, und dann die Ergebnisse Quadrat (was negativ oder positiv sein könnte), um Ihre tatsächlichen Parameter zu erhalten. Sie können auch Variablen definieren, die zwischen einem bestimmten Bereich liegen, indem Sie verschiedene Proxy-Formulare verwenden.
Also möchten Sie curve_fit auch herausfinden, wie viele Begriffe hinzuzufügen? Oder wollen Sie, dass eine generische Summe von Exponentialfunktionen dann eine andere Anzahl von Parametern erzeugt und sieht, wann Sie eine gute Anpassung erhalten? –
* "Zweite Frage: ..." * Das sollte eine separate Frage sein. Aber suchen Sie zuerst, bevor Sie es erstellen - ich denke, es wurde schon einmal gefragt. –