nichtlineare Optimierung (Solver)

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Xadoran
User
Beiträge: 2
Registriert: Donnerstag 29. Juni 2017, 07:27

Hallo Zusammen,

ich bin noch recht unerfahren was Programmieren mit Python angeht, bzw. was Programmieren generell angeht. Daher möchte ich mich im Vorfeld schon mal für meine naive Frage entschudligen.

Ich mag erst mal nen kurzen Kontext zu meiner Frage geben:
Ich messe mit meinem Messaufbau die mittlere Größe (y) zwischen zwei Temperaturen (T_cold und T_hot). Für die spätere Auswertung benötige ich aber den absoluten Y-Wert und nicht den gemessenen mittleren Y-Wert. Was also gemacht werden soll, ist die Y-Werte mittels eines Polynom 2ten Grades zu beschreiben. Hierfür wird die Stammfunktion des Polynom 2ten Gerades gebildet. Über den Minimalwert von Sum(Y-Wert - Funktion)^2 (also Chi^2) sollen nun die Koeffizieten des Polynom 2ten gerades (also, a, b und c) bestimmt werden.
Im Anschluss daran, soll dann das Polynmom 2ten Grades mit den Parametern aus der Stammfuntkion gefitet werden, um so die absolutzen y-Werte zu erhalten.
Ich hoffe das mein Problem soweit erst mal verständlich ist. Aktuell wird diese Funktion vom Excel Solver übernommen um die Parameter a,b,c zu bestimmen. Ich bin dabei ein Python Skript zu schreiben und will antürlich weg von Excel. Ich such also etwas, was mir im Grunde den Excel Solver ersetzt, nur das in Python.

Meine Idee war es also, dass ganze mit scipy.optimize und dort mit minimize zu erledigen. Nur verstehe ich nicht, wie ich das genau umsetzen soll, vorallem mit der Bedingung das Sum(Y-Wert - funktion)^2 minimiert werden soll. Ich wäre da also für einen Denkanstoß sehr dankbar.

Im nachfolgenden poste ich mal den Code soweit wie ich gekommen bin:

Code: Alles auswählen

import numpy as np
from scipy.optimize import minimize

t_cold = [24.0748596, 24.0544872, 24.0506344, 24-1045132, 24.1103535, 24.1609097, 24.2678242, 24.264658, 24.2447376, 24.3393669, 24.3229656, 24.3032017, 24.4870358, 24.4826298, 24.4822369, 24.4582634, 24.4526997, 24.4612923, 24.5144901, 24.5095539, 24.5003109, 24.497694, 24.486702, 24.5014896, 24.5418644, 24.5435753, 24.548748, 24.582634, 24.5871964, 24.5574017, 24.656168, 24.669838, 24.6919823]

t_hot = [50.67122729, 50.65991162, 50.71805647, 96.36947647, 96.26326107, 96.36350161, 191.769009, 191.4944201, 191.4023758, 286.582908, 286.3742023, 286.3808719, 381.3487512, 381.3131648, 381.2852264, 476.3730711, 476.3801156, 476.3648048, 428.700858, 428.6985609, 428.6607499, 333.5842968, 333.5856889, 333.7023666, 238.1507655, 238.4540823, 238.6981166, 143.2089996, 143.3022491, 143.5354933, 48.28117787, 48.31744219, 48.58118631]

y = [104.1033258, 104.268764, 104.1355003, 113.3404234, 113.3147113, 113.2679388, 127.0481031, 126.9848969, 126.9879057, 138.8625682, 138.7478924, 138.7199111, 149.6731061, 149.6032914, 149.4909512, 159.8340846, 159.8243828, 159.7165366, 154.423127, 154.4312708, 154.361452, 143.4842141, 143.5428114, 143.5941965, 131.9638515, 132.0143115, 132.092347, 119.7430734, 119.7682887, 119.8206729, 103.8211854, 103.8602143, 103.8950582]

#Erstellen des Messdaten arrays:
global messurment_data_array
messurment_data_array = []
for i in range(len(t_cold)):
    messurment_data_array.append([t_cold[i], t_hot[i], y[i]])

#Aufspitten des Messdaten arrays in ein x-value array und ein y-value array:
temp_coefficient = np.array(messurment_data_array)[:,0:2]
y = np.array(messurment_data_array)[:,-1]

#Definition des Models:
def objective(p, temp_coefficient):
    a,b,c = p
    cold = temp_coefficient[:,0]
    hot = temp_coefficient[:,1]
    model = ( ( ( (a/4) * ( hot**2 - cold**2 ) ) + ( (b/3) * ( hot - cold ) ) + c ) / ( hot - cold ) ) #Das die Stammfunktion von der ich Oben gesprochen hab
    return model
    
#Soweit ich scipy.optimize - minimize richtig verstehe, müssen constraint definiert werden, also in meinem fall, sowas wie ne error funktion oda?, da bin ich mir aber nicht mehr sicher.

def constraint1(p, y,  temp_coefficient):
    a,b,c = p
    err = ((mess_y- objective(p, temp_coefficient))**2).sum()
    return err

Wie gesagt Ziel ist es die Parameter a,b und c zu bestimmen, was auf jedenfall noch wichtig wäre, wäre der Fehler für die Parameter a,b,c. Da ich über das Polynom 2ten Gerades für bestimmte x werte, den y-Wert bestimmen muss und über eine partielle ableitung des Polynom 2ten gerades den fehler des y-Wertes gerne bestimmen mag.

Ich bedanke mich für Anregugen schon mal im vorraus :)
Zuletzt geändert von Anonymous am Donnerstag 29. Juni 2017, 09:05, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Xadoran
User
Beiträge: 2
Registriert: Donnerstag 29. Juni 2017, 07:27

Xadoran hat geschrieben:

Code: Alles auswählen

    
#Soweit ich scipy.optimize - minimize richtig verstehe, müssen constraint definiert werden, also in meinem fall, sowas wie ne error funktion oda?, da bin ich mir aber nicht mehr sicher.

def constraint1(p, y,  temp_coefficient):
    a,b,c = p
    err = ((y - objective(p, temp_coefficient))**2).sum()
    return err

Hab gerade einen Fehler gefunden, es muss naturlich bei def constraint1 heißen: err = ((y - objective(p, temp_coefficient))**2).sum()
hab das mal in dem Zitat direkt geändert. da stand vorher mess_y, aber die variable heißt nur y und nicht mess_y

P.S. Danke an BlackJack fürs umwandeln der Codebox :)
Antworten