Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using fixed parameters using scipy.optimize.minimize

I am currently using scipy optimize.minimize to get the minimal value of a function with 5 parameters. I would like for four of the inputs to be put in as fixed parameters of the function and I would like the optimize.minimize to give me the value of the fifth input in order to get the lowest possible output from the function.

Here is the code I have currently:

from numpy import array
import scipy.optimize as optimize
from scipy.optimize import minimize

def objective(speed, params):
    a,b,c,d=params
    return abs(rg.predict([[speed,params]]))

p0=np.array([[98.3,46.9,119.9,59.1]])

x0=np.array([[4]])
result = optimize.minimize(objective, x0, args=(p0,),method='nelder-mead')
print(result.x)

I am looking for a way to be able to pass a list or array of the fixed parameters inside of the optimize.minimize function. However the above code gives me this error:

ValueError: not enough values to unpack (expected 4, got 1)

The only way I can seem to make it work is to hard code in the inputs like this:

def objective(params):
 a=100
 b=20
 c=119.9
 d=params
 e=59.1
 return abs(rg.predict([[a,b,c,d,e]]))

x0=np.array([[4.5]])
result = optimize.minimize(objective, x0, method='nelder-mead')
print(result.x)

Am I approaching this in the correct way? How can I pass in a list or array as fixed inputs?

like image 421
Dana McDowelle Avatar asked Feb 13 '26 08:02

Dana McDowelle


1 Answers

The tuple passed as args will be passed as *args to the objective function. If you define the objective function in the way you did, it expects a single input argument (apart from speed to be minimized), so passing a single-element tuple (p0,) as the args keyword to minimize is perfect. Your error comes after the function call:

ValueError: not enough values to unpack (expected 4, got 1)

This actually comes from the first line of your objective function:

a,b,c,d=params # params = np.array([[98.3,46.9,119.9,59.1]])

The array you passed as p0 has two sets of square brackets, so it has shape (1,4). Arrays unpack along their first dimension, so during unpacking this behaves like a 1-tuple (that contains a 4-element array). This is why you can't unpack shape (1,4) to four variables, hence the error.

This is basically a typo (one too many pair of square brackets), which wouldn't merit a full answer. The reason I'm writing this after all is because depending on your use case it might be easier to define those arguments directly in your function's signature, and pass those on accordingly during minimization:

def objective(speed, a, b, c, d):
    ... # return stuff using a,b,c,d

# define a0, b0, c0, d0 as convenient
result = optimize.minimize(objective, x0, args=(a0,b0,c0,d0), method='nelder-mead')

Whether it's more elegant to define your function like this depends on how your fixed parameters can be easily defined and what happens with those arguments inside objective. If you're just going to pass on the list of arguments as in your MCVE then there's no need to separate those variables in the first place, but if those four inputs are involved very differently in the calculations then it may make sense to handle each individually starting with the definition of your objective function.

like image 159


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!