Versuch Gauskurve zu plotten -> Unsinn?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
p90
User
Beiträge: 198
Registriert: Donnerstag 22. Juli 2010, 17:30

Hi,
sry für den Titel aber das Problem ist leider zu komplex um es in einer Zeile zu beschreiben.

Ich versuche in einem Diagramm eine zweite Kurve einzufügen. Die erste Kurve sind meine Messdaten, die zweite soll nun die gefitteten Gauspeaks anzeigen.
Habe mit einem externen die Peaks gefittet, habe also die benötigten Werte bereits.
Ich muss nun aus diesen Werten wieder eine Kurve basteln.
Da ich Multipkeas habe brauche ich dazu die Summe aller Gausfunktionen für jeden peak.
Habe es zuerst so probiert:

Code: Alles auswählen

x1 = eingelesene x Werte meiner gemessenen Kurve
f = lambda x: 0
for peak_var in peak_list:
    center = peak_var[0]
    width = peak_var[1]
    height = peak_var[2]
    g = lambda x: height * math.exp(-1.0/2.0 * ((x - center)/width)**2))
    f = lambda x: f(x) + g(x)
y2 = [] # liste für meine peak werte
for x in x1:
    y2.append(f(x))

Leider schmeißt mir Python da einen Rekusions Tiefen Fehler. (peak_list ist max. 8 Elemente groß)

Also habe ich es so probiert:

Code: Alles auswählen

x1 = eingelesene x Werte meiner gemessenen Kurve
f_list = [] #liste für meiner funktionen
for peak_var in peak_list:
    center = peak_var[0]
    width = peak_var[1]
    height = peak_var[2]
    g = lambda x: height * math.exp(-1.0/2.0 * ((x - center)/width)**2))
    f_list.append(g)

y2 = [] # liste für meine peak werte
for x in x1:
    value = 0
    for f in f_list:
        value += f(x)
    y2.append(value)
Nur kommt da nur Müll raus. Es ergeben sich keine Gaußglocken sondern Streifen. Selbst wenn ich f_list auf eine funktion beschränke (und dann ja eine Gaußkuppel irgendwo bekommen sollte) bekomme ich mehrere Striche die über meinen ganzen Plot verteilt sind.
Wahrscheinlich sehe ich den Wald vor lauter Bäumen nicht aber ich habe jetzt bereits zwei Tage versucht raus zu finden was das Problem ist und wende mich deshalb an euch.
Kann mir jemand einen Tipp geben was ich falsch mache?
BlackJack

@p90: Die Namen in den ``lambda``-Funktion werden erst aufgelöst wenn die Funktion aufgerufen wird und nicht wenn die Funktion definiert wird. Deswegen auch das Problem mit der Rekursionstiefe beim ersten Beispiel. Das `f` in der Funktion wird erst beim Aufruf aufgelöst und da hat es den Wert den `f` halt nach dem abarbeiten der Schleife hatte. Und die Funtkion ruft sich dann endlos selbst auf -- beziehungsweise nur bis das Limit erreicht ist.

Das gleiche gilt natürlich analog für `height`, `center`, und `width` in `g`.

Du müsstest also jeweils die Werte zu dem Zeitpunkt wo die Funktionen definiert werden festsetzen. Das kannst Du bei den ``lambda``-Funktionen über Defaultwerte in der Argumentliste machen. Defaultwerte bei Funktionsdefinitionen werden nämlich nur einmal ausgewertet und zwar dann wenn die Funktion definiert wird. Oder Du schreibst Dir die `f`- und `g`-Funktionen einmal vor der Schleife hin und erzeugst dann mit `functools.partial()` innerhalb der Schleife neue Funktionen mit den gebundenen Werten.

Ich persönlich finde "benannte ``lambda``-Funktionen" übrigens vom Stil her ein wenig fragwürdig, weil das ein Widerspruch ist. Wenn man eine anonyme Funktion an einen Namen bindet, kann man auch gleich ``def`` verwenden.
p90
User
Beiträge: 198
Registriert: Donnerstag 22. Juli 2010, 17:30

Hi,

super! Danke!
Das war der Fehler. Benutze jetzt partial für das ganze und es geht ganz gut.
Nochmal Danke für die Hilfe selbst am Sonntag ^^
Antworten