web-dev-qa-db-ja.com

Pythonを使用して非線形方程式のペアを解く方法は?

Pythonを使用して非線形方程式のペアを解くための(最良の)方法は何ですか(Numpy、ScipyまたはSympy)

例えば:

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

上記のペアを解決するコードスニペットは素晴らしいでしょう

59
AIB

数値解法には、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))
66
HYRY

Sympyを好むなら nsolve を使用できます。

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

最初の引数は方程式のリスト、2番目は変数のリスト、3番目は初期推測です。

27
Krastanov

これを試してください。完璧に機能することを保証します。

    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」に置き換えることにより、「Broydenの近似」を使用することもできます。できます。やったよ。

Broydenの近似がどのように機能するかは正確にはわかりませんが、0.02秒かかりました。

また、Sympyの機能を使用しないことをお勧めします<-確かに便利ですが、速度の点では非常に遅いです。表示されます。

3
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

IDLで結合された非線形方程式(通常は多項式と指数関数を含む)で動作するようにBroydenの方法を取得しましたが、Pythonで試していません。

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]

Broydenの最初のヤコビアン近似を使用して、関数の根を見つけます。

この方法は「ブロイデンの良い方法」としても知られています。

1
Kevin H

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]

ソリューションが正しいことを確認します。

0
Cleb