问这里是我最后的手段,我不知道还能在哪里寻找或我的下一个选择将是什么,除了改变语言。
我有一组3重指数方程,有3个变量。指数内以及指数外都有未知变量。
我试过sympy的solve
、nsolve
和nonlinsolve
以及scipy的fsolve
。Scipy的fsolve
给出了一个解,但是这个解包含负值,这是不允许的,因为我试图计算的是一个人生病的过渡强度,它不可能是负值。我的猜测是基于经验数据,应用任何其他随机猜测没有一个健全的理由背后的决定。Sympy的solve
返回一个[]或只是继续运行,这取决于是从main还是独立调用(稍后复制),nsolve
会吐出下面的错误,而nonlinsolve
会无休止地运行而不返回任何东西。
x1c 0d1x的数据
我在主题列表中选择了MATLAB作为工具,但是,我宁愿留在Python中,因为我对MATLAB非常生疏,并且我已经写了一堆代码(无论多么糟糕,因为我不是一个真实的的程序员,只是一个使用Python写论文的人)来达到这个不愉快的点,我现在被卡住了。
如果有帮助的话,这就是方程的内容,以及我正在进行的求解调用的示例(从代码的其他部分提取):
import sympy as sm
from sympy import nsolve
from sympy import solve
sigma_R,sigma_SU,sigma_MU=sm.symbols("sigma_R,sigma_SU,sigma_MU", real=True)
f1 = -0.262617004746481*sigma_SU*sm.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/((-sigma_MU - sigma_R - sigma_SU + 0.000931334226877499)*(0.260884896827677*sigma_MU*sm.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/(-sigma_MU - sigma_R - sigma_SU + 0.00170434902663555) + 0.256617389979587*sigma_R*sm.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/(-sigma_MU - sigma_R - sigma_SU + 0.00363094118807797) + 0.262617004746481*sigma_SU*sm.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/(-sigma_MU - sigma_R - sigma_SU + 0.000931334226877499) + 0.719582172729324*sm.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU))) + 1.54
f3 = -0.260884896827677*sigma_MU*sm.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/((-sigma_MU - sigma_R - sigma_SU + 0.00170434902663555)*(0.260884896827677*sigma_MU*sm.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/(-sigma_MU - sigma_R - sigma_SU + 0.00170434902663555) + 0.256617389979587*sigma_R*sm.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/(-sigma_MU - sigma_R - sigma_SU + 0.00363094118807797) + 0.262617004746481*sigma_SU*sm.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/(-sigma_MU - sigma_R - sigma_SU + 0.000931334226877499) + 0.719582172729324*sm.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU))) + 0.3
f2 = -0.256617389979587*sigma_R*sm.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/((-sigma_MU - sigma_R - sigma_SU + 0.00363094118807797)*(0.260884896827677*sigma_MU*sm.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/(-sigma_MU - sigma_R - sigma_SU + 0.00170434902663555) + 0.256617389979587*sigma_R*sm.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/(-sigma_MU - sigma_R - sigma_SU + 0.00363094118807797) + 0.262617004746481*sigma_SU*sm.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/(-sigma_MU - sigma_R - sigma_SU + 0.000931334226877499) + 0.719582172729324*sm.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU))) + 0.37
sol=solve((f1,f2,f3),(sigma_R,sigma_SU,sigma_MU),simplify=False)
print(sol)
字符串
我的要求是:
1.有没有一种方法我可以调试,步骤等。在任何solve函数中,它是一个黑盒的事实并没有帮助,因为如果我以某种方式发送错误的数据,我不会得到任何例外。
1.如果有人知道我没有尝试过的方法,请分享;我没办法了。即使是一个数学建议也会起作用,但我看不出有任何方法可以简化方程本身。
如上所述,我尝试过:
sol = solve((f1,f2,f3),(sigma_R,sigma_SU,sigma_MU),simplify=False)
sol = nsolve((f1, f2,f3), (sigma_R,sigma_SU,sigma_MU), (0.0000813,0.0000202,0.000384))
sol = sm.nonlinsolve([y0,y1,y2],[sigma_R,sigma_SU,sigma_MU])
型fsolve
的部分:
from scipy.optimize import fsolve
import numpy as np
import math
import datetime as dt
def equations(z):
sigma_SU=z[0]
sigma_MU=z[1]
sigma_R=z[2]
f=np.empty(3)
f[0] = -0.262617004746481*sigma_SU*np.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/((-sigma_MU - sigma_R - sigma_SU + 0.000931334226877499)*(0.260884896827677*sigma_MU*np.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/(-sigma_MU - sigma_R - sigma_SU + 0.00170434902663555) + 0.256617389979587*sigma_R*np.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/(-sigma_MU - sigma_R - sigma_SU + 0.00363094118807797) + 0.262617004746481*sigma_SU*np.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/(-sigma_MU - sigma_R - sigma_SU + 0.000931334226877499) + 0.719582172729324*np.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU))) + 1.54
f[1] = -0.260884896827677*sigma_MU*np.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/((-sigma_MU - sigma_R - sigma_SU + 0.00170434902663555)*(0.260884896827677*sigma_MU*np.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/(-sigma_MU - sigma_R - sigma_SU + 0.00170434902663555) + 0.256617389979587*sigma_R*np.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/(-sigma_MU - sigma_R - sigma_SU + 0.00363094118807797) + 0.262617004746481*sigma_SU*np.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/(-sigma_MU - sigma_R - sigma_SU + 0.000931334226877499) + 0.719582172729324*np.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU))) + 0.3
f[2] = -0.256617389979587*sigma_R*np.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/((-sigma_MU - sigma_R - sigma_SU + 0.00363094118807797)*(0.260884896827677*sigma_MU*np.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/(-sigma_MU - sigma_R - sigma_SU + 0.00170434902663555) + 0.256617389979587*sigma_R*np.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/(-sigma_MU - sigma_R - sigma_SU + 0.00363094118807797) + 0.262617004746481*sigma_SU*np.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU)/(-sigma_MU - sigma_R - sigma_SU + 0.000931334226877499) + 0.719582172729324*np.exp(-45*sigma_MU - 45*sigma_R - 45*sigma_SU))) + 0.37
return f
myGuess=np.array([0.0000813,0.0000202,0.000384])
z=np.array([0,0,0])
counter=0
ct1 = dt.datetime.now()
print(ct1)
z=fsolve(equations, myGuess)
ct2=dt.datetime.now()
print(ct2-ct1)
print(z)
print(counter)
型
2条答案
按热度按时间i2loujxw1#
你需要重写你的公式,以确保合理性和性能,从而正确使用Numpy。然后,从
fsolve
(MINPACKhybr*
)切换到minimize
。初始向量(0,0,0)似乎比您提供的猜测更容易收敛。在以下四种无需额外“帮助”即可成功收敛的方法中,trust-constr是最快收敛到与机器精度“精确”的解的方法:
个字符
暴力外部搜索循环:
的字符串
yacmzcpb2#
由于我在评论中提到了它,为了完整性,我还将为@Reinderien的答案添加一个替代方法(尽管他们的答案更好,更完整,所以它应该比我的答案更好)。
如果你不想手动重写方程并得到等价的结果,你可以使用sympy的
lambdify
函数来为你正在使用的三个函数中的每一个生成向量化函数(这些函数在运行时不会是最有效的,但它是获得向量化函数的快速和肮脏的方法)。您可以使用“lambdified”函数来创建向量化的equations
函数。可以使用scipy.optimize.root
(fsolve
是传统语法;你应该使用这个函数代替)与np.zeros(3)
的初始猜测(在这种情况下,root
不收敛于问题的初始猜测)。字符串
输出量:
型
P.S.如果你通过计算前后时间来计算函数的速度,请使用
time
库中的time.perf_counter()
,而不是你使用的datetime
方法。型
如果你真的想认真对待时间,你可以看看
timeit
库。