double boxMuller(double mu, double sd) { // /* boxmuller.c Implements the Polar form of the Box-Muller /*Transformation (c) Copyright 1994, Everett F. Carter Jr. Permission is granted by the author to use this software for any application provided this copyright notice is preserved. [ smf's note: accessed online 12.03.06 at http:www.taygeta.com/random/boxmuller.html ]*/ double x1, x2, w, y1; static double y2; static int use_last = 0; if (use_last) /* use value from previous call */ { y1 = y2; use_last = 0; } else { do { x1 = 2.0 * ( randU() ) - 1.0; x2 = 2.0 * ( randU() ) - 1.0; w = x1 * x1 + x2 * x2; } while ( w >= 1.0 ); w = sqrt( (-2.0 * log( w ) ) / w ); y1 = x1 * w; y2 = x2 * w; use_last = 1; } return ( mu + y1 * sd ); }
static void resample(Filter& filter) { Scalar beta = 0; unsigned index = irandU<Filter::nofParticles>(); // Wheel of resampling for(auto& p : filter.particles) { beta += randU() * 2 * filter.maxWeight; while(filter.particles[index].weight < beta) { beta -= filter.particles[index].weight; index = (index + 1) % Filter::nofParticles; } //~ std::cout << "Chose particle " << index << " : " << filter.particles[index].state.transpose() << std::endl; p.state = filter.particles[index].state; } }
long int Poisson(double mm) { /* ================================================== * Returns a Poisson distributed non-negative integer. * NOTE: use mm > 0 * code modified from http://www.cs.wm.edu/~va/software/park/rvgs.c * accessed 4/12/12 * ================================================== */ double tt = 0.0; long int events = 0; while (tt < mm) { // cumulative "time" between events; mm is the expected events per unit of time tt += -(log(1.0 - randU())); /* adding an amount of "time" from a random exponential draw with mean 1.0 unit hence, this winds up treating mm as the expected number of units of time to achieve mm events. the number of times we have to increment tt to reach mm is the actual number of events that occurred in mm units of time + 1. x counts the number of increments. s*/ events++; // one more "event" } return (events-1); // corrects for counting one past the last "event" in the while loop }
void migration(int *demeIndexes) { int i, j, nmig = 0; FILE *finalLocations; for ( i = 0; i < nDEMES; i++ ) demeCounts[i] = 0; if ( nDEMES != 2 ) { fprintf(stderr, "\nError in migration()! Not set up for more than 2 demes!\n"); exit(-1); } for ( i = 0; i < TOTAL_N; i++ ) { if ( randU() < MIGRATION_RATE ) { nmig++; if ( demeLocations[i] == 1 ) demeLocations[i] = 0; else demeLocations[i] = 1; } if ( demeLocations[i] == 1 ) { *(demeIndexes + TOTAL_N + demeCounts[1]) = i; demeCounts[1] = demeCounts[1] + 1; } else { *(demeIndexes + demeCounts[0]) = i; demeCounts[0] = demeCounts[0] + 1; } } if ( (demeCounts[0] + demeCounts[1]) != TOTAL_N ) { fprintf(stderr, "\nError in migration()! Counts don't add up!\n"); exit(-1); } if ( t == TOTAL_GENERATIONS ) { finalLocations = fopen("finalLocations.m", "w"); //fprintf(stderr, "\nmig count = %i, demeCounts[0] = %i, demeCounts[1] = %i\n", nmig, demeCounts[0], demeCounts[1]); // array of counts of individuals in each deme fprintf(finalLocations, "demeCounts = ["); for (i = 0; i < nDEMES; i++ ) fprintf(finalLocations, "%i ", demeCounts[i]); fprintf(finalLocations, "];\n"); // array of deme location of each individual: fprintf(finalLocations, "demeLocations = ["); for (i = 0; i < TOTAL_N; i++ ) fprintf(finalLocations, "%i ", demeLocations[i]); fprintf(finalLocations, "];\n"); // arrays of indexes of individuals in each deme for ( i = 0; i < nDEMES; i++ ) { fprintf(finalLocations, "deme%iindexes = [", i); for ( j = 0; j < demeCounts[i]; j++ ) fprintf(finalLocations, "%i ", *(demeIndexes + (i * TOTAL_N) + j)); fprintf( finalLocations, "] + 1;\n"); } fclose(finalLocations); } }
void makeOffspring(int momi, int dadi, short int *offspringGTpt) { int i, j, csome, parent; double nextCrossover; short int *sipt, *parentpt, newAllele; static long int highMutCountdown = -1; static long int lowMutCountdown = -1; _Bool addMutation; if ( highMutCountdown == -1 ) // initialization flag highMutCountdown = (long int) ( (log(1.0 - randU())) * (-1.0/MU_HIGH) ); if ( lowMutCountdown == -1 ) // initialization flag lowMutCountdown = (long int) ( (log(1.0 - randU())) * (-1.0/MU_LOW) ); for ( i = 0; i < 2; i++ ) { // 2 is for two parents // set offspring genotype pointer to right spot sipt = offspringGTpt + i; // get the right parent index if ( i == 0 ) parent = momi; else parent = dadi; parentpt = genotypes + (2 * parent * totalSitesInGenome); csome = 0; // which haplotype is used from the parent for ( j = 0; j < totalSitesInGenome; j++ ) { if ( regionFlags[j] == REGION_FLAG_START ) { // pick a starting chromosome at random if ( randU() < 0.5 ) csome = 1; else csome = 0; // next crossover nextCrossover = genomeMap[j] + (log(1.0 - randU())) * (-50.0); // crossovers are i.i.d. with a mean of 50 cM between them } else { if ( genomeMap[j] > nextCrossover ) { do { // actuate crossover; do-while allows for multiple crossovers in short spans (unlikely but possible) if ( csome ) csome = 0; else csome = 1; nextCrossover += (log(1.0 - randU())) * (-50.0); } while ( genomeMap[j] > nextCrossover ); } } addMutation = 0; if ( mutationRateClass[j] == HIGH_MUT_FLAG ) { if ( highMutCountdown < 1 ) { addMutation = 1; highMutCountdown = (long int) ( (log(1.0 - randU())) * (-1.0/MU_HIGH) ); } else highMutCountdown--; } else { if ( lowMutCountdown < 1 ) { addMutation = 1; lowMutCountdown = (long int) ( (log(1.0 - randU())) * (-1.0/MU_LOW) ); } else lowMutCountdown--; } // now, we know which chromosome to use, and if we need to add a mutation or not! newAllele = *(parentpt + csome); // get allele from parent if ( addMutation ) newAllele = addAnewMutation(j, newAllele); // actuate mutation and update globals accordingly *sipt = newAllele; // put allele in offspring's genome sipt += 2; parentpt += 2; } } }
void buildFitnessArray(int *demeIndexesStart, int deme, int numInDeme ) { double siteTypeProbabilities[3], dum; int i; siteTypeProbabilities[0] = PROB_MUT_BENEFICIAL; siteTypeProbabilities[1] = siteTypeProbabilities[0] + PROB_MUT_BG; siteTypeProbabilities[2] = siteTypeProbabilities[1] + PROB_MUT_DIVERGENT; // make a check to see if the cumulative probabilites exceed 1 if (siteTypeProbabilities[0]+siteTypeProbabilities[1]+siteTypeProbabilities[2] > 1){ printf("error: cumulative site type probabilities exceed 1! (buildFitnessArray, line 372)"); exit(1); } // choose which sites are under selection if (initializer = 0){ for ( i = 0; i < totalSitesInGenome; i++ ) { dum = randU(); if ( dum < siteTypeProbabilities[0] ) { // for a selected site i // do once, at beginning of simulation selectionCoefficients[i] = log( 1.0 - randU() ) * -MEAN_S_BENEFICIAL; } else if ( dum < siteTypeProbabilities[1] ){ selectionCoefficients[i] = log( 1.0 - randU() ) * MEAN_S_BG; } else if ( dum < siteTypeProbabilities[2] ) { selectionCoefficients[i] = log( 1.0 - randU() ) * -MEAN_S_DIVERGENT; } else { selectionCoefficients[i] = 0.0; } initializer++; } } void calculateMetricsAndStats(void) { int i, j, k, locus, n, deme, alleleSum, numVariableInWindow; short int *gtpt; double *dpt1, *dpt2, p1, p2, pi, kbinv, *dpt3, pg; double dum, ninv, Dxy, FST; double pitotal, piwithin, n1frac, n2frac; int totalAlleleCount, demeAlleleCount; _Bool atLeastOneVariable; dpt1 = alleleFrequencies; ninv = 1.0 / ((double) (2 * TOTAL_N)); kbinv = 1.0 / ((double) nSITES_PER_WINDOW); // allele frequencies and by deme: for ( i = 0; i < totalSitesInGenome; i++ ) { // go sites 1 by 1 dpt2 = alleleFrequenciesByDeme + i; // pointer to allele frequency for site i in deme 0 if ( isVariableSite[i] ) { // if is variable site in population gtpt = genotypes + (2 * i); // pointer to first allele of this site in first individual totalAlleleCount = 0; for ( deme = 0; deme < nDEMES; deme++ ) { demeAlleleCount = 0; n = demeCounts[deme]; for ( j = 0; j < n; j++ ) { alleleSum = (*gtpt) + (*(gtpt + 1)); totalAlleleCount += alleleSum; demeAlleleCount += alleleSum; gtpt += 2 * totalSitesInGenome; } *dpt2 = ((double) demeAlleleCount) / ((double) (2 * n)); // 2 for diploid dpt2 += totalSitesInGenome; } if ( totalAlleleCount == 2 * TOTAL_N ) { // 2 for diploid isVariableSite[i] = 0; fixedAllele[i] = 1; *dpt1 = 1.0; fprintf(fixationLog, "%li,%i,1,%i\n", t, i, regionMembership[i]); } else if ( totalAlleleCount == 0 ) { isVariableSite[i] = 0; fixedAllele[i] = 0; fprintf(fixationLog, "%li,%i,0,%i\n", t, i, regionMembership[i]); *dpt1 = 0.0; } else *dpt1 = ((double) totalAlleleCount) * ninv; } else { if ( fixedAllele[i] ) dum = 1.0; else dum = 0.0; *dpt1 = dum; for ( j = 0; j < nDEMES; j++ ) { *dpt2 = dum; dpt2 += totalSitesInGenome; } } dpt1++; } if ( t % TS_SAMP_FREQ == 0 ) { if ( nDEMES > 2 ) { fprintf(stderr, "\nError in calculateMetricsAndStats(): methods assume only two demes!\n"); exit(-1); } fprintf(alleleFrequenciesOverTime, "%li", t); for ( i = 0; i < totalSitesInGenome; i++ ) { fprintf(alleleFrequenciesOverTime, ",%E", alleleFrequencies[i]); } dpt2 = alleleFrequenciesByDeme; for ( j = 0; j < nDEMES; j++ ) { for ( i = 0; i < totalSitesInGenome; i++ ) { fprintf(alleleFrequenciesOverTime, ",%E", *dpt2); dpt2++; } } fprintf(alleleFrequenciesOverTime,"\n"); // Dxy, pi, Da fprintf(piOverTime, "%li", t); fprintf(DxyOverTime, "%li", t); fprintf(DaOverTime, "%li", t); fprintf(FSToverTime, "%li", t); dpt1 = alleleFrequenciesByDeme; // deme 1 dpt2 = alleleFrequenciesByDeme + totalSitesInGenome; // deme 2 dpt3 = alleleFrequencies; // global locus = 0; n1frac = ((double) demeCounts[0]) / ((double) TOTAL_N); n2frac = ((double) demeCounts[1]) / ((double) TOTAL_N); for ( i = 0; i < nGENOMIC_REGIONS; i++ ) { for ( j = 0; j < nWINDOWS_PER_REGION; j++ ) { pi = 0.0; Dxy = 0.0; piwithin = 0.0; pitotal = 0.0; atLeastOneVariable = 0; for ( k = 0; k < nSITES_PER_WINDOW; k++ ) { if ( isVariableSite[locus] ) { atLeastOneVariable = 1; p1 = *dpt1; p2 = *dpt2; pg = *dpt3; // pi metric pi += (p1 * (1.0 - p1)) + (p2 * (1.0 - p2)); // Dxy Dxy += (p1 * (1.0 - p2)) + (p2 * (1.0 - p1)); // FST piwithin += (n1frac * (p1 * (1.0 - p1))) + (n2frac * (p2 * (1.0 - p2))); pitotal += pg * (1.0 - pg); if ( piwithin > pitotal ) { fprintf(stderr, "\nWarning: piwithin = %E > pitotal = %E\n\t p1 = %E, p2 = %E, pg = %E\n", piwithin, pitotal, p1, p2, pg); } } dpt1++; dpt2++; dpt3++; locus++; } pi *= kbinv; fprintf(piOverTime, ",%E", pi); Dxy *= kbinv; fprintf(DxyOverTime, ",%E", Dxy); fprintf(DaOverTime, ",%E", (Dxy - pi)); if ( atLeastOneVariable ) { FST = (pitotal - piwithin)/pitotal; if ( FST < 0.0 ) { fprintf(stderr, "\nWarning: FST = %E < 0.0\n", FST); } fprintf(FSToverTime, ",%E", FST); } else { fprintf(FSToverTime, ",NA"); } } } fprintf(piOverTime, "\n"); fprintf(DxyOverTime, "\n"); fprintf(DaOverTime, "\n"); fprintf(FSToverTime, "\n"); i = 0; for ( locus = 0; locus < totalSitesInGenome; locus++ ) { if ( isVariableSite[locus] ) i++; } fprintf(variableLociOverTime, "%li,%i", t, i); locus = 0; for ( i = 0; i < nGENOMIC_REGIONS; i++ ) { for ( j = 0; j < nWINDOWS_PER_REGION; j++ ) { numVariableInWindow = 0; for ( k = 0; k < nSITES_PER_WINDOW; k++ ) { if ( isVariableSite[locus] ) numVariableInWindow++; locus++; } fprintf(variableLociOverTime, ",%i", numVariableInWindow); } } fprintf(variableLociOverTime, "\n"); } }
//############################ INSTANCE OF FITNESS ARRAY!!!!! MODIFY ONCE FITNESS ARRAY BUILDER COMPLETE #################################### void reproduction(int *demeIndexes) { int i, j, n, count, dadi, momi, *ipt; short int *offspringGenotyes, *sipt; int *offspringDemeLocations; count = 0; offspringGenotyes = (short int *) malloc( (sizeof(short int) * 2 * totalSitesInGenome * TOTAL_N) ); offspringDemeLocations = (int *) malloc( (sizeof(int) * TOTAL_N) ); selectionCoefficients = (double *) malloc( (sizeof(double)*totalSitesInGenome)); sipt = offspringGenotyes; ipt = demeIndexes; for ( i = 0; i < nDEMES; i++ ) { n = demeCounts[i]; // set up fitness array for choosing parents if ( MODEL_TYPE == MODEL_TYPE_SELECTION ) buildFitnessArray(ipt, i, n );// buildFitnessArray uses addres else if ( MODEL_TYPE != MODEL_TYPE_NEUTRAL_ONLY ) { fprintf(stderr, "\nError in reproduction()! MODEL_TYPE (= %i) not recognized!\n", MODEL_TYPE); exit(-1); } // choose parents n times and make n offspring for ( j = 0; j < n; j++ ) { momi = pickParent( &selectionCoefficients[0], -1, n ); // -1 = flag for parent not chosen yet dadi = pickParent( &selectionCoefficients[0], momi, n ); momi = *(ipt + momi); // extract the right index from the overall index array; "momi" and "dadi" are "local" indexes in the consecutive fitness array dadi = *(ipt + dadi); // /* // test check: // if ( demeLocations[momi] != i || demeLocations[dadi] != i ) { // fprintf(stderr, "\nError in reproduction():\n\tLocations of parents not in right deme!\n\tdadi = %i, momi = %i\n", dadi, momi); // fprintf(stderr, "i = %i, demeLocations[momi] = %i, demeLocations[dadi] = %i\n\n", i, demeLocations[momi], demeLocations[dadi]); // exit(-1); // } // // */ // end test check makeOffspring(momi, dadi, sipt); sipt += 2 * totalSitesInGenome; // 2 for diploid; advance to next spot to start storing offspring genotype offspringDemeLocations[count] = i; count++; } ipt += TOTAL_N; // advance deme index pointer to next deme's set } if ( count != TOTAL_N ) { fprintf(stderr, "\nError in reproduction()! Made wrong number of offspring!\n\tcount (=%i) != TOTAL_N (= %i)\n", count, TOTAL_N); exit(-1); } free(genotypes); genotypes = offspringGenotyes; free(demeLocations); demeLocations = offspringDemeLocations; // // test check: // count = 0; // for ( i = 0; i < nDEMES; i++ ) { // for ( j = 0; j < demeCounts[i]; j++ ) { // if ( demeLocations[count] != i ) { // fprintf(stderr, "\nError in reproduction():\n\tOffspring count by location not consistent.\n"); // fprintf(stderr, "deme = %i, demeCounts[%i] = %i, j = %i, count = %i, demeLocations[count] = %i\n", i, i, demeCounts[i], j, count, demeLocations[count]); // exit(-1); // } // count++; // } // } // // end test check //} void RNGsetup(void) { int seed, rcount; FILE *fpt; int stime; long ltime; FILE *rseed; long int i; if (DETERMINISTIC) { fpt = fopen("RnumSeed.txt","r"); if (fpt == NULL) { perror("Can't open RnumSeed.txt"); exit(-1); } rcount = fscanf(fpt,"%i",&seed); if ( rcount ) { seedRand(seed); // fixed random number seed fclose(fpt); } else { fprintf(stderr, "\n\n\tError! nothing read from file! Exiting!\n\n"); exit(-1); } //fprintf(stderr, "\n\nSeed = %i\n\n",seed); } else { /* use calendar time to seed random number generator. Code adopted from Schildt's textbook */ /* get the calendar time */ ltime=time(NULL); stime=(unsigned) ltime/2; // generate and store random number seed rseed = fopen("RnumSeed.txt","w"); fprintf(rseed,"%i\n",stime); fclose(rseed); seedRand(stime); // get random number seed (system time) } // warm up for ( i = 0; i < 1000000; i++ ) randU(); }