Skip to content
Emmanuel Benazera edited this page Feb 23, 2015 · 9 revisions

Building the Python bindings

These are instruction for building the Python bindings and running Python code on Linux. For building on Mac OSX see https://github.com/beniz/libcmaes/wiki/Building-libcmaes-on-Mac-OSX

To build the Python bindings and use libcmaes from Python code:

  • install 'boost-python', on Debian/Ubuntu systems:
sudo apt-get install libboost-python-dev python-numpy
  • build the libcmaes with support for Python bindings:
./autogen.sh
./configure --enable-python --with-prefix=/home/yourusername
make
make install
  • test the bindings:
cd python
export LD_LIBRARY_PATH=/home/yourusername/lib
python ptest.py

Python API

Simplified pure Python API to libcmaes

'dev' branch has a simplified Python interface, here is an example:

import lcmaes_interface as lci                                                                        
                                                                                                          
# setup input parameters                                                                              
def myfun(x): return sum([xi**2 for xi in x])  # myfun accepts a list of numbers as input             
dimension = 10                                                                                        
x0 = [2.1] * dimension                                                                                
sigma0 = 0.1                                                                                          
                                                                                                          
# run optimization via lci                                                                            
res = lci.pcmaes(lci.to_fitfunc(myfun),                                                               
                 lci.to_params(x0, sigma0,  # all remaining parameters are optional                   
                     str_algo=b'aipop',  # b=bytes, because unicode fails                             
                     lbounds=[-5] * dimension, ubounds=[5] * dimension,                               
                     restarts=2,  # means 2 runs, i.e. one restart                                    
                     )                                                                                
                )                                                                                     lci.plot()  # plot from file set in lci.to_params 

Calling libcmaes from Python with bindings

A slightly lower level and lower level way to use the Python bindings:

import lcmaes

# input parameters for a 10-D problem
x = [10]*10
olambda = 10 # lambda is a reserved keyword in python, using olambda instead.
seed = 0 # 0 for seed auto-generated within the lib.
sigma = 0.1
p = lcmaes.make_simple_parameters(x,sigma,olambda,seed)

# objective function.
def nfitfunc(x,n):
    val = 0.0
    for i in range(0,n):
        val += x[i]*x[i]
    return val

# generate a function object
objfunc = lcmaes.fitfunc_pbf.from_callable(nfitfunc);

# pass the function and parameter to cmaes, run optimization and collect solution object.
cmasols = lcmaes.pcmaes(objfunc,p)

# collect and inspect results
bcand = cmasols.best_candidate()
bx = lcmaes.get_candidate_x(bcand)
print "best x=",bx
print "distribution mean=",lcmaes.get_solution_xmean(cmasols)
cov = lcmaes.get_solution_cov(cmasols) # numpy array
print "cov=",cov
print "elapsed time=",cmasols.elapsed_time(),"ms"

Getting help on API:

Full documentation is in code, and available from Python, such as:

python
Python 2.7.8 (default, Oct 20 2014, 15:05:19) 
[GCC 4.9.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import lcmaes
>>> help(lcmaes.CMAParametersNB)

yields:

Help on class CMAParametersNB in module lcmaes:

class CMAParametersNB(Boost.Python.instance)
 |  CMAParameters object for problems with unbounded function parameters
 |  
 |  Method resolution order:
 |      CMAParametersNB
 |      Boost.Python.instance
 |      __builtin__.object
 |  
 |  Methods defined here:
 |  
 |  __init__(...)
 |      __init__( (object)arg1) -> None
 |  
 |  __reduce__ = <unnamed Boost.Python function>(...)
 |  
 |  dim(...)
 |      dim( (CMAParametersNB)arg1) -> int :
 |          return the problem dimension
 |  
 |  get_algo(...)
 |      get_algo( (CMAParametersNB)arg1) -> int :
 |          return the optimization algorithm code (0 to 14)
 |  

Supplement: building with Anaconda Python

Assuming anaconda is installed in

/home/you/anaconda

the following steps should allow you to compile libcmaes and python bindings for anaconda and gcc (anaconda supplies a link to clang, which would otherwise be picked up by libcmaes, it is simpler with gcc).

From within libcmaes repository:

export PATH=/home/you/bin:/home/you/anaconda/bin:$PATH
export CXX=/usr/bin/g++
export CC=/usr/bin/gcc
./configure --enable-python
make
cd python
export LD_LIBRARY_PATH=../src/.libs
/home/you/anaconda/bin/python ptest.py