# Scipy basinhopping custom step update and constrained looping

I am searching for the global minimum of a certain function and trying to use its gradient (here same as Jacobin) to guide the step counter. However, my x is fix and so is my gradient. I am also trying to retrieve the fastest way possible the first x for which f(x)<1, therefore I am using a constraint.

• How can I update the x input and the Jacobin ?
• My f(x)<1 is not being very effective, so is there any alternative to achieve my requirement?

This is my code (more or less):

class MyBounds(object):
def __init__(self, xmax=[2*np.pi, 2*np.pi, 2*np.pi, 2*np.pi, 1.2, 1.2, 1.2, 1.2], xmin=[0, 0, 0, 0, 0, 0, 0, 0] ):
self.xmax = np.array(xmax)
self.xmin = np.array(xmin)

def __call__(self, **kwargs):
x    = kwargs["x_new"]
tmax = bool(np.all(x <= self.xmax))
tmin = bool(np.all(x >= self.xmin))
return tmax and tmin

class MyTakeStep(object):
def __init__(self, stepsize=1):
self.stepsize = stepsize

def compute_step(self, jacobi_matrix, x, i):
if   jacobi_matrix[i] < 0: r = np.random.uniform(0,      2*np.pi-x[i])
elif jacobi_matrix[i] > 0: r = np.random.uniform(0-x[i], 0)
else                     : r = 0
return r

def __call__(self, x):
print("ENTERING fROM CALL")
print("THIS IS X: ", x)
jacobi_matrix  = jacobian(x)
print("x     : ", x)
print("jacobi: ", jacobi_matrix)
x += self.compute_step(jacobi_matrix, x, 0)
x += self.compute_step(jacobi_matrix, x, 1)
x += self.compute_step(jacobi_matrix, x, 2)
x += self.compute_step(jacobi_matrix, x, 3)
x += self.compute_step(jacobi_matrix, x, 4)
x += self.compute_step(jacobi_matrix, x, 5)
x += self.compute_step(jacobi_matrix, x, 6)
x += self.compute_step(jacobi_matrix, x, 7)
print("newx  : ", x)
return x

def f(x):
# objective function componenets
result  = g1
result += g2
result += g3
return result

def jacobian(x):
print("input_list in Jacobi: ", x)

# define full derivatives
dG_dphi  = dg1_dphi + dg2_dphi + dg3_dphi
dG_dr    = dg1_dr   + dg2_dr   + dg3_dr

def callback(x, f, accept):
print("x: %65s | f: %5s | accept: %5s" % (str([round(e,3) for e in x]), str(round(f, 3)), accept))

def hopping_solver(min_f, min_x, input_excitation):
# define bounds
mybounds   = MyBounds()
mytakestep = MyTakeStep()
comb       = [deg2rad(phi) for phi in  input_excitation[:4]] + input_excitation[4:]
print("comb: ", comb)
min_f = 10
tol   = 0
cons = {'type':'ineq','fun': lambda x: 1-f(x)}
k    = {"method":'Nelder-Mead', 'constraints': cons, 'jac': jacobian, 'tol': tol}
optimal_c = optimize.basinhopping(f,
x0               = comb,
niter            = 1000000,
T                = 8,
stepsize         = 1,
minimizer_kwargs = k,
take_step        = mytakestep,
accept_test      = mybounds,
callback         = callback,
interval         = 100000,
disp             = True,
niter_success    = None)
print(optimal_c)
min_x, min_f = optimal_c['x'], optimal_c['fun']
comb         = min_x
sol          = np.array(list([np.rad2deg(phi) for phi in list(optimal_c['x'][:4])]) + list(optimal_c['x'][4:]))
min_x        = sol
return min_x, min_f


Any help is much appreciated, thank you in advance.