以下是我可以把它煮沸的。
我试图用18个方程和18个变量求解方程组。目前,我已经修复了其中4个变量。最初,我得到了奇怪的结果。所以我到目前为止简化了这个问题,以便前9个和后9个方程是分开且相同的。此外,问题已确切确定:应该有一个独特的解决方案。
解决方案向量包含14个元素(18减去4个固定变量)。由于这些是正确排序的,因此前7个解决方案变量应与最后7个解决方案变量相同。但是,他们不是。
x[:7] = x[7:]
并检查res[:9] == res[9:]
是否都是真的来检查方程的身份。以下是我得到的输出:
Optimization terminated successfully. (Exit mode 0)
Current function value: 0.125393271845
Iterations: 18
Function evaluations: 297
Gradient evaluations: 18
Out[223]:
J W w v U u Y
0 0.663134 0.237578 0.251245 10.00126 0.165647 0.093939 0.906657
1 0.022635 0.825547 1.000000 10.00340 0.512898 0.089790 0.909918
我将前7个变量堆叠到第一行,接下来的7个变量堆积到第二行。显然,这些并不完全相同。
复制代码如下
import numpy as np
# parameters
class Parameters(object):
r = 1.03
sBar = 0.1
sB = 0.1
c = 0.1
z = 0.001
H = 1
epsilon = 1
beta = 0.1
def q(theta):
if theta <= 0:
return 999
return float(1)/theta
def f(theta):
if theta < 1:
return 0
return 1 - float(1)/theta
# sum_all allows to see residual as vector, not summed
def twoSectorFake(x, Param, sum_all=True):
JBar, WBar, wBar, vBar, UBar, uBar, YBar = x[:7]
JB, WB, wB, vB, UB, uB, YB = x[7:]
VBar = 0
VB = 0
pB = 1
pBar = 1
#theta = float(vB + vBar)/u
thetaBar = float(vBar)/uBar
thetaB = float(vB)/uB
res = np.empty(18,)
res[0] = Param.r*JBar - (pBar - wBar - Param.sBar*(JBar - VBar) )
res[1] = Param.r * VBar - ( -Param.c + q(thetaBar) * (JBar - VBar) )
res[2] = Param.r * WBar - (wBar - Param.sBar * (WBar - UBar) )
res[3] = Param.r * UBar - (Param.z + f(thetaBar) * (WBar - UBar) )
res[4] = Param.sBar * YBar - vBar * q(thetaBar)
res[5] = Param.sBar * YBar - uBar * f(thetaBar)
res[6] = JBar - (1 - Param.beta) * (JBar + WBar - UBar)
res[7] = Param.H - YBar - uBar
res[8] = thetaBar * uBar - vBar
res[9] = Param.r*JB - (pB - wB - Param.sB*(JB - VB))
res[10] = Param.r*VB - ( -Param.c + q(thetaB) * (JB - VB))
res[11] = Param.r * WB - (wB - Param.sB * (WB - UB))
res[12] = Param.r * UB - (Param.z + f(thetaB) * (WB - UB))
res[13] = Param.sB * YB - vB*q(thetaB)
res[14] = Param.sB * YB - uB * f(thetaB)
res[15] = JB - (1 - Param.beta) * (JB + WB - UB)
res[16] = Param.H - YB - uB
res[17] = thetaB * uB - vB
idx = abs(res > 10000)
# don't square too big numbers, they may become INF and the problem won't solve
res[idx] = abs(res[idx])
res[~idx] = res[~idx]**2
if (sum_all==False):
return res
return sum(res)
Param = Parameters()
x2 = np.empty(0,)
boundaries2 = []
# JBar
x2 = np.append(x2, 1)
boundaries2.append([0, 100])
# WBar
x2 = np.append(x2, 1)
boundaries2.append([0, 100])
# wBar
x2 = np.append(x2, 0.5)
boundaries2.append([0.01, 100])
# vBar
x2 = np.append(x2, 10)
boundaries2.append([0.01, 100000])
# UBar
x2 = np.append(x2, float(Param.z)/(Param.r-1)+1)
boundaries2.append([float(Param.z)/(Param.r-1) - 0.1, 100])
# uBar
x2 = np.append(x2, 0.5*Param.H)
boundaries2.append([0.0000001, Param.H])
# YBar
x2 = np.append(x2, 0.5*Param.H)
boundaries2.append([0.0001, Param.H])
# JB
x2 = np.append(x2, 1)
boundaries2.append([0, 100])
# WB
x2 = np.append(x2, 1)
boundaries2.append([0, 100])
# wB
x2 = np.append(x2, 0.5)
boundaries2.append([1, 100])
# vB
x2 = np.append(x2, 10)
boundaries2.append([0.01, 100])
# UB
x2 = np.append(x2, float(Param.z)/(Param.r-1)+1)
boundaries2.append([float(Param.z)/(Param.r-1) - 0.1, 100])
# uB
x2 = np.append(x2, 0.5*Param.H)
boundaries2.append([0.0000001, Param.H])
# YB
x2 = np.append(x2, 0.5*Param.H)
boundaries2.append([0.0001, Param.H])
result = optimize.fmin_slsqp(func=twoSectorFake, x0=x2, bounds=boundaries2, args=(Param,), iter=200)
res1 = result[:7]
res2 = result[7:]
df = pd.DataFrame(np.reshape(res1, (1,7)), columns=['J', 'W', 'w', 'v', 'U', 'u','Y'])
df.loc[1] = np.reshape(res2, (1,7))
print df
答案 0 :(得分:1)
编辑:
您的变量boundaries2
不是对称的,即boundaries2[7:]!=boundaries2[:7]
。
尝试写作
boundaries2 = boundaries2[7:]*2
在您致电fmin_slsqp
之前,您将获得对称的本地最低要求。我在下面的设置中留下以前的一般性评论,因为它们适用于任何情况。
首先,您确定您的问题只有一个解决方案吗?如果没有,我不会期望scipy
数字例程必须返回你想到的解决方案。它可以收敛到任何其他非对称解决方案。
在第二种情况下,你没有解决方程组。如果您在代码末尾评估twoSectorFake(result,Param)
,则会获得0.15
。使用其他根解算器可能会更好,请参阅root finding部分。
这意味着您将查看目标函数的局部最小值,即不是零。同样,没有理由为什么数值例程必须计算对称的局部最小值。