/// <summary>
 /// stimates the tau-th quantile from the provided samples.
 /// The tau-th quantile is the data value where the cumulative distribution
 /// function crosses tau. The quantile definition can be specificed to be compatible
 /// with an existing system.
 /// </summary>
 /// <param name="data">The data sample sequence.</param>
 /// <param name="tau">Quantile selector, between 0.0 and 1.0 (inclusive).</param>
 /// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
 public static double QuantileCustom(this IEnumerable<double?> data, double tau, QuantileDefinition definition)
 {
     if (data == null) throw new ArgumentNullException("data");
     var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
     return ArrayStatistics.QuantileCustomInplace(array, tau, definition);
 }
Example #2
0
        /// <summary>
        /// stimates the tau-th quantile from the provided samples.
        /// The tau-th quantile is the data value where the cumulative distribution
        /// function crosses tau. The quantile definition can be specificed to be compatible
        /// with an existing system.
        /// </summary>
        /// <param name="data">The data sample sequence.</param>
        /// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
        public static Func <double, double> QuantileCustomFunc(this IEnumerable <double?> data, QuantileDefinition definition)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();

            Array.Sort(array);
            return(tau => SortedArrayStatistics.QuantileCustom(array, tau, definition));
        }
Example #3
0
 public static double QuantileCustom(this IEnumerable <double> data, double tau, QuantileDefinition definition)
 {
     double[] array = data.ToArray();
     return(ArrayStatistics.QuantileCustomInplace(array, tau, definition));
 }
        /// <summary>
        /// Estimates the tau-th quantile from the sorted data array (ascending).
        /// The tau-th quantile is the data value where the cumulative distribution
        /// function crosses tau. The quantile definition can be specified to be compatible
        /// with an existing system.
        /// </summary>
        /// <param name="data">Sample array, must be sorted ascendingly.</param>
        /// <param name="tau">Quantile selector, between 0.0 and 1.0 (inclusive).</param>
        /// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
        public static double QuantileCustom(double[] data, double tau, QuantileDefinition definition)
        {
            if (tau < 0d || tau > 1d || data.Length == 0)
            {
                return double.NaN;
            }

            if (tau == 0d || data.Length == 1)
            {
                return data[0];
            }

            if (tau == 1d)
            {
                return data[data.Length - 1];
            }

            switch (definition)
            {
                case QuantileDefinition.R1:
                {
                    double h = data.Length*tau + 0.5d;
                    return data[(int)Math.Ceiling(h - 0.5d) - 1];
                }

                case QuantileDefinition.R2:
                {
                    double h = data.Length*tau + 0.5d;
                    return (data[(int)Math.Ceiling(h - 0.5d) - 1] + data[(int)(h + 0.5d) - 1])*0.5d;
                }

                case QuantileDefinition.R3:
                {
                    double h = data.Length*tau;
                    return data[Math.Max((int)Math.Round(h) - 1, 0)];
                }

                case QuantileDefinition.R4:
                {
                    double h = data.Length*tau;
                    var hf = (int)h;
                    var lower = data[Math.Max(hf - 1, 0)];
                    var upper = data[Math.Min(hf, data.Length - 1)];
                    return lower + (h - hf)*(upper - lower);
                }

                case QuantileDefinition.R5:
                {
                    double h = data.Length*tau + 0.5d;
                    var hf = (int)h;
                    var lower = data[Math.Max(hf - 1, 0)];
                    var upper = data[Math.Min(hf, data.Length - 1)];
                    return lower + (h - hf)*(upper - lower);
                }

                case QuantileDefinition.R6:
                {
                    double h = (data.Length + 1)*tau;
                    var hf = (int)h;
                    var lower = data[Math.Max(hf - 1, 0)];
                    var upper = data[Math.Min(hf, data.Length - 1)];
                    return lower + (h - hf)*(upper - lower);
                }

                case QuantileDefinition.R7:
                {
                    double h = (data.Length - 1)*tau + 1d;
                    var hf = (int)h;
                    var lower = data[Math.Max(hf - 1, 0)];
                    var upper = data[Math.Min(hf, data.Length - 1)];
                    return lower + (h - hf)*(upper - lower);
                }

                case QuantileDefinition.R8:
                {
                    double h = (data.Length + 1/3d)*tau + 1/3d;
                    var hf = (int)h;
                    var lower = data[Math.Max(hf - 1, 0)];
                    var upper = data[Math.Min(hf, data.Length - 1)];
                    return lower + (h - hf)*(upper - lower);
                }

                case QuantileDefinition.R9:
                {
                    double h = (data.Length + 0.25d)*tau + 0.375d;
                    var hf = (int)h;
                    var lower = data[Math.Max(hf - 1, 0)];
                    var upper = data[Math.Min(hf, data.Length - 1)];
                    return lower + (h - hf)*(upper - lower);
                }

                default:
                    throw new NotSupportedException();
            }
        }
Example #5
0
        /// <summary>
        /// stimates the tau-th quantile from the provided samples.
        /// The tau-th quantile is the data value where the cumulative distribution
        /// function crosses tau. The quantile definition can be specificed to be compatible
        /// with an existing system.
        /// </summary>
        /// <param name="data">The data sample sequence.</param>
        /// <param name="tau">Quantile selector, between 0.0 and 1.0 (inclusive).</param>
        /// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
        public static double QuantileCustom(this IEnumerable <double?> data, double tau, QuantileDefinition definition)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();

            return(ArrayStatistics.QuantileCustomInplace(array, tau, definition));
        }
        /// <summary>
        /// Estimates the tau-th quantile from the unsorted data array.
        /// The tau-th quantile is the data value where the cumulative distribution
        /// function crosses tau. The quantile definition can be specified to be compatible
        /// with an existing system.
        /// WARNING: Works inplace and can thus causes the data array to be reordered.
        /// </summary>
        /// <param name="data">Sample array, no sorting is assumed. Will be reordered.</param>
        /// <param name="tau">Quantile selector, between 0.0 and 1.0 (inclusive)</param>
        /// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
        public static double QuantileCustomInplace(double[] data, double tau, QuantileDefinition definition)
        {
            if (tau < 0d || tau > 1d || data.Length == 0)
            {
                return(double.NaN);
            }

            if (tau == 0d || data.Length == 1)
            {
                return(Minimum(data));
            }

            if (tau == 1d)
            {
                return(Maximum(data));
            }

            switch (definition)
            {
            case QuantileDefinition.R1:
            {
                double h = data.Length * tau + 0.5d;
                return(SelectInplace(data, (int)Math.Ceiling(h - 0.5d) - 1));
            }

            case QuantileDefinition.R2:
            {
                double h = data.Length * tau + 0.5d;
                return((SelectInplace(data, (int)Math.Ceiling(h - 0.5d) - 1) + SelectInplace(data, (int)(h + 0.5d) - 1)) * 0.5d);
            }

            case QuantileDefinition.R3:
            {
                double h = data.Length * tau;
                return(SelectInplace(data, (int)Math.Round(h) - 1));
            }

            case QuantileDefinition.R4:
            {
                double h     = data.Length * tau;
                var    hf    = (int)h;
                var    lower = SelectInplace(data, hf - 1);
                var    upper = SelectInplace(data, hf);
                return(lower + (h - hf) * (upper - lower));
            }

            case QuantileDefinition.R5:
            {
                double h     = data.Length * tau + 0.5d;
                var    hf    = (int)h;
                var    lower = SelectInplace(data, hf - 1);
                var    upper = SelectInplace(data, hf);
                return(lower + (h - hf) * (upper - lower));
            }

            case QuantileDefinition.R6:
            {
                double h     = (data.Length + 1) * tau;
                var    hf    = (int)h;
                var    lower = SelectInplace(data, hf - 1);
                var    upper = SelectInplace(data, hf);
                return(lower + (h - hf) * (upper - lower));
            }

            case QuantileDefinition.R7:
            {
                double h     = (data.Length - 1) * tau + 1d;
                var    hf    = (int)h;
                var    lower = SelectInplace(data, hf - 1);
                var    upper = SelectInplace(data, hf);
                return(lower + (h - hf) * (upper - lower));
            }

            case QuantileDefinition.R8:
            {
                double h     = (data.Length + 1 / 3d) * tau + 1 / 3d;
                var    hf    = (int)h;
                var    lower = SelectInplace(data, hf - 1);
                var    upper = SelectInplace(data, hf);
                return(lower + (h - hf) * (upper - lower));
            }

            case QuantileDefinition.R9:
            {
                double h     = (data.Length + 0.25d) * tau + 0.375d;
                var    hf    = (int)h;
                var    lower = SelectInplace(data, hf - 1);
                var    upper = SelectInplace(data, hf);
                return(lower + (h - hf) * (upper - lower));
            }

            default:
                throw new NotSupportedException();
            }
        }
Example #7
0
 /// <summary>
 /// Estimates the tau-th quantile from the provided samples.
 /// The tau-th quantile is the data value where the cumulative distribution
 /// function crosses tau. The quantile definition can be specified to be compatible
 /// with an existing system.
 /// </summary>
 /// <param name="data">The data sample sequence.</param>
 /// <param name="tau">Quantile selector, between 0.0 and 1.0 (inclusive).</param>
 /// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
 public static float QuantileCustom(this IEnumerable<float> data, double tau, QuantileDefinition definition)
 {
     float[] array = data.ToArray();
     return ArrayStatistics.QuantileCustomInplace(array, tau, definition);
 }
        /// <summary>
        /// Estimates the tau-th quantile from the unsorted data array.
        /// The tau-th quantile is the data value where the cumulative distribution
        /// function crosses tau. The quantile definition can be specificed to be compatible
        /// with an existing system.
        /// WARNING: Works inplace and can thus causes the data array to be reordered.
        /// </summary>
        /// <param name="data">Sample array, no sorting is assumed. Will be reordered.</param>
        /// <param name="tau">Quantile selector, between 0.0 and 1.0 (inclusive)</param>
        /// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
        public static double QuantileCustomInplace(double[] data, double tau, QuantileDefinition definition)
        {
            if (tau < 0d || tau > 1d || data.Length == 0) return double.NaN;
            if (tau == 0d || data.Length == 1) return Minimum(data);
            if (tau == 1d) return Maximum(data);

            switch (definition)
            {
                case QuantileDefinition.R1:
                {
                    double h = data.Length*tau + 0.5d;
                    return SelectInplace(data, (int)Math.Ceiling(h - 0.5d) - 1);
                }
                case QuantileDefinition.R2:
                {
                    double h = data.Length*tau + 0.5d;
                    return (SelectInplace(data, (int)Math.Ceiling(h - 0.5d) - 1) + SelectInplace(data, (int)(h + 0.5d) - 1))*0.5d;
                }
                case QuantileDefinition.R3:
                {
                    double h = data.Length*tau;
                    return SelectInplace(data, (int)Math.Round(h) - 1);
                }
                case QuantileDefinition.R4:
                {
                    double h = data.Length*tau;
                    var hf = (int)h;
                    var lower = SelectInplace(data, hf - 1);
                    var upper = SelectInplace(data, hf);
                    return lower + (h - hf)*(upper - lower);
                }
                case QuantileDefinition.R5:
                {
                    double h = data.Length*tau + 0.5d;
                    var hf = (int)h;
                    var lower = SelectInplace(data, hf - 1);
                    var upper = SelectInplace(data, hf);
                    return lower + (h - hf)*(upper - lower);
                }
                case QuantileDefinition.R6:
                {
                    double h = (data.Length + 1)*tau;
                    var hf = (int)h;
                    var lower = SelectInplace(data, hf - 1);
                    var upper = SelectInplace(data, hf);
                    return lower + (h - hf)*(upper - lower);
                }
                case QuantileDefinition.R7:
                {
                    double h = (data.Length - 1)*tau + 1d;
                    var hf = (int)h;
                    var lower = SelectInplace(data, hf - 1);
                    var upper = SelectInplace(data, hf);
                    return lower + (h - hf)*(upper - lower);
                }
                case QuantileDefinition.R8:
                {
                    double h = (data.Length + 1/3d)*tau + 1/3d;
                    var hf = (int)h;
                    var lower = SelectInplace(data, hf - 1);
                    var upper = SelectInplace(data, hf);
                    return lower + (h - hf)*(upper - lower);
                }
                case QuantileDefinition.R9:
                {
                    double h = (data.Length + 0.25d)*tau + 0.375d;
                    var hf = (int)h;
                    var lower = SelectInplace(data, hf - 1);
                    var upper = SelectInplace(data, hf);
                    return lower + (h - hf)*(upper - lower);
                }
                default:
                    throw new NotSupportedException();
            }
        }
Example #9
0
        /// <summary>
        /// Estimates the tau-th quantile from the provided samples.
        /// The tau-th quantile is the data value where the cumulative distribution
        /// function crosses tau. The quantile definition can be specificed to be compatible
        /// with an existing system.
        /// </summary>
        /// <param name="data">The data sample sequence.</param>
        /// <param name="tau">Quantile selector, between 0.0 and 1.0 (inclusive).</param>
        /// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
        public static double QuantileCustom(this IEnumerable <double?> data, double tau, QuantileDefinition definition)
        {
            var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();

            return(ArrayStatistics.QuantileCustomInplace(array, tau, definition));
        }
Example #10
0
 /// <summary>
 /// Estimates the tau-th quantile from the provided samples.
 /// The tau-th quantile is the data value where the cumulative distribution
 /// function crosses tau. The quantile definition can be specificed to be compatible
 /// with an existing system.
 /// </summary>
 /// <param name="data">The data sample sequence.</param>
 /// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
 public static Func<double, double> QuantileCustomFunc(this IEnumerable<double> data, QuantileDefinition definition)
 {
     var array = data.ToArray();
     Array.Sort(array);
     return tau => SortedArrayStatistics.QuantileCustom(array, tau, definition);
 }
Example #11
0
 /// <summary>
 /// Estimates the tau-th quantile from the provided samples.
 /// The tau-th quantile is the data value where the cumulative distribution
 /// function crosses tau. The quantile definition can be specificed to be compatible
 /// with an existing system.
 /// </summary>
 /// <param name="data">The data sample sequence.</param>
 /// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
 public static Func<double, double> QuantileCustomFunc(this IEnumerable<double?> data, QuantileDefinition definition)
 {
     var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
     Array.Sort(array);
     return tau => SortedArrayStatistics.QuantileCustom(array, tau, definition);
 }
Example #12
0
 /// <summary>
 /// Estimates the tau-th quantile from the provided samples.
 /// The tau-th quantile is the data value where the cumulative distribution
 /// function crosses tau. The quantile definition can be specificed to be compatible
 /// with an existing system.
 /// </summary>
 /// <param name="data">The data sample sequence.</param>
 /// <param name="tau">Quantile selector, between 0.0 and 1.0 (inclusive).</param>
 /// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
 public static double QuantileCustom(this IEnumerable<double?> data, double tau, QuantileDefinition definition)
 {
     var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
     return ArrayStatistics.QuantileCustomInplace(array, tau, definition);
 }
Example #13
0
 /// <summary>
 /// Estimates the tau-th quantile from the provided samples.
 /// The tau-th quantile is the data value where the cumulative distribution
 /// function crosses tau. The quantile definition can be specificed to be compatible
 /// with an existing system.
 /// </summary>
 /// <param name="data">The data sample sequence.</param>
 /// <param name="tau">Quantile selector, between 0.0 and 1.0 (inclusive).</param>
 /// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
 public static double QuantileCustom(this IEnumerable<double> data, double tau, QuantileDefinition definition)
 {
     var array = data.ToArray();
     return ArrayStatistics.QuantileCustomInplace(array, tau, definition);
 }
Example #14
0
 /// <summary>
 /// Estimates the tau-th quantile from the provided samples.
 /// The tau-th quantile is the data value where the cumulative distribution
 /// function crosses tau. The quantile definition can be specified to be compatible
 /// with an existing system.
 /// </summary>
 /// <param name="data">The data sample sequence.</param>
 /// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
 public static Func<float, float> QuantileCustomFunc(this IEnumerable<float> data, QuantileDefinition definition)
 {
     float[] array = data.ToArray();
     Array.Sort(array);
     return tau => SortedArrayStatistics.QuantileCustom(array, tau, definition);
 }
Example #15
0
 /// <summary>
 /// stimates the tau-th quantile from the provided samples.
 /// The tau-th quantile is the data value where the cumulative distribution
 /// function crosses tau. The quantile definition can be specificed to be compatible
 /// with an existing system.
 /// </summary>
 /// <param name="data">The data sample sequence.</param>
 /// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
 public static Func<double, double> QuantileCustomFunc(this IEnumerable<double?> data, QuantileDefinition definition)
 {
     if (data == null) throw new ArgumentNullException("data");
     var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();
     Array.Sort(array);
     return tau => SortedArrayStatistics.QuantileCustom(array, tau, definition);
 }
Example #16
0
        /// <summary>
        /// Estimates the tau-th quantile from the provided samples.
        /// The tau-th quantile is the data value where the cumulative distribution
        /// function crosses tau. The quantile definition can be specificed to be compatible
        /// with an existing system.
        /// </summary>
        /// <param name="data">The data sample sequence.</param>
        /// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
        public static Func <double, double> QuantileCustomFunc(this IEnumerable <double> data, QuantileDefinition definition)
        {
            var array = data.ToArray();

            Array.Sort(array);
            return(tau => SortedArrayStatistics.QuantileCustom(array, tau, definition));
        }
Example #17
0
        /// <summary>
        /// Estimates the tau-th quantile from the sorted data array (ascending).
        /// The tau-th quantile is the data value where the cumulative distribution
        /// function crosses tau. The quantile definition can be specified to be compatible
        /// with an existing system.
        /// </summary>
        /// <param name="data">Sample array, must be sorted ascendingly.</param>
        /// <param name="tau">Quantile selector, between 0.0 and 1.0 (inclusive).</param>
        /// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
        public static float QuantileCustom(float[] data, double tau, QuantileDefinition definition)
        {
            if (tau < 0d || tau > 1d || data.Length == 0)
            {
                return(float.NaN);
            }

            if (tau == 0d || data.Length == 1)
            {
                return(data[0]);
            }

            if (tau == 1d)
            {
                return(data[data.Length - 1]);
            }

            switch (definition)
            {
            case QuantileDefinition.R1:
            {
                double h = data.Length * tau + 0.5d;
                return(data[(int)Math.Ceiling(h - 0.5d) - 1]);
            }

            case QuantileDefinition.R2:
            {
                double h = data.Length * tau + 0.5d;
                return((data[(int)Math.Ceiling(h - 0.5d) - 1] + data[(int)(h + 0.5d) - 1]) * 0.5f);
            }

            case QuantileDefinition.R3:
            {
                double h = data.Length * tau;
                return(data[Math.Max((int)Math.Round(h) - 1, 0)]);
            }

            case QuantileDefinition.R4:
            {
                double h     = data.Length * tau;
                var    hf    = (int)h;
                var    lower = data[Math.Max(hf - 1, 0)];
                var    upper = data[Math.Min(hf, data.Length - 1)];
                return((float)(lower + (h - hf) * (upper - lower)));
            }

            case QuantileDefinition.R5:
            {
                double h     = data.Length * tau + 0.5d;
                var    hf    = (int)h;
                var    lower = data[Math.Max(hf - 1, 0)];
                var    upper = data[Math.Min(hf, data.Length - 1)];
                return((float)(lower + (h - hf) * (upper - lower)));
            }

            case QuantileDefinition.R6:
            {
                double h     = (data.Length + 1) * tau;
                var    hf    = (int)h;
                var    lower = data[Math.Max(hf - 1, 0)];
                var    upper = data[Math.Min(hf, data.Length - 1)];
                return((float)(lower + (h - hf) * (upper - lower)));
            }

            case QuantileDefinition.R7:
            {
                double h     = (data.Length - 1) * tau + 1d;
                var    hf    = (int)h;
                var    lower = data[Math.Max(hf - 1, 0)];
                var    upper = data[Math.Min(hf, data.Length - 1)];
                return((float)(lower + (h - hf) * (upper - lower)));
            }

            case QuantileDefinition.R8:
            {
                double h     = (data.Length + 1 / 3d) * tau + 1 / 3d;
                var    hf    = (int)h;
                var    lower = data[Math.Max(hf - 1, 0)];
                var    upper = data[Math.Min(hf, data.Length - 1)];
                return((float)(lower + (h - hf) * (upper - lower)));
            }

            case QuantileDefinition.R9:
            {
                double h     = (data.Length + 0.25d) * tau + 0.375d;
                var    hf    = (int)h;
                var    lower = data[Math.Max(hf - 1, 0)];
                var    upper = data[Math.Min(hf, data.Length - 1)];
                return((float)(lower + (h - hf) * (upper - lower)));
            }

            default:
                throw new NotSupportedException();
            }
        }
Example #18
0
        /// <summary>
        /// Estimates the tau-th quantile from the provided samples.
        /// The tau-th quantile is the data value where the cumulative distribution
        /// function crosses tau. The quantile definition can be specificed to be compatible
        /// with an existing system.
        /// </summary>
        /// <param name="data">The data sample sequence.</param>
        /// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
        public static Func <double, double> QuantileCustomFunc(this IEnumerable <double?> data, QuantileDefinition definition)
        {
            var array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray();

            Array.Sort(array);
            return(tau => SortedArrayStatistics.QuantileCustom(array, tau, definition));
        }
        /// <summary>
        /// Estimates the tau-th quantile from the unsorted data array.
        /// The tau-th quantile is the data value where the cumulative distribution
        /// function crosses tau. The quantile definition can be specified to be compatible
        /// with an existing system.
        /// WARNING: Works inplace and can thus causes the data array to be reordered.
        /// </summary>
        /// <param name="data">Sample array, no sorting is assumed. Will be reordered.</param>
        /// <param name="tau">Quantile selector, between Zero and One (inclusive)</param>
        /// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
        public static decimal QuantileCustomInplace(decimal[] data, decimal tau, QuantileDefinition definition)
        {
            if (tau < Zero || tau > One || data.Length == 0)
            {
                return(NaN);
            }

            if (tau == Zero || data.Length == 1)
            {
                return(Minimum(data));
            }

            if (tau == One)
            {
                return(Maximum(data));
            }

            switch (definition)
            {
            case QuantileDefinition.R1:
            {
                var h = data.Length * tau + Half;
                return(SelectInplace(data, (int)Ceiling(h - Half) - 1));
            }

            case QuantileDefinition.R2:
            {
                var h = data.Length * tau + Half;
                return((SelectInplace(data, (int)Ceiling(h - Half) - 1) + SelectInplace(data, (int)(h + Half) - 1)) * Half);
            }

            case QuantileDefinition.R3:
            {
                var h = data.Length * tau;
                return(SelectInplace(data, (int)Round(h) - 1));
            }

            case QuantileDefinition.R4:
            {
                var h     = data.Length * tau;
                var hf    = (int)h;
                var lower = SelectInplace(data, hf - 1);
                var upper = SelectInplace(data, hf);
                return(lower + (h - hf) * (upper - lower));
            }

            case QuantileDefinition.R5:
            {
                var h     = data.Length * tau + Half;
                var hf    = (int)h;
                var lower = SelectInplace(data, hf - 1);
                var upper = SelectInplace(data, hf);
                return(lower + (h - hf) * (upper - lower));
            }

            case QuantileDefinition.R6:
            {
                var h     = (data.Length + 1) * tau;
                var hf    = (int)h;
                var lower = SelectInplace(data, hf - 1);
                var upper = SelectInplace(data, hf);
                return(lower + (h - hf) * (upper - lower));
            }

            case QuantileDefinition.R7:
            {
                var h     = (data.Length - 1) * tau + One;
                var hf    = (int)h;
                var lower = SelectInplace(data, hf - 1);
                var upper = SelectInplace(data, hf);
                return(lower + (h - hf) * (upper - lower));
            }

            case QuantileDefinition.R8:
            {
                var h     = (data.Length + Third) * tau + Third;
                var hf    = (int)h;
                var lower = SelectInplace(data, hf - 1);
                var upper = SelectInplace(data, hf);
                return(lower + (h - hf) * (upper - lower));
            }

            case QuantileDefinition.R9:
            {
                var h     = (data.Length + Quarter) * tau + HalfThreeQuarter;
                var hf    = (int)h;
                var lower = SelectInplace(data, hf - 1);
                var upper = SelectInplace(data, hf);
                return(lower + (h - hf) * (upper - lower));
            }

            default:
                throw new NotSupportedException();
            }
        }
 /// <summary>
 /// Estimates the pointwise tau-th quantile from the vectors.
 /// The tau-th quantile is the data value where the cumulative distribution
 /// function crosses tau. The quantile definition can be specified to be compatible
 /// with an existing system.
 /// </summary>
 /// <param name="data">Vector array, where all vectors have the same length.</param>
 /// <param name="tau">Quantile selector, between 0.0 and 1.0 (inclusive)</param>
 /// <param name="definition">Quantile definition, to choose what product/definition it should be consistent with</param>
 public static Vector<double> QuantileCustom(this Vector<double>[] data, double tau, QuantileDefinition definition)
 {
     return data.TransposeArrayMap(array => ArrayStatistics.QuantileCustomInplace(array, tau, definition));
 }