我想找到以下指数方程的数值解,其中a,b,c,d是常数,我想求r,它不等于1.
a ^ r + b ^ r = c ^ r + d ^ r(等式1)
我定义了一个函数,以便使用Scipy.optimize.fsolve:
from scipy.optimize import fsolve
def func(r,a,b,c,d):
if r==1:
return 10**5
else:
return ( a**(1-r) + b**(1-r) ) - ( c**(1-r) + d**(1-r) )
fsolve(funcp,0.1, args=(5,5,4,7))
然而,fsolve总是返回1作为解决方案,这不是我想要的。有人可以帮我解决这个问题吗?或者一般来说,告诉我如何解决(等式1)。很久以前我使用过在线数值求解器,但我再也找不到它了。这就是我试图用Python解决问题的原因。
答案 0 :(得分:2)
在选择初始猜测时,您需要应用一些数学推理。考虑你的问题f(r)=(5 1-r + 5 1-r ) - (4 1-r + 7 1-R )
当r≤1时,f(r)总是负的并且减小(因为7 1-r 比其他项更快地增长)。因此,所有根寻找算法将被推向1,直到达到本地解决方案。
你需要选择一个远离1的点来找到非常重要的解决方案:
>>> scipy.optimize.fsolve(lambda r: 5**(1-r)+5**(1-r)-4**(1-r)-7**(1-r), 2.0)
array([ 2.48866034])
简单地设置f(1)= 10 5 不会产生任何影响,因为根寻找算法不会检查f(1)直到最后一步(注释)
如果您希望应用惩罚,则必须将惩罚应用于1左右的值范围。在不影响其他根的位置的情况下,这样做的一种方法是将整个函数除以(r - 1) :
>>> scipy.optimize.fsolve(lambda r: (5**(1-r)+5**(1-r)-4**(1-r)-7**(1-r)) / (r-1), 0.1)
array([ 2.48866034])
(注意):它们可能像f(0.1)→f(0.4)→f(0.7)→f(0.86)→f(0.96)→f(0.997)→......一样爬升,并且| f一直停止( X)| < 10 -5 ,所以永远不会评估你的f(1)
答案 1 :(得分:1)
您的第一个代码似乎使用了与您的问题不同的等式:1-r
而不仅仅是r
。
等式的有效答案为1
和2.4886
,大概如here所示。使用fsolve
的第二个参数,您可以指定starting estimate。我认为由于0.1
接近1
,你会得到这个结果。使用2.1
作为起始估算值,我得到另一个答案2.4886
。
from scipy.optimize import fsolve
def func(r,a,b,c,d):
if r==1:
return 10**5
else:
return ( a**(1-r) + b**(1-r) ) - ( c**(1-r) + d**(1-r) )
print(fsolve(func, 2.1, args=(5,5,4,7)))
选择起始估算非常棘手,因为许多人都会出现以下错误:ValueError: Integers to negative integer powers are not allowed.