Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

differential_evolution: make callback receive fun(xk) #6878

Closed
ZacDiggum opened this issue Dec 22, 2016 · 11 comments
Closed

differential_evolution: make callback receive fun(xk) #6878

ZacDiggum opened this issue Dec 22, 2016 · 11 comments
Labels
enhancement A new feature or improvement scipy.optimize

Comments

@ZacDiggum
Copy link

ZacDiggum commented Dec 22, 2016

In differential_evolution the callback function receives the current best parameter set xk and convergence but not the current function value fun(xk). For implementing a function value driven termination one needs to evaluate the function once more inside callback with the help of xk. Especially with small poplation sizes this creates an unnecessary overhead.
Could callback be altered so that it receives xk, fun(xk), convergence? Please?

@ZacDiggum
Copy link
Author

see #6890

@rgommers
Copy link
Member

Could callback be altered so that it receives xk, fun(xk), convergence?

This change would break any current usage of callback, because the function signatures would not match.

It is not easy to add an extra argument without breaking backwards compat, would need:

  • the new argument to be at the end, rather than in the middle as you propose
  • introspection of self.callback to check that it supports a second keyword argument with the right name

It is possible, and I can see the benefit, but the implementation would be ugly.

Any other opinions?

@dlax
Copy link
Member

dlax commented Dec 28, 2016

Any other opinions?

I'd rather have the "internal" iteration loop exposed in an API so that users would be free to invoke a "callback" as they want. DifferentialEvolutionSolver already abstracts out part of this in an iteration protocol (__next__ method), so it could just be one step further. We could even handle the solver initialization and termination using a context manager.

Something like:

with DifferentialEvolutionSolver(myfunc, mybounds) as solver:
   for i in range(maxiter):  # or for step in solver: # (if it is aware of maxiter)
        step = next(solver)
        mycallback(step.population, step.population_energies, step.convergence)
        if solver.converged:
            break

result = solver.result

Just a thought...

@andyfaff
Copy link
Contributor

andyfaff commented Dec 28, 2016 via email

@dlax
Copy link
Member

dlax commented Dec 28, 2016 via email

@ZacDiggum
Copy link
Author

Hm, I'm giving up for now. But creating custom termination functions would still be useful...
I'm using differential_evolution as a robust solver for high dimensional model fitting, that's where the motivation comes from. So, if this topic could be solved, I'd be very grateful...

@ZacDiggum
Copy link
Author

ZacDiggum commented Dec 31, 2016

#6905 exposes func_val, nfev, nit and population to callback.
These could be used to create custom terminators.

@ZacDiggum
Copy link
Author

#6907 now the diff is displayed correctly

@ZacDiggum
Copy link
Author

@dlax's suggestion sounds good to me...

@dlax
Copy link
Member

dlax commented Jan 2, 2017 via email

@mdhaber
Copy link
Contributor

mdhaber commented Oct 8, 2022

It sounds like the preferred approach would be a different interface with more control (rather than adding more information to the callbacks), so I'll go ahead and close this. Feel free to reopen if I've missed something.

@mdhaber mdhaber closed this as not planned Won't fix, can't repro, duplicate, stale Oct 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement A new feature or improvement scipy.optimize
Projects
None yet
Development

No branches or pull requests

5 participants