ingresar - ¿Cómo resolver un par de ecuaciones no lineales usando Python?
como ingresar una ecuacion en python (6)
¿Cuál es la (mejor) forma de resolver un par de ecuaciones no lineales usando Python? (Numpy, Scipy o Sympy)
p.ej:
- x + y ^ 2 = 4
- e ^ x + xy = 3
Un fragmento de código que resuelva el par de arriba será genial
Obtuve el método de Broyden para trabajar con ecuaciones no lineales acopladas (generalmente involucrando polinomios y exponenciales) en IDL, pero no lo he intentado en Python:
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]
Encuentra una raíz de una función, usando la primera aproximación jacobiana de Broyden.
Este método también se conoce como "buen método de Broyden".
Prueba este, te aseguro que funcionará perfectamente.
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
FYI. como se mencionó anteriormente, también puede usar ''aproximación de Broyden'' reemplazando ''fsolve'' por ''broyden1''. Funciona. Lo hice.
No sé exactamente cómo funciona la aproximación de Broyden, pero tardó 0.02 s.
Y le recomiendo que no use las funciones de Sympy <- de hecho, es conveniente, pero en términos de velocidad, es bastante lento. Ya verás.
Puede usar el paquete openopt y su método NLP. Tiene muchos algoritmos de programación dinámica para resolver ecuaciones algebraicas no lineales que consisten en:
goldenSection, scipy_fminbound, scipy_bfgs, scipy_cg, scipy_ncg, amsg2p, scipy_lbfgsb, scipy_tnc, bobyqa, ralg, ipopt, scipy_slsqp, scipy_cobyla, lincher, algencan, de los que puede elegir.
Algunos de los últimos algoritmos pueden resolver un problema de programación no lineal restringido. Entonces, puede introducir su sistema de ecuaciones en openopt.NLP () con una función como esta:
lambda x: x[0] + x[1]**2 - 4, np.exp(x[0]) + x[0]*x[1]
Si prefieres sympy puedes usar nsolve .
>>> nsolve([x+y**2-4, exp(x)+x*y-3], [x, y], [1, 1])
[0.620344523485226]
[1.83838393066159]
El primer argumento es una lista de ecuaciones, el segundo es una lista de variables y el tercero es una suposición inicial.
para una solución numérica, puede usar fsolve:
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))
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])