Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scipy minimize fmin - problems with syntax

I have a function which takes several arguments (one array and two floats) and returns a scalar (float). Now I want to minimize this function by varying two of the arguments: the two floats. The array is "unpacked" inside the function at its contents (arrays and floats) are then used.

How can this be done using SciPy's fmin function? I am having a very hard time figuring out the right syntax for this..

The function is something like:

def func(x, y, data)
    data1=data[0]
    data2=data[...]
    ...
    ...
    result = ...x...y...data1...data2... #result is a scalar (float)
    return result

What should scipy.optimize.fmin look like in this case?

optimize.fmin(func, ???)

Many thanks in advance!

All the best, p.p.

like image 648
user1987501 Avatar asked Jan 17 '13 16:01

user1987501


2 Answers

scipy assumes that the arguments are in an array. You can define a helper function:

def helper(xy):
    return func(xy[0], xy[1], data)

and minimize it with optimize.fmin:

optimize.fmin(helper, np.array([x0, y0]), ...)
like image 133
Lev Levitsky Avatar answered Oct 30 '22 15:10

Lev Levitsky


I found the answer in SciPy's documentation! I am just not used to the programming "lingo" of the documentation... (although the documentation has been VERY useful for a newbie as myself).

So, the way to do it is the following:

  • Instead of defining the function (to be minimized) as in my question, it should be defined as

    def func(x, *args) #it is literally "*args"!
        y=x[0]
        z=x[1]
        data1=data[0]
        data2=data[...]
        ...
        result = ...y...z...data1...data2... #result is a scalar (float)
        return result
    
  • Now, the optimize.fmin function should be

    optimize.fmin(func, x0=[y_estimate, z_estimate], args=(data))
    

Apparently (maybe I'm wrong) when you provide the array x0 (initial guess) to the optimize.fmin function, it then knows that the it will have to optimize an array with the "size" of x0. All other data you need in your function has to be given in the tuple args (in this example there is only one array in the tuple args, but it could be args=(data1, data2, ...), in which case you wouldn't need to unpack it inside the function).

Summary: the initial guess x0 is just an array; the extra arguments args is just a tuple; the function should be (literally!) defined as def func(x, *args); the array x and the tuple args can then be 'unpacked' inside the function (with y=x[0], z=x[1], ... and data1=args[0], data2=args[1], ...).

like image 23
user1987501 Avatar answered Oct 30 '22 16:10

user1987501