I am trying to solve a minimization problem following this structure:
res=minimize(objective_fnc, x0, args=param, method='Nelder-Mead)
I need to pass a series of arguments that are not par of the optimization variables but parameters to change the conditions/boundaries of the problem in a more general way. For instance, the variable param is a tuple with the next parameters: param = (p1,p2,p3)
Whenever I call the objective_fnc
I need to pass the initial conditions x0
and the tuples with the parameters to use these parameters inside the objective function. For instance, objective_fnc(x0,param)
The problem is that I get this error: objective_fnc() takes 2 positional arguments but 4 were given
I know that if I pass the initial conditions and the parameters (without being part of a tuple, this way: objective_fnc(x0,p1,p2,p3)
) it works, but I want to write it in a more simplified way in case I need to pass additional parameters later on.
Here you have minimal reproducible example that works, where all the arguments were passed one by one. But if I change p1,p2,p3
for `param' I get the error.
import numpy as np
from scipy.optimize import minimize
def objective_fnc(x,p1,p2,p3):
"""The Rosenbrock function"""
return sum(100.0*(x[1:]-x[:-1]**2.0)**2.0 + (1-x[:-1])**2.0)
class CallbackFunctor:
def __init__(self, obj_fun):
self.num_calls = 0
if self.num_calls == 0:
print('Optimization problem started')
self.obj_fun = obj_fun
def __call__(self, x):
fun_val = self.obj_fun(x,p1,p2,p3)
self.num_calls += 1
if self.num_calls % 5 == 0:
print('Work in progress...')
print(p1)
print(p2)
print(p3)
cb = CallbackFunctor(objective_fnc)
# Parameters
p1=10
p2=20
p3=30
param=(p1,p2,p3)
x0 = np.array([1.3, 0.7, 0.8, 1.9, 1.2])
res = minimize(objective_fnc, x0, args=(p1,p2,p3), method='nelder-mead', callback=cb, options={'xatol': 1e-8, 'disp': True})
print(res.x)