I am trying to minimize a function of two variables using SciPy. The function itself is a chain of multiple lambda functions (makes it complicated but unfortunately it is the easiest way to write the expressions I need).
However, when using SciPy’s minimize routine, I get the error “TypeError: () missing 1 required positional argument: ‘labour'”
Strangely enough, if I pass the arguments to the function directly, there is no error, so I assume that my chaining was correct.
Here is a minimum reproducible example:
# Preliminaries 0: import packages import numpy as np from scipy import optimize # Preliminaries 1: Set parameters alpha = 0.4 gamma = 0.4 delta = 0.05 beta = 0.95 # Preliminaries 2: Define functions production_f = lambda capital, labour : (capital** alpha) * (labour ** (1-alpha)) utility_f_uni = lambda consumption, labour : np.log(consumption) + gamma * np.log(1-labour) if (consumption > 0 and labour > 0 and labour < 1) else -5000 law_of_motion_f = lambda current_capital, next_capital, labour : production_f(current_capital, labour) - next_capital + (1-delta) * current_capital utility_f_multi = lambda current_capital, next_capital, labour : utility_f_uni(law_of_motion_f(current_capital, next_capital, labour), labour) optimization_f = lambda current_capital, next_capital, labour, value_f: utility_f_multi(current_capital, next_capital, labour) + beta * value_f(next_capital) max_capital = lambda capital : production_f(capital, 1) + (1 - delta) * capital
For those knowledgeable of Dynamic Programming, I am trying to derive the value function of a growth model using Value Function iteration, but I didn’t get so far yet. The period payoff is given by utility_f_multi. The Value function guess is given by optimization_f, which takes in four arguments including the previous value function guess.
In my example, I generate an interpolation that is closer to the true value function, but for all intents and purposes the constant 0 function also suffices. I then go on to create the optimization problem given our state variable
initial_value = lambda x : 0 current_optimization_f = lambda next_capital, labour: -optimization_f(3, next_capital, labour, initial_value)
Finally, I pass on the problem to the minimize function, from which the error results:
optimized_problem = optimize.minimize(current_optimization_f, [2,0.2])
The message, as mentioned previously, is “() missing 1 required positional argument: ‘labour'”
However, if I just pass on the two arguments to the function by hand, I receive no issue
print(current_optimization_f(2, 0.3))
which returns a value without problems.
Any help on this issue would be appreciated!
Advertisement
Answer
The function that you pass to scipy.minimize must use a singular argument for all the numerical inputs.
Imaging you wrote your function like:
def current_optimization_f(next_capital, labour): return optimization_f(3, next_capital, labour, initial_value)
scipy will call:
current_optimization([2, 0.3])
rather than
current_optimization(2, 0.3)
You can use an additional lambda to unpack the arguments:
obj_func = lambda x: current_optimization(*x) rtn = optimize.minimize(obj_func, [2, 0.3])
And also, unrelated to your question, you should look at CasADI to solve these types of questions