I’m working with the following scipy code.
JavaScript
x
15
15
1
import numpy as np
2
from scipy.optimize import basinhopping
3
4
n_iter = 100
5
6
@np.vectorize
7
def f(x):
8
return ( x * np.sin(x) + 2*x) ** 2
9
10
x0 = -6
11
minimizer_kwargs = {"method": "BFGS"}
12
ret = basinhopping(f, x0, minimizer_kwargs=minimizer_kwargs, niter=n_iter)
13
14
print("global minimum: x = %.4f, f(x0) = %.4f" % (ret.x, ret.fun))
15
The global minimum of this function is at 0, but this isn’t what basin hopping returns. Depending on the start position x0, it returns different local minima – not the global one at 0. If we set x_0 = -6, it returns a minima at -7.7, if we set x0 = 1, then it returns a minima at 0, so on.
Why is it not returning the global minima? Why is it returning the local minimum closest to its start position?
Advertisement
Answer
If you increase n_iter
to 1000
it works!
The output is
JavaScript
1
2
1
"global minimum: x = 0.0000, f(x0) = 0.0000"
2
It is a stochastic algorithm and in this case it requires some more attempts, indeed using
JavaScript
1
17
17
1
import numpy as np
2
from scipy.optimize import basinhopping
3
4
5
while True:
6
n_iter = 850
7
8
@np.vectorize
9
def f(x):
10
return ( x * np.sin(x) + 2*x) ** 2
11
12
x0 = -6
13
minimizer_kwargs = {"method": "BFGS"}
14
ret = basinhopping(f, x0, minimizer_kwargs=minimizer_kwargs, niter=n_iter)
15
16
print("global minimum: x = %.4f, f(x0) = %.4f" % (ret.x, ret.fun))
17
prints
JavaScript
1
14
14
1
"""
2
global minimum: x = -7.7230, f(x0) = 60.6709
3
global minimum: x = -0.0000, f(x0) = 0.0000
4
global minimum: x = -0.0000, f(x0) = 0.0000
5
global minimum: x = 0.0000, f(x0) = 0.0000
6
global minimum: x = -0.0000, f(x0) = 0.0000
7
global minimum: x = 0.0000, f(x0) = 0.0000
8
global minimum: x = -0.0000, f(x0) = 0.0000
9
global minimum: x = -0.0000, f(x0) = 0.0000
10
global minimum: x = -0.0000, f(x0) = 0.0000
11
global minimum: x = -7.7230, f(x0) = 60.6709
12
13
"""
14
Not always the algorithm with n_iter=850
finds the global minimum.