/*************************************************************************/ /* */ /* 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. */ /* */ /*************************************************************************/ /********************************************/ /********************************************/ /** **/ /** **/ /** "pop_gen.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 "050605" double double_rand() { double to_return; to_return = ((double)RAND_MAX * rand() + rand())/((double)RAND_MAX * (double)RAND_MAX); return to_return; } // 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_HAPLOID_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_int; // more utlity vars int to_kick; // <- to kick or not to kick the Pseudo-Random Number Generator (PRNG) int cur_genotype, parent_one, parent_two; // simple genotypes are hald in ints char a, b; // 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_HAPLOID_GENOTYPES], cur_generation[NUM_HAPLOID_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 remember 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[%s]<-\n",input_buffer); if(input_buffer[0]!='#') { // Nothing fancy. Tokenize the line and grab the right column cur_token = (char *)strtok(input_buffer, "\t"); cur_col_num = 0; cur_genotype = 0; //printf("[%d -> [%s]]\n",cur_col_num,cur_token); // Figure out which row we're looking at while(cur_token) { cur_int = atoi(cur_token); if(cur_col_num==0) { cur_genotype += (cur_int-1); } else if(cur_col_num==1) { cur_genotype += (cur_int-1)*3; } //else if(cur_col_num==2) //{ // cur_genotype += (cur_int-1)*9; //} //else if(cur_col_num==3) //{ // cur_genotype += (cur_int-1)*27; //} else if(cur_col_num==(fitness_col_num+1)) { //printf("*%d*",cur_int); //a1,a2,b1,b2 fitnesses[cur_genotype] = fitness_codes(cur_int,s,k); } cur_token = (char *)strtok(NULL, "\t"); cur_col_num++; } } } fclose(fitness_functions); // Print out the fittnesses for future references for(i=0;i\t%f\n",i,fitnesses[i]); } fclose(param_file); // Initailize the 0th generation for(i=0;i= 0.0) || (cur_rand_for_two >= 0.0));j++) { // From which genotype do we pick? if((cur_rand_for_one >= 0.0) && (cur_rand_for_one < (((float)(prev_generation[j]))/((float)num_organisms)))) { parent_one = j; } cur_rand_for_one -= (((float)(prev_generation[j]))/((float)num_organisms)); // From which genotype do we pick? if((cur_rand_for_two >= 0.0) && (cur_rand_for_two < (((float)(prev_generation[j]))/((float)num_organisms)))) { parent_two = j; } cur_rand_for_two -= (((float)(prev_generation[j]))/((float)num_organisms)); } cur_genotype = 0; // Gen an a gene from one of the parents //(flip a coin) cur_rand = rand(); if((char)cur_rand & 0x01) { cur_genotype += (parent_one%3); } else { cur_genotype += (parent_two%3); } // Gen a b gene from one of the parents //(flip a coin) if((char)cur_rand & 0x02) { cur_genotype += ((parent_one/3)%3) * 3; } else { cur_genotype += ((parent_two/3)%3) * 3; } 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