/*----------------------------------------------------------------------+
|	Title:	Herdstats.java                                          |
|                                                                       |
|	Author:	David E. Joyce                                          |
|        Department of Mathematics and Computer Science                 |
|        Clark University                                               |
|        Worcester, MA 01610-1477                                       |
|        U.S.A.                                                         |
|                                                                       |
|        http://aleph0.clarku.edu/~djoyce/home.html                     |
|        djoyce@clarku.edu                                              |
|                                                                       |
|	Date:	May, 2001.                                              |
+----------------------------------------------------------------------*/

public class Herdstats {

  // parameters
 
  int cost;              // cost to altruist in 10ths of a unit
  int benefit;           // benefit from altruist in 10ths of a unit
  int herd_size;         // each herd has this population
  int init_alt;          // how many initial altruists
  int deaths;            // this many die and are born each day in each herd

  Herd h = new Herd();   // Only one herd
  int day;

  Herdstats () {} // default constructor
  
  void reset(int cost_init, int benefit_init, int hs_init, int ia_init,
             int deaths_init) {
    cost = cost_init;
    benefit = benefit_init;
    herd_size = hs_init;
    init_alt = ia_init;
    deaths = deaths_init;
  }

  // doSimulation performs n simulations on individual herds
  // It collects the following data:
  public int countsel; // the number of herds that become entirely selfish
  public int countalt; // the number of herds that become entirely altruist
  public int aveselday; // the average number of days to become totally selfish
  public int stdevsel; // the standard deviation for that
  public int avealtday; // the average number of days to become totally altruist
  public int stdevalt; // the standard deviation for that

  public void doSimulation (int n) {
    countsel = 0;
    countalt = 0;
    double totselday = 0, totaltday = 0;
    double totselday2 = 0, totaltday2 = 0;
    for (int i=0; i<n; ++i) {
      simulateOne();
      if (h.selfish > 0) { // herd became totally selfish
        countsel++;
        totselday += day;
	totselday2 += (double)day*day;
      } else {            // herd became totally altruist
        countalt++;
        totaltday += day;
	totaltday2 += (double)day*day;
      }
    }
    if (countsel > 0)
      aveselday = (int)(totselday/countsel);
    else
      aveselday = 0;
    if (countsel > 1)
      stdevsel =
        (int) Math.sqrt((totselday2-totselday*aveselday)/(countsel-1.0));
    else
      stdevsel = -1;
    if (stdevsel == 0)
      System.out.println("totselday2="+totselday2+
	" totselday="+totselday+
	" aveselday="+aveselday+
	" countsel="+countsel);
    if (countalt > 0)
      avealtday = (int)(totaltday/countalt);
    else
      avealtday = 0;
    if (countalt > 1)
      stdevalt =
        (int) Math.sqrt((totaltday2-totaltday*avealtday)/(countalt-1.0));
    else
      stdevalt = -1;
    if (stdevalt == 0)
      System.out.println("totaltday2="+totaltday2+
	" totaltday="+totaltday+
	" avealtday="+avealtday+
	" countalt="+countalt);
  }

  public void simulateOne() {
    day = 1;
    h.set(0,init_alt,herd_size-init_alt);    // initialize the herd
    while (h.selfish !=0 && (h.paired!=0 || h.unpaired!=0))
      next_day();
  }
  
  void next_day() {
      // The animals pair off at the beginning of the day and a certain number
      // are born based on vitality.  The same number die at random
      h.pairing();
      h.birth(cost/10.0, benefit/10.0, deaths);
      h.death(deaths);
      ++day;
  }

  public String getStats() {
    return countsel+"\t"+countalt+"\t"+
           aveselday+"\t"+stdevsel+"\t"+avealtday+"\t"+stdevalt;
  }

  public void printStats() {
    System.out.println("\n  Herd size: " + herd_size);
    System.out.println("  Deaths: " + deaths);
    System.out.println("  Altruists: " + init_alt);
    System.out.println("  Cost: " + cost + ". Benefit: " + benefit);
    System.out.println("\n  selfish: " + countsel);
    System.out.println("  altruist: " + countalt);
    System.out.println("  aveselday: " + aveselday);
    System.out.println("  stdevsel:" + stdevsel);
    System.out.println("  avealtday: " + avealtday);
    System.out.println("  stdevalt:" + stdevalt);
  }

}

