xtellixClient

A Python Client for Connecting to xtellix Optimization Servers using REST API


License
MIT
Install
pip install xtellixClient==0.0.2

Documentation

Python Client to Connect Solve-Hub xtellix Optimization Server

Draft Version 0.0.1

This is a simple example usage of how to initialize the Optimization Engine Server and Perform Optimization on your objective functions. The remaining documents is in two (2) parts: Section A: Initializing Server; and Section B: Running the Optimization Loop.

SECTION A

PREREQUISITES: INSTALL KEY LIBRARIES & INITIALIZE SERVER

Install xtellixClient using pip command https://pypi.org/project/xtellixClient-0.0.1/ Read more at Github

pip install xtellixClient-0.0.1

STEP 1A: IMPORT XTELLIX CLIENT LIBRARIES

Import the xtellixClient module

import xtellixClient.xtellixClient as xm

STEP 1B: IMPORT OTHER KEY LIBRARIES

import math
import numpy as np
from tqdm import trange
import time

STEP 2: OBJECTIVE FUNCTION

Define your cost or objective function Here we define the Griewank function as en example. More infomation about the Griewank benchmark function can be found on the web.

def griewank_function(x, dim):
    """Griewank's function 	multimodal, symmetric, inseparable """
    sumPart = 0
    prodPart = 1
    for i in range(dim):
        sumPart += x[i]**2
        prodPart *= math.cos(float(x[i]) / math.sqrt(i+1))
    return 1 + (float(sumPart)/4000.0) - float(prodPart)  

OPTIONAL STEP 2B: COST FUNCTION WRAPPERS FOR THE OBJECTIVE FUNCTION

To make it easier to dynamically call other benchmark functions without changing much of the code, we recommend defining a general purpose wrapper to be called during the optimization process

def cost_function(newSuggestions, dim):
    """Generic function wrapper for the cost function """
    return griewank_function(newSuggestions, dim)

STEP 3: INITIALIZE CONNECTION TO THE OPTIMIZATION SERVER

Connect to your unique optimization server using your provided credentials: server_endpoint, and client_secret_token. These are two are used to established a secured successful connection before you can begin any optimization project. Watch for server connection errors and contact the support team for assistance

#set server_endpoint and client_secret_token as variables
sever_endpoint = "http://127.0.0.1:5057"
client_secret = 1234567890

#Initialize connection and watch for errors
xm.connect(sever_endpoint, client_secret)

STEP 4: INITIALIZE THE OPTIMIZATION ENGINE

Let's begin by setting up all the initial parameters for the objective function, then the optimization engine

a. Initial parameters for the Cost Function

ubound=600  #upper bound of the Griewank function
lbound=-600 #lower bound of the Griewank function
dim=100      #problem dimension

b. Optimization Engine Settings

initMetric = 30000000 #largest possible cost function value - arbitrary very large/low number for minimization/maximization problems respectively
maxIter=dim*200 # maximum number of iterations. We recommend 100 to 200 times the dimension of the problem. and 10 - 50 times for intensive CPU problems
maxSamples=8 # maximum number of default stochastic sampling
iseedId=0 #Seed value for random number generator
minOrMax = True  ### True for MINIMIZATION | False for MAXIMIZATION

c. Prepare the initial parameter value

x0 = np.ones([dim]) * lbound 

d. Compute the first objective function

fobj = cost_function(x0, dim)
initMetric = fobj #Optional: use the first value as initial metric
print("Initial Objective Function Value = ",fobj)

e. Initialize Optimization Engine

xm.initializeOptimizer(initMetric,ubound, lbound, dim, maxIter, maxSamples, x0, iseedId,minOrMax)

SECTION B

THE OPTIMIZATION LOOP: SOLVING YOUR OPTIMIZATION PROBLEM

3 SIMPLE STEPS: GET -> COMPUTE -> UPDATE

Solving the optimizatin problem (here: Griewank function) is done in the following three (3) steps: a. Get new suggested parameters from the optimization server

newSuggestions = xm.getParameters()

b. Compute new cost function based on the new parameters

fobj = cost_function(newSuggestions, dim)

c. Send new cost function value to the optimization server

xm.updateObjectiveFunctionValue(fobj)

d. Repeat the whole process until optimization is achieved The whole process can be summarized below:

The Optimization Loop with comments

#OPtional Step: Use TQDM Library for nice progress bar 
with trange(maxIter) as t:
    for i in t:
        ##a: Get parameters from Optimization Engine
        newSuggestions = xm.getParameters()
        
        ##b: Compute new cost function value based on the parameters
        fobj = cost_function(newSuggestions, dim)
        
        ##c: Send new cost function value to optimization server
        xm.updateObjectiveFunctionValue(fobj)

        ##Optional step: Check the progress of the optmization
        obj,pareato,_,svrit = xm.getProgress()        

        ###Optional step: Update the progress bar
        t.set_description('Function Eval %i' % i)
        t.set_postfix(current=obj, best=pareato)

The Optimization Loop WITHOUT comments

We see the simplicity of the process without the comments

for i in range(maxIter):
    newSuggestions = xm.getParameters()        
    fobj = cost_function(newSuggestions, dim)        
    xm.updateObjectiveFunctionValue(fobj)

GET FINAL PARAMETERS FROM SERVER

Get the optimized parameters

x0 = xm.getParameters()

Or Get the optimized parameter (force download a fresh copy from the server)

x0 = xm.getParameters(False)

Calculate the final objective function value

fobj = cost_function(x0, dim)

Print final objective function value and optimized parameters

print(fobj)
print(x0)

The full code for the above example

import xtellixClient.xtellixClient as xm
import math
import numpy as np
from tqdm import trange

def griewank_function(x, dim):
    """Griewank's function 	multimodal, symmetric, inseparable """
    sumPart = 0
    prodPart = 1
    for i in range(dim):
        sumPart += x[i]**2
        prodPart *= math.cos(float(x[i]) / math.sqrt(i+1))
    return 1 + (float(sumPart)/4000.0) - float(prodPart) 

def cost_function(newSuggestions, dim):
    """Generic function wrapper for the cost function """
    return griewank_function(newSuggestions, dim)

#set server_endpoint and client_secret_token as variables
sever_endpoint = "http://127.0.0.1:5057"
client_secret = 1234567890

#Initialize connection and watch for errors
xm.connect(sever_endpoint, client_secret)

ubound=600  
lbound=-600 
dim=100
initMetric = 30000000 
maxIter=dim*200 
maxSamples=8 
iseedId=0 
minOrMax = True  ## True for MINIMIZATION | False for MAXIMIZATION

x0 = np.ones([dim]) * lbound 
fobj = cost_function(x0, dim)
print("Initial Objective Function Value = ",fobj)

xm.initializeOptimizer(initMetric,ubound, lbound, dim, maxIter, maxSamples, x0, iseedId,minOrMax)

##OPTIMIZATION LOOP
for i in range(maxIter):
    newSuggestions = xm.getParameters()        
    fobj = cost_function(newSuggestions, dim)        
    xm.updateObjectiveFunctionValue(fobj)

    ##Optional step: Check the progress of the optmization
    obj,pareato,feval,_ = xm.getProgress()   
    print("Feval = ", feval, " Best Objective = ", pareato, " Current Objective = ", obj)

x0 = xm.getParameters(False)
fobj = cost_function(x0, dim)
print(fobj)
print(x0)