NEURON interface to GAUL (Neymotin and Lytton)

This interface allows the use of genetic algorithms for optimization and search in high-dimensional spaces from within the NEURON environment. It includes converted .c,.h files from GAUL wrapped in proper MOD file syntax as well as MOD code interfacing to the library. It also comes with hoc utilitiy functions to make it easier to use the GA.
Tool Information (Click on a link to find other Tools with that property)
Tool Type: Control Simulations;
Simulation Environment: NEURON;
$Id: NEURON_GA.dol,v 1.14 2007/12/05 06:18:46 samn Exp $ 

SA Neymotin , WW Lytton - 3/2007

* What are genetic algorithms?

 An introduction to genetic algorithms can be found at :

* NEURON interface to GAUL - Genetic Algorithms Utility Library 

 GAUL is available at :

 This interface allows the use of genetic algorithms for optimization
 and search in high-dimensional spaces from within the NEURON
 environment. It includes converted .c,.h files from GAUL wrapped in
 proper MOD file syntax as well as MOD code interfacing to the
 library. It also comes with hoc utilitiy functions to make it easier
 to use the GA.

** Compilation

Compilation was done on a Linux system. It has not been tested on

The mod files should be placed in the NEURON project directory and
built with the command

nrnivmodl -loadflags "-pthread -lpthread"

This means you need to have the pthreads library installed on your
machine. Most standard Linux boxes will have pthreads. For more info
on pthreads look here : .

The files in the gaul subdirectory are the .h header files used for
compilation of the MOD files. These should be placed in a subdirectory
of the NEURON project, so that the mod files can access them properly
at compile-time.

ga_hoc.mod has the main interface between NEURON and GAUL.

ga_utils.hoc has the hoc utility functions that make it easier to use.

ga_test.hoc has a simple demonstration showing how to setup and use
the GA. The GA will then solve a polynomial. This should be loaded
with load_file("mosinit.hoc")

The Neural Query System (1) and associated mod and hoc files was also
included because of certain dependencies on it's functionality.

** Usage 

The main steps for usage are:

0) Set verbose_GA = 0 unless you want to get lots and lots of
   information from the GA printed out during evolution.

1) At the top of your hoc file call install_ga_methods_GA() to install
   the mod functions needed by the GA

2) Create a fitness function in hoc : this function will be called by
the genetic algorithm to evaluate members of the population. The
function should be called GetFitness. The following steps must occur
in the fitness function: 

a) vparams.get_alleles() //get param/allele values from GA 

This will get the population member's properties from the GA and load
them into the Vector vparams 

b) The fitness evaluation will take place - this is the custom
part. you should write code that will use the parameters in vparams to
evaluate how 'good' the population member is. The higher the value,
the better the member (and solution), and the more likely it is to
have kids, etc.  

c) The function should call the function SetFitness, defined in
ga_hoc.mod, passing it the computed fitness value,
i.e. SetFitness_GA(value_just_computed_in_b)

   Here is a sample fitness function:
    func GetFitness(){ local fitness
      vparams.get_alleles() //get param/allele values from GA
      fitness = vparams.sum() //stupid - but works for demo
      return fitness

    Other possibilities for a fitness function include running a
    simulation on a model file to optimize it's parameters.

3) The following hoc variables must be set:
   NumIslands : number of islands that members of population live on - explained
                in the GAUL documentation in the link mentioned above
   Mutate     : mutation rate
   Crossover  : crossover rate
   Migrate    : migration rate
   PopSize    : population size (each island will have this many 'citizens')
   MaxGen     : maximum generation to run the GA 
   NumParams  : number of variables each population member has to optimize
   Elitism    : elitism option mentioned in GAUL docs
   MinFitness : minimum fitness a 'citizen' can have

4) Set the mininimum and maximum value of each param in the vectors
   vallele_mins and vallele_maxs. These vectors must have the same
   size as NumParams and each location will specify the min,max value
   of the given param. For example, if param0 should be between 0 and
   10, you'd do vallele_mins.x(0)=0 vallele_maxs.x(0)=10 . The same
   thing should be done for all the params.

5) There are other variables and functions in the file ga_utils.hoc
   that must be defined.  Don't get rid of them if you want to use the
   hoc utility functions.  Some of these include:

     vparams - stores the parameters passed back and forth between hoc
     and the GA
     vfitnessbest - Vector for each island containing best fitness of
     each generation
     vfitnessavg - Vector for each island containing average fitness
     of each generation
     vfitnessstddev - Vector for each island containing standard
     deviation of each generation
     UpdateGenStats - updates stats for each generation

6) Plotting/param options in hoc variables:

    plot_fitness : whether to plot fitness as a function of
    save_params : save ga params for a run

7) Another option allows scaling of allele values to be between 0 and
   1 for use by GA.  When evaluation of the fitness function in NEURON
   is called, the value for each parameter/allele, is descaled back to
   where value_0_1 is the scaled value of the parameter between 0 and
   1. This option may be useful for allowing "uniform" drift of all
   alleles during mutations. This is set with SetAlleleScale_GA(1).
   The default is off.

8) By default, GAUL will randomly initialize each population member's
    parameters when they are created. There is also an option that
    enables a user-defined population member initialization
    function. This is by calling
    SetHocSeedFunc_GA("FunctionName"). The specified function MUST
    call the Vector method v2data (defined in ga_hoc.mod) at the
    end. This will copy parameter values to internal variables in the
    GA before returning. If this is not done, garbage will be used to
    initialize the new entity. The function should also return 1 to
    indicate success. Here is an example:

      func SetSeed(){ local idx localobj vseed,rdm
        rdm=new Random()
        vseed = new Vector(NumParams)
        for idx=0,NumParams-1 vseed.x(idx)=rdm.uniform(0,1)
        return 1.0

9) You can set the initial random seed used by GAUL by calling
    SetRandSeed_GA(seed_value) and get the random seed value with
    GetRandSeed_GA() . This will allow you to re-produce the results
    of an evolution/optimization.

10) Call SetStatFile_GA to set the file path for statistics to be
    written to during run. If no path is specified, no stats will be

11) There are some other commented functions in ga_hoc.mod which may
    be of use. For example, GAPrintSettings_GA() will print the
    current settings used by the GA.

12) Final step: Call the hoc function Evolution()

13) Watch the evolution. There will be many printouts if
    verbose_GA=1. If not, you will get an update each generation. If
    the run takes too long you can abort and look at the results with
    the BestIsland() hoc function. This will print the best fitness
    and parameters found.

* If you have questions, comments, or want to help improve this

   Email: Sam Neymotin - samn at neurosim dot downstate dot edu

* References:

(1) Lytton WW, Neural Query System: Data-mining from within the NEURON simulator.
    Neuroinformatics, 2006 Springer