source: trunk/packages/optimizer/src/plugin_pgapack.c

Last change on this file was 5673, checked in by ldelgass, 9 years ago

Fix line endings, set eol-style to native on all C/C++ sources.

  • Property svn:eol-style set to native
File size: 41.4 KB
Line 
1/*
2 * ----------------------------------------------------------------------
3 *  OPTIMIZER PLUG-IN:  Pgapack
4 *
5 *  This code connects Pgapack into the Rappture Optimization
6 *  infrastructure.
7 *
8 * ======================================================================
9 *  AUTHOR:  Michael McLennan, Purdue University
10 *  Copyright (c) 2004-2012  HUBzero Foundation, LLC
11 *
12 *  See the file "license.terms" for information on usage and
13 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14 * ======================================================================
15 */
16#include "pgapack.h"
17#include "rp_optimizer.h"
18
19typedef struct PgapackData {
20    int operation;       /* operation <=> PGA_MINIMIZE/PGA_MAXIMIZE */
21    int maxRuns;         /* maximum runs <=> PGASetMaxGAIterValue() */
22    int popSize;         /* population size <=> PGASetPopSize() */
23    int popRepl;         /* replacement <=> PGASetPopReplacementType() */
24    int numReplPerPop;   /* number of new strings created per population, the rest are the best strings from the previous population*/
25    double tgtFitness;   /* target fitness for stoppage --either best or average*/
26    double fitnessTol;   /* %diff betn tgt fit. and current population fit. -- best or avg*/
27    double tgtVariance;  /* target fitness variance*/
28    double varianceTol;  /* tolerance : %diff betn tgt and current pop. fitness variance*/
29    double tgtElapsedTime;   /* target stoppage time from start of execution*/
30    int stpcriteria;     /*stoppage criteria <=> PGASetStoppingRuleType()*/
31    int randnumseed;  /*Random Number Seed <=> PGASetRandomSeed()*/
32    double mutnrate;     /*Mutation Rate <=> PGASetMutatuionProb()*/
33    double mutnValue;     /*use this value while mutating*/
34    double crossovrate;  /*Crossover Rate <=> PGASetCrossoverProb();*/
35    int crossovtype;    /*Crossover Type <=> UNIFORM/SBX/TRIANGULAR (SBX Defined from Deb and Kumar 1995)*/
36    int allowdup;        /*Allow duplicate strings in the population or not*/
37    int mutnandcrossover;/*By default strings that do not undergo crossover undergo mutation, this option allows strings to crossover and be mutated*/
38    double randReplProp; /*By default, random replacement is off, therefore randReplaceProp is zero by default, */
39                                                /*a nonzero replacement value causes random generation of individuals in later generations*/
40} PgapackData;
41
42RpCustomTclOptionGet RpOption_GetStpCriteria;
43RpCustomTclOptionParse RpOption_ParseStpCriteria;
44RpTclOptionType RpOption_StpCriteria = {
45        "pga_stpcriteria", RpOption_ParseStpCriteria,RpOption_GetStpCriteria,NULL
46};
47
48RpCustomTclOptionParse RpOption_ParseOper;
49RpCustomTclOptionGet RpOption_GetOper;
50RpTclOptionType RpOption_Oper = {
51    "pga_operation", RpOption_ParseOper, RpOption_GetOper, NULL
52};
53
54RpCustomTclOptionParse RpOption_ParseCrossovType;
55RpCustomTclOptionGet RpOption_GetCrossovType;
56RpTclOptionType RpOption_CrossovType = {
57        "pga_crossovtype", RpOption_ParseCrossovType,RpOption_GetCrossovType,NULL
58};
59
60RpCustomTclOptionParse RpOption_ParsePopRepl;
61RpCustomTclOptionGet RpOption_GetPopRepl;
62RpTclOptionType RpOption_PopRepl = {
63    "pga_poprepl", RpOption_ParsePopRepl, RpOption_GetPopRepl, NULL
64};
65
66
67typedef struct PgapackRuntimeDataTable{
68        double **data;                          /*Actual data per sample, like values of the genes, fitness of a sample, etc*/
69        int num_of_rows;                        /*Number of rows alloced..should be constant for a run*/
70        int no_of_samples_evaled;       /*Number of samples evaluated so far*/
71        int no_of_columns;                                      /*Number of columns allocated to the data table so far*/
72}PgapackRuntimeDataTable;
73
74RpTclOption PgapackOptions[] = {
75  {"-maxruns", RP_OPTION_INT, Rp_Offset(PgapackData,maxRuns)},
76  {"-operation", &RpOption_Oper, Rp_Offset(PgapackData,operation)},
77  {"-poprepl", &RpOption_PopRepl, Rp_Offset(PgapackData,popRepl)},
78  {"-numReplPerPop",RP_OPTION_INT,Rp_Offset(PgapackData,numReplPerPop)},
79  {"-popsize", RP_OPTION_INT, Rp_Offset(PgapackData,popSize)},
80  {"-mutnrate",RP_OPTION_DOUBLE,Rp_Offset(PgapackData,mutnrate)},
81  {"-mutnValue",RP_OPTION_DOUBLE,Rp_Offset(PgapackData,mutnValue)},
82  {"-crossovrate",RP_OPTION_DOUBLE,Rp_Offset(PgapackData,crossovrate)},
83  {"-crossovtype",&RpOption_CrossovType,Rp_Offset(PgapackData,crossovtype)},
84  {"-randnumseed",RP_OPTION_INT,Rp_Offset(PgapackData,randnumseed)},
85  {"-tgtFitness",RP_OPTION_DOUBLE,Rp_Offset(PgapackData,tgtFitness)},
86  {"-fitnessTol",RP_OPTION_DOUBLE,Rp_Offset(PgapackData,fitnessTol)},
87  {"-tgtVariance",RP_OPTION_DOUBLE,Rp_Offset(PgapackData,tgtVariance)},
88  {"-varianceTol",RP_OPTION_DOUBLE,Rp_Offset(PgapackData,varianceTol)},
89  {"-tgtElapsedTime",RP_OPTION_DOUBLE,Rp_Offset(PgapackData,tgtElapsedTime)},
90  {"-stpcriteria",&RpOption_StpCriteria,Rp_Offset(PgapackData,stpcriteria)},
91  {"-allowdup",RP_OPTION_BOOLEAN,Rp_Offset(PgapackData,allowdup)},
92  {"-mutnandcrossover",RP_OPTION_BOOLEAN,Rp_Offset(PgapackData,mutnandcrossover)},
93  {"-randReplProp",RP_OPTION_DOUBLE,Rp_Offset(PgapackData,randReplProp)},
94  {NULL, NULL, 0}
95};
96
97static double PgapEvaluate _ANSI_ARGS_((PGAContext *ctx, int p, int pop));
98static void PgapCreateString _ANSI_ARGS_((PGAContext *ctx, int, int, int));
99static int PgapMutation _ANSI_ARGS_((PGAContext *ctx, int, int, double));
100static void PgapCrossover _ANSI_ARGS_((PGAContext *ctx, int, int, int,
101    int, int, int));
102static void PgapPrintString _ANSI_ARGS_((PGAContext *ctx, FILE*, int, int));
103static void PgapCopyString _ANSI_ARGS_((PGAContext *ctx, int, int, int, int));
104static int PgapDuplicateString _ANSI_ARGS_((PGAContext *ctx, int, int, int, int));
105static MPI_Datatype PgapBuildDT _ANSI_ARGS_((PGAContext *ctx, int, int));
106
107static void PgapLinkContext2Env _ANSI_ARGS_((PGAContext *ctx,
108    RpOptimEnv *envPtr));
109static RpOptimEnv* PgapGetEnvForContext _ANSI_ARGS_((PGAContext *ctx));
110static void PgapUnlinkContext2Env _ANSI_ARGS_((PGAContext *ctx));
111void PGARuntimeDataTableInit _ANSI_ARGS_((RpOptimEnv *envPtr));
112void PGARuntimeDataTableDeInit();
113void GetSampleInformation _ANSI_ARGS_((char *buffer, int sampleNumber));
114void PGARuntimeDataTableSetSampleValue _ANSI_ARGS_((RpOptimParam *chrom, double fitness));
115static PgapackRuntimeDataTable table;
116/*
117 * ----------------------------------------------------------------------
118 * PgapackInit()
119 *
120 * This routine is called whenever a new optimization object is created
121 * to initialize Pgapack.  Returns a pointer to PgapackData that is
122 * used in later routines.
123 * ----------------------------------------------------------------------
124 */
125ClientData
126PgapackInit()
127{
128    PgapackData *dataPtr;
129
130    dataPtr = (PgapackData*)malloc(sizeof(PgapackData));
131    dataPtr->operation = PGA_MINIMIZE;
132    dataPtr->maxRuns = 10000;
133    dataPtr->popRepl = PGA_POPREPL_BEST;
134    dataPtr->crossovtype = PGA_CROSSOVER_UNIFORM;
135    dataPtr->popSize = 200;
136    dataPtr->numReplPerPop = (dataPtr->popSize)/10; /*10% replaced by default, change to whatever value you need*/
137    dataPtr->crossovrate = 0.85;
138    dataPtr->mutnrate = 0.05; /*by default in PGAPack 1/stringlength*/
139    dataPtr->mutnValue = 0.01;/*value of this number will be changed by plus/minus hundredth of its current value*/
140    dataPtr->randnumseed = 1; /*should be a number greater than one, PGAPack requires it*/
141    dataPtr->tgtFitness = PGA_UNINITIALIZED_DOUBLE; 
142    dataPtr->fitnessTol = PGA_UNINITIALIZED_DOUBLE;  /*by default stop only if desired fitness is exactly achieved*/
143    dataPtr->tgtVariance = PGA_UNINITIALIZED_DOUBLE;
144    dataPtr->varianceTol = PGA_UNINITIALIZED_DOUBLE; /* by default stop only if desired variance is exactly achieved*/
145    dataPtr->tgtElapsedTime = PGA_UNINITIALIZED_DOUBLE; /* stop if 100 minutes have elapsed since start of optim run*/
146    dataPtr->stpcriteria = PGA_STOP_NOCHANGE;
147    dataPtr->allowdup = PGA_FALSE; /*Do not allow duplicate strings by default*/
148    dataPtr->mutnandcrossover = PGA_FALSE;/*do not allow mutation and crossover to take place on the same string by default*/
149    dataPtr->randReplProp = 0; /*0 randomly generated individuals after initialization, per generation*/
150    return (ClientData)dataPtr;
151}
152
153int pgapack_abort = 0;
154int pgapack_restart_user_action = 0;
155
156/*
157 * ----------------------------------------------------------------------
158 * PgapackRun()
159 *
160 * This routine is called to kick off an optimization run.  Sets up
161 * a PGApack context and starts invoking runs.
162 * ----------------------------------------------------------------------
163 */
164RpOptimStatus
165PgapackRun(envPtr, evalProc, fitnessExpr)
166    RpOptimEnv *envPtr;           /* optimization environment */
167    RpOptimEvaluator *evalProc;   /* call this proc to run tool */
168    char *fitnessExpr;            /* fitness function in string form */
169{
170    PgapackData *dataPtr =(PgapackData*)envPtr->pluginData;
171    PGAContext *ctx;
172
173    /* pgapack requires at least one arg -- the executable name */
174    /* fake it here by just saying something like "rappture" */
175    int argc = 1; char *argv[] = {"rappture"};
176
177    pgapack_abort = 0;          /* FALSE */
178    PGASetAbortVar(&pgapack_abort);
179    PGASetRestartUserAction(&pgapack_restart_user_action);
180
181    ctx = PGACreate(&argc, argv, PGA_DATATYPE_USER, envPtr->numParams,
182        dataPtr->operation);
183
184    PGASetMaxGAIterValue(ctx, dataPtr->maxRuns);
185    PGASetPopSize(ctx, dataPtr->popSize);
186    PGASetPopReplaceType(ctx, dataPtr->popRepl);
187    PGASetTgtFitnessVal(ctx,dataPtr->tgtFitness);
188    PGASetFitnessTol(ctx,dataPtr->fitnessTol);
189    PGASetTgtFitnessVariance(ctx,dataPtr->tgtVariance);
190    PGASetVarTol(ctx,dataPtr->varianceTol);
191    PGASetTgtElapsedTime(ctx,dataPtr->tgtElapsedTime);
192    PGASetStoppingRuleType(ctx, dataPtr->stpcriteria);
193    PGASetMutationProb(ctx,dataPtr->mutnrate);
194    PGASetMutationRealValue(ctx,dataPtr->mutnValue);
195    PGASetCrossoverProb(ctx,dataPtr->crossovrate);
196    PGASetRandomSeed(ctx,dataPtr->randnumseed);
197    PGASetCrossoverType(ctx, dataPtr->crossovtype);
198    PGASetNoDuplicatesFlag(ctx,!(dataPtr->allowdup));
199    PGASetMutationAndCrossoverFlag(ctx,dataPtr->mutnandcrossover);
200    PGASetNumReplaceValue(ctx,dataPtr->numReplPerPop);
201    PGASetRandReplProp(ctx,dataPtr->randReplProp);
202
203
204    PGASetUserFunction(ctx, PGA_USERFUNCTION_CREATESTRING, PgapCreateString);
205    PGASetUserFunction(ctx, PGA_USERFUNCTION_MUTATION, PgapMutation);
206    PGASetUserFunction(ctx, PGA_USERFUNCTION_CROSSOVER, PgapCrossover);
207    PGASetUserFunction(ctx, PGA_USERFUNCTION_PRINTSTRING, PgapPrintString);
208    PGASetUserFunction(ctx, PGA_USERFUNCTION_COPYSTRING, PgapCopyString);
209    PGASetUserFunction(ctx, PGA_USERFUNCTION_DUPLICATE, PgapDuplicateString);
210    PGASetUserFunction(ctx, PGA_USERFUNCTION_BUILDDATATYPE, PgapBuildDT);
211
212    envPtr->evalProc = evalProc;   /* plug these in for later during eval */
213    envPtr->fitnessExpr = fitnessExpr;
214
215    /*
216     * We need a way to convert from a PGAContext to our RpOptimEnv
217     * data.  This happens when Pgapack calls routines like
218     * PgapCreateString, passing in the PGAContext, but nothing else.
219     * Call PgapLinkContext2Env() here, so later on we can figure
220     * out how many parameters, names, types, etc.
221     */
222    PgapLinkContext2Env(ctx, envPtr);
223
224    PGASetUp(ctx);
225    PGARun(ctx, PgapEvaluate);
226    PGADestroy(ctx);
227    PgapUnlinkContext2Env(ctx);
228
229    if (pgapack_abort) {
230        return RP_OPTIM_ABORTED;
231    }
232    return RP_OPTIM_SUCCESS;
233}
234
235/*
236 * ----------------------------------------------------------------------
237 * PgapackEvaluate()
238 *
239 * Called by PGApack whenever a set of input values needs to be
240 * evaluated.  Passes the values on to the underlying Rappture tool,
241 * launches a run, and computes the value of the fitness function.
242 * Returns the value for the fitness function.
243 * ----------------------------------------------------------------------
244 */
245double
246PgapEvaluate(ctx, p, pop)
247    PGAContext *ctx;  /* pgapack context for this optimization */
248    int p;            /* sample #p being run */
249    int pop;          /* identifier for this population */
250   
251{
252    double fit = 0.0;
253    RpOptimEnv *envPtr;
254    RpOptimParam *paramPtr;
255    RpOptimStatus status;
256    envPtr = PgapGetEnvForContext(ctx);
257    paramPtr = (RpOptimParam*)PGAGetIndividual(ctx, p, pop)->chrom;
258    status = (*envPtr->evalProc)(envPtr, paramPtr, envPtr->numParams, &fit);
259       
260    if (pgapack_abort) {
261        fprintf(stderr, "==WARNING: run aborted!");
262        return 0.0;
263    }
264       
265    if (status != RP_OPTIM_SUCCESS) {
266        fprintf(stderr, "==WARNING: run failed!");
267        PgapPrintString(ctx, stderr, p, pop);
268    }
269       
270        /*populate the table with this sample*/
271        PGARuntimeDataTableSetSampleValue(paramPtr,fit);
272    return fit;
273}
274
275/*
276 * ----------------------------------------------------------------------
277 * PgapackCleanup()
278 *
279 * This routine is called whenever an optimization object is deleted
280 * to clean up data associated with the object.  Frees the data
281 * allocated in PgapackInit.
282 * ----------------------------------------------------------------------
283 */
284void
285PgapackCleanup(cdata)
286    ClientData cdata;  /* data from to be cleaned up */
287{
288    PgapackData *dataPtr = (PgapackData*)cdata;
289    free(dataPtr);
290}
291
292/*
293 * ======================================================================
294 *  ROUTINES FOR MANAGING DATA STRINGS
295 * ======================================================================
296 * PgapCreateString()
297 *
298 * Called by pgapack to create the so-called "string" of data used for
299 * an evaluation.
300 * ----------------------------------------------------------------------
301 */
302void
303PgapCreateString(ctx, p, pop, initFlag)
304    PGAContext *ctx;  /* pgapack context for this optimization */
305    int p;            /* sample #p being run */
306    int pop;          /* identifier for this population */
307    int initFlag;     /* non-zero => fields should be initialized */
308{
309    int n, ival;
310    double dval;
311    RpOptimEnv *envPtr;
312    RpOptimParam *oldParamPtr, *newParamPtr;
313    PGAIndividual *newData;
314    RpOptimParamNumber *numPtr;
315    RpOptimParamString *strPtr;
316
317    envPtr = PgapGetEnvForContext(ctx);
318
319    newData = PGAGetIndividual(ctx, p, pop);
320    newData->chrom = malloc(envPtr->numParams*sizeof(RpOptimParam));
321    newParamPtr = (RpOptimParam*)newData->chrom;
322
323    for (n=0; n < envPtr->numParams; n++) {
324        oldParamPtr = envPtr->paramList[n];
325        newParamPtr[n].name = oldParamPtr->name;
326        newParamPtr[n].type = oldParamPtr->type;
327        switch (oldParamPtr->type) {
328        case RP_OPTIMPARAM_NUMBER:
329            newParamPtr[n].value.dval = 0.0;
330            break;
331        case RP_OPTIMPARAM_STRING:
332            newParamPtr[n].value.sval.num = -1;
333            newParamPtr[n].value.sval.str = NULL;
334            break;
335        default:
336            panic("bad parameter type in PgapCreateString()");
337        }
338    }
339
340    if (initFlag) {
341        for (n=0; n < envPtr->numParams; n++) {
342            switch (newParamPtr[n].type) {
343            case RP_OPTIMPARAM_NUMBER:
344                numPtr = (RpOptimParamNumber*)envPtr->paramList[n];
345                if(numPtr->randdist == RAND_NUMBER_DIST_UNIFORM){
346                        dval = PGARandom01(ctx,0);
347                        newParamPtr[n].value.dval = (numPtr->max - numPtr->min)*dval + numPtr->min;
348                }else if(numPtr->randdist == RAND_NUMBER_DIST_GAUSSIAN){
349                                dval = PGARandomGaussian(ctx,numPtr->mean,numPtr->stddev);
350                                if(numPtr->strictmax){
351                                        if(dval>numPtr->max){
352                                                dval = numPtr->max;
353                                        }
354                                }
355                                if(numPtr->strictmin){
356                                        if(dval<numPtr->min){
357                                                dval = numPtr->min;
358                                        }
359                                }
360                                newParamPtr[n].value.dval = dval;
361                }else{
362                        panic("Incorrect Random Number distribution option in PgapcreateString()");
363                }
364                break;
365            case RP_OPTIMPARAM_STRING:
366                strPtr = (RpOptimParamString*)envPtr->paramList[n];
367                ival = (int)floor(PGARandom01(ctx,0) * strPtr->numValues);
368                envPtr->paramList[n]->value.sval.num = ival;
369                envPtr->paramList[n]->value.sval.str = strPtr->values[ival];
370                break;
371            default:
372                panic("bad parameter type in PgapCreateString()");
373            }
374        }
375    }
376}
377
378/*
379 * ----------------------------------------------------------------------
380 * PgapMutation()
381 *
382 * Called by pgapack to perform random mutations on the input data
383 * used for evaluation.
384 * ----------------------------------------------------------------------
385 */
386int
387PgapMutation(ctx, p, pop, mr)
388    PGAContext *ctx;  /* pgapack context for this optimization */
389    int p;            /* sample #p being run */
390    int pop;          /* identifier for this population */
391    double mr;        /* probability of mutation for each gene */
392{
393    int count = 0;    /* number of mutations */
394
395    int n, ival,tempmr;
396    double mutnVal;
397    RpOptimEnv *envPtr;
398    RpOptimParam *paramPtr;
399    RpOptimParamNumber *numPtr;
400    RpOptimParamString *strPtr;
401
402    envPtr = PgapGetEnvForContext(ctx);
403    paramPtr = (RpOptimParam*)PGAGetIndividual(ctx, p, pop)->chrom;
404
405    for (n=0; n < envPtr->numParams; n++) {
406
407
408            switch (paramPtr[n].type) {
409            case RP_OPTIMPARAM_NUMBER:
410                numPtr = (RpOptimParamNumber*)envPtr->paramList[n];
411                if(numPtr->mutnrate!=PARAM_NUM_UNSPEC_MUTN_RATE){
412                        tempmr = numPtr->mutnrate;
413                        mutnVal = numPtr->mutnValue;
414                }else{
415                        tempmr = mr;
416                        mutnVal = PGAGetMutationRealValue(ctx);
417                }
418                if (PGARandomFlip(ctx, tempmr)) {
419                            /* won the coin toss -- change this parameter */
420                                count++;
421                               
422                        /* bump the value up/down a little, randomly */
423                        if (PGARandomFlip(ctx, 0.5)) {
424                            paramPtr[n].value.dval += mutnVal*paramPtr[n].value.dval; /*Made the mutation amount configurable*/
425                        } else {
426                            paramPtr[n].value.dval -= mutnVal*paramPtr[n].value.dval;
427                        }
428                        /* make sure the resulting value is still in bounds */
429                        if(numPtr->randdist == RAND_NUMBER_DIST_UNIFORM ||
430                         (numPtr->randdist == RAND_NUMBER_DIST_GAUSSIAN && numPtr->strictmax)){
431                                if (paramPtr[n].value.dval > numPtr->max) {
432                                    paramPtr[n].value.dval = numPtr->max;
433                                }
434                         }
435                         /*also make sure it obeys configured parameters when gaussian*/
436                         if(numPtr->randdist == RAND_NUMBER_DIST_UNIFORM ||
437                         (numPtr->randdist == RAND_NUMBER_DIST_GAUSSIAN && numPtr->strictmin)){
438                                if (paramPtr[n].value.dval < numPtr->min) {
439                                    paramPtr[n].value.dval = numPtr->min;
440                                }
441                         }
442                       
443                }
444                break;
445               
446
447            case RP_OPTIMPARAM_STRING:
448                    if (PGARandomFlip(ctx, mr)) {
449                    /* won the coin toss -- change this parameter */
450                        count++;
451               
452                        ival = paramPtr[n].value.sval.num;
453                        if (PGARandomFlip(ctx, 0.5)) {
454                            ival += 1;
455                        } else {
456                            ival -= 1;
457                        }
458                        strPtr = (RpOptimParamString*)envPtr->paramList[n];
459                        if (ival < 0) ival = 0;
460                        if (ival >= strPtr->numValues) ival = strPtr->numValues-1;
461                        paramPtr[n].value.sval.num = ival;
462                        paramPtr[n].value.sval.str = strPtr->values[ival];
463                    }
464                   
465                    break;
466                   
467            default:
468                panic("bad parameter type in PgapMutation()");
469            }
470       
471    }
472    return count;
473}
474
475/*
476 * ----------------------------------------------------------------------
477 * PgapCrossover()
478 *
479 * Called by pgapack to perform cross-over mutations on the input data
480 * used for evaluation.
481 * ----------------------------------------------------------------------
482 */
483void
484PgapCrossover(ctx, p1, p2, pop1, c1, c2, pop2)
485    PGAContext *ctx;  /* pgapack context for this optimization */
486    int p1;           /* sample # for parent of input string1 */
487    int p2;           /* sample # for parent of input string2 */
488    int pop1;         /* population containing p1 and p2 */
489    int c1;           /* sample # for child of input string1 */
490    int c2;           /* sample # for child of input string2 */
491    int pop2;         /* population containing c1 and c2 */
492{
493    int n;
494    RpOptimEnv *envPtr;
495    RpOptimParam *parent1, *parent2, *child1, *child2;
496    double pu;
497    PgapackData *dataPtr;
498    /*declare variables for SBX*/
499    double ui,beta,eta = 1.5,powVal;
500    double slope = 3,xi;
501
502    envPtr = PgapGetEnvForContext(ctx);
503    parent1 = (RpOptimParam*)PGAGetIndividual(ctx, p1, pop1)->chrom;
504    parent2 = (RpOptimParam*)PGAGetIndividual(ctx, p2, pop1)->chrom;
505    child1  = (RpOptimParam*)PGAGetIndividual(ctx, c1, pop2)->chrom;
506    child2  = (RpOptimParam*)PGAGetIndividual(ctx, c2, pop2)->chrom;
507       
508        pu = PGAGetCrossoverProb(ctx);
509        dataPtr =(PgapackData*)envPtr->pluginData;
510       
511        for (n=0; n < envPtr->numParams; n++) {
512        if (PGARandomFlip(ctx, pu)) {
513            /* crossover */
514            switch(dataPtr->crossovtype){
515                case PGA_CROSSOVER_UNIFORM:
516                        memcpy(&child1[n], &parent2[n], sizeof(RpOptimParam));
517                        memcpy(&child2[n], &parent1[n], sizeof(RpOptimParam));
518                        break;
519                case PGA_CROSSOVER_SBX:
520                        /*Implement a Simulated Binary Crossover for Real Encoding*/
521                        /*From Deb and Agrawal, 1995; Deb and Kumar, 1995)*/
522                        switch(parent1[n].type){
523                                case RP_OPTIMPARAM_NUMBER:
524                                        ui = PGARandom01(ctx,0);
525                                        powVal = 1/(eta+1);
526                                        if(ui<=0.5){
527                                                beta = pow(2*ui,powVal);
528                                        }else{
529                                                beta = pow(0.5/(1-ui),powVal);
530                                        }
531                                        child1[n].value.dval = 0.5*((1+beta)*(parent1[n].value.dval) + (1-beta)*(parent2[n].value.dval));
532                                        child2[n].value.dval = 0.5*((1-beta)*(parent1[n].value.dval) + (1+beta)*(parent2[n].value.dval));
533                                        break;
534                                default:
535                                        panic("Bad Optim Param Type in PgapCrossover()");
536                        }
537                        break;
538                       
539                       
540                        case PGA_CROSSOVER_TRIANGULAR:
541                        xi = 1/sqrt(slope);
542                        switch(parent1[n].type){
543                                case RP_OPTIMPARAM_NUMBER:
544                                        ui = PGARandom01(ctx,0);
545                                       
546                                        if(ui<=0.5){
547                                                beta = sqrt(2*ui/slope);
548                                                }else{
549                                                beta = 2*xi-sqrt(2*(1-ui)/slope);
550                                                }
551                                        child1[n].value.dval = beta + (parent1[n].value.dval - xi) ;
552                                        child2[n].value.dval = beta + (parent2[n].value.dval - xi) ;
553                                        break;
554                                default:
555                                        panic("Bad Optim Param Type in PgapCrossover()");
556                        }
557                        break;
558                       
559                       
560                default:
561                        panic("bad parameter type in PgapCrossover()");
562            }
563        } else {
564            /* child inherits from parent */
565            memcpy(&child1[n], &parent1[n], sizeof(RpOptimParam));
566            memcpy(&child2[n], &parent2[n], sizeof(RpOptimParam));
567        }
568    }
569                       
570               
571}
572
573/*
574 * ----------------------------------------------------------------------
575 * PgapPrintString()
576 *
577 * Called by pgapack to format the values for a particular string of
578 * input data.
579 * ----------------------------------------------------------------------
580 */
581void
582PgapPrintString(ctx, fp, p, pop)
583    PGAContext *ctx;  /* pgapack context for this optimization */
584    FILE *fp;         /* write to this file pointer */
585    int p;            /* sample #p being run */
586    int pop;          /* identifier for this population */
587{
588    int n;
589    RpOptimEnv *envPtr;
590    RpOptimParam *paramPtr;
591
592    envPtr = PgapGetEnvForContext(ctx);
593    paramPtr = (RpOptimParam*)PGAGetIndividual(ctx, p, pop)->chrom;
594
595    for (n=0; n < envPtr->numParams; n++) {
596        fprintf(fp, "#%4d: ", n);
597        switch (paramPtr[n].type) {
598        case RP_OPTIMPARAM_NUMBER:
599            fprintf(fp, "[%11.7g] (%s)\n", paramPtr[n].value.dval,
600                paramPtr[n].name);
601            break;
602        case RP_OPTIMPARAM_STRING:
603            fprintf(fp, "[%d]=\"%s\" (%s)\n", paramPtr[n].value.sval.num,
604                paramPtr[n].value.sval.str, paramPtr[n].name);
605            break;
606        default:
607            panic("bad parameter type in PgapPrintString()");
608        }
609    }
610}
611
612/*
613 * ----------------------------------------------------------------------
614 * PgapCopyString()
615 *
616 * Called by pgapack to copy one input string to another.
617 * ----------------------------------------------------------------------
618 */
619void
620PgapCopyString(ctx, p1, pop1, p2, pop2)
621    PGAContext *ctx;  /* pgapack context for this optimization */
622    int p1;           /* source sample # being run */
623    int pop1;         /* population containing p1 */
624    int p2;           /* destination sample # being run */
625    int pop2;         /* population containing p1 */
626{
627    int n;
628    RpOptimEnv *envPtr;
629    RpOptimParam *src, *dst;
630
631    envPtr = PgapGetEnvForContext(ctx);
632    src = (RpOptimParam*)PGAGetIndividual(ctx, p1, pop1)->chrom;
633    dst = (RpOptimParam*)PGAGetIndividual(ctx, p2, pop2)->chrom;
634
635    for (n=0; n < envPtr->numParams; n++) {
636        dst[n].type = src[n].type;
637        switch (src[n].type) {
638        case RP_OPTIMPARAM_NUMBER:
639            dst[n].value.dval = src[n].value.dval;
640            break;
641        case RP_OPTIMPARAM_STRING:
642            dst[n].value.sval.num = src[n].value.sval.num;
643            dst[n].value.sval.str = src[n].value.sval.str;
644            break;
645        default:
646            panic("bad parameter type in PgapCopyString()");
647        }
648    }
649}
650
651/*
652 * ----------------------------------------------------------------------
653 * PgapDuplicateString()
654 *
655 * Called by pgapack to compare two input strings.  Returns non-zero if
656 * the two are duplicates and 0 otherwise.
657 * ----------------------------------------------------------------------
658 */
659int
660PgapDuplicateString(ctx, p1, pop1, p2, pop2)
661    PGAContext *ctx;  /* pgapack context for this optimization */
662    int p1;           /* sample #p being run */
663    int pop1;         /* population containing p1 */
664    int p2;           /* sample #p being run */
665    int pop2;         /* population containing p1 */
666{
667    int n;
668    RpOptimEnv *envPtr;
669    RpOptimParam *param1, *param2;
670
671    envPtr = PgapGetEnvForContext(ctx);
672    param1 = (RpOptimParam*)PGAGetIndividual(ctx, p1, pop1)->chrom;
673    param2 = (RpOptimParam*)PGAGetIndividual(ctx, p2, pop2)->chrom;
674
675    for (n=0; n < envPtr->numParams; n++) {
676        if (param1[n].type != param2[n].type) {
677            return 0;  /* different! */
678        }
679        switch (param1[n].type) {
680        case RP_OPTIMPARAM_NUMBER:
681            if (param1[n].value.dval != param2[n].value.dval) {
682                return 0;  /* different! */
683            }
684            break;
685        case RP_OPTIMPARAM_STRING:
686            if (param1[n].value.sval.num != param2[n].value.sval.num) {
687                return 0;  /* different! */
688            }
689            break;
690        default:
691            panic("bad parameter type in PgapDuplicateString()");
692        }
693    }
694    return 1;
695}
696
697
698
699/*
700 * ----------------------------------------------------------------------
701 * PgapCopyString()
702 *
703 * Called by pgapack to copy one input string to another.
704 * ----------------------------------------------------------------------
705 */
706MPI_Datatype
707PgapBuildDT(ctx, p, pop)
708    PGAContext *ctx;  /* pgapack context for this optimization */
709    int p;            /* sample # being run */
710    int pop;          /* population containing sample */
711{
712    panic("MPI support not implemented!");
713    return NULL;
714}
715
716/*
717 * ======================================================================
718 *  OPTION:  -operation <=> PGA_MINIMIZE / PGA_MAXIMIZE
719 * ======================================================================
720 */
721int
722RpOption_ParseOper(interp, valObj, cdata, offset)
723    Tcl_Interp *interp;  /* interpreter handling this request */
724    Tcl_Obj *valObj;     /* set option to this new value */
725    ClientData cdata;    /* save in this data structure */
726    int offset;          /* save at this offset in cdata */
727{
728    int *ptr = (int*)(cdata+offset);
729    char *val = Tcl_GetStringFromObj(valObj, (int*)NULL);
730    if (strcmp(val,"minimize") == 0) {
731        *ptr = PGA_MINIMIZE;
732    }
733    else if (strcmp(val,"maximize") == 0) {
734        *ptr = PGA_MAXIMIZE;
735    }
736    else {
737        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
738            "bad value \"", val, "\": should be minimize, maximize",
739            (char*)NULL);
740        return TCL_ERROR;
741    }
742    return TCL_OK;
743}
744
745int
746RpOption_GetOper(interp, cdata, offset)
747    Tcl_Interp *interp;  /* interpreter handling this request */
748    ClientData cdata;    /* get from this data structure */
749    int offset;          /* get from this offset in cdata */
750{
751    int *ptr = (int*)(cdata+offset);
752    switch (*ptr) {
753    case PGA_MINIMIZE:
754        Tcl_SetResult(interp, "minimize", TCL_STATIC);
755        break;
756    case PGA_MAXIMIZE:
757        Tcl_SetResult(interp, "maximize", TCL_STATIC);
758        break;
759    default:
760        Tcl_SetResult(interp, "???", TCL_STATIC);
761        break;
762    }
763    return TCL_OK;
764}
765
766
767/*
768 * ======================================================================
769 *  OPTION:  -crossovtype <=> PGA_CROSSOVER_UNIFORM / PGA_CROSSOVER_SBX
770 * ======================================================================
771 */
772int
773RpOption_ParseCrossovType(interp, valObj, cdata, offset)
774    Tcl_Interp *interp;  /* interpreter handling this request */
775    Tcl_Obj *valObj;     /* set option to this new value */
776    ClientData cdata;    /* save in this data structure */
777    int offset;          /* save at this offset in cdata */
778{
779    int *ptr = (int*)(cdata+offset);
780    char *val = Tcl_GetStringFromObj(valObj, (int*)NULL);
781    if (strcmp(val,"uniform") == 0) {
782        *ptr = PGA_CROSSOVER_UNIFORM;
783    }
784    else if (strcmp(val,"sbx") == 0) {
785        *ptr = PGA_CROSSOVER_SBX;
786    }
787    else if (strcmp(val,"triangular")== 0 ){
788        *ptr = PGA_CROSSOVER_TRIANGULAR;
789    }
790    else {
791        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
792            "bad value \"", val, "\": should be either 'uniform' or 'sbx'",
793            (char*)NULL);
794        return TCL_ERROR;
795    }
796    return TCL_OK;
797}
798
799int
800RpOption_GetCrossovType(interp, cdata, offset)
801    Tcl_Interp *interp;  /* interpreter handling this request */
802    ClientData cdata;    /* get from this data structure */
803    int offset;          /* get from this offset in cdata */
804{
805    int *ptr = (int*)(cdata+offset);
806    switch (*ptr) {
807    case PGA_CROSSOVER_UNIFORM:
808        Tcl_SetResult(interp, "uniform", TCL_STATIC);
809        break;
810    case PGA_CROSSOVER_SBX:
811        Tcl_SetResult(interp, "sbx", TCL_STATIC);
812        break;
813    case PGA_CROSSOVER_TRIANGULAR:
814        Tcl_SetResult(interp,"triangular",TCL_STATIC);
815        break;   
816    default:
817        Tcl_SetResult(interp, "???", TCL_STATIC);
818        break;
819    }
820    return TCL_OK;
821}
822
823
824
825
826/*
827 * ======================================================================
828 *  OPTION:  -poprepl <=> PGASetPopReplacementType()
829 * ======================================================================
830 */
831int
832RpOption_ParsePopRepl(interp, valObj, cdata, offset)
833    Tcl_Interp *interp;  /* interpreter handling this request */
834    Tcl_Obj *valObj;     /* set option to this new value */
835    ClientData cdata;    /* save in this data structure */
836    int offset;          /* save at this offset in cdata */
837{
838    int *ptr = (int*)(cdata+offset);
839    char *val = Tcl_GetStringFromObj(valObj, (int*)NULL);
840    if (*val == 'b' && strcmp(val,"best") == 0) {
841        *ptr = PGA_POPREPL_BEST;
842    }
843    else if (*val == 'r' && strcmp(val,"random-repl") == 0) {
844        *ptr = PGA_POPREPL_RANDOM_REP;
845    }
846    else if (*val == 'r' && strcmp(val,"random-norepl") == 0) {
847        *ptr = PGA_POPREPL_RANDOM_NOREP;
848    }
849    else {
850        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
851            "bad value \"", val, "\": should be best, random-norepl,"
852            " or random-repl", (char*)NULL);
853        return TCL_ERROR;
854    }
855    return TCL_OK;
856}
857
858int
859RpOption_GetPopRepl(interp, cdata, offset)
860    Tcl_Interp *interp;  /* interpreter handling this request */
861    ClientData cdata;    /* get from this data structure */
862    int offset;          /* get from this offset in cdata */
863{
864    int *ptr = (int*)(cdata+offset);
865    switch (*ptr) {
866    case PGA_POPREPL_BEST:
867        Tcl_SetResult(interp, "best", TCL_STATIC);
868        break;
869    case PGA_POPREPL_RANDOM_REP:
870        Tcl_SetResult(interp, "random-repl", TCL_STATIC);
871        break;
872    case PGA_POPREPL_RANDOM_NOREP:
873        Tcl_SetResult(interp, "random-norepl", TCL_STATIC);
874        break;
875    default:
876        Tcl_SetResult(interp, "???", TCL_STATIC);
877        break;
878    }
879    return TCL_OK;
880}
881
882/*
883 * ==================================================================================================================
884 *  OPTION:  -stpcriteria <=> PGA_STOP_MAXITER / PGA_STOP_NOCHANGE / PGA_STOP_TOOSIMILAR /
885 *      PGA_STOP_AV_FITNESS / PGA_STOP_BEST_FITNESS / PGA_STOP_VARIANCE / PGA_STOP_TIMEELAPSED
886 * ==================================================================================================================
887 */
888int
889RpOption_ParseStpCriteria(interp, valObj, cdata, offset)
890    Tcl_Interp *interp;  /* interpreter handling this request */
891    Tcl_Obj *valObj;     /* set option to this new value */
892    ClientData cdata;    /* save in this data structure */
893    int offset;          /* save at this offset in cdata */
894{
895    int *ptr = (int*)(cdata+offset);
896    char *val = Tcl_GetStringFromObj(valObj, (int*)NULL);
897    if (strcmp(val,"maxiter") == 0) {
898        *ptr = PGA_STOP_MAXITER;
899    }
900    else if (strcmp(val,"nochange") == 0) {
901        *ptr = PGA_STOP_NOCHANGE;
902    }
903    else if (strcmp(val,"toosimilar") == 0){
904        *ptr = PGA_STOP_TOOSIMILAR;
905    }
906    else if (strcmp(val,"avfitness") == 0){
907        *ptr = PGA_STOP_AV_FITNESS;
908    }
909    else if (strcmp(val,"bestfitness") == 0){
910        *ptr = PGA_STOP_BEST_FITNESS;
911    }
912    else if (strcmp(val,"varoffitness") == 0){
913        *ptr = PGA_STOP_VARIANCE;
914    }
915    else if (strcmp(val,"timeelapsed") == 0){
916        *ptr = PGA_STOP_TIMEELAPSED;
917    }
918   
919    else {
920        Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
921            "bad value \"", val, "\": should be one of the following: maxiter, nochange, toosimilar, avfitness, bestfitness, varoffitness or timeelapsed",
922            (char*)NULL);
923        return TCL_ERROR;
924    }
925    return TCL_OK;
926}
927
928int
929RpOption_GetStpCriteria(interp, cdata, offset)
930    Tcl_Interp *interp;  /* interpreter handling this request */
931    ClientData cdata;    /* get from this data structure */
932    int offset;          /* get from this offset in cdata */
933{
934    int *ptr = (int*)(cdata+offset);
935    switch (*ptr) {
936    case PGA_STOP_MAXITER:
937        Tcl_SetResult(interp, "maxiter", TCL_STATIC);
938        break;
939    case PGA_STOP_NOCHANGE:
940        Tcl_SetResult(interp, "nochange", TCL_STATIC);
941        break;
942    case PGA_STOP_TOOSIMILAR:
943        Tcl_SetResult(interp, "toosimilar", TCL_STATIC);
944        break;
945    case PGA_STOP_AV_FITNESS:
946        Tcl_SetResult(interp, "avfitness", TCL_STATIC);
947        break;
948    case PGA_STOP_BEST_FITNESS:
949        Tcl_SetResult(interp, "bestfitness", TCL_STATIC);
950        break;
951    case PGA_STOP_VARIANCE:
952        Tcl_SetResult(interp, "varoffitness", TCL_STATIC);
953        break;
954    case PGA_STOP_TIMEELAPSED:
955        Tcl_SetResult(interp, "timeelapsed", TCL_STATIC);
956        break;       
957    default:
958        Tcl_SetResult(interp, "???", TCL_STATIC);
959        break;
960    }
961    return TCL_OK;
962}
963
964/*
965 * ======================================================================
966 *  ROUTINES FOR CONNECTING PGACONTEXT <=> RPOPTIMENV
967 * ======================================================================
968 * PgapLinkContext2Env()
969 *   This routine is used internally to establish a relationship between
970 *   a PGAContext token and its corresponding RpOptimEnv data.  The
971 *   PGA routines don't provide a way to pass the RpOptimEnv data along,
972 *   so we use these routines to find the correspondence.
973 *
974 * PgapGetEnvForContext()
975 *   Returns the RpOptimEnv associated with a given PGAContext.  If the
976 *   link has not been established via PgapLinkContext2Env(), then this
977 *   routine returns NULL.
978 *
979 * PgapUnlinkContext2Env()
980 *   Breaks the link between a PGAContext and its RpOptimEnv.  Should
981 *   be called when the PGAContext is destroyed and is no longer valid.
982 * ----------------------------------------------------------------------
983 */
984static Tcl_HashTable *Pgacontext2Rpenv = NULL;
985
986void
987PgapLinkContext2Env(ctx, envPtr)
988    PGAContext *ctx;      /* pgapack context for this optimization */
989    RpOptimEnv *envPtr;   /* corresponding Rappture optimization data */
990{
991    Tcl_HashEntry *ctxEntry;
992    int newEntry;
993
994    if (Pgacontext2Rpenv == NULL) {
995        Pgacontext2Rpenv = (Tcl_HashTable*)malloc(sizeof(Tcl_HashTable));
996        Tcl_InitHashTable(Pgacontext2Rpenv, TCL_ONE_WORD_KEYS);
997    }
998    ctxEntry = Tcl_CreateHashEntry(Pgacontext2Rpenv, (char*)ctx, &newEntry);
999    Tcl_SetHashValue(ctxEntry, (ClientData)envPtr);
1000}
1001
1002RpOptimEnv*
1003PgapGetEnvForContext(ctx)
1004    PGAContext *ctx;
1005{
1006    Tcl_HashEntry *entryPtr;
1007
1008    if (Pgacontext2Rpenv) {
1009        entryPtr = Tcl_FindHashEntry(Pgacontext2Rpenv, (char*)ctx);
1010        if (entryPtr) {
1011            return (RpOptimEnv*)Tcl_GetHashValue(entryPtr);
1012        }
1013    }
1014    return NULL;
1015}
1016
1017void
1018PgapUnlinkContext2Env(ctx)
1019    PGAContext *ctx;
1020{
1021    Tcl_HashEntry *entryPtr;
1022
1023    if (Pgacontext2Rpenv) {
1024        entryPtr = Tcl_FindHashEntry(Pgacontext2Rpenv, (char*)ctx);
1025        if (entryPtr) {
1026            Tcl_DeleteHashEntry(entryPtr);
1027        }
1028    }
1029}
1030/*---------------------------------------------------------------------------------
1031 * PGARuntimeDTInit(): It initializes the runtime data table.
1032 * The table is organized slightly counter-intuitively
1033 * Instead of a
1034 *  param1|param2|param3  |param4...
1035 *      val11 |val12 |val13   |val14...
1036 *      val12 |val22 |val23   |val24....
1037 * orientation, it is organized as
1038 *      param1|val11|val12
1039 *      param2|val21|val22
1040 *      param3|val31|val32
1041 *      param4|val41|val42
1042 * Reallocating for additional columns is easier than reallocating additional rows and then
1043 * reallocating for columns
1044 * --------------------------------------------------------------------------------
1045 */
1046
1047void PGARuntimeDataTableInit(envPtr)
1048RpOptimEnv *envPtr;
1049{   
1050        int i;
1051        if(envPtr != NULL){
1052                table.num_of_rows = (envPtr->numParams)+1;
1053                table.data = malloc((table.num_of_rows)*sizeof(double*));
1054                if(table.data == NULL){
1055                        panic("\nAllocation for Runtime Data Table failed\n");
1056                }
1057                for(i=0;i<table.num_of_rows;i++){
1058                        table.data[i] = malloc(PGAPACK_RUNTIME_TABLE_DEFAULT_SIZE*sizeof(double));
1059                        if(table.data[i] == NULL){
1060                                panic("\nAllocation for Runtime Data Table failed\n");
1061                        }                       
1062                }
1063                table.no_of_samples_evaled = 0;
1064                table.no_of_columns = PGAPACK_RUNTIME_TABLE_DEFAULT_SIZE;
1065               
1066        }else{
1067                panic("\nError: NULL Environment variable OR Table pointer passed to Data Table Init\n");
1068        }
1069}
1070
1071void PGARuntimeDataTableDeInit()
1072{       
1073        int i;
1074        if((&table) == NULL){
1075                panic("Error: Table not present, therefore cannot free memory..");
1076        }
1077        for(i=0;i<table.num_of_rows;i++){
1078                free(table.data[i]);
1079        }
1080        free(table.data);
1081}
1082
1083void PGARuntimeDataTableSetSampleValue(chrom,fitness)
1084RpOptimParam *chrom;
1085double fitness;
1086{
1087        int i;
1088        //printf("\nSetting sample value.......................\n");
1089        if(chrom!=NULL && (&table)!=NULL){
1090                (table.no_of_samples_evaled)+=1;
1091                if((table.no_of_samples_evaled) > table.no_of_columns){
1092                        /* then Reallocate space for more columns)*/
1093                        (table.no_of_columns)+=(table.no_of_columns);
1094                                //TODO GTG: Delete printing stuff
1095                        for(i=0;i<(table.num_of_rows);i++){
1096                                table.data[i] = realloc(table.data[i],table.no_of_columns);
1097                                if(table.data[i]==NULL){
1098                                        panic("\nError: Could not Reallocate more space for the table");
1099                                }                               
1100                        }
1101                }else{
1102                        if(chrom->type == RP_OPTIMPARAM_NUMBER){
1103                                for(i=0;i<(table.num_of_rows);i++){
1104                                        if(i==0){
1105                                                table.data[i][(table.no_of_samples_evaled)-1] = fitness;
1106                                                //printf("\nSample Number %d:- Fitness: %lf\t",table.no_of_samples_evaled,fitness);
1107                                        }else{
1108                                                table.data[i][(table.no_of_samples_evaled)-1] = chrom[i-1].value.dval;
1109                                                //printf("Param %d %lf\t",i,table.data[i][(table.no_of_samples_evaled)-1]);
1110                                        }
1111                }
1112                        }else{
1113                                panic("\n Chromosome value is RP_OPTIMPARAM_STRING\n");
1114                                //GTG TODO: find out what happens in this case. Will we be better off handling Tcl_objects?
1115                        }       
1116                }
1117        }else{
1118                panic("\nError:Either Chromosome, or table passed to PGARuntimeDataTableSetSampleValue() is NULL\n");
1119        }
1120       
1121}
1122
1123void GetSampleInformation(buffer,sampleNumber)
1124        char *buffer;
1125        int sampleNumber;
1126{
1127        int i;
1128        char tempBuff[50];
1129        printf("\nFetching sample information.........................\n");
1130        if((&table) == NULL){
1131                panic("Table uninitialized");
1132        }
1133        if(sampleNumber<=0){
1134                sprintf(buffer,"\nNumber of Samples Evaluated so far: %d\n",(table.no_of_samples_evaled)+1);
1135                return;
1136        }
1137        if(((table.num_of_rows)-1)*10>SINGLE_SAMPLE_DATA_BUFFER_DEFAULT_SIZE){
1138                buffer = realloc(buffer,50+25*(table.num_of_rows));
1139                //resizing the buffer, keeping 50 for display related jazz, around 12-15 characs for param names
1140                //and 10 characs for Fl.pt. display of the value
1141                if(buffer == NULL){
1142                        panic("\nError: Could not reallocate space for sample data buffer");
1143                }
1144        }
1145        for(i=0;i<(table.num_of_rows);i++){
1146                if(i==0){
1147                        sprintf(buffer,"\nSample Number %d ----> Fitness: %lf  ",sampleNumber,table.data[i][sampleNumber-1]);
1148                }else{
1149                        sprintf(tempBuff,"Param %d: %lf  ",i,table.data[i][sampleNumber-1]);
1150                        strcat(buffer,tempBuff);
1151                }
1152        }
1153        strcat(buffer,"\n");
1154}
Note: See TracBrowser for help on using the repository browser.