/*************************************************************************/ /* */ /* Copyright 2003, Living Circuit LLC. */ /* */ /* For academic use with the following condition: */ /* */ /* Material is provided "as is" and "as available", without any */ /* warranty, and if you use it you do it at your own risk, with no */ /* support agreement expressed or implied. */ /* */ /* Any other use of this software is contingent on having a valid and */ /* signed license agreement with Living Circuit (livingCircuit.com) */ /* */ /* All other rights reserved. */ /* */ /*************************************************************************/ /********************************************/ /********************************************/ /** **/ /** **/ /** "synth_pop.c" reads does a long- **/ /** term population simulation based **/ /** on relative fitnesses and **/ /** mutation probabilities. **/ /** **/ /** Written by Michael Molla **/ /** September, 2003 **/ /** **/ /** **/ /** **/ /*******************************************/ /*******************************************/ #include #include #include //#include #include "synth_pop.h" #define VERSION "110303" // This is the function that decodes the fittness file double fitness_codes(char code, double s, float t) { double to_return = 1.0; // If you want to define a fittness function, add it here as another case switch(code) { case(0): to_return = 0.0; break; case(1): to_return = 1.0; break; case(2): to_return = 1.0 + ((t-s)/2.0); break; case(3): to_return = 1.0 + ((3.0 * t)/4.0); break; case(4): to_return = 1.0 + t; break; case(5): to_return = 1.0 + t/2.0; break; case(6): to_return = 1.0 + t/4.0; break; case(7): to_return = 1.0 - s; break; case(8): to_return = 1.0 - s/2; break; default: printf("Unknown code [%d].\n",code); } return to_return; } main(int argc, char **argv) { FILE *fitness_functions; // <- to input the fitnesses char fitness_fname[MAX_FNAME]; // <- to input the fitnesses FILE *output_file; // <- to output the results char output_fname[MAX_FNAME]; // <- to output the results FILE *param_file; // <- to output the params char param_fname[MAX_FNAME]; // <- to output the params double fitnesses[NUM_GENOTYPES]; // <- remember the fitnesses char input_buffer[MAX_LINE]; // <- for reading the fitness file char *cur_token; // <- the file is tokenized char cur_col_num, fitness_col_num; // <- which in the fitness file float s,k; // some utlilty vars long x, i, j, num_organisms; // double cur_rand, cur_rand_for_one, cur_rand_for_two; // For picking random numbers int rand_seed; // int m, n, array_position, cur_genotype, cur_int; // more utlity vars char a[2], b[2]; // For holding a "genome" double mutations[2][3]; // For holding the mutation probs // For holding the gernations while we mutate them int prev_generation[NUM_GENOTYPES], cur_generation[NUM_GENOTYPES]; float cur_fittness; // <- current fittness long generation_size; // Checkpointing variables int new_n = -1, old_n; char tmp_fname[MAX_FNAME]; FILE *tmp_file; int result, num_tokens_read; char cur_buffer[MAX_LINE]; // <- for reading the progress file char tmp_buffer[MAX_LINE]; // <- for reading the progress file char prev_buffer[MAX_LINE]; // <- for reading the progress file // In case we crash, make sure we even got started printf("Called [%s] version %s\nrand_max=[%ld].\n",argv[0],VERSION,RAND_MAX); if((argc==2) || (argc==3)) // <- no longer allow a new "n" on the command line { // We need to find m, s, k, n, a12, a13, a23, b12, b13, b23 and the fitnesses strcpy(output_fname, argv[1]); if(!(output_file = fopen(output_fname, "r+"))) { printf("Could not open output file [%s] to read and modify.\n", output_fname); exit(1); } strcpy(param_fname, output_fname); strcat(param_fname, PARAM_FILE_SUFFIX); if(!(param_file = fopen(param_fname, "r"))) { printf("Could not open param file [%s] to read.\n", param_fname); exit(1); } if(argc>2) { new_n = atoi(argv[2]); printf("New n is [%d].\n",new_n); } // Read each line, but rmember the previous one // in case the last one is not complete result = (int)fgets(prev_buffer,MAX_LINE,output_file); if(!result) { printf("You have to reenter the parameters. We can't checkpoint because we've failed to read even one line of [%s].\n", output_fname); exit(1); } result = (int)fgets(cur_buffer,MAX_LINE,output_file); while(result) { strcpy(tmp_buffer, cur_buffer); result = (int)fgets(cur_buffer,MAX_LINE,output_file); if(result) { strcpy(prev_buffer, tmp_buffer); } } m = atoi((char *)strtok(cur_buffer, "\t")); printf("m (where we left off) is [%d].\n", m);fflush(NULL); for(num_tokens_read=0;num_tokens_read\t%f\n",i,fitnesses[i]); } fclose(tmp_file); } else { printf("Could not open [%s] to write.\n",tmp_fname); } } // The last line in the file could be chopped. fprintf(output_file,"\n"); fprintf(output_file,"%d",m);fflush(NULL); for(i=0;i 2)(x10^10)> 3)(x10^10)> 3)(x10^10)> 2)(x10^10)> 3)(x10^10)> 3)(x10^10)> [random seed]\n or %s [new n]\n",argv[0],argv[0]); exit(1); } // What's the fittness file? strcpy(fitness_fname, argv[1]); if(!(fitness_functions = fopen(fitness_fname, "r"))) { printf("Could not open fitness file [%s] to read.\n", fitness_fname); exit(1); } strcpy(output_fname, argv[13]); if(!(output_file = fopen(output_fname, "w"))) { printf("Could not open output file [%s] to write.\n", output_fname); exit(1); } strcpy(param_fname, output_fname); strcat(param_fname, PARAM_FILE_SUFFIX); if(!(param_file = fopen(param_fname, "w"))) { printf("Could not open param file [%s] to write.\n", param_fname); exit(1); } // Grab the rest of the params s = (float)(atoi(argv[3]))/100.0; k = (float)(atoi(argv[4]))/100.0; n = atoi(argv[5]); generation_size = atoi(argv[6]); mutations[A_MUTATION_RATE][ONE_TO_TWO] = (double)(atoi(argv[7]))/10000000000.0; mutations[A_MUTATION_RATE][TWO_TO_THREE] = (double)(atoi(argv[8]))/10000000000.0; mutations[A_MUTATION_RATE][ONE_TO_THREE] = (double)(atoi(argv[9]))/10000000000.0; mutations[B_MUTATION_RATE][ONE_TO_TWO] = (double)(atoi(argv[10]))/10000000000.0; mutations[B_MUTATION_RATE][TWO_TO_THREE] = (double)(atoi(argv[11]))/10000000000.0; mutations[B_MUTATION_RATE][ONE_TO_THREE] = (double)(atoi(argv[12]))/10000000000.0; if(argc>14)rand_seed = atoi(argv[14]); else rand_seed = DEFAULT_SEED; // Print out what we got for future reference fprintf(param_file, "s = [%f], k = [%f], n = [%d] gerneration_size=[%ld].\n",s,k,n,generation_size); for(i=0;i\t%f\n",i,fitnesses[i]); } fclose(param_file); // Initailize the 0th generation prev_generation[0] = generation_size; for(i=1;i= 0.0) || (cur_rand_for_two >= 0.0));j++) { // From which genotype to we pick? if((cur_rand_for_one >= 0.0) && (cur_rand_for_one < (((float)(prev_generation[j]))/((float)num_organisms)))) { // Do we grab the a1 or a2 from this one? // flip a coin (this is a bug fix (9/03/03). if(rand()/((double)RAND_MAX) < 0.5) { cur_genotype += (j%3); } else { cur_genotype += ((j/3)%3); } // Do we grab the b1 or b2 from this one? // flip a coin (this is a bug fix (9/03/03). if(rand()/((double)RAND_MAX) < 0.5) { cur_genotype += ((j/9)%3) * 9; } else { cur_genotype += (j/27) * 9; } } cur_rand_for_one -= (((float)(prev_generation[j]))/((float)num_organisms)); // From which genotype to we pick? if((cur_rand_for_two >= 0.0) && (cur_rand_for_two < (((float)(prev_generation[j]))/((float)num_organisms)))) { // Do we grab the a1 or a2 from this one? // flip a coin (this is a bug fix (9/03/03). if(rand()/((double)RAND_MAX) < 0.5) { cur_genotype += (j%3) * 3; } else { cur_genotype += ((j/3)%3) * 3; } // Do we grab the b1 or b2 from this one? // flip a coin (this is a bug fix (9/03/03). if(rand()/((double)RAND_MAX) < 0.5) { cur_genotype += ((j/9)%3) * 27; } else { cur_genotype += (j/27) * 27; } } cur_rand_for_two -= (((float)(prev_generation[j]))/((float)num_organisms)); } cur_generation[cur_genotype]++; } // Make the output (once for every "OUTPUT PERIOD") if(!(m%OUTPUT_PERIOD)) { printf(".");fflush(NULL); fprintf(output_file,"%d",m);fflush(NULL); for(i=0;i