scipy.optimise.differential_evolution returns result, which has the population of samples and corresponding energies from the final generation. I have submitted a PR request which adds a class attribute to result to store all the populations and their energies, across generations. The list of population can help in tracking the population throughout generations, and in generating appropriate cornerplots for the retrieval. This addition is backward compatible.
I did the following:
- Initialise
population_history and energy_history in __init__ method in DifferentialEvolutionSolver.
- Store the initial population and energies in
solve method before the optimisation loop begins
- Append the population and energies to the initial list after each generation is completed.
- Add the
population_history and energy_history as attributes to the result object to be returned.
I’m -1 on this suggestion.
Firstly, it’s already possible to track the evolution of the population and population_energies per iteration using the callback keyword. The OptimizeResult: intermediate_result contains those attributes. It would be simple for the user to construct the entire history in their own callback. e.g.
class Callback:
def __init__(self):
self.population_history = []
def __call__(self, intermediate_result):
self.population_history.append(intermediate_result.population
Secondly, there are circumstances where tracking history would lead to large memory usage. Imagine a situation where there are e.g. 1000 parameters. If popsize=15 that means the total number of population members is 1_000 * 1_000 * 15 = 15_000_000, which is ~120 megabytes. If there are 1000 iterations that would be 120 gigabytes of memory you’d have to find to store the population history. Therefore, it would seem unwise to store the history of the population and its associated energies.