package probability_distribution;

/**
 * This class implements the Exponential distribution.
 * 
 * For example, producing a collection of 100 numbers by invoking getNextValue()
 * method 100 times, will produce a collection of numbers that conform to an
 * exponential distribution.
 * 
 * @author Majd Kokaly
 * 
 */
public class ExponentialDist extends ProbabilityDist {
	/**
	 * Every exponential distribution has a mean and 1/Lambda is the mean
	 */
	protected double lambda; 

	protected double getLambda() {
		return lambda;
	}

	protected void setLambda(double lambda) {
		this.lambda = lambda;
	}

	/**
	 * The default constructor
	 * @param lambda (1/lambda) is the mean of this distribution
	 */
	public ExponentialDist(double lambda) {
		this.setLambda(lambda);
	}
	
	/**
	 * @param x is double
	 * @return y such that y = f(x) and f is the probability density function
	 */
	protected double f(double x) { // Probability density function
		if (x >= 0)
			return this.getLambda() * Math.exp(-1 * this.getLambda() * x);
		else
			return 0;
	}
	
	/**
	 * @param x is double
	 * @return y such that y = F(x) and f is the Cumulative distribution function
	 */
	protected double F(double x) { // Cumulative distribution function
		if (x >= 0)
			return 1 - Math.exp(-1 * this.getLambda() * x);
		else
			return 0;
	}
	
	/**
	 * @param y is double
	 * @return x such that y = F(x) and f is the Cumulative distribution function
	 */
	public double FInverse(double x) {
		return (-1 * Math.log(x)) / this.getLambda();
	}
	
	public double FInverse()
	{
		return (-1 * Math.log(Math.random()) / this.getLambda());
	}
	
	public static void main(String[] args) {
		double x;
		double y;

		int TU_InMinutes = 1;

		ExponentialDist exp = new ExponentialDist(
				3.0 / (TU_InMinutes * 60.0 * 1000.0));
		int count = 10000;
		double sum = 0;
		for (int i = 0; i < count; i++) {
			x = Math.random();
			y = exp.getTimeToNextEvent();
			sum += y;
			System.out.print(x + "\t" + y + "\n");
		}
		System.out.println("Inter Arival: " + (sum / count));
		System.out.println("Rate: " + (count / sum) + "or Rate: " + count
				/ (sum / 1000.0 / 60.0 / TU_InMinutes) + " Per Time Unit");
		System.out.flush();

	}

}
