import org.apache.commons.math.MathException;
import org.apache.commons.math.distribution.*;

/**
 * The BranchingProcess class creates a branching process with given parameter.
 * The process can then be run to see if the process survives "indefinitely" or
 * ends in a finite number of generations.
 * 
 */
public class BranchingProcess {
	AbstractIntegerDistribution zeta;

	// Creates a BranchingProcess with distribution X
	public BranchingProcess(AbstractIntegerDistribution X) {
		try {
			if (X.cumulativeProbability(-1) > 0) {
				throw new MathException();
			}
		} catch (MathException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		zeta = X;
	}

	// Runs a branching process up to maxGen generations and stores the population of each
	// generation in an array.
	public int[] run(int maxGen) {
		int[] population = new int[maxGen + 1];
		population[0] = 1;
		int currentGen = 1;
		int[] children = new int[0];
		while (population[currentGen - 1] > 0 && currentGen <= maxGen) {
			try {
				children = zeta.sample(population[currentGen - 1]);
			} catch (MathException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			for (int i = 0; i < population[currentGen - 1]; i++) {
				population[currentGen] += children[i];
			}
			currentGen++;
		}
		return population;
	}

}
