Search code examples
pythonscipyscipy-optimizecomsol

Differential evolution in parallel in Python


I am looking for a differential evolution algorithm (hopefully the one from Scipy) I could use in an unorthodox way. I would like that for each generation, the DE gives me all the child members of the new generation in advance and that I evaluate them all at once in my objective function. The reason is that my objective function calls COMSOL. I can do a batch of calculations in a COMSOL that COMSOl is going to parallelize carefully, so I don't want the DE to parallelize it itself. So in the end, I want to calculate all the members in one call of COMSOL. Do you have any idea of a package in Python with this kind of freedom?

Thank you for your help!


Solution

  • You can vectorise differential_evolution by using the ability of the workers keyword to accept a map-like callable that is sent the entire population and is expected to return an array with the function values evaluated for the entire population:

    from scipy.optimize import rosen, differential_evolution
    bounds=[(0, 10), (0, 10)]
    
    def maplike_fun(func, x):
        # x.shape == (S, N), where S is the size of the population and N
        # is the number of parameters. This is where you'd call out from
        # Python to COMSOL, instead of the following line.
        return func(x.T)
    
    res = differential_evolution(rosen, bounds, workers=maplike_fun, polish=False, updating='deferred')
    

    From scipy 1.9 there will also be a vectorized keyword, which will send the entire population to the objective function at each iteration.