next up previous
Next: Pointer Up: Wright-Fisher model Previous: Wright-Fisher model

Source Code

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAX_POP_SIZE 10000

int popB[MAX_POP_SIZE], popR[MAX_POP_SIZE];

void GetPara(int *popSizePtr, double *freqPtr);
void InitPop(int *popPtr, int popSize, double initFreq);
void CreateNextGenPanmictic(int *curPop, int *nextPop, int popSize);
int RandInt(int max);
int MyRound(double x);

int main(void) {
  int gen, *currentPtr, *nextPtr;
  int popSize, numGen = 100000;
  double initFreq;
  
  GetPara(&popSize, &initFreq);  /* get the values from the user */
  
  if (popSize > MAX_POP_SIZE) {  /* Make sure we have big enough arrays */
    fprintf(stderr, "pop size: %d is bigger than the max: %d\n",
	    popSize, MAX_POP_SIZE);
    exit(EXIT_FAILURE);
  }
  srand(time(NULL));
  InitPop(popB, popSize, initFreq);  /* randomly assign alleles */

  for (gen = 0; gen < numGen; gen++) {
    if (gen % 2 == 0) {
      currentPtr = popB;
      nextPtr = popR;
    } else {
      currentPtr = popR;
      nextPtr = popB;
    }
    
    CreateNextGenPanmictic(currentPtr, nextPtr, popSize);
  }
  return 0;
}

/* Initialize the parameters */
void GetPara(int *popSizePtr, double *freqPtr) {
  fprintf(stderr, "Population Size?: ");
  scanf("%d", popSizePtr);
  fprintf(stderr, "Init freq. of allele 1?: ");
  scanf("%lf", freqPtr);
  return;
}

/*
 * Assume that there are two alleles: 0 and 1
 * Initialize the population, so that the allele frequency of allele 1
 * is initFreq.
 */
void InitPop(int *popPtr, int popSize, double initFreq) {
  int i, numAlleles, cntr, index;
  numAlleles =  MyRound(popSize *  initFreq);
  
  for (i = 0; i < popSize; i++) {
    popPtr[i] = 0;
  }
  
  cntr = 0;
  while (cntr < numAlleles) {
    index = RandInt(popSize - 1);
    if (popPtr[index] == 0) {
      popPtr[index] = 1;
      cntr++;
    }
  }
  return;
}

void CreateNextGenPanmictic(int *curPop, int *nextPop, int popSize) {
  int i, parent;
  
  for (i = 0; i < popSize; i ++) {
    parent = RandInt(popSize - 1);
    nextPop[i] = curPop[parent];
  }
  
  return;
}

/* 
 * Returns a uniform random integer between 0 and max (ends inclusive) 
 * It uses rand(), so you need to srand() in main()
 */
int RandInt(int max) {
  int r = rand();
  return r % (max+1);
}

/* 
 * Round the floating points to the nearest integer 
 * For example, 9.5 <= x < 10.5 become 10
 * This function can cause integer over-flow when x is large
 */
int MyRound(double x) {
  int intPart;
  
  if (x > 0) {
    return (int) (x + 0.5);
  } else {
    return (int) (x - 0.5);
  }
}



Naoki Takebayashi 2008-04-15