Search code examples
arrayspython-3.xnumpyscipyscipy-optimize

Problem with bounds array shape in scipy.optimize constrained methods


Followup to my previous question now I have a problem with the shape of the bounds array in the constrained bfgs method.

My code is the following:

nr      = 5
lag     = 1


guess       =numpy.array([[[ random.uniform(-1.0,1.0) for k in range(nr)] for l in range(lag)],
                          [[ random.uniform( 0.0,1.0) for k in range(nr)] for l in range(lag)],
                          [[ random.uniform(-1.0,1.0) for k in range(nr)] for l in range(lag)]])

bounds      =numpy.array([[[ [-1.0,1.0] for k in range(nr)] for l in range(lag)],
                          [[ [ 0.0,1.0] for k in range(nr)] for l in range(lag)],
                          [[ [-1.0,1.0] for k in range(nr)] for l in range(lag)]])

result      =   optimize.fmin_l_bfgs_b( myfunc,guess.flatten(),bounds=bounds.reshape(15,2) ) 

As you can see I start out with a (3,1,5) shaped list of lists, which is my preferred format with which I work inside the myfunc() because it's easy to parse with nested for loops.Then this list gets crunched into a (15,) shaped numpy array to satisfy the x0 parameter's format needs, but don't worry because the X value inside the myfunc() is then transformed back into my (3,1,5) format via X=X.reshape(origshape) where the origshape global variable will save the original format. It may seem inefficient and a useless back and forth but I couldn't find a way to do it easier.

Now this works with every fmin_ function so far except with bounds like fmin_l_bfgs_b, I couldn't figure out what shape the bounded values need to be in. The documentation says:

"(min, max) pairs for each element in x, defining the bounds on that parameter."

So I thought this means 1 pair for each element, so a (15,2) shape in my situation, but when I use the code above, it gives me the following error:

TypeError: 'float' object is not subscriptable

So I guess I got the shape wrong. Please help me to fix this.


Solution

  • result      =   optimize.fmin_l_bfgs_b( myfunc,guess.flatten(),bounds=bounds.reshape(15,2),approx_grad=True ) 
    

    It seems like it doesn't work without setting the approx_grad variable to True. Otherwise I guess you need to specify the fprime function.

    Either way the function seems to be depreciated and using the scipy.optimize.minimize function is better.