Пример #1
0
        public GPDApproximation(IList <double> data, FittingMethod method = FittingMethod.Pickands_SupNorm, Random rand = null)
        {
            if (data.Count < 30)
            {
                throw new ArgumentException("Insufficient data count for Pickands Balkema De Haan theorem.");
            }
            sortedData = new List <double>(data);
            sortedData.Sort();
            int m; // Transition index

            switch (method)
            {
            case FittingMethod.BFGS_MSE:
                ApproximateExcessDistributionParametersBFGS(sortedData, out a, out c, out transitionAbscissa);
                // Compute the index of the closest element that is at or before u in the data
                int transitionIndex = sortedData.BinarySearch(transitionAbscissa);
                if (transitionIndex < 0)
                {
                    transitionIndex = ~transitionIndex;
                }
                transitionProportion = transitionIndex * 1.0 / sortedData.Count;     // Shouldn't this be + 1 here?
                break;

            case FittingMethod.Moments_MSE:
                ApproximateExcessDistributionParametersMoments(sortedData, out a, out c, out m);
                transitionProportion = (sortedData.Count - m + 1.0) / sortedData.Count;
                transitionAbscissa   = sortedData[sortedData.Count - m];   // Convert from m to the actual transitionIndex; m is guaranteed to be > 0
                break;

            case FittingMethod.V4:
                ApproximateExcessDistributionParametersV4(sortedData, out a, out c, out transitionAbscissa);
                int transitionIdx = sortedData.BinarySearch(transitionAbscissa);
                if (transitionIdx < 0)
                {
                    transitionIdx = ~transitionIdx;     // Now the index of the next-largest element
                    if (transitionIdx == 0)
                    {
                        transitionProportion = 0; break;
                    }
                    transitionProportion = Interpolation.Lerp(
                        sortedData[transitionIdx - 1], transitionIdx * 1.0 / sortedData.Count,
                        sortedData[transitionIdx], (transitionIdx + 1) * 1.0 / sortedData.Count,
                        transitionAbscissa);
                    break;
                }
                transitionProportion = (transitionIdx + 1) * 1.0 / sortedData.Count;
                break;

            default:
                ApproximateExcessDistributionParametersPickands(sortedData, out a, out c, out m); // Write m to transitionIndex
                transitionProportion = (sortedData.Count - 4 * m + 1.0) / sortedData.Count;
                transitionAbscissa   = sortedData[sortedData.Count - 4 * m];                      // Convert from m to the actual transitionIndex; m is guaranteed to be > 0
                break;
            }

            this.rand = rand ?? Program.rand;
        }
Пример #2
0
        public static double Quantile(IList <double> sortedData, double q)
        {
            if (q < 0 || q > 1)
            {
                throw new ArgumentOutOfRangeException($"Desired percentile is out of range: {q}");
            }
            if (q == 0)
            {
                return(sortedData[0]);
            }
            if (q == 1)
            {
                return(sortedData[sortedData.Count - 1]);
            }

            double product = (sortedData.Count - 1) * q;
            int    idx     = (int)product;

            //return data[idx + 1] * (product - idx) + data[idx] * (idx + 1 - product);
            return(Interpolation.Lerp(idx, sortedData[idx], idx + 1, sortedData[idx + 1], product));
        }
Пример #3
0
        /// <summary>
        /// Returns the value of the quantile function for this distribution at a given quantile
        /// </summary>
        public double Quantile(double q)
        {
            // Edge cases
            if (q < cumulativeDensities[0])
            {
                return(abscissas[0]);
            }
            if (q > cumulativeDensities[cumulativeDensities.Count - 1])
            {
                return(abscissas[abscissas.Count - 1]);
            }
            // Fast search for which elements to interpolate between
            int idx = cumulativeDensities.BinarySearch(q);

            // If q is an element of the cumulative densities list, return the corresponding abscissa
            if (idx > -1)
            {
                return(abscissas[idx]);
            }
            // Interpolate
            idx = ~idx; // idx is now the index of the next largest element of cumulative densities from q
            return(Interpolation.Lerp(cumulativeDensities[idx - 1], abscissas[idx - 1], cumulativeDensities[idx], abscissas[idx], q));
        }
Пример #4
0
        /// <summary>
        /// Returns the value of this distribution's CDF at the given location
        /// </summary>
        public double CumulativeDensity(double x)
        {
            // Edge cases
            if (x < abscissas[0])
            {
                return(0);
            }
            if (x > abscissas[abscissas.Count - 1])
            {
                return(1);
            }
            // Fast search for which elements to interpolate between
            int idx = abscissas.BinarySearch(x);

            // If x is an element of the abscissas, return the corresponding value
            if (idx > -1)
            {
                return(cumulativeDensities[idx]);
            }
            // Interpolate
            idx = ~idx; // idx is now the index of the next largest element of abscissas from x
            return(Interpolation.Lerp(abscissas[idx - 1], cumulativeDensities[idx - 1], abscissas[idx], cumulativeDensities[idx], x));
        }