26

Currently I have the following code that defines the function f.

a = #something
b = #something
c = #something
def f(x):
    """Evaluates some function that depends on parameters a, b, and c"""
    someNumber = #some calculation
    return someNumber

Ideally I would do def f(x, a, b, c), BUT I am minimizing f with respect to x and SciPy's optimization toolbox doesn't allow for one to minimize functions with parameters in the arguments. That said I would like to run my minimization code for multiple values of a, b and c. Is there a way I can do this?

3
  • 3
    "Freeze" the function with particular a, b, c values using functools.partial ? Commented Mar 25, 2017 at 14:54
  • @PM2Ring this would work, and I'm glad I know about this tool now, but as @Liteye pointed out minimize actually allows me to pass it parameters. Thanks! Commented Mar 25, 2017 at 16:17
  • 1
    No worries. partial is great when you need it, but I don't know SciPy, so it was only a suggestion. Obviously, Liteye's answer is the proper way to do this. :) Commented Mar 25, 2017 at 16:34

2 Answers 2

37

You can specify additional arguments in args

from scipy.optimize import minimize 
minimize(f, x0, args=(a, b, c))
Sign up to request clarification or add additional context in comments.

1 Comment

Do parameters in args need to be called in the same way they are called in the body of the function f? Does also f remain f(x) or does it become f(x,a,b,c)?
17

This is a straightforward question and answer about using minimize. In case other users need something more concrete, here's a simple example.

A generalized quadratic equation:

In [282]: def fun(x, a,b,c):
     ...:     return a*x**2 + b*x + c

In [283]: optimize.minimize(fun, 10, args=(1,0,0))
Out[283]: 
      fun: 1.7161984122524196e-15
 hess_inv: array([[ 0.50000001]])
      jac: array([ -6.79528891e-08])
  message: 'Optimization terminated successfully.'
     nfev: 15
      nit: 4
     njev: 5
   status: 0
  success: True
        x: array([ -4.14270251e-08])

In [284]: optimize.minimize(fun, 10, args=(1,1,1))
Out[284]: 
      fun: 0.7500000000000221
 hess_inv: array([[ 0.49999999]])
      jac: array([  3.12924385e-07])
  message: 'Optimization terminated successfully.'
     nfev: 12
      nit: 2
     njev: 4
   status: 0
  success: True
        x: array([-0.49999985])

The function could take arrays as input as well, but still needs to return a single (scalar) value:

In [289]: optimize.minimize(fun, [10,10,10], args=(np.array([1,2,3]), 1, 1))
Out[289]: 
      fun: 2.541666666667115
 hess_inv: array([[ 0.50021475, -0.00126004,  0.00061239],
       [-0.00126004,  0.25822101, -0.00259327],
       [ 0.00061239, -0.00259327,  0.16946887]])
      jac: array([ -8.94069672e-08,   4.47034836e-07,  -2.20537186e-06])
  message: 'Optimization terminated successfully.'
     nfev: 55
      nit: 9
     njev: 11
   status: 0
  success: True
        x: array([-0.50000006, -0.2499999 , -0.16666704])

In [286]: def fun(x, a,b,c):
 ...:     return (a*x**2 + b*x + c).sum()

It's a good idea to make sure the function runs with the proposed x0 and args, e.g.

In [291]: fun(np.array([10,10,10]), np.array([1,2,3]), 1, 1)
Out[291]: 633

If you can't call the objective function, or are confused as to how its arguments work, minimize isn't a magic bullet. This minimization is only as good as your understanding of the objective function.

3 Comments

Sorry to dig up an old answer but I think another question is probably a duplicate. How would you add a constraint that depends on both the minimization variable, x, and one of the arguments, say a. I have a similar problem with the additional constraint that x + a < 1.
@user1936752, I think the constraints are called with the same arguments as the objective function, i.e. (x,) + args (tuple join). So they have to have the same signature, or at least a compatible one.
thanks for the comment. Maybe I was unable to express my question properly so I've asked a separate question here: stackoverflow.com/questions/54611746/…. If you have time to look at it, I'd be most grateful!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.