Как решить пару нелинейных уравнений с помощью Python?
каков (лучший) способ решить a пара нелинейных уравнений с использованием Python. (Numpy, Scipy или Sympy)
например:
- x+y^2 = 4
- e^x+ xy = 3
фрагмент кода, который решает вышеуказанную пару, будет отличным
7 ответов:
для численного решения, вы можете использовать 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))
Если вы предпочитаете sympy вы можете использовать nsolve.
>>> nsolve([x+y**2-4, exp(x)+x*y-3], [x, y], [1, 1]) [0.620344523485226] [1.83838393066159]
первый аргумент-это список уравнений, второй-список переменных, а третий-начальная догадка.
попробуйте этот, я уверяю вас, что он будет работать отлично.
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
к вашему сведению. как упоминалось выше, вы также можете использовать "приближение Бройдена", заменив "fsolve" на "broyden1". Это работает. Я сделал это.
Я точно не знаю, как работает приближение Бройдена, но это заняло 0,02 С.
и я рекомендую вам не использовать функции Sympy
вы можете использовать пакет openopt и его метод NLP. Она имеет много алгоритмов динамического программирования для решения нелинейных алгебраических уравнений, состоящую:
goldenSection, scipy_fminbound, scipy_bfgs, scipy_cg, scipy_ncg, amsg2p, scipy_lbfgsb, scipy_tnc, bobyqa, ralg, ipopt, scipy_slsqp, scipy_cobyla, lincher, algencan, который вы можете выбрать.
Некоторые из последних алгоритмов могут решить ограниченную задачу нелинейного программирования. Таким образом, вы можете ввести свою систему уравнения для openopt.НЛП () С такой функцией:
lambda x: x[0] + x[1]**2 - 4, np.exp(x[0]) + x[0]*x[1]
Я получил метод Бройдена для работы с связанными нелинейными уравнениями (обычно с полиномами и экспонентами) в IDL, но я не пробовал его в Python:
scipy.оптимизировать.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]
найти корни функции, используя первый аппроксимация Якобиана Бройдена по.
этот метод также известен как"хороший метод Бройдена".
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])
альтернатива
fsolve
и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)
выводит
[0.62034452 1.83838393]
если вы затем проверить
print(your_funcs(sol.x))
вы получаете
[4.4508396968012676e-11, -1.0512035686360832e-11]
подтверждение правильности решения.