用python在有限定义区间上数值求解非线性方程组
假设出现以下问题: 我必须使用函数,其中一个函数由t参数化,两个函数都定义在自变量z:f(t,z,*ags),g(z,*args)上 我想找到一对值(t0,z0),这样 函数及其相对于z的导数是相同的 f(t0,z0,*args)=g(z0,*args) 和 df/dz(t0,z0,*参数)=dg/dz(z0,*参数) 我知道存在一个解决方案,我得到了一个合理的起点(tS,zS)。 但是,至少有一个函数仅在指定的间隔[zL..zH](我知道)上定义 我现在的问题是,用python数值求解方程组的最佳方法是什么 我尝试了scipys fsolve,但似乎失败了,我想是因为它无法处理有限的定义间隔。我尝试了差分进化软件包,只是为了最小化一个复合函数,但这似乎是完全的矫枉过正 我有所有函数及其导数的表达式(尽管它们很复杂) 当然,必须有一个简单的python rootfinder,它能够解决两个非线性方程组的系统,这两个方程组仅在有限的时间间隔内定义 出于某种原因,我所发现的要么能解方程组,不考虑极限,要么能求极限,但一次只解一个方程用python在有限定义区间上数值求解非线性方程组,python,solver,nonlinear-functions,Python,Solver,Nonlinear Functions,假设出现以下问题: 我必须使用函数,其中一个函数由t参数化,两个函数都定义在自变量z:f(t,z,*ags),g(z,*args)上 我想找到一对值(t0,z0),这样 函数及其相对于z的导数是相同的 f(t0,z0,*args)=g(z0,*args) 和 df/dz(t0,z0,*参数)=dg/dz(z0,*参数) 我知道存在一个解决方案,我得到了一个合理的起点(tS,zS)。 但是,至少有一个函数仅在指定的间隔[zL..zH](我知道)上定义 我现在的问题是,用python数值求解方程组的
如果有人能给我指出正确的方向,我会非常感激的 这个问题需要假设1)存在多个解,2)至少有一个解在指定区间的边界内。如果不满足这些假设,您的问题就变成了优化——最小化函数之间的差异 我生成了以下符合假设的示例:
import numpy as np
from scipy.optimize import fsolve
def f(t,z):
return t**2 + z + z**2 + np.sin(z)
def g(z):
return z**2
def dfdz(t,z):
return 1 + 2*z + np.cos(z)
def dgdz(z):
return 2*z
def solve(x):
t,z = x
#residual array
r = np.zeros(2)
#match equations
r[0] = (f(t,z) - g(z))**2
#match derivatives
r[1] = dfdz(t,z) - dgdz(z)
return r
x0 = [10,-10]
x = fsolve(solve,x0)
t,z = x
print(t,z)
在这些初始条件下,答案是[3.06998012761-9.42477800292]。
使用fsolve,当超出范围时,可以通过添加残差来要求有界变量。这是一个相当粗糙的解决方案,不是很健壮。
通过以下修改,我们可以将z绑定到[-5,0](其中有另一个正确答案):
def solve(x,zL,zH):
t,z = x
#penalize deviation from range
if z < zL:
e = z - zL
elif z > zH:
e = z - zH
else:
e = 0
#residual array
r = np.zeros(2)
#match equations
r[0] = (f(t,z) - g(z))**2 + (e)**2
#match derivatives
r[1] = dfdz(t,z) - dgdz(z)
return r
x0 = [10,-10]
x = fsolve(solve,x0,args=(-5,0))
t,z = x
print(t,z)
[-1.772454][3.142608]
from gekko import GEKKO
#initialize a GEKKO model
m = GEKKO()
#add GEKKO variables
t = m.Var(value = -10)
z = m.Var(value = -10, lb=-5, ub=0)
#define the constraints
m.Equation(t**2 + z + z**2 + m.sin(z) == z**2)
m.Equation(1 + 2*z + m.cos(z) == 2*z)
#solve a system of non-dynamic equations
m.options.IMODE = 1
m.solve(disp=False)
print(t.value,z.value)