用python在有限定义区间上数值求解非线性方程组

用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数值求解方程组的

假设出现以下问题: 我必须使用函数,其中一个函数由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,它能够解决两个非线性方程组的系统,这两个方程组仅在有限的时间间隔内定义

出于某种原因,我所发现的要么能解方程组,不考虑极限,要么能求极限,但一次只解一个方程


如果有人能给我指出正确的方向,我会非常感激的

这个问题需要假设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)