Search code examples
pythonscipyscipy-optimizescipy-optimize-minimize

Minimal example of multivariate minimization


so I'm trying to write a minimal working example of scipy.optimize.minimize with more than just one example.

Basically, my example works for a lambda-function of one variable but as soon as I add another one, It crashes.

lamX = lambda x: (x-2)**2
q0X = np.ones(1)
solX = optimize.minimize(lamX, x0=q0X)

lamXY = lambda x,y: (x-2)**2 + y**2
q0XY = np.ones(2)
solXY = optimize.minimize(lamXY, x0=q0XY)

The first three lines execute without errors and give the correct result, but the last three lines give me the following error

    solXY = optimize.minimize(lamXY, x0=q0XY)
  File "/usr/lib/python3/dist-packages/scipy/optimize/_minimize.py", line 444, in minimize
    return _minimize_bfgs(fun, x0, args, jac, callback, **options)
  File "/usr/lib/python3/dist-packages/scipy/optimize/optimize.py", line 913, in _minimize_bfgs
    gfk = myfprime(x0)
  File "/usr/lib/python3/dist-packages/scipy/optimize/optimize.py", line 292, in function_wrapper
    return function(*(wrapper_args + args))
  File "/usr/lib/python3/dist-packages/scipy/optimize/optimize.py", line 688, in approx_fprime
    return _approx_fprime_helper(xk, f, epsilon, args=args)
  File "/usr/lib/python3/dist-packages/scipy/optimize/optimize.py", line 622, in _approx_fprime_helper
    f0 = f(*((xk,) + args))
  File "/usr/lib/python3/dist-packages/scipy/optimize/optimize.py", line 292, in function_wrapper
    return function(*(wrapper_args + args))
TypeError: <lambda>() missing 1 required positional argument: 'y'

Anyone can give me a hint on what I'm doing wrong?


Solution

  • Your lambda needs to use an array-like object for x. I got it to work using this:

    >>> lamXY = lambda x: (x[0]-2)**2 + x[1]**2
    >>> q0XY = np.ones(2)
    >>> solXY = optimize.minimize(lamXY, x0=q0XY)
    >>> solXY
          fun: 3.865407235741147e-16
     hess_inv: array([[0.75, 0.25],
           [0.25, 0.75]])
          jac: array([-9.04871520e-09, -1.62848344e-08])
      message: 'Optimization terminated successfully.'
         nfev: 12
          nit: 2
         njev: 3
       status: 0
      success: True
            x: array([ 1.99999999e+00, -1.55929978e-08])
    

    While this isn't generally true for lambdas in python, it looks like scipy expects the lambda to have a single input variable.