Giter Club home page Giter Club logo

c-cmaes's Introduction

c-cmaes

CMA-ES written in ANSI C in a fairly object-oriented style.

For the general purpose of this software see doc.txt or here, for more documentation on this library see docfunctions.txt, for how to start see below.


Files in this Repository

  • README.md : this file
  • LICENSE : users agreement (no worries)
  • doc.txt : describes general purpose and an application issue
  • docfunctions.txt : Documentation of the library functions.
  • cmaes_interface.h : User interface header.
  • example_short.c : Very short example source code. The purpose of the example codes is to be edited/extended.
  • example_restarts.c : implements additional restarts with increasing population size (Auger & Hansen 2005).
  • example_boundary.c : combination with boundary handling (box constraints)
  • example_noise.c : (future versions) implements an additional uncertainty handling (Hansen et al 2009).
  • cmaes.h : Header, e.g. declaration of struct cmaes_t.
  • cmaes.c : Source code.
  • cmaes_initials.par : Parameters to be read by the cmaes, e.g. problem dimension, initial search point and initial standard deviation. This file should be edited.
  • cmaes_signals.par : File for controlling the running program. Printing or writing to a file/console can be set on/off while the program is running. Regular termination can be forced. On delivery the writing is in accordance with the plotting using:
  • plotcmaesdat.m : Plots default output files in Matlab or Octave.
  • plotcmaesdat.sci : Plots default output files in Scilab.
  • boundary_transformation.c : implements a boundary transformation
  • boundary_transformation.h : header file.

Files You May Need to Edit

  • example_*.c: Plug in the objective function (pointer) that should be minimized.
  • cmaes_initials.par: Parameter file for changing e.g. initial values and stopping criteria without recompiling.
  • cmaes_signals.par: File to control termination and output during runtime.

Output files written by cmaes_t

  • actparcmaes.par : Parameters as actually used by the program. The actual parameter setting is appended to the file after each start of the cmaes.
  • errcmaes.err : Error messages.

HOW TO START

  1. get code via git ... or download button

A1) Take five minutes to look at file example_short.c.

A2) You might have a glance at the documentation provided in file docfunctions.txt.

A3) You might have a glance at cmaes_initials.par, where input parameters are defined.

B1) Compile and run the example program. Compilation e.g. with the GNU c-compiler in the src folder:

gcc -Wall -o evo cmaes.c example_short.c -lm

and run with evo or ./evo. Take a look at the output.

B2a) (optional but highly recommended: plotting) Invoke Scilab (freely available for Linux/Windows/Mac) or Matlab/Octave, change to the working directory and type (Scilab) getf('plotcmaesdat.sci'); plotcmaesdat; or (Matlab/Octave) plotcmaesdat; You need to have the file plotcmaesdat.sci or .m and the output data files in the working directory. You get a nice plot of the executed run. The same works with cma.py via python cma.py plot

B2b) (optional) Change (increase) problem dimension and/or problem number in file initials.par and re-run.

B2c) (optional) Change problem dimension in initials.par to 300 and change output verbosity via file signals.par while the program is running: change e.g. "print fewinfo 200" into "print fewinfo -200" and back. Read comments.

B2d) Change back problem dimension.

  1. Now you are ready to inspect and edit example_restarts.c or example_boundary.c to plug in the function you want to optimize. Refer to doc.txt and see here for a practical issue on objective function design. Refer to docfunctions.txt to find more documentation about the functions in this package.

  2. Check "obligatory settings" part in initials.par regarding your function. Make sure that the scale of all objective parameter components of the function is somewhat similar and sigma corresponds to about 1/4 of the respective search intervals.

  3. output files are overwritten with each program call.

Questions? go here or send an email to hansen at lri dot fr.

See also:

c-cmaes's People

Contributors

adamkewley avatar antoinemazuyer avatar chrisdembia avatar nikohansen avatar sherm1 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

c-cmaes's Issues

extern C in boundary_transformation header

Hey there,

I just wanted to inform you that if a user utilizes your code from C++ the compiler won't find anything of the boundary_transformation stuff, because the extern "C" call is missing in the header file.

Thanks for your code and best regards
Max

Problem with a simple benchmark function

Hi! Congratulations on your CMA-ES method! I myself am developing an optimization method, and I'm using your method for comparison purposes. Your method is very competitive, I can't reach its convergence speed yet in dimensions above 10.

My benchmarking suite uses random offsetting and rotation in the same manner as BBOB benchmark suite.

I'm having problems with CMA-ES optimizing such function in 14 dimensions, x[] is in the range -25 to 25. CMA-ES simply crashes the program without providing any output. I have a diverse set of functions, and basically only this function causes issues. Note that a random offsetting and rotation should be applied to this function.

static double calcZeroSum( const double* const x, const int N )
{
    double s = 0.0;
    int i;
    for( i = 0; i < N; i++ )
    {
        s += x[i];
    }
    return( s == 0.0 ? 0.0 : 1.0+pow(10000.0*fabs(s),0.5) );
}

generation number in cmaes_t is type double, causes compiler warning

The member gen of struct cmaes_t is described as "generation number" but its type is defined here as double. Then it is assigned to a long here which causes the following compiler warning in VC++:

cmaes.c(742): warning C4244: 'initializing' : conversion from 'double' to 'long', possible loss of data

Even in 64 bit mode, a Visual C++ long is 32 bits (weird, but allowed by the C standard), so this warning is correct.

Is gen intentionally a double or should it be an integer type? If intentional there should be an explicit cast here to avoid the warning, assuming the generation can be guaranteed to fit in a signed 32 bit integer (i.e., less than about 2 billion). Otherwise a long long type could be used to guarantee a 64 bit integer.

cc/ @nikohansen, @chrisdembia

How to modify parameters programmatically?

I see that the parameters are stored in evo->sp. What is the best and safest way to modify these parameters programmatically instead of via input files?

My hunch is that the following sequence of calls would be safe:

cmaes_t evo;
cmaes_init(&evo, ...);
evo.sp.stopMaxIter = 500;
readpara_SupplementDefaults(&evo.sp);

I want to modify the readpara_t entries but I don't want to put the parameters in an inconsistent state, and I still want to benefit from the supplemented defaults. It seems that readpara_t.damps is set based on the value of stopMaxIter. If I update stopMaxIter, I must call readpara_SupplementDefaults to have a consistent value of damps. Are there other additional steps I must take?

Thanks!

boundary_transformation() functions not prefixed with cmaes_

Hi, Niko. While incorporating cma-es into Simbody, we noticed some external functions boundary_transformation() etc. that don't have the usual cmaes_ prefix so would potentially cause link-time conflicts for our users. @chrisdembia removed those files from our port for now, but I would like to be able to include the whole package unchanged to facilitate later updating, and in case someone wants to take advantage of those functions later. Please prefix all the extern functions if possible.

Sherm

transformed points written to file

Hey there,

me again. I used now this library with boundaries quite a bit and I just noticed that there is no option to write out the transformed values natively. I'd like to help out, since I'm profiting from this library, however I'm asking myself, if you would even like to have it as a feature in the library. If so, is there any preferred way of implementing it, e.g. a new pointer for the transformed mean or transformed xbest in cmaes_t?

Best
Max

Eigen decomposition and Gaussian noise vector question

This is not so much an issue, but a fellow researcher question. In CMA-ES an Eigen decomposition is used. While it provides a good estimation of space directionality of sample distribution, this method only ranks the standard deviations in the sample distribution. Yet, CMA-ES uses t->rgD[i] that are ranked. So, when a Gaussian noise vector is generated, its components do not correspond to standard deviations of the sample distribution along its axes. Maybe this is already handled, but I have not found how.

Also I've spotted that in cmaes_interface.cpp:1939 the t->rgD[i] = sqrt(t->rgD[i]); equation is used. From my personal experience, the problem is, Householder and QLalgo may produce small negative values in t->rgD, so a sqrt(abs(t->rgD[i])) is needed to handle such cases.

Switching between related functions

In my application, I first optimize a function f(x1, ..., xn) which is relatively cheap; then I add a perturbation to that function which is very expensive to compute, so I would like to retain as much information from the first optimization as possible. It is clear how to use the optimum (x1, ..., xn) from the first optimization as a starting point for the second, but I am unsure how best to retain covariance matrix and step size information. There are two related scenarios:

  1. The perturbation takes the form g(x1, ..., xn), so the dimension is the same. In this case, is this the right approach?
/* Evaluations use f(x1, ..., xn) up to here. */
cmaes_WriteToFile(evo_ptr, "resume", filename);
cmaes_exit(evo_ptr);
cmaes_init(evo_ptr, dimension, initialX, initialStdDev, seed, lambda, input_parameter_filename);
cmaes_resume_distribution(evo_ptr, filename);
/* Evaluations continue with f(x1, ..., xn) + g(x1, ..., xn). */
  1. The dimension of the problem also increases, so the function becomes f(x1, ..., xn) + g(x1, ..., xn, ..., xm). Is there a recommended way to retain information about the n dimensions which have already been studied, while feeding in default values for new dimensions?

Thanks!

CMA-ES alternative

Sorry to bother you with my request, but I have developed an alternative optimization method based on CMA-ES concept. I've literally reassembled CMA-ES. The method is called SA-ES (sigma adaptation evolution strategy). It performs vector sigma adaptations directly plus covariance matrix update via simple leaky integrator filtering.

It can be downloaded here: https://github.com/avaneev/biteopt
required files: saesopt.h, biteoptort.h, biternd.h. saesopt.h is a front-end class compatible with my BiteOpt optimizer. biteoptort.h is the actual implementation - it was suitably commented on the update steps performed.

SA-ES is a little bit more effective than CMA-ES in my tests, but not by a huge margin. Maybe you can find some creative ideas in it.

Error in formula for chiN

cmaes.c uses the formula (

t->chiN = sqrt((double) N) * (1. - 1./(4.*N) + 1./(21.*N*N));
):

t->chiN = sqrt((double) N) * (1. – 1./(4.*N) + 1./(21.*N*N));

The number “21” is also used in your tutorial at https://www.lri.fr/~hansen/cmatutorial.pdf. However, I believe that it is not the correct asymptotic expansion of chiN. See http://www.wolframalpha.com/input/?i=series+expansion+for+sqrt%282%29*gamma%28%28n%2B1%29%2F2%29%2Fgamma%28n%2F2%29+at+n%3Dinfinity, which indicates that “21” should be changed to “32”.

Alternatively, C99 standardizes the tgamma function, so if you assume C99 compilers then it could be replaced entirely with

t->chiN = sqrt(2.) * tgamma((double)(N+1)/2)/tgamma((double)N/2);

or, for to avoid overflow with roughly N > 340, the slightly less accurate

t->chiN = sqrt(2.) * exp(lgamma((double)(N+1)/2) – lgamma((double)N/2));

Problem with cumulation for covariance matrix (pc) using B*D*z~N(0,C)

Hello,

I use CMAES and its C implementation to deal with stress inversion.
When my problem is very ill conditionned, I have a floating point exception in cmaes.c at line 893/894

/* cumulation for covariance matrix (pc) using B*D*z~N(0,C) */                                                                                                                                      
 hsig = sqrt(psxps) / sqrt(1. - pow(1.-t->sp.cs, 2*t->gen)) / t->chiN 
  < 1.4 + 2./(N+1); 

its with the "pow" function, t->gen = 752 and 1.-t->sp.cs = 0.62435950746181024, so the result must be really close to 0....

Have you got an idea how to avoid this kind of problens, moreover, it has begin to converge !!

screenshot from 2018-01-24 15-17-55

Cheers,

Antoine

Unconditional printf warnings

Some warnings are unconditionally printed to stdout (e.g. here). We would like to control the output that our library produces. Would it be possible to add a verbosity setting? The setting could default to "on" or "1", and we could override it to be zero by default in our library. What do you think?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.