HGDL Constrained Optimization of Rosenbrock’s Function

In this script, we show how HGDL is used for constrained optimization. Unconstrained optimization is simpler and automatically included.

#!pip install hgdl==2.1.9

First some function to make nice plots

%load_ext autoreload
%autoreload 2
import numpy as np
import plotly.graph_objects as go
def plot(x,y,z,data = None, constr = None):
    fig = go.Figure()
    fig.add_trace(go.Surface(x = x, y = y,z=z))
    if data is not None: 
        fig.add_trace(go.Scatter3d(x=data[:,0], y=data[:,1], z=data[:,2] + 50,
                                   mode='markers'))
    if constr is not None: 
        fig.add_trace(go.Scatter3d(x=constr[:,0], y=constr[:,1], z=constr[:,2],
                                   mode='markers')) 

    fig.update_layout(title='Surface Plot', autosize=True,
                  width=800, height=800, font=dict(
                  family="Courier New, monospace",
                  size=18),
                  margin=dict(l=65, r=50, b=65, t=90))

    fig.show()

def make_plot(bounds, function, data = None, constraint = None):
    x1,x2 = np.linspace(bounds[0,0],bounds[0,1],100),np.linspace(bounds[1,0],bounds[1,1],100)
    x_pred = np.transpose([np.tile(x1, len(x2)), np.repeat(x2, len(x1))])
    x1,x2 = np.meshgrid(x1,x2)
    z = np.zeros((10000))
    func = np.zeros((10000))
    cons = np.zeros((10000))
    for i in range(10000): 
        z[i] = rosen(x_pred[i])
        if constraint: cons[i] = constraint(x_pred[i])

    
    plot(x1, x2, z.reshape(100,100).T, data = data)

    if constraint: 
        fig = go.Figure()
        fig.add_trace(go.Surface(x = x1, y = x2,z = cons.reshape(100,100).T))
        fig.show()
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Cell In[2], line 4
      2 get_ipython().run_line_magic('autoreload', '2')
      3 import numpy as np
----> 4 import plotly.graph_objects as go
      5 def plot(x,y,z,data = None, constr = None):
      6     fig = go.Figure()

ModuleNotFoundError: No module named 'plotly'

Defining the Constraints and some Bounds

Keep in mind that not all local optimizers allow any combination of bounds and constraints Visit https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html for more information on that

bounds = np.array([[-4,4],[-4,4]])
def g1(x):
    return (np.linalg.norm(x)**2/10.0) - 1.0

Now we import HGDL and run a constrained optimization

from hgdl.hgdl import HGDL as hgdl
from hgdl.support_functions import *
import time
from scipy.optimize import rosen, rosen_der, rosen_hess


#constraint definitions form scipy
from scipy.optimize import NonlinearConstraint
nlc = NonlinearConstraint(g1, 0, 10)


a = hgdl(rosen, rosen_der, bounds,
            hess = rosen_hess, ##if this is None, the Hessian will be approximated if the local optimizer needs it
            #global_optimizer = "random", #there are a few options to choose from for the global optimizer
            global_optimizer = "genetic",
            local_optimizer = "L-BFGS-B", #dNewton is an example and will be changed automatically to "SLSQP" because constraints are used
            number_of_optima = 30000, #the number fo optima that will be stored and used for deflation
            args = (), num_epochs = 1000, #the number fo total epochs. Since this is an asynchronous algorithms, this number can be very high 
            constraints = (nlc,) #the constraints
            #constraints = () #if no constraints are used
            )
    
a.optimize(x0=None)
res = a.get_latest()
for entry in res: print(entry)
res = a.kill_client()
print(res)

Making a Plot

You should see the constraints and the found optima. If everything worked, the found points are in between the two constraints.

data = [np.append(entry["x"],entry["f(x)"]) for entry in res]
make_plot(bounds, rosen, data = np.array(data), constraint = g1)