webentwicklung-frage-antwort-db.com.de

Wie löse ich ein Paar nichtlinearer Gleichungen mit Python?

Was ist der (beste) Weg, um ein Paar nichtlinearer Gleichungen mit Python zu lösen? (Numpy, Scipy oder Sympy)

z.B:

  • x + y ^ 2 = 4
  • e ^ x + xy = 3

Ein Code-Snippet, der das obige Paar löst, ist großartig

55
AIB

für numerische Lösungen können Sie fsolve verwenden:

http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fsolve.html#scipy.optimize.fsolve

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))
61
HYRY

Wenn Sie Sympy bevorzugen, können Sie nsolve verwenden.

>>> nsolve([x+y**2-4, exp(x)+x*y-3], [x, y], [1, 1])
[0.620344523485226]
[1.83838393066159]

Das erste Argument ist eine Liste von Gleichungen, das zweite ist eine Liste von Variablen und das dritte ist eine erste Schätzung. 

27
Krastanov

Probieren Sie es aus, ich versichere Ihnen, dass es perfekt funktioniert.

    import scipy.optimize as opt
    from numpy import exp
    import timeit

    st1 = timeit.default_timer()

    def f(variables) :
        (x,y) = variables

        first_eq = x + y**2 -4
        second_eq = exp(x) + x*y - 3
        return [first_eq, second_eq]

    solution = opt.fsolve(f, (0.1,1) )
    print(solution)


    st2 = timeit.default_timer()
    print("RUN TIME : {0}".format(st2-st1))

->

[ 0.62034452  1.83838393]
RUN TIME : 0.0009331008900937708

Zu Ihrer Information. Wie oben erwähnt, können Sie auch 'Broydens Näherung' verwenden, indem Sie 'fsolve' durch 'broyden1' ersetzen. Es klappt. Ich habs geschafft.

Ich weiß nicht genau, wie Broydens Approximation funktioniert, aber es dauerte 0,02 Sekunden.

Ich empfehle Ihnen, die Funktionen von Sympy nicht zu verwenden. Du wirst sehen. 

2
Dane Lee
from scipy.optimize import fsolve

def double_solve(f1,f2,x0,y0):
    func = lambda x: [f1(x[0], x[1]), f2(x[0], x[1])]
    return fsolve(func,[x0,y0])

def n_solve(functions,variables):
    func = lambda x: [ f(*x) for f in functions]
    return fsolve(func, variables)

f1 = lambda x,y : x**2+y**2-1
f2 = lambda x,y : x-y

res = double_solve(f1,f2,1,0)
res = n_solve([f1,f2],[1.0,0.0])
2
Victor

Ich habe Broydens Methode in IDL für gekoppelte nichtlineare Gleichungen (im Allgemeinen mit Polynomen und Exponentialen) arbeiten lassen, aber in Python habe ich es nicht versucht:

http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.broyden1.html#scipy.optimize.broyden1

scipy.optimize.broyden1

scipy.optimize.broyden1(F, xin, iter=None, alpha=None, reduction_method='restart', max_rank=None, verbose=False, maxiter=None, f_tol=None, f_rtol=None, x_tol=None, x_rtol=None, tol_norm=None, line_search='armijo', callback=None, **kw)[source]

Finden Sie eine Wurzel einer Funktion, indem Sie Broydens erste Jacobi-Approximation verwenden.

Diese Methode wird auch als "Broydens gute Methode" bezeichnet.

1
Kevin H

Eine Alternative zu fsolve ist root :

import numpy as np
from scipy.optimize import root    

def your_funcs(X):

    x, y = X
    # all RHS have to be 0
    f = [x + y**2 - 4,
         np.exp(x) + x * y - 3]

    return f

sol = root(your_funcs, [1.0, 1.0])
print(sol.x)

Dies wird gedruckt

[0.62034452 1.83838393]

Wenn du dann prüfst

print(your_funcs(sol.x))

du bekommst

[4.4508396968012676e-11, -1.0512035686360832e-11]

bestätigen, dass die Lösung korrekt ist.

0
Cleb