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 );
}
Esempio n. 2
0
                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();
}