2012-01-05 43 views
46

Cách tốt nhất để giải quyết một cặp phương trình phi tuyến tính bằng cách sử dụng Python là . (numpy, scipy hoặc Sympy)Làm thế nào để giải quyết một cặp phương trình phi tuyến bằng Python?

ví dụ:

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

Một đoạn mã mà giải quyết các cặp trên sẽ là tuyệt vời

+1

'sage' có thể thực hiện việc này. – Blender

+0

yea Tôi biết rằng .. Tôi muốn làm điều đó trong python, bởi vì tôi muốn làm điều đó lặp đi lặp lại cho các bộ phương trình khác nhau – AIB

+0

Bạn có thể 'nhập khẩu sage' từ bất kỳ tập lệnh Python nào. – Blender

Trả lời

25

Nếu bạn thích sympy bạn có thể sử dụng nsolve.

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

Đối số đầu tiên là danh sách các phương trình, danh sách thứ hai là danh sách biến và thứ ba là dự đoán ban đầu.

1

Bạn có thể sử dụng gói openopt và phương thức NLP của nó. Nó có nhiều thuật toán quy hoạch động để giải quyết các phương trình đại số tuyến tính bao gồm:
goldenSection, scipy_fminbound, scipy_bfgs, scipy_cg, scipy_ncg, amsg2p, scipy_lbfgsb, scipy_tnc, bobyqa, ralg, ipopt, scipy_slsqp, scipy_cobyla, lincher, algencan, mà bạn có thể chọn từ.
Một số thuật toán sau có thể giải quyết vấn đề lập trình phi tuyến bị hạn chế. Vì vậy, bạn có thể giới thiệu hệ thống của bạn các phương trình để openopt.NLP() với một chức năng như thế này:

lambda x: x[0] + x[1]**2 - 4, np.exp(x[0]) + x[0]*x[1]

0

tôi có phương pháp Broyden để làm việc cho phương trình kết hợp phi tuyến tính (thường liên quan đến đa thức và hàm mũ) trong IDL, nhưng tôi đã không thử nó bằng 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] 

Tìm một gốc rễ của một chức năng, sử dụng xấp xỉ Jacobian đầu tiên Broyden của.

Phương pháp này còn được gọi là "phương pháp tốt của Broyden".

+1

Tại sao điều này lại bị bỏ phiếu? Có vẻ như một cách hợp pháp để tiến hành ... – aquirdturtle

0

Hãy thử cái này, tôi đảm bảo với bạn rằng nó sẽ hoạt động hoàn hảo.

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. như đã đề cập ở trên, bạn cũng có thể sử dụng 'xấp xỉ Broyden' bằng cách thay thế 'fsolve' bằng 'broyden1'. Nó hoạt động. Tôi đã làm nó.

Tôi không biết chính xác cách tính xấp xỉ của Broyden hoạt động, nhưng phải mất 0.02 giây

Và tôi khuyên bạn không nên sử dụng các chức năng của Sympy < - tiện lợi thực sự, nhưng xét về tốc độ, nó khá chậm. Bạn sẽ thấy.

0
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])