如何使用python求解非线性方程

时间:2014-08-21 06:44:11

标签: python python-2.7 scipy

我有以下代码:

#!/usr/bin/env python
from scipy.optimize import fsolve
import math

h = 6.634e-27
k = 1.38e-16

freq1 = 88633.9360e6
freq2 = 88631.8473e6
freq3 = 88630.4157e6

def J(freq,T):
     return (h*freq/k)/(math.exp(h*freq/(k*T))-1)

def equations(x,y,z,w,a,b,c,d):
     f1 = a*(J(freq1,y)-J(freq1,2.73))*(1-math.exp(-a*z))-(J(freq2,x)-J(freq2,2.73))*(1-math.exp(-z))
     f2 = b*(J(freq3,w)-J(freq3,2.73))*(1-math.exp(-b*z))-(J(freq2,x)-J(freq2,2.73))*(1-math.exp(-z))
     f3 = c*(J(freq3,w)-J(freq3,2.73))*(1-math.exp(-b*z))-(J(freq1,y)-J(freq1,2.73))*(1-math.exp(-a*z))
     f4 = d*(J((freq3+freq1)/2,(y+w)/2)-J((freq3+freq1)/2,2.73))-(J(freq2,x)-J(freq2,2.73))*(1-math.exp(-z))
     return (f1,f2,f3,f4)

所以,我在上面的代码中定义了方程式。 4-非线性方程组包括4个变量,a-> d,它们是预定的,4个未知数,x,y,z和w。我希望以某种方式定义a-> d并将它们馈送到fsolve中,从而为x,y,z和w创建唯一的解决方案。这可能吗?

1 个答案:

答案 0 :(得分:1)

我没有得到x未定义的错误,但是在命令行上可能出现了问题。这可以在脚本中轻松完成,但不做任何更改。

Scipy的fsolve将可调用函数作为输入。因此,如果您想要解决f1,例如,您可以执行以下操作:

def f1(x, y, z, a):
    return a*(J(freq1,y)-J(freq1,2.73))*(1-math.exp(-a*z))-(J(freq2,x)-J(freq2,2.73))*(1-math.exp(-z))

root = fsolve(f1, x0=1, args=(1, 1, 1))

这解决了x的f1(x,y,z,a)= 0,其中y,z和a作为附加参数(在这种情况下为1)。因此,根据您要解决的变量,该变量应首先出现在参数顺序中,例如求解a将需要f1(a,x,y,z)。 x0是根的起始估计值。

然后返回带有根的ndarray。

有关详细信息,请查看http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.fsolve.html

<强>更新 查看How to solve a pair of nonlinear equations using Python?

的答案

要解决所有x,y,z和w,您需要将它们作为单个参数传递。所以你最终得到这样的东西:

h = 6.634e-27
k = 1.38e-16

freq1 = 88633.9360e6
freq2 = 88631.8473e6
freq3 = 88630.4157e6

def J(freq,T):
    return (h*freq/k)/(math.exp(h*freq/(k*T))-1)

def equations(p, a, b, c, d):
    x, y, z, w = p
    f1 = a*(J(freq1,y)-J(freq1,2.73))*(1-math.exp(-a*z))-(J(freq2,x)-J(freq2,2.73))*(1-math.exp(-z))
    f2 = b*(J(freq3,w)-J(freq3,2.73))*(1-math.exp(-b*z))-(J(freq2,x)-J(freq2,2.73))*(1-math.exp(-z))
    f3 = c*(J(freq3,w)-J(freq3,2.73))*(1-math.exp(-b*z))-(J(freq1,y)-J(freq1,2.73))*(1-math.exp(-a*z))
    f4 = d*(J((freq3+freq1)/2,(y+w)/2)-J((freq3+freq1)/2,2.73))-(J(freq2,x)-J(freq2,2.73))*(1-math.exp(-z))
    return (f1,f2,f3,f4)

x, y, z, w = fsolve(equations, x0=(1, 1, 1, 1), args=(1, 1, 1, 1), xtol=1e-13) # x0=(x, y, z, w) args=(a, b, c, d)
print x, y, z, w # prints [2.73, 2.73, <some value>, 2.73]
print equations((x, y, z, w), 1, 1, 1, 1) # prints a tuple with values of order 1e-13 to 1e-16 (so we can assume they are indeed the roots)