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

Last change on this file since 1272 was 1271, checked in by liveletlive, 14 years ago

Changes made to API and pgapack for addition of new stoppage criteria. TIMEElapsed criteria is not yet added.

File size: 41.3 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) 2008  Purdue Research Foundation
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.