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

ENH minimize, minimize_scalar: Add support for user-provided methods #3369

Merged
merged 1 commit into from
Feb 27, 2014

Conversation

pasky
Copy link
Contributor

@pasky pasky commented Feb 22, 2014

I'm using the excellent scipy.optimize infrastructure for research, experiments and benchmarking of some custom local minimization strategies. However, without this simple change, I have no easy way to plug my minimizer to basinhopping to overload it for global minimization as well; first I added a direct override possibility in PR #3321, but it has been pointed out that a more generic mechanism that could cover other cases would be nicer. A global registry of custom method names has been another idea, implemented in PR #3333 and it has its merits, but it has been deemed that overally a simpler and nicer way is simply passing a callable as the method parameter, instead of a string.

Therefore, this change does just that, checking if method is a callable instead of a string and in that case just going ahead and calling it - both in minimize and minimize_scalar of scipy.optimize. It now also includes examples in the documentation and test suite checks.

@coveralls
Copy link

Coverage Status

Coverage remained the same when pulling d17d264 on pasky:minimize-custom into 1b34692 on scipy:master.

@pv pv added PR labels Feb 22, 2014
@@ -328,11 +394,11 @@ def minimize(fun, x0, args=(), method=None, jac=None, hess=None,
warn('Method %s does not use gradient information (jac).' % method,
RuntimeWarning)
# - hess
if meth not in ('newton-cg', 'dogleg', 'trust-ncg') and hess is not None:
if meth not in ('newton-cg', 'dogleg', 'trust-ncg', '_custom') and hess is not None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the point of this addition? A custom method could use hess or hessp. If something needs to be checked I'd say it should be in the method function itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Sun, Feb 23, 2014 at 12:00:38PM -0800, Denis Laxalde wrote:

@@ -328,11 +394,11 @@ def minimize(fun, x0, args=(), method=None, jac=None, hess=None,
# - hess

  • if meth not in ('newton-cg', 'dogleg', 'trust-ncg') and hess is not None:
  • if meth not in ('newton-cg', 'dogleg', 'trust-ncg', '_custom') and hess is not None:

What's the point of this addition? A custom method could use hess or hessp. If something needs to be checked I'd say it should be in the method function itself.

Exactly - a custom method could use hess, therefore it is
inappropriate to print a warning when hess is passed that asserts that
the method does not use Hessian. I agree with your second sentence,
that is why I'm exempting _custom from these checks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes. I missed the not in.

@pasky
Copy link
Contributor Author

pasky commented Feb 24, 2014

Thank you both for reviewing the patch! I have updated the pull request with a revised commit, I believe (and hope) I have addressed all your comments (and I changed nothing else).

@coveralls
Copy link

Coverage Status

Coverage remained the same when pulling a002360 on pasky:minimize-custom into 0da153e on scipy:master.

@dlax
Copy link
Member

dlax commented Feb 24, 2014

Petr Baudis a écrit :

Thank you both for reviewing the patch! I have updated the pull request
with a revised commit, I believe (and hope) I have addressed all your
comments (and I changed nothing else).

Looks good to me, except for the example in the docstring which I still
find a bit long and believe it could be removed. Anybody else has an
opinion on this?

@ev-br
Copy link
Member

ev-br commented Feb 24, 2014

my 2cts: maybe a tutorial is a better home for this example

@rgommers rgommers added this to the 0.14.0 milestone Feb 24, 2014
@rgommers
Copy link
Member

Tutorial makes sense. @pasky do you want to move that to doc/source/tutorial/optimize.rst?

@pasky
Copy link
Contributor Author

pasky commented Feb 25, 2014

All right, I have pushed an update that just moves the example code to a tutorial (with tiny introduction) and adds a reference to the tutorial to the docstring.

@coveralls
Copy link

Coverage Status

Coverage remained the same when pulling e8d4678 on pasky:minimize-custom into 3b0c4a0 on scipy:master.

@dlax
Copy link
Member

dlax commented Feb 25, 2014

Just one more thing @pasky. Do you find it convenient to unpack the options dict in the custom method callable? The custom method could just be called as method(fun, x0, args=args, options=options, **kwargs). The point of having options unpacked for "built-in" solvers is to check if unused options are passed; that does not really make sense for a custom method I think.

@pasky
Copy link
Contributor Author

pasky commented Feb 25, 2014

I had two motivations to keep unpacking **options:

(i) Consistency. This seems to me to be a worthy goal by itself to me,
but it may also help in case a third-party method gets promoted to
scipy, the usage (of the method as well as of the parameters within the
method) will not have to change.

(ii) Convenience. If I accept options, I can simply specify them in
the parameter list of the function, including default values (or no
defaults if the option is required). Even in the example function, this
helps me avoid a lot of glue code I would have to use instead, instead
I can use a natural Python way to express which options I accept, which
are required and what the defaults are.

@pasky
Copy link
Contributor Author

pasky commented Feb 26, 2014

This update just adds a description of the change to the release notes.

bestx = testx
improved = True
if callback is not None:
callback(x0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TravisCI pyflakes run flagged that x0 is not defined here.

@rgommers
Copy link
Member

Other TravisCI failures are unrelated.

@rgommers
Copy link
Member

@dlax are you OK with the reply to your options question? If so I think this can go in after fixing the two trivial things I flagged.

@pasky
Copy link
Contributor Author

pasky commented Feb 26, 2014

Thanks, fixed the callback() parameter and added a note about version. (I think versionadded tag is not appropriate as that has to be a separate paragraph?)

@rgommers
Copy link
Member

Indeed, the way you added the version info looks good.

@dlax
Copy link
Member

dlax commented Feb 27, 2014

Ralf Gommers a écrit :

@dlax https://github.com/dlax are you OK with the reply to your
|options| question? If so I think this can go in after fixing the two
trivial things I flagged.

Yes, it's fine. Will merge.

dlax added a commit that referenced this pull request Feb 27, 2014
ENH minimize, minimize_scalar: Add support for user-provided methods
@dlax dlax merged commit 3ec3cb6 into scipy:master Feb 27, 2014
@rgommers
Copy link
Member

Great, thanks @pasky and @dlax

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

Successfully merging this pull request may close these issues.

None yet

6 participants