2017-11-15 1 views
0

Einige hypothetisches Beispiel ein nicht-lineares Gleichungssystem mit fsolve Lösung:Lösen Sie eine nicht-lineare Gleichungssystem mit Einschränkungen für die Variablen

from scipy.optimize import fsolve 
import math 

def equations(p): 
    x, y = p 
    return (x+y**2-4, math.exp(x) + x*y - 3) 

x, y = fsolve(equations, (1, 1)) 

print(equations((x, y))) 

Ist es irgendwie möglich, es zu lösen mit scipy.optimize.brentq mit einem Intervall, z.B. [-1,1]? Wie funktioniert das Auspacken in diesem Fall?

+1

brent ist Skalar-only. Sie scheinen 2 Variablen zu haben. Also [diese] (https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.root.html#scipy.optimize.root) sind Ihre Kandidaten. Wenn Sie Grenzen benötigen, können Sie optimize.minimize verwenden, benötigen aber eine andere Formulierung. – sascha

+0

Das ist richtig, ich habe zwei Variablen und ich brauche Grenzen für jeden von ihnen. Können Sie ein Beispiel geben, um ein Gleichungssystem auf diese Weise zu lösen? – Peterhack

+0

Schauen Sie sich das Tutorial und die API von scipy.optimize.minimize an. Es ist nicht so schwer. Versuchen Sie etwas und bearbeiten Sie Ihre Frage, wenn es Probleme gibt. – sascha

Antwort

2

Wie von sascha vorgeschlagen, ist die Constrained-Optimierung der einfachste Weg, um fortzufahren. Die least_squares Methode ist hier praktisch: Sie können Ihre equations direkt daran übergeben, und es wird die Summe der Quadrate seiner Komponenten minimieren.

from scipy.optimize import least_squares 
res = least_squares(equations, (1, 1), bounds = ((-1, -1), (2, 2))) 

Die Struktur ist bounds((min_first_var, min_second_var), (max_first_var, max_second_var)) oder in ähnlicher Weise für weitere Variablen.

Das resultierende Objekt hat eine Reihe von Feldern, wie unten gezeigt. Die wichtigsten sind: res.cost ist im Wesentlichen Null, was bedeutet, dass eine Wurzel gefunden wurde; und res.x sagt, was die Wurzel ist: [0,62034453, 1,83838393]

active_mask: array([0, 0]) 
     cost: 1.1745369255773682e-16 
     fun: array([ -1.47918522e-08, 4.01353883e-09]) 
     grad: array([ 5.00239352e-11, -5.18964300e-08]) 
     jac: array([[ 1.  , 3.67676787], 
     [ 3.69795254, 0.62034452]]) 
    message: '`gtol` termination condition is satisfied.' 
     nfev: 7 
     njev: 7 
    optimality: 8.3872972696740977e-09 
     status: 1 
    success: True 
      x: array([ 0.62034453, 1.83838393]) 
+0

Ich habe total '' 'least_squares''' vergessen, was offensichtlich besser ist als die allgemeineren Methoden in' 'minimize'''! – sascha

+0

Prost. Angenommen, es gibt mehrere Wurzeln im Intervall, können Sie sie alle irgendwie anzeigen? – Peterhack

+0

@Peterhack Das ist nicht, wofür diese Optimierer gebaut werden. Natürlich können Sie mit verschiedenen Startpunkten optimieren, was zu verschiedenen lokalen Minima führt, wenn es einige gibt ... Aber das ist schwierig und ziemlich instabil. Du musst dich auch für diese Ausgangspunkte entscheiden ... Ich beginne mich zu fragen, ob du hier keine symbolischen Methoden verfolgen solltest (sympy). – sascha

Verwandte Themen