pythonscipydifferential-evolution

Scipy differential evolution: How to pass a matrix as parameter to optimize?


Good morning,

I use scipy's differential evolution to optimize a complex problem which involves, in addition to a lot of other parameters, a matrix.

Is there an efficient way to pass this as an array or simmiliar to the function that is optimzied?

My solution at the moment is to flatten the array representing this matrix as a list and treat it like a bunch of scalar parameters. But this requires reshaping in every call of the function to be optimized.

from scipy.optimize import differential_evolution


#Bounds for a 3x3-Matrix
bounds_a=[[-1,1],[-1,1],[-1,1],[-1,1],[-1,1],[-1,1],[-1,1],[-1,1],[-1,1]]


#vector to simulate a system to be optimized 
vec1=([1,1,1])

#function to be optimized

def obj(x, *data): 
    # reshape the flattened matrix
    x=x.reshape(3,3)
        
    # do the calculations
    z=(sum(x.dot(data)))**2    
    return z  

#call the solver 
result = differential_evolution(obj, bounds_a, args=vec1)

Is there a way to pass the matrix-valued part of the system-parameters that need to be optimized directly?

I don´t reallly like the list for two reasons: It makes it harder to keep the list of parameters in order, since the actual system will have a lot of them and the list to array operation hast to be done every step of the evolution.


Solution

  • differential_evolution minimises a scalar function of one or more variables. The x array passed to obj will always be an 1-D array of shape (N,). The reshape should be a very cheap call if you setup + use the parameters in row-major order, the reshape will normally return a view.

    If your calling code wants to keep the list of parameters (and bounds) in a 2-D fashion, then simply flatten at the last minute before you call the minimiser. i.e. differential_evolution(obj, bounds_a.flatten(), args=(vec1,))