非线性方程组
System of nonlinear equations
我想求解一个由四个非线性方程组成的系统,每个方程都等于 0,未知数是:h、C、M0、V0。我尝试了下面的代码,但奇怪的是,当我得到结果时,第一个方程不等于零。
from scipy.optimize import fsolve
p= 90
b = 45/2
d = 20
c = 500
E = 205000
I = b*d**3/12
k = b*c
L = (4*E*I/k)**(1/4)
fy = 355
W = b*d**2/4
def equations1(everything):
h,C,V0,M0 = everything
return ((np.sqrt(2*M0*b*p+V0**2)+V0)/(p*b)-L-h,
(4*(M0*h+(1/2)*V0*h**2-(1/6)*p*b*h**3+C))/(L**4*b*c),
-(3*L**2*b*h**2*p+b*h**4*p-6*L**2*W*fy-12*L*W*fy*h+6*W*fy*h**2+12*C*h)/(6*(L**2+h**2))-M0,
(3*L**2*b*h*p+2*b*h**3*p-6*L*W*fy+6*W*fy*h+6*C)/(3*(L**2+h**2))-V0)
h,C,V0,M0 = fsolve(equations1, (153,0,800000,-0.1E6))
print('h = {} mm, C = {}, V0 = {} kN, M0 = {} kNm'.format(h, C, V0*1E-3,M0*1E-6))
现在,当您计算第一个方程时,您希望它为零:
(np.sqrt(2*M0*b*p+V0**2)+V0)/(p*b)-L-h = 0
但实际上是:
(np.sqrt(2*M0*b*p+V0**2)+V0)/(p*b)-L-h = -24.75
你知道为什么这不接近于零吗?
当我 运行 您的代码时收到此警告:
[...]/site-packages/scipy/optimize/minpack.py:175: RuntimeWarning: The iteration is not making good progress, as measured by the
improvement from the last ten iterations.
warnings.warn(msg, RuntimeWarning)
警告告诉您有些东西不起作用。遗憾的是,return 值中没有任何内容指示问题,因此如果您没有注意到警告,您将不知道存在问题。
这就是为什么将 fsolve
与参数 full_output=True
一起使用通常是个好主意。将此参数设置为 True 后,将 returned 四个对象:x
(估计的解决方案)、infodict
(包含解决方案过程详细信息的字典)、ier
(整数代码;1 表示成功)和 mesg
(包含收敛消息的字符串)。
在你的情况下,
In [37]: x, info, ier, mesg = fsolve(equations1, (153, 0, 800000, -0.1E6), full_output=True)
In [38]: ier
Out[38]: 5
In [39]: mesg
Out[39]: 'The iteration is not making good progress, as measured by the \n improvement from the last ten iterations.'
ier
不是 1,这表明求解器没有收敛到一个解。
或者,您可以使用函数 root
而不是 fsolve
。它的 return 值始终是一个具有多个属性的对象,包括指示成功或失败的布尔值 success
。
In [84]: result = root(equations1, (153, 0, 800000, -0.1E6))
In [85]: result.success
Out[85]: False
(如果 success
为 True,则您可以使用存储在 result.x
中的解决方案。)
我想求解一个由四个非线性方程组成的系统,每个方程都等于 0,未知数是:h、C、M0、V0。我尝试了下面的代码,但奇怪的是,当我得到结果时,第一个方程不等于零。
from scipy.optimize import fsolve
p= 90
b = 45/2
d = 20
c = 500
E = 205000
I = b*d**3/12
k = b*c
L = (4*E*I/k)**(1/4)
fy = 355
W = b*d**2/4
def equations1(everything):
h,C,V0,M0 = everything
return ((np.sqrt(2*M0*b*p+V0**2)+V0)/(p*b)-L-h,
(4*(M0*h+(1/2)*V0*h**2-(1/6)*p*b*h**3+C))/(L**4*b*c),
-(3*L**2*b*h**2*p+b*h**4*p-6*L**2*W*fy-12*L*W*fy*h+6*W*fy*h**2+12*C*h)/(6*(L**2+h**2))-M0,
(3*L**2*b*h*p+2*b*h**3*p-6*L*W*fy+6*W*fy*h+6*C)/(3*(L**2+h**2))-V0)
h,C,V0,M0 = fsolve(equations1, (153,0,800000,-0.1E6))
print('h = {} mm, C = {}, V0 = {} kN, M0 = {} kNm'.format(h, C, V0*1E-3,M0*1E-6))
现在,当您计算第一个方程时,您希望它为零:
(np.sqrt(2*M0*b*p+V0**2)+V0)/(p*b)-L-h = 0
但实际上是:
(np.sqrt(2*M0*b*p+V0**2)+V0)/(p*b)-L-h = -24.75
你知道为什么这不接近于零吗?
当我 运行 您的代码时收到此警告:
[...]/site-packages/scipy/optimize/minpack.py:175: RuntimeWarning: The iteration is not making good progress, as measured by the
improvement from the last ten iterations.
warnings.warn(msg, RuntimeWarning)
警告告诉您有些东西不起作用。遗憾的是,return 值中没有任何内容指示问题,因此如果您没有注意到警告,您将不知道存在问题。
这就是为什么将 fsolve
与参数 full_output=True
一起使用通常是个好主意。将此参数设置为 True 后,将 returned 四个对象:x
(估计的解决方案)、infodict
(包含解决方案过程详细信息的字典)、ier
(整数代码;1 表示成功)和 mesg
(包含收敛消息的字符串)。
在你的情况下,
In [37]: x, info, ier, mesg = fsolve(equations1, (153, 0, 800000, -0.1E6), full_output=True)
In [38]: ier
Out[38]: 5
In [39]: mesg
Out[39]: 'The iteration is not making good progress, as measured by the \n improvement from the last ten iterations.'
ier
不是 1,这表明求解器没有收敛到一个解。
或者,您可以使用函数 root
而不是 fsolve
。它的 return 值始终是一个具有多个属性的对象,包括指示成功或失败的布尔值 success
。
In [84]: result = root(equations1, (153, 0, 800000, -0.1E6))
In [85]: result.success
Out[85]: False
(如果 success
为 True,则您可以使用存储在 result.x
中的解决方案。)