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: optimize: add optional parameters of adaptive step size adjustment in bashinhopping. #14941

Merged
merged 4 commits into from
Nov 11, 2021

Conversation

AtsushiSakai
Copy link
Member

Reference issue

Fix #8774

What does this implement/fix?

optimize.bashinhopping has adaptive step size adjustment using this class.

class AdaptiveStepsize:
"""
Class to implement adaptive stepsize.
This class wraps the step taking class and modifies the stepsize to
ensure the true acceptance rate is as close as possible to the target.
Parameters
----------
takestep : callable
The step taking routine. Must contain modifiable attribute
takestep.stepsize
accept_rate : float, optional
The target step acceptance rate
interval : int, optional
Interval for how often to update the stepsize
factor : float, optional
The step size is multiplied or divided by this factor upon each
update.
verbose : bool, optional
Print information about each update
"""
def __init__(self, takestep, accept_rate=0.5, interval=50, factor=0.9,
verbose=True):

The AdaptiveStepsize class has optional parameters accept_rate and factor to configure the behavior of adaptive step size adjustment.
However, scipy users cannot configure these parameters because bashinhopping does not have arguments to set these.
bashinhopping only provides an argument to set intervel.
So, I added the optional parameters accept_rate and factor for bashinhopping.

@AtsushiSakai AtsushiSakai added the enhancement A new feature or improvement label Oct 30, 2021
Copy link
Member

@tupui tupui left a comment

Choose a reason for hiding this comment

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

Thanks @AtsushiSakai. Seems like it was missing, but maybe there was a reason behind this 🤷‍♂️. @andyfaff is this ok to add these? Or should we just fix these as constants?

I can see there are no tests for these 2 parameters in general.

scipy/optimize/_basinhopping.py Outdated Show resolved Hide resolved
scipy/optimize/_basinhopping.py Outdated Show resolved Hide resolved
AtsushiSakai and others added 2 commits November 3, 2021 21:40
Co-authored-by: Pamphile ROY <roy.pamphile@gmail.com>
Co-authored-by: Pamphile ROY <roy.pamphile@gmail.com>
Copy link
Contributor

@andyfaff andyfaff left a comment

Choose a reason for hiding this comment

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

It looks good to me. Are there sensible ranges for the newly added keywords? If so, then they should be outlined, otherwise how is the user supposed to know how to change them for different performance?


.. versionadded:: 1.8.0

factor : float, optional
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the sensible value range for factor??

Copy link
Contributor

Choose a reason for hiding this comment

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

0 and < 1.

It might make sense to raise an exception if it is out of that range.

@@ -437,6 +437,19 @@ def basinhopping(func, x0, niter=100, T=1.0, stepsize=0.5,
`take_step` and `accept_test`, and these functions use random
number generation, then those functions are responsible for the state
of their random number generator.
accept_rate : float, optional
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the sensible value range for accept_rate?

Copy link
Contributor

Choose a reason for hiding this comment

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

> 0 and < 1. It would probably make sense to raise an exception otherwise.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks and good point about the validation since this is going to be exposed. Same for factor.

@tupui
Copy link
Member

tupui commented Nov 10, 2021

@js850 do you recall why you set fix values for these 2 parameters? Is this empirical or from some literature?
cc @dlax since you reviewed this as well. I did not find anything in the original PR introducing basinhopping.

@js850
Copy link
Contributor

js850 commented Nov 10, 2021

In my original PR there was some discussion about how many parameters to expose, i.e. the tension between simplicity for the new user and flexibility for the power user.

It's been some time since I was immersed in this topic, but if I recall correctly, both of these are adjustable parameters, i.e. there is no theory saying what the right value is. If there is demand for exposing them as publicly adjustable parameters then have no reason to oppose it.


.. versionadded:: 1.8.0

factor : float, optional
Copy link
Contributor

Choose a reason for hiding this comment

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

0 and < 1.

It might make sense to raise an exception if it is out of that range.

@@ -437,6 +437,19 @@ def basinhopping(func, x0, niter=100, T=1.0, stepsize=0.5,
`take_step` and `accept_test`, and these functions use random
number generation, then those functions are responsible for the state
of their random number generator.
accept_rate : float, optional
Copy link
Contributor

Choose a reason for hiding this comment

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

> 0 and < 1. It would probably make sense to raise an exception otherwise.


.. versionadded:: 1.8.0

factor : float, optional
Copy link
Contributor

Choose a reason for hiding this comment

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

You might consider giving it a more self-explanatory name. e.g. stepsize_adjustment_factor. But then that is quite long, so I will leave it up to you.

Copy link
Member

Choose a reason for hiding this comment

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

At most I would go with stepsize_factor or it would be long as you said.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think stepsize_factor works here.

@@ -437,6 +437,19 @@ def basinhopping(func, x0, niter=100, T=1.0, stepsize=0.5,
`take_step` and `accept_test`, and these functions use random
number generation, then those functions are responsible for the state
of their random number generator.
accept_rate : float, optional
Copy link
Contributor

Choose a reason for hiding this comment

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

target_accept_rate would be more self-explanatory, but it is also longer, so whatever you feel is better is fine.

Copy link
Member

Choose a reason for hiding this comment

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

Isn't target already implied?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think target_accept_rate would be preferred here.

Copy link
Member

@tupui tupui left a comment

Choose a reason for hiding this comment

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

It's been some time since I was immersed in this topic, but if I recall correctly, both of these are adjustable parameters, i.e. there is no theory saying what the right value is.

Thanks @js850 for the information and review. It's fine if we don't have more knowledge on these for now. Interested people might ask to improve the doc once this has been used or if some already know.

@@ -437,6 +437,19 @@ def basinhopping(func, x0, niter=100, T=1.0, stepsize=0.5,
`take_step` and `accept_test`, and these functions use random
number generation, then those functions are responsible for the state
of their random number generator.
accept_rate : float, optional
Copy link
Member

Choose a reason for hiding this comment

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

Thanks and good point about the validation since this is going to be exposed. Same for factor.


.. versionadded:: 1.8.0

factor : float, optional
Copy link
Member

Choose a reason for hiding this comment

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

At most I would go with stepsize_factor or it would be long as you said.

@@ -437,6 +437,19 @@ def basinhopping(func, x0, niter=100, T=1.0, stepsize=0.5,
`take_step` and `accept_test`, and these functions use random
number generation, then those functions are responsible for the state
of their random number generator.
accept_rate : float, optional
Copy link
Member

Choose a reason for hiding this comment

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

Isn't target already implied?

@andyfaff
Copy link
Contributor

To summarise:

  1. change factor to stepwise_factor
  2. change accept_rate to target_accept_rate
  3. Document acceptable ranges for both those parameters. target_accept_rate and stepwise_factor should be greater than zero and less than 1.

@tupui
Copy link
Member

tupui commented Nov 11, 2021

  1. Add input validation and corresponding tests

Copy link
Member

@tupui tupui left a comment

Choose a reason for hiding this comment

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

LGTM, thanks @AtsushiSakai and everyone for the help reviewing.

@tupui tupui merged commit fa58cce into scipy:master Nov 11, 2021
@tupui tupui added this to the 1.8.0 milestone Nov 11, 2021
@AtsushiSakai AtsushiSakai deleted the issue_8774 branch November 11, 2021 13:58
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.

In optimize.basinhopping, the target acceptance rate should be passable as a keyword argument.
4 participants