void PGASetUp()

in build/pga/source/create.c [382:779]


void PGASetUp ( PGAContext *ctx )
{
    /*  These are for temporary storage of datatype specific functions.
     *  They allow some (understatement of the yesr!!) cleaning of the
     *  code below.
     */
    void         (*CreateString)(PGAContext *, int, int, int);
    int          (*Mutation)(PGAContext *, int, int, double);
    void         (*Crossover)(PGAContext *, int, int, int, int, int, int);
    void         (*PrintString)(PGAContext *, FILE *, int, int);
    void         (*CopyString)(PGAContext *, int, int, int, int);
    int          (*Duplicate)(PGAContext *, int, int, int, int);
    void         (*InitString)(PGAContext *, int, int);
    MPI_Datatype (*BuildDatatype)(PGAContext *, int, int);
    int err=0, i;

    PGADebugEntered("PGASetUp");
    PGAFailIfSetUp("PGASetUp");

    ctx->sys.SetUpCalled = PGA_TRUE;

    if ( ctx->ga.datatype           == PGA_DATATYPE_BINARY   &&
         ctx->ga.tw                 == PGA_UNINITIALIZED_INT )
      PGAError( ctx,
               "PGASetUp: Binary: Total Words (ctx->ga.tw) == UNINITIALIZED?",
               PGA_FATAL, PGA_INT, (void *) &ctx->ga.tw );

    if ( ctx->ga.datatype           == PGA_DATATYPE_BINARY  &&
         ctx->ga.fw                 == PGA_UNINITIALIZED_INT )
      PGAError( ctx,
               "PGASetUp: Binary: Full Words (ctx->ga.fw) == UNINITIALIZED?",
               PGA_FATAL, PGA_INT,  (void *) &ctx->ga.fw );

    if ( ctx->ga.datatype           == PGA_DATATYPE_BINARY  &&
         ctx->ga.eb                 == PGA_UNINITIALIZED_INT )
      PGAError( ctx,
               "PGASetUp: Binary: Empty Bits (ctx->ga.eb) == UNINITIALIZED?",
               PGA_FATAL, PGA_INT, (void *) &ctx->ga.eb );

    if ( ctx->ga.PopSize            == PGA_UNINITIALIZED_INT)
      ctx->ga.PopSize                = 100;

    if ( ctx->ga.MaxIter            == PGA_UNINITIALIZED_INT)
         ctx->ga.MaxIter             = 1000;

    if ( ctx->ga.MaxNoChange        == PGA_UNINITIALIZED_INT)
         ctx->ga.MaxNoChange         = 100;

    if ( ctx->ga.MaxSimilarity      == PGA_UNINITIALIZED_INT)
         ctx->ga.MaxSimilarity       = 95;

    if ( ctx->ga.NumReplace         == PGA_UNINITIALIZED_INT)
         ctx->ga.NumReplace          = (int) ceil(ctx->ga.PopSize * 0.1);

    if ( ctx->ga.NumReplace          > ctx->ga.PopSize)
         PGAError(ctx, "PGASetUp: NumReplace > PopSize",
                  PGA_FATAL, PGA_VOID, NULL);

    if ( ctx->ga.CrossoverType      == PGA_UNINITIALIZED_INT)
         ctx->ga.CrossoverType       = PGA_CROSSOVER_TWOPT;

    if (ctx->ga.CrossoverType       == PGA_CROSSOVER_TWOPT &&
        ctx->ga.StringLen == 2)
         PGAError(ctx, "PGASetUp: Invalid Crossover type for string of length "
                  "2", PGA_FATAL, PGA_INT, (void *) &ctx->ga.CrossoverType);

    if ( ctx->ga.SelectType        == PGA_UNINITIALIZED_INT)
         ctx->ga.SelectType         = PGA_SELECT_TOURNAMENT;

    if ( ctx->ga.FitnessType       == PGA_UNINITIALIZED_INT)
         ctx->ga.FitnessType        = PGA_FITNESS_RAW;

    if ( ctx->ga.FitnessMinType    == PGA_UNINITIALIZED_INT)
         ctx->ga.FitnessMinType     = PGA_FITNESSMIN_CMAX;

    if ( ctx->ga.MutateOnlyNoCross == PGA_UNINITIALIZED_INT)
         ctx->ga.MutateOnlyNoCross  = PGA_TRUE;

    if ( ctx->ga.MutationProb      == PGA_UNINITIALIZED_DOUBLE)
         ctx->ga.MutationProb       = 1. / ctx->ga.StringLen;

    if ( ctx->ga.MutationType      == PGA_UNINITIALIZED_INT) {
        switch (ctx->ga.datatype) {
        case PGA_DATATYPE_BINARY:
        case PGA_DATATYPE_CHARACTER:
        case PGA_DATATYPE_USER:
             /* leave PGA_UNINITIALIZED_INT for these data types */
             break;
        case PGA_DATATYPE_REAL:
             ctx->ga.MutationType   = PGA_MUTATION_GAUSSIAN;
             break;
        case PGA_DATATYPE_INTEGER:
             switch (ctx->init.IntegerType) {
                 case PGA_UNINITIALIZED_INT:
                 case PGA_IINIT_PERMUTE:
                     ctx->ga.MutationType   = PGA_MUTATION_PERMUTE;
                     break;
                 case PGA_IINIT_RANGE:
                     ctx->ga.MutationType   = PGA_MUTATION_RANGE;
                     break;
             }
             break;
        default:
             PGAError( ctx, "PGASetup: Invalid value of ctx->ga.datatype:",
                       PGA_FATAL, PGA_INT, (void *) &(ctx->ga.datatype) );
         }
    }

    if (ctx->ga.MutateRealValue   == PGA_UNINITIALIZED_DOUBLE) {
        switch (ctx->ga.MutationType) {
        case PGA_MUTATION_GAUSSIAN:
            ctx->ga.MutateRealValue   = 0.1;
            break;
        case PGA_MUTATION_UNIFORM:
            ctx->ga.MutateRealValue   = 0.1;
            break;
        case PGA_MUTATION_CONSTANT:
            ctx->ga.MutateRealValue   = 0.01;
            break;
        case PGA_MUTATION_RANGE:
        default:
            ctx->ga.MutateRealValue   = 0.0;
        }
    }

    if ( ctx->ga.MutateIntegerValue == PGA_UNINITIALIZED_INT)
         ctx->ga.MutateIntegerValue  = 1;

    if ( ctx->ga.MutateBoundedFlag == PGA_UNINITIALIZED_INT)
         ctx->ga.MutateBoundedFlag  = PGA_FALSE;

    if ( ctx->ga.NoDuplicates      == PGA_UNINITIALIZED_INT)
         ctx->ga.NoDuplicates       = PGA_FALSE;

    if ( ctx->ga.NoDuplicates && ((ctx->ga.StoppingRule & PGA_STOP_TOOSIMILAR)
                                   == PGA_STOP_TOOSIMILAR))
         PGAError(ctx, "PGASetUp: No Duplicates inconsistent with Stopping "
                  "Rule:", PGA_FATAL, PGA_INT, (void *) &ctx->ga.StoppingRule);

    if ( ctx->ga.CrossoverProb     == PGA_UNINITIALIZED_DOUBLE)
         ctx->ga.CrossoverProb      = 0.85;

    if ( ctx->ga.UniformCrossProb  == PGA_UNINITIALIZED_DOUBLE)
         ctx->ga.UniformCrossProb   = 0.6;

    if ( ctx->ga.PTournamentProb   == PGA_UNINITIALIZED_DOUBLE)
         ctx->ga.PTournamentProb    = 0.6;

    if ( ctx->ga.FitnessRankMax    == PGA_UNINITIALIZED_DOUBLE)
         ctx->ga.FitnessRankMax     = 1.2;

    if ( ctx->ga.FitnessCmaxValue  == PGA_UNINITIALIZED_DOUBLE)
         ctx->ga.FitnessCmaxValue   = 1.01;

    if ( ctx->ga.PopReplace        == PGA_UNINITIALIZED_INT)
         ctx->ga.PopReplace         = PGA_POPREPL_BEST;

    if ( ctx->ga.restart           == PGA_UNINITIALIZED_INT)
         ctx->ga.restart            = PGA_FALSE;

    if ( ctx->ga.restartFreq       == PGA_UNINITIALIZED_INT)
         ctx->ga.restartFreq        = 50;

    if ( ctx->ga.restartAlleleProb == PGA_UNINITIALIZED_DOUBLE)
         ctx->ga.restartAlleleProb = 0.5;


/* ops */
    /*  If no user supplied "done" function, use the built in one.
     *  No need to check EndOfGen; they only get called if they
     *  are defined.
     */
    if (((void *)ctx->cops.StopCond == (void *)PGADone) ||
	((void *)ctx->fops.StopCond == (void *)PGADone))
	PGAError( ctx,
		 "PGASetUp: Using PGADone as the user stopping condition will"
		 " result in an infinite loop!", PGA_FATAL, PGA_VOID, NULL);

    switch (ctx->ga.datatype) {
    case PGA_DATATYPE_BINARY:
	CreateString  = PGABinaryCreateString;
	BuildDatatype = PGABinaryBuildDatatype;
	Mutation      = PGABinaryMutation;

        switch (ctx->ga.CrossoverType) {
	  case PGA_CROSSOVER_ONEPT:
	    Crossover  = PGABinaryOneptCrossover;
            break;
	  case PGA_CROSSOVER_TWOPT:
	    Crossover  = PGABinaryTwoptCrossover;
            break;
	  case PGA_CROSSOVER_UNIFORM:
	    Crossover  = PGABinaryUniformCrossover;
            break;
        }
	PrintString    = PGABinaryPrintString;
	CopyString     = PGABinaryCopyString;
	Duplicate      = PGABinaryDuplicate;
	InitString     = PGABinaryInitString;
        break;
      case PGA_DATATYPE_INTEGER:
        CreateString   = PGAIntegerCreateString;
        BuildDatatype  = PGAIntegerBuildDatatype;
        Mutation       = PGAIntegerMutation;
        switch (ctx->ga.CrossoverType) {
	  case PGA_CROSSOVER_ONEPT:
	    Crossover  = PGAIntegerOneptCrossover;
            break;
	  case PGA_CROSSOVER_TWOPT:
	    Crossover  = PGAIntegerTwoptCrossover;
            break;
	  case PGA_CROSSOVER_UNIFORM:
	    Crossover  = PGAIntegerUniformCrossover;
            break;
        }
	PrintString    = PGAIntegerPrintString;
	CopyString     = PGAIntegerCopyString;
	Duplicate      = PGAIntegerDuplicate;
	InitString     = PGAIntegerInitString;
        break;
      case PGA_DATATYPE_REAL:
	CreateString   = PGARealCreateString;
	BuildDatatype  = PGARealBuildDatatype;
	Mutation       = PGARealMutation;
        switch (ctx->ga.CrossoverType) {
	  case PGA_CROSSOVER_ONEPT:
	    Crossover  = PGARealOneptCrossover;
            break;
	  case PGA_CROSSOVER_TWOPT:
	    Crossover  = PGARealTwoptCrossover;
            break;
	  case PGA_CROSSOVER_UNIFORM:
	    Crossover  = PGARealUniformCrossover;
            break;
        }
	PrintString    = PGARealPrintString;
	CopyString     = PGARealCopyString;
	Duplicate      = PGARealDuplicate;
	InitString     = PGARealInitString;
        break;
      case PGA_DATATYPE_CHARACTER:
	CreateString   = PGACharacterCreateString;
	BuildDatatype  = PGACharacterBuildDatatype;
	Mutation       = PGACharacterMutation;
        switch (ctx->ga.CrossoverType) {
	  case PGA_CROSSOVER_ONEPT:
	    Crossover  = PGACharacterOneptCrossover;
            break;
	  case PGA_CROSSOVER_TWOPT:
	    Crossover  = PGACharacterTwoptCrossover;
            break;
	  case PGA_CROSSOVER_UNIFORM:
	    Crossover  = PGACharacterUniformCrossover;
            break;
	}
	PrintString    = PGACharacterPrintString;
	CopyString     = PGACharacterCopyString;
	Duplicate      = PGACharacterDuplicate;
	InitString     = PGACharacterInitString;
        break;
      case PGA_DATATYPE_USER:
        if (ctx->cops.CreateString == NULL)
            PGAError( ctx,
		     "PGASetUp: User datatype needs CreateString function:",
                     PGA_WARNING, PGA_INT, (void *) &err );
        if (ctx->cops.Mutation     == NULL)
            PGAError( ctx,
		     "PGASetUp: User datatype needs Mutation function:",
                     PGA_WARNING, PGA_INT, (void *) &err );
        if (ctx->cops.Crossover    == NULL)
            PGAError( ctx,
		     "PGASetUp: User datatype needs Crossover function:",
                     PGA_WARNING, PGA_INT, (void *) &err );
        if (ctx->cops.PrintString  == NULL)
            PGAError( ctx,
		     "PGASetUp: User datatype needs PrintString function:",
                     PGA_WARNING, PGA_INT, (void *) &err );
	if (ctx->cops.Duplicate    == NULL)
            PGAError( ctx,
		     "PGASetUp: User datatype needs Duplicate function:",
                     PGA_WARNING, PGA_INT, (void *) &err );
	if (ctx->cops.CopyString    == NULL)
            PGAError( ctx,
		     "PGASetUp: User datatype needs CopyString function:",
                     PGA_WARNING, PGA_INT, (void *) &err );
        if (ctx->cops.BuildDatatype == NULL)
             PGAError(ctx,
                      "PGASetUp: User datatype needs BuildDatatype "
                      "function:", PGA_FATAL, PGA_INT, (void *) &err );
        break;
    }
    if ((ctx->cops.Mutation     == NULL) && (ctx->fops.Mutation    == NULL))
	ctx->cops.Mutation      = Mutation;
    if ((ctx->cops.Crossover    == NULL) && (ctx->fops.Crossover   == NULL))
	ctx->cops.Crossover     = Crossover;
    if ((ctx->cops.PrintString  == NULL) && (ctx->fops.PrintString == NULL))
	ctx->cops.PrintString   = PrintString;
    if ((ctx->cops.Duplicate    == NULL) && (ctx->fops.Duplicate   == NULL))
	ctx->cops.Duplicate     = Duplicate;
    if ((ctx->cops.InitString   == NULL) && (ctx->fops.InitString  == NULL))
	ctx->cops.InitString    = InitString;
    if (ctx->cops.CreateString  == NULL) 
	ctx->cops.CreateString  = CreateString;
    if (ctx->cops.CopyString    == NULL)
	ctx->cops.CopyString    = CopyString;
    if (ctx->cops.BuildDatatype == NULL)
	ctx->cops.BuildDatatype = BuildDatatype;
    
/* par */
    if ( ctx->par.NumIslands       == PGA_UNINITIALIZED_INT)
         ctx->par.NumIslands        = 1;
    if ( ctx->par.NumDemes         == PGA_UNINITIALIZED_INT)
         ctx->par.NumDemes          = 1;
    if ( ctx->par.DefaultComm      == NULL )
         ctx->par.DefaultComm       = MPI_COMM_WORLD;

    

/* rep */
    if ( ctx->rep.PrintFreq == PGA_UNINITIALIZED_INT)
         ctx->rep.PrintFreq  = 10;

/* sys */
    /* no more sets necessary here. */

/* debug */

/* init */
    if ( ctx->init.RandomInit == PGA_UNINITIALIZED_INT)
         ctx->init.RandomInit  = PGA_TRUE;

    if ( ctx->init.BinaryProbability == PGA_UNINITIALIZED_DOUBLE)
         ctx->init.BinaryProbability  = 0.5;

    if ( ctx->init.RealType == PGA_UNINITIALIZED_INT)
         ctx->init.RealType  = PGA_RINIT_RANGE;
    if ( ctx->init.IntegerType == PGA_UNINITIALIZED_INT)
         ctx->init.IntegerType  = PGA_IINIT_PERMUTE;
    if ( ctx->init.CharacterType == PGA_UNINITIALIZED_INT)
         ctx->init.CharacterType = PGA_CINIT_LOWER;

    switch (ctx->ga.datatype)
    {
    case PGA_DATATYPE_INTEGER:
         for (i = 0; i < ctx->ga.StringLen; i++)
         {
              if (ctx->init.IntegerMin[i] == PGA_UNINITIALIZED_INT)
                   ctx->init.IntegerMin[i] = 0;
              if (ctx->init.IntegerMax[i] == PGA_UNINITIALIZED_INT)
                   ctx->init.IntegerMax[i] = ctx->ga.StringLen - 1;
         }
         break;
    case PGA_DATATYPE_REAL:
         for (i = 0; i < ctx->ga.StringLen; i++)
         {
              if (ctx->init.RealMin[i] == PGA_UNINITIALIZED_DOUBLE)
                   ctx->init.RealMin[i] = 0.;
              if (ctx->init.RealMax[i] == PGA_UNINITIALIZED_DOUBLE)
                   ctx->init.RealMax[i] = 1.;
         }
         break;
    }

    /* If a seed was not specified, get one from a time of day call */
    if ( ctx->init.RandomSeed == PGA_UNINITIALIZED_INT)
         ctx->init.RandomSeed = (int)time(NULL);

    /* seed random number generator with this process' unique seed */
    ctx->init.RandomSeed += PGAGetRank(ctx, MPI_COMM_WORLD);
    PGARandom01( ctx, ctx->init.RandomSeed );

    ctx->ga.selected        = (int *)malloc( sizeof(int) * ctx->ga.PopSize );
    if (ctx->ga.selected == NULL)
         PGAError(ctx, "PGASetUp: No room to allocate ctx->ga.selected",
                  PGA_FATAL, PGA_VOID, NULL);

    ctx->ga.sorted          = (int *)malloc( sizeof(int) * ctx->ga.PopSize );
    if (ctx->ga.sorted == NULL)
         PGAError(ctx, "PGASetUp: No room to allocate ctx->ga.sorted",
                  PGA_FATAL, PGA_VOID, NULL);

    ctx->scratch.intscratch = (int *)malloc( sizeof(int) * ctx->ga.PopSize );
    if (ctx->scratch.intscratch == NULL)
         PGAError(ctx, "PGASetUp: No room to allocate ctx->scratch.intscratch",
                  PGA_FATAL, PGA_VOID, NULL);

    ctx->scratch.dblscratch = (double *)malloc(sizeof(double) * ctx->ga.PopSize);
    if (ctx->scratch.dblscratch == NULL)
         PGAError(ctx, "PGASetUp: No room to allocate ctx->scratch.dblscratch",
                  PGA_FATAL, PGA_VOID, NULL);

    PGACreatePop ( ctx , PGA_OLDPOP );
    PGACreatePop ( ctx , PGA_NEWPOP );

    ctx->rep.starttime = time(NULL);

    PGADebugExited("PGASetUp");
}