using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using U.StringOperations;

namespace StatisticalDistribution
{
    // F(x) = 1 - EXP((A-x) / B)
    // f(x) = 1/B . EXP((A-x) / B)
    // x >= A   ;   B > 0

    public class ExponentialDist : Distribution
    {
        public static string abbr = "Exp";
        private double A;
        private double B;


        #region CONSTRUCTORS
        public ExponentialDist(double location, double scale)
            : base(Distribution.Type.Exponential)
        {
            this.A = location;
            this.B = scale;
        }
        #endregion

        #region GETTERS
        public double getLocation() { return this.A; }
        public double getScale() { return this.B; } 
        #endregion

        #region OVERRIDE
        public override double pdf(double x) { return Math.Exp((A - x) / B) / B; }
        public override double cdf(double x) { if (x < A) { return 0.0; } return 1.0 - Math.Exp((A - x) / B); }
        public override double cdfInv(double p) { return A - B * Math.Log(1 - p); }
        public override double variance() { return Math.Pow(B, 2.0); }
        public override double mean() { return A + B; }
        public override double std() { return B; }
        public override double skewness() { return 2 * Math.Pow(B, 3.0); }
        public override double kurtosis() { return 9 * Math.Pow(B, 4.0); }
        public override double mode() { return A; }
        public override double median() { return A + B * Math.Log(2); }
        public override double Q1() { return A + B * Math.Log(4.0 / 3.0); }
        public override double Q3() { return A + B * Math.Log(4.0); } 
        #endregion

        #region TOSTRING and CLONE
        public override string ToString() { return StrFunc.getFuncString(abbr, new List<double>() { A, B }, DStr.PAR, DStr.DEL); }
        public override Distribution Clone() { return new ExponentialDist(this.A, this.B); } 
        #endregion

    }

}