leastsq Integral als Funktion

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Franzel
User
Beiträge: 2
Registriert: Montag 29. Mai 2017, 15:57

Hallo zusammen,

ich bin ziemlich neu in Python und steh vor einem Minimierungsproblem.

Ich habe ein überbestimmtes nicht lineares Gleichungssystem und wollte dies über "leastsq" lösen. Allerdings habe ich eine Funktion als Integral gegeben, die ich integrieren muss, von Null bis unendlich und in der zwei unbekannte vorkommen. D.h. ich muss ein Integral als Funktion an "leastsq" übergeben um meine zwei Unbekannte zu erhalten. Und daran verzweifle ich gerade.

Code: Alles auswählen

#Boltzmann in [J/K]
k=1.38*(10)**(-23)

fact=2*3.14159

#B in Angstroem
B=np.array([-312.52, -167.55, -67.59, -24.41, 13.78])
#T in K
T=np.array([145, 200, 300, 400, 600]) 
#Schaetzwerte
x0=np.array([160.0,4.0])

def B_T(x,T,B):
        def integriere_B(r,T,x1,x2):
            return( 1-exp( -4*x1*10**(-23)*( (x2/r)**(12)-(x2/r)**(6) )/(k*T) ) ) 
        return(B-fact*integrate.quad( iintegriere_B,0,10**(10), args=(T,x1,x2)) (T,x[0],x[1] ) )

print (optimization.leastsq( B_T,x0, args=(T,B) ) )
"NameError: name 'x1' is not defined " ist die häufigst Fehlermeldung. Und da hänge ich, er soll ja x1 und x2 ja berechnen.!!!!!!!!

Und wie ich von null bis unendlich integrieren kann weiß ich auch nicht, da ich aber weiß das sich der Wert von B weiter hinten kaum noch ändert, dachte ich es ist okay einfach eine Hohe zahl zu nehmen.

Bin für alle Tipps dankbar.

Liebe Grüße ;)
Zuletzt geändert von Anonymous am Montag 29. Mai 2017, 16:28, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@Franzel: Ich bekomme den `NameError` ja bei `np`. Das habe ich noch erraten können, das dort ein ``import numpy as np`` fehlt, aber da gibt's noch mehr Namen die nicht definiert sind, und wahrscheinlich von irgendwo her importiert wurden, wo ich jetzt nicht raten möchte.
Franzel
User
Beiträge: 2
Registriert: Montag 29. Mai 2017, 15:57

ich habe nur den oberen Teil der Datei ausgelassen um es ein bisschen übersichtlicher zu halten, aber ja man muss natürlich noch sämtlichen module hinzufügen wie z.B.
import scipy.optimize as optimization
from scipy.optimize import leastsq,least_squares
import numpy as np
from scipy import integrate as integrate
....
BlackJack

@Franzel: Dann ist `exp` immer noch unbekannt, also müssen wir jetzt raten wo das her kommt. Und wenn man das Programm dann mal laufen lässt, bekommt man folgende Ausnahme: ``NameError: global name 'iintegriere_B' is not defined``, ein Fehler dessen Lösung zumindest sehr offensichtlich ist, wo ich mich dann frage warum Du ein Programm mit *so* einem Fehler zeigst. Ich würde ja wenigstens erwarten das bei dem gezeigten Quelltext auch der Fehler kommt, den Du im Eingangsbeitrag erwähnst. Der kommt erst wenn man diesen Flüchtigkeitsfehler behebt.

Und dann kommt der auch zurecht, denn dort wo Du `x1` und `x2` verwendest, sind diese beiden Namen tatsächlich nicht definiert. Wenn man in Python einen Namen in einem Ausdruck verwendet, dann muss der Name vorher an einen Wert gebunden werden. Das ist in den meisten gängigen Programmiersprachen so. Denn der Ausdruck muss ja seinerseits irgendwie zu einem konkreten Wert ausgewertet werden. Was nicht geht wenn darin undefinierte Namen vorkommen.

Du benutzt die `quad()`-Funktion falsch. Du scheinst den Rückgabewert der Funktion aufrufen zu wollen. Das wird bei einem Tupel nicht gehen. Schau Dir mal die Dokumentation von dieser Funktion an. Das sollte auch die Frage nach der Obergrenze Unendlich für ein Integral beantworten.

Anmerkungen zum Quelltext:

Die Importe sind teilweise seltsam. Unnötige Umbenennungen. Davon noch eine Steigerung: Umbenennungen die effektiv gar nichts umbenennen. Importierte Werte die nicht verwendet werden.

Es gibt unnötige Klammern um literale Zahlwerte. Und ``return`` ist keine Funktion. Hinter das Schlüsselwort gehört ein Leerzeichen und keine unnötigen Klammern um den Rückgabewert, damit das auch nicht so aussieht wie ein Funktionsaufruf.

Ein paar mehr Leerzeichen um ``=`` bei Zuweisungen und binären Rechenoperatoren erhöhen die Lesbarkeit.

Eingerückt wird per Konvention mit vier Leerzeichen pro Ebene.

Zwischenstand:

Code: Alles auswählen

from math import exp

import numpy as np
from scipy import integrate, optimize


# Boltzmann in [J/K]
k = 1.38 * 10e-23

fact = 2 * 3.14159

# B in Angstroem
B = np.array([-312.52, -167.55, -67.59, -24.41, 13.78])
# T in K
T = np.array([145, 200, 300, 400, 600])
# Schaetzwerte
x0 = np.array([160.0, 4.0])


def integriere_B(r, T, x1, x2):
    return 1 - exp(-4 * x1 * 10e-23 * ((x2 / r)**12 - (x2 / r)**6) / (k * T))


def B_T(x, T, B):
    return (
        B - fact * integrate.quad(
            integriere_B, 0, 10e10, args=(T, x1, x2)
        )(T, x[0], x[1])
    )

print(optimize.leastsq(B_T, x0, args=(T, B)))
Antworten