Differential evolution: stopping criteria

281 views
Skip to first unread message

Olivier B.

unread,
Sep 19, 2021, 4:46:21 PM9/19/21
to lmfit-py
Hi everyone,

We are having some issues when setting the maximum number of iterations for the differential evolution algorithm. So far we discovered that setting a maximum only works via max_nfev and not via maxiter. However we still have a hard stop at 1000 iterations of the differential evolution algorithm.

Example:

minner1 = Minimizer(func, params, fcn_args=(args))
result1 = minner1.minimize(method='differential_evolution',disp=True, popsize = 10 ,tol = 10**-100, max_nfev= 10000000) 
print(result1.call_kws)

When we execute this we get the following output:

differential_evolution step 1: f(x)= 2.90649e+07
differential_evolution step 2: f(x)= 168681
differential_evolution step 3: f(x)= 40888.4
...
differential_evolution step 1000: f(x)= 10.1097

{'args': (), 'strategy': 'best1bin', 'maxiter': None, 'popsize': 10, 'tol': 1e-100, 'mutation': (0.5, 1), 'recombination': 0.7, 'seed': None, 'callback': None, 'disp': True, 'polish': True, 'init': 'latinhypercube', 'atol': 0, 'updating': 'immediate', 'workers': 1}

[[Fit Statistics]]
    # fitting method   = differential_evolution
    # function evals   = 30090

In the above example you can see that we set a very high number of maximum function evaluations and a tolerance below machine precision. Yet, the algorithm still stop at 1000 iterations, while the number of function evaluations (30090) is still way below the limit (10000000).

What should we change if we want do more than 1000 iterations of the differential evolution algorithm?


Kind regards,

Olivier

Matt Newville

unread,
Sep 19, 2021, 9:12:40 PM9/19/21
to lmfit-py
So, if you deliberately set the tolerance to below machine precision, is the idea that you want the fit to never finish because the result is within tolerance?   I'm sort of stumped why you would want to do that, but then again, you're in the unfortunate situation of using differential evolution, so things must look pretty bleak. 


What should we change if we want do more than 1000 iterations of the differential evolution algorithm?

What happens if you add a maxiter argument:
   result1 = minner1.minimize(method='differential_evolution',disp=True, popsize = 10 ,tol = 10**-100, max_nfev= 10000000, maxiter=1500) 
?


Olivier B.

unread,
Sep 21, 2021, 3:31:40 AM9/21/21
to lmfit-py

Hi Matt,

We wanted to do this to check if our solution approach also works if we need more than 1000 generations to converge. We were just playing with the settings a bit to test this out, when we stumbled on this.

Then the option maxiter gets filtered out because lmfit tells you to use max_nfev instead, even when there is also an argument max_nfev:

result1 = minner1.minimize(method='differential_evolution',disp=True, popsize = 10 ,tol = 10**-100, max_nfev= 10000000,maxiter=1500) 

RuntimeWarning: ignoring `maxiter` argument to `minimize()`. Use `max_nfev` instead.

differential_evolution step 1: f(x)= 2332.01
differential_evolution step 2: f(x)= 2332.01
differential_evolution step 3: f(x)= 744.048
...
differential_evolution step 1000: f(x)= 10.1097

The filtering out can also be seen in the call_kws:
{'args': (), 'strategy': 'best1bin', 'maxiter': None, 'popsize': 10, 'tol': 1e-100, 'mutation': (0.5, 1), 'recombination': 0.7, 'seed': None, 'callback': None, 'disp': True, 'polish': True, 'init': 'latinhypercube', 'atol': 0, 'updating': 'immediate', 'workers': 1}



Kind regards,

Olivier
Op maandag 20 september 2021 om 03:12:40 UTC+2 schreef Matt Newville:

Matt Newville

unread,
Sep 21, 2021, 7:05:15 PM9/21/21
to lmfit-py
Hi Olivier, 

On Tue, Sep 21, 2021 at 2:31 AM Olivier B. <garageb...@gmail.com> wrote:

Hi Matt,

We wanted to do this to check if our solution approach also works if we need more than 1000 generations to converge. We were just playing with the settings a bit to test this out, when we stumbled on this.

Then the option maxiter gets filtered out because lmfit tells you to use max_nfev instead, even when there is also an argument max_nfev:

result1 = minner1.minimize(method='differential_evolution',disp=True, popsize = 10 ,tol = 10**-100, max_nfev= 10000000,maxiter=1500) 

RuntimeWarning: ignoring `maxiter` argument to `minimize()`. Use `max_nfev` instead.

Ah, yeah that is a problem. I think it should be that "max_nfev" -- your 10000000  should actually get mapped to 'differential_evolution's maxiter.  That would be more consistent and should be a one-line fix, I think.


--Matt

Olivier B.

unread,
Sep 23, 2021, 6:10:48 AM9/23/21
to lmfit-py
Okay great! Should I open an issue on github about this?

Op woensdag 22 september 2021 om 01:05:15 UTC+2 schreef Matt Newville:

Matt Newville

unread,
Sep 23, 2021, 8:08:15 AM9/23/21
to lmfit-py
On Thu, Sep 23, 2021 at 5:10 AM Olivier B. <garageb...@gmail.com> wrote:
Okay great! Should I open an issue on github about this?

I made a Pull Request - this should be fixed in the next version.


Reply all
Reply to author
Forward
0 new messages