/******************************************************************************
*     FILE: report.c:
*
*     Authors: David M. Levine, Philip L. Hallstrom, David M. Noelle
******************************************************************************/
#include "pgapack.h"


/*U****************************************************************************
   PGAPrintPopulation - Calls PGAPrintIndividual to print each member of a
   population

   Category: Reporting

   Inputs:
      ctx - context variable
      fp  - file pointer to print the output to
      pop - symbolic constant of the population to be printed
      
   Outputs:
      The strings and associated fields that make up a population member

   Example:
      PGAContext *ctx;
      :
      PGAPrintPopulation(ctx, stdout, PGA_NEWPOP);

****************************************************************************U*/
void PGAPrintPopulation ( PGAContext *ctx, FILE *fp, int pop )
{
    int i;

    
    PGADebugPrint( ctx, PGADEBUG_ENTERED, "PGAPrintPopulation", "Entered", 
                   PGA_VOID, NULL );

    for ( i=0; i < ctx->ga.PopSize; i++ )
	 PGAPrintIndividual ( ctx, fp,  i, pop );
    fprintf(fp,"\n");

    PGADebugPrint( ctx, PGADEBUG_EXIT,    "PGAPrintPopulation", "Exit", 
                   PGA_VOID, NULL );
    return;
}

/*U****************************************************************************
   PGAPrintIndividual - prints the allele values of a string and associated
   fields (evaluation, fitness, etc.) of a string

   Category: Reporting

   Inputs:
      ctx - context variable
      fp  - file pointer to print the output to
      p   - string index
      pop - symbolic constant of the population string p is in
      
   Outputs:
      The allele values of string p and associated fields

   Example:
      PGAContext *ctx;
      int p;
      :
      PGAPrintIndividual(ctx, stdout, p, PGA_NEWPOP);

****************************************************************************U*/
void PGAPrintIndividual ( PGAContext *ctx, FILE *fp, int p, int pop )
{
    PGAIndividual *ind;

    PGADebugPrint( ctx, PGADEBUG_ENTERED, "PGAPrintIndividual", "Entered", 
                   PGA_VOID, NULL );
    
    ind = PGAGetIndividual ( ctx, p, pop );

    fprintf( fp,"%d  %e %e ", p, ind->evalfunc, ind->fitness);
    if ( ind->evaluptodate )
	fprintf( fp, "T\n" );
    else
	fprintf( fp, "F\n" );
    PGAWriteString ( ctx, fp, p, pop );

    PGADebugPrint( ctx, PGADEBUG_EXIT, "PGAPrintIndividual", "Exit", 
                   PGA_VOID, NULL );
    return;    
}

/*U****************************************************************************
   PGAPrintReport - prints genetic algorithm statistics.  The statistics
   that are printed are determined by PGASetPrintOptions

   Category: Reporting

   Inputs:
      ctx - context variable
      fp  - file pointer to print the output to
      pop - symbolic constant of the population whose statistics are printed
      
   Outputs:
      genetic algorithm statistics

   Example:
      PGAContext *ctx;
      int p;
      :
      PGAPrintIndividual(ctx, stdout, p, PGA_NEWPOP);

****************************************************************************U*/
void PGAPrintReport(PGAContext *ctx, FILE *fp, int pop)
{
     int p, best_p;
     double e, best_e;

     if (ctx->ga.iter == 1)
	  fprintf (fp, "Iter #     Field      Value\n");

     best_p = PGAGetBest(ctx, pop);
     best_e = PGAGetEvaluate(ctx, best_p, pop);
     if (!(ctx->ga.iter % ctx->rep.PrintFreq) || ctx->ga.iter == 1)
     {
	  fprintf(fp, "%-11dBest       %e\n", PGAGetIter(ctx), best_e);
	  if ((ctx->rep.PrintOptions & PGA_WORST) == PGA_WORST)
	  {
	       p = PGAGetWorst(ctx, pop);
	       e = PGAGetEvaluate(ctx, p, pop);
	       fprintf(fp, "           Worst      %e\n", e);
	  }
	  if ((ctx->rep.PrintOptions & PGA_OFFLINE) == PGA_OFFLINE)
	       fprintf(fp, "           Offline    %e\n", ctx->rep.Offline);
	  
	  if ((ctx->rep.PrintOptions & PGA_ONLINE) == PGA_ONLINE)
	       fprintf(fp, "           Online     %e\n", ctx->rep.Online);
	  
	  if((ctx->rep.PrintOptions & PGA_HAMMING) == PGA_HAMMING)
	       fprintf(fp, "           Hamming    %e\n",
		       PGAHammingDistance(ctx, pop));
	  if ((ctx->rep.PrintOptions & PGA_STRING) == PGA_STRING)
	       PGAWriteString(ctx, fp, best_p, pop);
     }
     if (ctx->ga.iter > ctx->ga.MaxIter)
     {
	  fprintf(fp, "The Best Evaluation: %e.\n", best_e);
	  fprintf(fp, "The Best String:\n");
	  PGAWriteString(ctx, fp, best_p, pop);
     }
}

/*U****************************************************************************
   PGAPrintContext - prints the value of all the fields in the context
   variable.

   Category: Reporting

   Inputs:
      ctx - context variable
      fp  - file pointer to print the output to
      
   Outputs:
      The value of all the fields in the context variable

   Example:
      PGAContext *ctx;
      int p;
      :
      PGAPrintIndividual(ctx, stdout, p, PGA_NEWPOP);
      PGAPrintContext(ctx,stdout);

****************************************************************************U*/
void PGAPrintContext ( PGAContext *ctx, FILE *fp )
{

    PGADebugPrint( ctx, PGADEBUG_ENTERED, "PGAPrintContext", "Entered", 
                   PGA_VOID, NULL );
    
    fprintf( fp,"\n-------------- Start Context Variable --------------\n");

    fprintf( fp,"Algorithm\n");
  
    fprintf( fp,"    Data type                 : ");
    switch(ctx->ga.datatype) {
      case PGA_DATATYPE_BINARY:
        fprintf( fp,"Bit\n");
        fprintf( fp,"    Bit Type Total Words      : ");
        switch(ctx->ga.tw) {
          case PGA_UNINITIALIZED_INT:
            fprintf( fp,"*UNINITIALIZED*\n");
            break;
          default:
            fprintf( fp,"%d\n",ctx->ga.tw);
            break;
        };
        fprintf( fp,"    Bit Type Full Words       : ");
        switch(ctx->ga.fw) {
          case PGA_UNINITIALIZED_INT:
            fprintf( fp,"*UNINITIALIZED*\n");
            break;
          default:
            fprintf( fp,"%d\n",ctx->ga.fw);
            break;
        };
        fprintf( fp,"    Bit Type Extra Bits       : ");
        switch(ctx->ga.eb) {
          case PGA_UNINITIALIZED_INT:
            fprintf( fp,"*UNINITIALIZED*\n");
            break;
          default:
            fprintf( fp,"%d\n",ctx->ga.eb);
            break;
        };
        break;
      case PGA_DATATYPE_INTEGER:
        fprintf( fp,"Integer\n");
        break;
      case PGA_DATATYPE_REAL:
        fprintf( fp,"Real\n");
        break;
      case PGA_DATATYPE_USER:
        fprintf( fp,"User Defined\n");
        break;
      case PGA_UNINITIALIZED_INT:
        fprintf( fp,"?UNINITIALIZED?\n");
        break;
      default:
        fprintf( fp,"!ERROR!  =(%d)?\n", ctx->ga.datatype);
        break;
    };
    
    fprintf( fp,"    Optimization Direction    : ");
    switch(ctx->ga.optdir) {
      case PGA_MAXIMIZE:
        fprintf( fp,"Maximize\n");
        break;
      case PGA_MINIMIZE:
        fprintf( fp,"Minimize\n");
        break;
      case PGA_UNINITIALIZED_INT:
        fprintf( fp,"?UNINITIALIZED?\n");
        break;
      default:
        fprintf( fp,"!ERROR!  =(%d)?\n", ctx->ga.optdir);
        break;
    };

    fprintf( fp,"    Total Population Size     : ");
    switch(ctx->ga.PopSize) {
      case PGA_UNINITIALIZED_INT:
        fprintf( fp,"*UNINITIALIZED*\n");
        break;
      default:
        fprintf( fp,"%d\n",ctx->ga.PopSize);
        break;
    };
    
    fprintf( fp,"    String Length             : ");
    switch(ctx->ga.StringLen) {
      case PGA_UNINITIALIZED_INT:
        fprintf( fp,"?UNINITIALIZED?\n");
        break;
      default:
        fprintf( fp,"%d\n",ctx->ga.StringLen);
        break;
    };
    
    fprintf( fp,"    Stopping Rule             :\n");
    if ((ctx->ga.StoppingRule & PGA_STOP_MAXITER) == PGA_STOP_MAXITER)
	 fprintf(fp, "%50s", "Maximum iterations\n");
    if ((ctx->ga.StoppingRule & PGA_STOP_NOCHANGE) == PGA_STOP_NOCHANGE)
	 fprintf(fp, "%49s", "No change in best\n");
    if ((ctx->ga.StoppingRule & PGA_STOP_TOOSIMILAR) == PGA_STOP_TOOSIMILAR)
	 fprintf(fp, "%54s", "Population Homogeneity\n");
    if (ctx->ga.StoppingRule == PGA_UNINITIALIZED_INT)
	 fprintf(fp, "%47s", "*UNINITIALIZED*\n");
    
    fprintf( fp,"    Maximum Iterations        : ");
    switch(ctx->ga.MaxIter) {
      case PGA_UNINITIALIZED_INT:
        fprintf( fp,"*UNINITIALIZED*\n");
        break;
      default:
        fprintf( fp,"%d\n",ctx->ga.MaxIter);
        break;
    };

    fprintf(fp, "    Max Iters With No Change  : ");
    switch(ctx->ga.MaxNoChange)
    {
    case PGA_UNINITIALIZED_INT:
	 fprintf(fp, "*UNINITIALIZED*\n");
	 break;
    default:
	 fprintf(fp, "%d\n", ctx->ga.MaxNoChange);
	 break;
    }
    
    fprintf(fp, "    Max Percent of Similarity : ");
    switch(ctx->ga.MaxSimilarity)
    {
    case PGA_UNINITIALIZED_INT:
	 fprintf(fp, "*UNINITIALIZED*\n");
	 break;
    default:
	 fprintf(fp, "%d\n", ctx->ga.MaxSimilarity);
	 break;
    }
    
    fprintf( fp,"    Pop. Replacement Frequency: ");
    switch(ctx->ga.NumReplace) {
      case PGA_UNINITIALIZED_INT:
        fprintf( fp,"*UNINITIALIZED*\n");
        break;
      default:
        fprintf( fp,"%d\n",ctx->ga.NumReplace);
        break;
    };
    
    fprintf( fp,"    Crossover Type            : ");
    switch(ctx->ga.CrossoverType) {
      case PGA_CROSSOVER_ONEPT:
        fprintf( fp,"One Point\n");
        break;
      case PGA_CROSSOVER_TWOPT:
        fprintf( fp,"Two Point\n");
        break;
      case PGA_CROSSOVER_UNIFORM:
        fprintf( fp,"Uniform\n");
        break;
      case PGA_UNINITIALIZED_INT:
        fprintf( fp,"*UNINITIALIZED*\n");
        break;
      default:
        fprintf( fp,"!ERROR!  =(%d)?\n", ctx->ga.CrossoverType);
        break;
    };
      
    fprintf( fp,"    Selection Method          : ");
    switch(ctx->ga.SelectType) {
      case PGA_SELECT_PROPORTIONAL:
        fprintf( fp,"Proportional\n");
        break;
      case PGA_SELECT_SUS:
        fprintf( fp,"Stochastic Universal\n");
        break;
      case PGA_SELECT_TOURNAMENT:
        fprintf( fp,"Binary Tournament\n");
        break;
      case PGA_SELECT_PTOURNAMENT:
        fprintf( fp,"Probabilistic Binary Tournament\n");
        break;
      case PGA_UNINITIALIZED_INT:
        fprintf( fp,"*UNINITIALIZED*\n");
        break;
      default:
        fprintf( fp,"!ERROR!  =(%d)?\n", ctx->ga.SelectType);
        break;
    };
    
    fprintf( fp,"    Fitness Type              : ");
    switch(ctx->ga.FitnessType) {
      case PGA_FITNESS_RAW:
        fprintf( fp,"Raw\n");
        break;
      case PGA_FITNESS_NORMAL:
        fprintf( fp,"Linear Normalization\n");
        break;
      case PGA_FITNESS_RANKING:
        fprintf( fp,"Linear Ranking\n");
        break;
      case PGA_UNINITIALIZED_INT:
        fprintf( fp,"*UNINITIALIZED*\n");
        break;
      default:
        fprintf( fp,"!ERROR!  =(%d)?\n", ctx->ga.FitnessType);
        break;
    };

    if ( ctx->ga.optdir == PGA_MINIMIZE ) {
        fprintf( fp,"    Fitness Type(Minimization): ");
        switch(ctx->ga.FitnessMinType) {
          case PGA_FITNESSMIN_RECIPROCAL:
            fprintf( fp,"Reciprocal\n");
            break;
          case PGA_FITNESSMIN_CMAX:
            fprintf( fp,"CMax\n");
            break;
          case PGA_UNINITIALIZED_INT:
            fprintf( fp,"*UNINITIALIZED*\n");
            break;
          default:
            fprintf( fp,"!ERROR!  =(%d)?\n", ctx->ga.FitnessMinType);
            break;
        };
    }
    
    fprintf( fp,"    Mutation Type             : ");
    switch(ctx->ga.MutationType) {
      case PGA_MUTATION_FIXED:
        fprintf( fp,"Fixed\n");
        break;
      case PGA_MUTATION_STRINGLEN:
        fprintf( fp,"1/StringLength\n");
        break;
      case PGA_MUTATION_HAMMING:
        fprintf( fp,"Hamming\n");
        break;
      case PGA_UNINITIALIZED_INT:
        fprintf( fp,"*UNINITIALIZED*\n");
        break;
      default:
        fprintf( fp,"!ERROR!  =(%d)?\n", ctx->ga.MutationType);
        break;
    };
    
    fprintf( fp,"    Mutate Only Non-Crossover : ");
    switch(ctx->ga.MutateOnlyNoCross) {
      case PGATRUE:
        fprintf( fp,"On\n");
        break;
      case PGAFALSE:
        fprintf( fp,"Off\n");
        break;
      case PGA_UNINITIALIZED_INT:
        fprintf( fp,"*UNINITIALIZED*\n");
        break;
      default:
        fprintf( fp,"!ERROR!  =(%d)?\n", ctx->ga.MutateOnlyNoCross);
        break;
    };
    
    fprintf( fp,"    Mutate Duplicates         : ");
    switch(ctx->ga.NoDuplicates) {
      case PGATRUE:
        fprintf( fp,"On\n");
        break;
      case PGAFALSE:
        fprintf( fp,"Off\n");
        break;
      case PGA_UNINITIALIZED_INT:
        fprintf( fp,"*UNINITIALIZED*\n");
        break;
      default:
        fprintf( fp,"!ERROR!  =(%d)?\n", ctx->ga.NoDuplicates);
        break;
    };
    
    fprintf( fp,"    Mutation Probability      : ");
    if (ctx->ga.MutationProb == PGA_UNINITIALIZED_DOUBLE)
        fprintf( fp,"*UNINITIALIZED*\n");
    else
        fprintf( fp,"%f\n",ctx->ga.MutationProb);
  
    fprintf( fp,"    Mutation Real Value      : ");
    if (ctx->ga.MutationProb == PGA_UNINITIALIZED_DOUBLE)
        fprintf( fp,"*UNINITIALIZED*\n");
    else
        fprintf( fp,"%f\n",ctx->ga.MutateRealVal);
  
    fprintf( fp,"    Crossover Probability     : ");
    if (ctx->ga.CrossoverProb == PGA_UNINITIALIZED_DOUBLE)
        fprintf( fp,"*UNINITIALIZED*\n");
    else
        fprintf( fp,"%f\n",ctx->ga.CrossoverProb);
  
    fprintf( fp,"    Uniform Cross Bit Prob.   : ");
    if (ctx->ga.UniformCrossProb == PGA_UNINITIALIZED_DOUBLE)
        fprintf( fp,"*UNINITIALIZED*\n");
    else
        fprintf( fp,"%f\n",ctx->ga.UniformCrossProb);
  
    fprintf( fp,"    Fitness Ranking Maximum   : ");
    if (ctx->ga.FitnessRankMax == PGA_UNINITIALIZED_DOUBLE)
        fprintf( fp,"*UNINITIALIZED*\n");
    else
        fprintf( fp,"%f\n",ctx->ga.FitnessRankMax);
  
    fprintf( fp,"    Copy to Next Population   : ");
    switch(ctx->ga.PopReplace) {
      case PGA_POPREPL_BEST:
        fprintf( fp,"Best\n");
        break;
      case PGA_POPREPL_RANDOM_NOREP:
        fprintf( fp,"Random without replacement\n");
        break;
      case PGA_POPREPL_RANDOM_REP:
        fprintf( fp,"Random with replacement\n");
        break;
      case PGA_UNINITIALIZED_INT:
        fprintf( fp,"*UNINITIALIZED*\n");
        break;
      default:
        fprintf( fp,"!ERROR!  =(%d)?\n", ctx->ga.PopReplace);
        break;
    };
    
    fprintf( fp,"    Generation Count (iter)   : ");
    switch(ctx->ga.iter) {
      case PGA_UNINITIALIZED_INT:
        fprintf( fp,"?UNINITIALIZED?\n");
        break;
      default:
        fprintf( fp,"%d\n",ctx->ga.iter);
        break;
    };

    fprintf(fp, "    Num Iters With No Change  : ");
    switch(ctx->ga.ItersOfSame)
    {
    case PGA_UNINITIALIZED_INT:
	 fprintf(fp, "?UNINITIALIZED?\n");
	 break;
    default:
	 fprintf(fp, "%d\n", ctx->ga.ItersOfSame);
	 break;
    }
    
    fprintf(fp, "    Percent Similarity In Pop : ");
    switch(ctx->ga.PercentSame)
    {
    case PGA_UNINITIALIZED_INT:
	 fprintf(fp, "?UNINITIALZED?\n");
	 break;
    default:
	 fprintf(fp, "%d\n", ctx->ga.PercentSame);
	 break;
    }
    
    fprintf( fp,"    Selection Index           : ");
    switch(ctx->ga.SelectIndex) {
      case PGA_UNINITIALIZED_INT:
        fprintf( fp,"?UNINITIALIZED?\n");
        break;
      default:
        fprintf( fp,"%d\n",ctx->ga.SelectIndex);
        break;
    };

/* ops */
    fprintf( fp,"Operations\n");

    fprintf( fp,"    CreateString function : ");
    if (ctx->ops.CreateString == NULL)
        fprintf( fp,"NULL\n");
    else if (ctx->ops.CreateString == PGABinaryCreateString)
	fprintf( fp,"PGABinaryCreateString\n");
    else if (ctx->ops.CreateString == PGAIntegerCreateString)
	fprintf( fp,"PGAIntegerCreateString\n");
    else if (ctx->ops.CreateString == PGARealCreateString)
	fprintf( fp,"PGARealCreateString\n");
    else
        fprintf( fp,"%p\n",ctx->ops.CreateString);

    fprintf( fp,"    Mutation function         : ");
    if (ctx->ops.Mutation == NULL)
        fprintf( fp,"NULL\n");
    else if (ctx->ops.Mutation == PGABinaryMutation)
	fprintf( fp,"PGABinaryMutation\n");
    else if (ctx->ops.Mutation == PGAIntegerMutation)
	fprintf( fp,"PGAIntegerMutation\n");
    else if (ctx->ops.Mutation == PGARealMutation)
	fprintf( fp,"PGRealMutation\n");
    else
        fprintf( fp,"%p\n",ctx->ops.Mutation);

    fprintf( fp,"    Crossover function        : ");
    if (ctx->ops.Crossover == NULL)
        fprintf( fp,"NULL\n");
    else if (ctx->ops.Crossover == PGABinaryOneptCrossover)
	fprintf( fp,"PGABinaryOneptCrossover\n");
    else if (ctx->ops.Crossover == PGAIntegerOneptCrossover)
	fprintf( fp,"PGAIntegerOneptCrossover\n");
    else if (ctx->ops.Crossover == PGARealOneptCrossover)
	fprintf( fp,"PGRealOneptCrossover\n");
    else if (ctx->ops.Crossover == PGABinaryTwoptCrossover)
	fprintf( fp,"PGABinaryTwoptCrossover\n");
    else if (ctx->ops.Crossover == PGAIntegerTwoptCrossover)
	fprintf( fp,"PGAIntegerTwoptCrossover\n");
    else if (ctx->ops.Crossover == PGARealTwoptCrossover)
	fprintf( fp,"PGRealTwoptCrossover\n");
    else if (ctx->ops.Crossover == PGABinaryUniformCrossover)
	fprintf( fp,"PGABinarytUniformCrossover\n");
    else if (ctx->ops.Crossover == PGAIntegerUniformCrossover)
	fprintf( fp,"PGAIntegerUniformCrossover\n");
    else if (ctx->ops.Crossover == PGARealUniformCrossover)
	fprintf( fp,"PGRealUniformCrossover\n");
    else
        fprintf( fp,"%p\n",ctx->ops.Crossover);

    fprintf( fp,"    WriteString function  : ");
    if (ctx->ops.WriteString == NULL)
        fprintf( fp,"NULL\n");
    else if (ctx->ops.WriteString == PGABinaryWriteString)
	fprintf( fp,"PGABinaryWriteString\n");
    else if (ctx->ops.WriteString == PGAIntegerWriteString)
	fprintf( fp,"PGAIntegerWriteString\n");
    else if (ctx->ops.WriteString == PGARealWriteString)
	fprintf( fp,"PGRealWriteString\n");
    else
        fprintf( fp,"%p\n",ctx->ops.WriteString);

    fprintf( fp,"    CopyString function   : ");
    if (ctx->ops.CopyString == NULL)
        fprintf( fp,"NULL\n");
    else if (ctx->ops.CopyString == PGABinaryCopyString)
	fprintf( fp,"PGABinaryCopyString\n");
    else if (ctx->ops.CopyString == PGAIntegerCopyString)
	fprintf( fp,"PGAIntegerCopyString\n");
    else if (ctx->ops.CopyString == PGARealCopyString)
	fprintf( fp,"PGRealCopyString\n");
    else
        fprintf( fp,"%p\n",ctx->ops.CopyString);

    fprintf( fp,"    Duplicate function        : ");
    if (ctx->ops.Duplicate == NULL)
        fprintf( fp,"NULL\n");
    else if (ctx->ops.Duplicate == PGABinaryDuplicate)
	fprintf( fp,"PGABinaryDuplicate\n");
/*    else if (ctx->ops.Duplicate == PGAIntegerDuplicate)
	fprintf( fp,"PGAIntegerDuplicate\n");
    else if (ctx->ops.Duplicate == PGARealDuplicate)
	fprintf( fp,"PGRealDuplicate\n"); */
    else
        fprintf( fp,"%p\n",ctx->ops.Duplicate);

    
    fprintf( fp,"Report\n");
  
    fprintf( fp,"    Report Frequency          : ");
    switch(ctx->rep.PrintFreq) {
      case PGA_UNINITIALIZED_INT:
        fprintf( fp,"*UNINITIALIZED*\n");
        break;
      default:
        fprintf( fp,"%d\n",ctx->rep.PrintFreq);
        break;
   };
    
  
    fprintf( fp,"System\n");
  
    fprintf( fp,"    Maximum Integer           : ");
    switch(ctx->sys.PGAMaxInt) {
      case PGA_UNINITIALIZED_INT:
        fprintf( fp,"*UNINITIALIZED*\n");
        break;
      default:
        fprintf( fp,"%d\n",ctx->sys.PGAMaxInt);
        break;
    };
    
    fprintf( fp,"    Minimum Integer           : ");
    switch(ctx->sys.PGAMinInt) {
      case PGA_UNINITIALIZED_INT:
        fprintf( fp,"*UNINITIALIZED*\n");
        break;
      default:
        fprintf( fp,"%d\n",ctx->sys.PGAMinInt);
        break;
    };
    
    fprintf( fp,"    Maximum Double            : ");
    if (ctx->sys.PGAMaxDouble == PGA_UNINITIALIZED_DOUBLE)
        fprintf( fp,"*UNINITIALIZED*\n");
    else
        fprintf( fp,"%e\n",ctx->sys.PGAMaxDouble);
        /*fprintf( fp,"%f\n",ctx->sys.PGAMaxDouble);*/
  
    fprintf( fp,"    Minimum Double            : ");
    if (ctx->sys.PGAMinDouble == PGA_UNINITIALIZED_DOUBLE)
        fprintf( fp,"*UNINITIALIZED*\n");
    else
        fprintf( fp,"%e\n",ctx->sys.PGAMinDouble);
        /*fprintf( fp,"%lf\n",ctx->sys.PGAMinDouble);*/
  
  
/*    fprintf( fp,"Debug\n");
    for ( i=0; i<PGADEBUG_NUMFLAGS+1; i++  ) {
        fprintf( fp,"    DebugFlags[%d]             : ",i);
        switch(ctx->debug.PGADebugFlags[i]) {
          case PGA_UNINITIALIZED_INT:
            fprintf( fp,"*UNINITIALIZED*\n");
            break;
          default:
            fprintf( fp,"%d\n",ctx->debug.PGADebugFlags[i]);
            break;
        };
    } */
    
  
    fprintf( fp,"Initialization\n");
  
    fprintf( fp,"    Use Random Initialization : ");
    switch(ctx->init.RandomInit) {
      case PGATRUE:
        fprintf( fp,"On\n");
        break;
      case PGAFALSE:
        fprintf( fp,"Off\n");
        break;
      case PGA_UNINITIALIZED_INT:
        fprintf( fp,"*UNINITIALIZED*\n");
        break;
      default:
        fprintf( fp,"!ERROR!  =(%d)?\n", ctx->init.RandomInit);
        break;
    };
    
    fprintf( fp,"    Init Bit Probability      : ");
    if (ctx->init.BinaryProbability == PGA_UNINITIALIZED_DOUBLE)
        fprintf( fp,"*UNINITIALIZED*\n");
    else
        fprintf( fp,"%f\n",ctx->init.BinaryProbability);

    if ( ctx->ga.datatype == PGA_DATATYPE_INTEGER ) {
        
        fprintf( fp,"    Integer: Method            : ");
        switch(ctx->init.IntegerType) {
          case PGA_RANGE:
            fprintf( fp,"Range (uniform random)\n");
            break;
          case PGA_PERMUTE:
            fprintf( fp,"Permutation (ordering)\n");
            break;
          case PGA_UNINITIALIZED_INT:
            fprintf( fp,"*UNINITIALIZED*\n");
            break;
          default:
            fprintf( fp,"!ERROR!  =(%d)?\n", ctx->init.IntegerType);
            break;
        };
    }    
    fprintf( fp,"    Random Number Seed        : ");
    switch(ctx->init.RandomSeed) {
      case PGA_UNINITIALIZED_INT:
        fprintf( fp,"*UNINITIALIZED*\n");
        break;
      default:
        fprintf( fp,"%d\n", ctx->init.RandomSeed);
        break;
    };

    fprintf( fp,"\n-------------- End   Context Variable --------------\n");
}
