Python を使用して一対の非線形方程式を解く (最良の) 方法は何ですか? (Numpy、Scipy、または Sympy)
例えば:
- x+y^2 = 4
- e^x+ xy = 3
上記のペアを解決するコードスニペットは素晴らしいでしょう
数値解法には、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]
最初の引数は方程式のリスト、2 番目は変数のリスト、3 番目は初期推定値です。
これを試してみてください。完全に機能することを保証します。
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 の関数は使用しないことをお勧めします <- 確かに便利ですが、速度に関しては、かなり遅いです。あなたが見るでしょう。
Broyden の方法を IDL の結合された非線形方程式 (通常は多項式と指数関数を含む) で使用できるようにしましたが、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]
Broyden の最初のヤコビアン近似を使用して、関数の根を見つけます。
この方法は、「ブロイデンの良い方法」としても知られています。
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.NLP()に導入できます。
lambda x: x[0] + x[1]**2 - 4, np.exp(x[0]) + x[0]*x[1]