Search code examples
python-3.xmathematical-optimization

Multivariable function local minimum using SciPy


Consider the function:

def f(x,y):
    return x + 3*exp(y**2)

I was wondering, is it possible to use SciPy.optimize.minimize

to find the minimum value on say [0,1] (the unit interval) (for both, x and y)?

Here is my attempt:

bound = (0,1)
bds = [bound,bound]
x_0 = [0,0] (initial guess)

And thus,

scipy.optimize.minimize(f,x_0,method='SLSQP', \ bounds = bds)

But this isn't working.

I keep getting:

"unexpected character after line continuation character" At \ bounds = bnds

Note that I want my x and y to vary over the real numbers on [0,1]

Edit:

def f(x):
    return x[0] + 3*exp(x[1]**2)

bound = (0,1)
bds = [bound,bound]
x_0 = [0,0] (initial guess)


scipy.optimize.minimize(f,x_0,method='SLSQP', bounds = bds)

Is this minimise function looking at only integer values 0 and 1? or is it looking at all real numbers in [0,1] (the unit interval?). If its the first, im not sure how to make it to the second how do I do so?


Solution

  • Your original code wouldn't work because

    ""unexpected character after line continuation character" At \ bounds = bnds":

    is telling you that the "line continuation character" (the backslash) is causing a problem. You can't have anything after that character. Insert a line break after the backslash, or remove the backslash altogether

    Once you fix that, you'll get an error saying

    TypeError: f() missing 1 required positional argument: 'y'
    

    This is because minimize wants a function that takes one input (read the "Parameters: fun part of the documentation). That input can be an array of shape (n, ). When you want a multivariate minimization, all n variables go into that single argument to your function


    Re: "Is this minimise function looking at only integer values 0 and 1? or is it looking at all real numbers in [0,1] (the unit interval?). If its the first, im not sure how to make it to the second."

    It would be a pretty useless optimizer if it only checked the values at the bounds, don't you think?

    This is easy enough to check though! Your current function has a minimum at [0, 0], so it's not a great way to test what the function does. Let's define a function that has a minimum at a different number. For example, let's define a function that has a minimum at [0.5, 0.5]

    def f(X):
        return abs(X[0] - 0.5) * abs(X[1] - 0.5)
    

    Running your code gives the result:

         fun: 0.0
         jac: array([0., 0.])
     message: 'Optimization terminated successfully.'
        nfev: 8
         nit: 2
        njev: 2
      status: 0
     success: True
           x: array([0.5, 0.5])
    

    which makes it pretty clear that minimize() looks in the entire interval.

    It doesn't really look at all real numbers in the interval though (that would be impossible, given that there are infinite real numbers in any interval). Instead, it uses the optimization algorithms that you specify in the method argument.