VahidEtt
VahidEtt

Reputation: 11

How I can Update args value in scipy.optimize.minimize function?

In my problem, I need to update the args value inside the cost function, but the args is a function argument and also has the tuple structure. I was wondering is there a way to change the element of args and update it to use it by jac function? For example, in the below codes

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]

I would like to update para[3], para[4], para[5] in the args argument.

Upvotes: 1

Views: 1242

Answers (1)

askewchan
askewchan

Reputation: 46530

In order to minimize costFunc you must be able to vary the input parameters (otherwise it'll always have the same value!). The optimize.minimize function will vary ("update") the x but it will leave args untouched as it calls costFunc, which means that your paraList should really be given as x, not args.

Since costFunc depends only on the first three values in your parameter list para[:3], updating the last three para[3:] will have no effect, so you can use x = para[:3] and args = para[3:]. In fact, you don't even need args at all, since it has no effect.

Something like:

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}) 

So the optimal result you'll get (returned in res.x) will be the best values for the first three parameters in paraList: detValVec, projTrans, and MeasVec. If you want to get the last three values that they imply, you can just call forwardModelFunc on res.x:

paraList_opt = list(res.x) + list(forwardModelFunc(*res.x)

Of course, it's important to understand the limitations of optimize.minimize: it can only minimize over an array x if it is a 1d array of scalars, so hopefully the values in your paramList are scalars. If not, you'll have to flatten and concatenate them. Also, it will pass the same x and args to the jacobian gradientFunc, so be sure that it is properly formatted as well.

Upvotes: 1

Related Questions