在我的问题中,我需要更新成本函数内的args值,但args是一个函数参数,也具有元组结构。我想知道是否有一种方法可以改变args的元素并更新它以通过jac函数使用它?例如,在以下代码
中paraList = [detValVec, projTrans, MeasVec,
coeMat, resVec, absCoeRec]
res = optimize.minimize(costFunc, x0, args=(paraList,), method='BFGS', jac=gradientFunc, options={'gtol': 1e-6, 'disp': True})
def costFunc(x0,arg):
para = list(arg)
para[3], para[4], para[5] = forwardModelFunc(para[0], para[1], para[2])
return para[5]
我想更新args参数中的para[3], para[4], para[5]。
为了最小化costFunc
,你必须能够改变输入参数(否则它将始终具有相同的值!)。optimize.minimize
函数将改变("更新")x
,但它将保持args
不变,因为它调用costFunc
,这意味着您的paraList
应该真正被给定为x
,而不是args
。
由于costFunc
仅依赖于参数列表para[:3]
中的前三个值,更新最后三个para[3:]
将没有影响,因此您可以使用x = para[:3]
和args = para[3:]
。事实上,你甚至根本不需要args
,因为它没有任何作用。
类似:
paraList = [detValVec, projTrans, MeasVec, coeMat, resVec, absCoeRec]
def costFunc(x):
out = forwardModelFunc(x[0], x[1], x[2])
return out[2]
x0 = paraList[:3] # the initial guess
res = optimize.minimize(costFunc, x0, method='BFGS', jac=gradientFunc,
options={'gtol': 1e-6, 'disp': True})
因此,您将得到的最佳结果(在res.x
中返回)将是paraList
中前三个参数的最佳值:detValVec
, projTrans
和MeasVec
。如果您想获得它们所暗示的最后三个值,您可以在res.x
上调用forwardModelFunc
:
paraList_opt = list(res.x) + list(forwardModelFunc(*res.x)
当然,理解optimize.minimize
的局限性是很重要的:它只能在数组x
上最小化,如果它是一个一维标量数组,那么希望paramList
中的值是标量。如果没有,则必须将它们平铺并连接起来。而且,它将同样的x
和args
传递给雅可比矩阵gradientFunc
,所以要确保它也被正确格式化。