/// <summary>Initializes the <see cref="EmpiricalDistribution" /> class.
 /// </summary>
 static EmpiricalDistribution()
 {
     StandardDensityEstimator  = new SquareRootChoiceDensityEstimator();
     StandardEmpiricalQuantile = new StandardEmpiricalQuantile();
     StandardMomentEstimator   = new StandardEmpiricalMomentEstimator();
 }
 /// <summary>Creates a new <see cref="EmpiricalDistribution"/> object.
 /// </summary>
 /// <param name="sample">The sample.</param>
 /// <param name="empiricalQuantileMethod">The empirical quantile method.</param>
 /// <param name="isSorted">A value indicating whether the values in the <paramref name="sample"/> are sorted in ascending order.</param>
 /// <param name="densityEstimator">The density estimator.</param>
 /// <param name="empiricalMomentEstimator">The empirical moment estimator.</param>
 /// <returns>A new <see cref="EmpiricalDistribution"/> object.</returns>
 public static EmpiricalDistribution Create(IEnumerable <double> sample, EmpiricalQuantile empiricalQuantileMethod, bool isSorted, DensityEstimator densityEstimator, EmpiricalMomentEstimator empiricalMomentEstimator)
 {
     return(new EmpiricalDistribution(sample, empiricalQuantileMethod, isSorted, densityEstimator, empiricalMomentEstimator));
 }
        /// <summary>Initializes a new instance of the <see cref="EmpiricalDistribution" /> class.
        /// </summary>
        /// <param name="sample">The sample.</param>
        /// <param name="empiricalQuantileMethod">The empirical quantile method.</param>
        /// <param name="isSorted">A value indicating whether the values in the <paramref name="sample"/> are sorted in ascending order.</param>
        /// <param name="densityEstimator">The density estimator.</param>
        /// <param name="empiricalMomentEstimator">A empirical moment estimator, used for example for a bootstrap approach.</param>
        public EmpiricalDistribution(IEnumerable <double> sample, EmpiricalQuantile empiricalQuantileMethod, bool isSorted, DensityEstimator densityEstimator, EmpiricalMomentEstimator empiricalMomentEstimator)
        {
            if (sample == null)
            {
                throw new ArgumentNullException("sample");
            }
            Sample = sample.Skip(0);  // is used to avoid a cast to the original sample!

            InfoOutputDetailLevel = InfoOutputDetailLevel.Middle;
            m_Quantile            = new Lazy <IQuantileFunction>(() => empiricalQuantileMethod.Create(sample, isSorted)); // sorted sample will be computed on demand only!
            m_Median = new Lazy <double>(() => GetSampleMedian(SortedSample));                                            // required sorted sample, i.e. will create quantile calculation before

            m_MomentCalculator = new Lazy <ProbabilityDistributionMoments>(() => empiricalMomentEstimator.Create(sample));
            m_DensityEstimator = densityEstimator.Create(this);

            Name     = new IdentifierString("Empirical distribution");
            LongName = new IdentifierString("Empirical distribution");
        }