Reputation: 2022
I would like to minimize the following function using scipy.minimize
def lower_bound(x, mu, r, sigma):
mu_h = mu_hat(x, mu, r)
sigma_h = sigma_hat(x, sigma)
gauss = np.polynomial.hermite.hermgauss(10)
return (1 + mu_h + math.sqrt(2) * sigma_h * min(gauss[1]))
all the involved function are tested and return values as expected. Now for setting up the minimization process, I defined
cons = ({"type": "ineq",
"fun": mu_hat,
"args": (mu, r)},
{"type": "ineq",
"fun": lambda x, sigma: -1.0*sigma_hat(x, sigma),
"args": (sigma)},
{"type": "ineq",
"fun": lambda x: x},
{"type": "ineq",
"fun": lambda x: 1-np.dot(np.ones(x.size), x)})
as the constraints. When I run this code scipy.minimize gives me the following error message for the constraints:
File "/usr/local/lib/python3.5/dist-packages/scipy/optimize/slsqp.py", line 312, in <listcomp>
mieq = sum(map(len, [atleast_1d(c['fun'](x, *c['args'])) for c in cons['ineq']]))
TypeError: <lambda>() argument after * must be an iterable, not float
what is not correct with the defined constraints?
Upvotes: 0
Views: 1287
Reputation: 249123
The error message says:
mieq = sum(map(len, [atleast_1d(c['fun'](x, *c['args'])) for c in cons['ineq']]))
TypeError: <lambda>() argument after * must be an iterable, not float
So we can infer that c['args']
is of type float
, because c['args']
is the only variable with *
applied to it. Clearly the lookup of 'args'
in c
has succeeded, so we know that c
is a float
where an iterable (list, tuple, etc.) was expected.
If we now look at your constraints, the args
passed are (mu, r)
in one case and (sigma)
in the other. The problem is clear now: (sigma)
is equivalent to sigma
, and is not a tuple. To make a 1-tuple in Python, you must say (sigma,)
.
Upvotes: 1