// // Math.NET Numerics, part of the Math.NET Project // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // // Copyright (c) 2009-2015 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, // copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections.Generic; using System.Linq; using Complex = System.Numerics.Complex; namespace IStation.Numerics.Statistics { /// /// Extension methods to return basic statistics on set of data. /// public static class Statistics { /// /// Returns the minimum value in the sample data. /// Returns NaN if data is empty or if any entry is NaN. /// /// The sample data. /// The minimum value in the sample data. public static double Minimum(this IEnumerable data) { return data is double[] array ? ArrayStatistics.Minimum(array) : StreamingStatistics.Minimum(data); } /// /// Returns the minimum value in the sample data. /// Returns NaN if data is empty or if any entry is NaN. /// /// The sample data. /// The minimum value in the sample data. public static float Minimum(this IEnumerable data) { return data is float[] array ? ArrayStatistics.Minimum(array) : StreamingStatistics.Minimum(data); } /// /// Returns the minimum value in the sample data. /// Returns NaN if data is empty or if any entry is NaN. /// Null-entries are ignored. /// /// The sample data. /// The minimum value in the sample data. public static double Minimum(this IEnumerable data) { return StreamingStatistics.Minimum(data.Where(d => d.HasValue).Select(d => d.Value)); } /// /// Returns the maximum value in the sample data. /// Returns NaN if data is empty or if any entry is NaN. /// /// The sample data. /// The maximum value in the sample data. public static double Maximum(this IEnumerable data) { return data is double[] array ? ArrayStatistics.Maximum(array) : StreamingStatistics.Maximum(data); } /// /// Returns the maximum value in the sample data. /// Returns NaN if data is empty or if any entry is NaN. /// /// The sample data. /// The maximum value in the sample data. public static float Maximum(this IEnumerable data) { return data is float[] array ? ArrayStatistics.Maximum(array) : StreamingStatistics.Maximum(data); } /// /// Returns the maximum value in the sample data. /// Returns NaN if data is empty or if any entry is NaN. /// Null-entries are ignored. /// /// The sample data. /// The maximum value in the sample data. public static double Maximum(this IEnumerable data) { return StreamingStatistics.Maximum(data.Where(d => d.HasValue).Select(d => d.Value)); } /// /// Returns the minimum absolute value in the sample data. /// Returns NaN if data is empty or if any entry is NaN. /// /// The sample data. /// The minimum value in the sample data. public static double MinimumAbsolute(this IEnumerable data) { return data is double[] array ? ArrayStatistics.MinimumAbsolute(array) : StreamingStatistics.MinimumAbsolute(data); } /// /// Returns the minimum absolute value in the sample data. /// Returns NaN if data is empty or if any entry is NaN. /// /// The sample data. /// The minimum value in the sample data. public static float MinimumAbsolute(this IEnumerable data) { return data is float[] array ? ArrayStatistics.MinimumAbsolute(array) : StreamingStatistics.MinimumAbsolute(data); } /// /// Returns the maximum absolute value in the sample data. /// Returns NaN if data is empty or if any entry is NaN. /// /// The sample data. /// The maximum value in the sample data. public static double MaximumAbsolute(this IEnumerable data) { return data is double[] array ? ArrayStatistics.MaximumAbsolute(array) : StreamingStatistics.MaximumAbsolute(data); } /// /// Returns the maximum absolute value in the sample data. /// Returns NaN if data is empty or if any entry is NaN. /// /// The sample data. /// The maximum value in the sample data. public static float MaximumAbsolute(this IEnumerable data) { return data is float[] array ? ArrayStatistics.MaximumAbsolute(array) : StreamingStatistics.MaximumAbsolute(data); } /// /// Returns the minimum magnitude and phase value in the sample data. /// Returns NaN if data is empty or if any entry is NaN. /// /// The sample data. /// The minimum value in the sample data. public static Complex MinimumMagnitudePhase(this IEnumerable data) { return data is Complex[] array ? ArrayStatistics.MinimumMagnitudePhase(array) : StreamingStatistics.MinimumMagnitudePhase(data); } /// /// Returns the minimum magnitude and phase value in the sample data. /// Returns NaN if data is empty or if any entry is NaN. /// /// The sample data. /// The minimum value in the sample data. public static Complex32 MinimumMagnitudePhase(this IEnumerable data) { return data is Complex32[] array ? ArrayStatistics.MinimumMagnitudePhase(array) : StreamingStatistics.MinimumMagnitudePhase(data); } /// /// Returns the maximum magnitude and phase value in the sample data. /// Returns NaN if data is empty or if any entry is NaN. /// /// The sample data. /// The minimum value in the sample data. public static Complex MaximumMagnitudePhase(this IEnumerable data) { return data is Complex[] array ? ArrayStatistics.MaximumMagnitudePhase(array) : StreamingStatistics.MaximumMagnitudePhase(data); } /// /// Returns the maximum magnitude and phase value in the sample data. /// Returns NaN if data is empty or if any entry is NaN. /// /// The sample data. /// The minimum value in the sample data. public static Complex32 MaximumMagnitudePhase(this IEnumerable data) { return data is Complex32[] array ? ArrayStatistics.MaximumMagnitudePhase(array) : StreamingStatistics.MaximumMagnitudePhase(data); } /// /// Evaluates the sample mean, an estimate of the population mean. /// Returns NaN if data is empty or if any entry is NaN. /// /// The data to calculate the mean of. /// The mean of the sample. public static double Mean(this IEnumerable data) { return data is double[] array ? ArrayStatistics.Mean(array) : StreamingStatistics.Mean(data); } /// /// Evaluates the sample mean, an estimate of the population mean. /// Returns NaN if data is empty or if any entry is NaN. /// /// The data to calculate the mean of. /// The mean of the sample. public static double Mean(this IEnumerable data) { return data is float[] array ? ArrayStatistics.Mean(array) : StreamingStatistics.Mean(data); } /// /// Evaluates the sample mean, an estimate of the population mean. /// Returns NaN if data is empty or if any entry is NaN. /// Null-entries are ignored. /// /// The data to calculate the mean of. /// The mean of the sample. public static double Mean(this IEnumerable data) { return StreamingStatistics.Mean(data.Where(d => d.HasValue).Select(d => d.Value)); } /// /// Evaluates the geometric mean. /// Returns NaN if data is empty or if any entry is NaN. /// /// The data to calculate the geometric mean of. /// The geometric mean of the sample. public static double GeometricMean(this IEnumerable data) { return data is double[] array ? ArrayStatistics.GeometricMean(array) : StreamingStatistics.GeometricMean(data); } /// /// Evaluates the geometric mean. /// Returns NaN if data is empty or if any entry is NaN. /// /// The data to calculate the geometric mean of. /// The geometric mean of the sample. public static double GeometricMean(this IEnumerable data) { return data is float[] array ? ArrayStatistics.GeometricMean(array) : StreamingStatistics.GeometricMean(data); } /// /// Evaluates the harmonic mean. /// Returns NaN if data is empty or if any entry is NaN. /// /// The data to calculate the harmonic mean of. /// The harmonic mean of the sample. public static double HarmonicMean(this IEnumerable data) { return data is double[] array ? ArrayStatistics.HarmonicMean(array) : StreamingStatistics.HarmonicMean(data); } /// /// Evaluates the harmonic mean. /// Returns NaN if data is empty or if any entry is NaN. /// /// The data to calculate the harmonic mean of. /// The harmonic mean of the sample. public static double HarmonicMean(this IEnumerable data) { return data is float[] array ? ArrayStatistics.HarmonicMean(array) : StreamingStatistics.HarmonicMean(data); } /// /// Estimates the unbiased population variance from the provided samples. /// On a dataset of size N will use an N-1 normalizer (Bessel's correction). /// Returns NaN if data has less than two entries or if any entry is NaN. /// /// A subset of samples, sampled from the full population. public static double Variance(this IEnumerable samples) { return samples is double[] array ? ArrayStatistics.Variance(array) : StreamingStatistics.Variance(samples); } /// /// Estimates the unbiased population variance from the provided samples. /// On a dataset of size N will use an N-1 normalizer (Bessel's correction). /// Returns NaN if data has less than two entries or if any entry is NaN. /// /// A subset of samples, sampled from the full population. public static double Variance(this IEnumerable samples) { return samples is float[] array ? ArrayStatistics.Variance(array) : StreamingStatistics.Variance(samples); } /// /// Estimates the unbiased population variance from the provided samples. /// On a dataset of size N will use an N-1 normalizer (Bessel's correction). /// Returns NaN if data has less than two entries or if any entry is NaN. /// Null-entries are ignored. /// /// A subset of samples, sampled from the full population. public static double Variance(this IEnumerable samples) { return StreamingStatistics.Variance(samples.Where(d => d.HasValue).Select(d => d.Value)); } /// /// Evaluates the variance from the provided full population. /// On a dataset of size N will use an N normalizer and would thus be biased if applied to a subset. /// Returns NaN if data is empty or if any entry is NaN. /// /// The full population data. public static double PopulationVariance(this IEnumerable population) { return population is double[] array ? ArrayStatistics.PopulationVariance(array) : StreamingStatistics.PopulationVariance(population); } /// /// Evaluates the variance from the provided full population. /// On a dataset of size N will use an N normalizer and would thus be biased if applied to a subset. /// Returns NaN if data is empty or if any entry is NaN. /// /// The full population data. public static double PopulationVariance(this IEnumerable population) { return population is float[] array ? ArrayStatistics.PopulationVariance(array) : StreamingStatistics.PopulationVariance(population); } /// /// Evaluates the variance from the provided full population. /// On a dataset of size N will use an N normalize and would thus be biased if applied to a subset. /// Returns NaN if data is empty or if any entry is NaN. /// Null-entries are ignored. /// /// The full population data. public static double PopulationVariance(this IEnumerable population) { return StreamingStatistics.PopulationVariance(population.Where(d => d.HasValue).Select(d => d.Value)); } /// /// Estimates the unbiased population standard deviation from the provided samples. /// On a dataset of size N will use an N-1 normalizer (Bessel's correction). /// Returns NaN if data has less than two entries or if any entry is NaN. /// /// A subset of samples, sampled from the full population. public static double StandardDeviation(this IEnumerable samples) { return samples is double[] array ? ArrayStatistics.StandardDeviation(array) : StreamingStatistics.StandardDeviation(samples); } /// /// Estimates the unbiased population standard deviation from the provided samples. /// On a dataset of size N will use an N-1 normalizer (Bessel's correction). /// Returns NaN if data has less than two entries or if any entry is NaN. /// /// A subset of samples, sampled from the full population. public static double StandardDeviation(this IEnumerable samples) { return samples is float[] array ? ArrayStatistics.StandardDeviation(array) : StreamingStatistics.StandardDeviation(samples); } /// /// Estimates the unbiased population standard deviation from the provided samples. /// On a dataset of size N will use an N-1 normalizer (Bessel's correction). /// Returns NaN if data has less than two entries or if any entry is NaN. /// Null-entries are ignored. /// /// A subset of samples, sampled from the full population. public static double StandardDeviation(this IEnumerable samples) { return StreamingStatistics.StandardDeviation(samples.Where(d => d.HasValue).Select(d => d.Value)); } /// /// Evaluates the standard deviation from the provided full population. /// On a dataset of size N will use an N normalizer and would thus be biased if applied to a subset. /// Returns NaN if data is empty or if any entry is NaN. /// /// The full population data. public static double PopulationStandardDeviation(this IEnumerable population) { return population is double[] array ? ArrayStatistics.PopulationStandardDeviation(array) : StreamingStatistics.PopulationStandardDeviation(population); } /// /// Evaluates the standard deviation from the provided full population. /// On a dataset of size N will use an N normalizer and would thus be biased if applied to a subset. /// Returns NaN if data is empty or if any entry is NaN. /// /// The full population data. public static double PopulationStandardDeviation(this IEnumerable population) { return population is float[] array ? ArrayStatistics.PopulationStandardDeviation(array) : StreamingStatistics.PopulationStandardDeviation(population); } /// /// Evaluates the standard deviation from the provided full population. /// On a dataset of size N will use an N normalizer and would thus be biased if applied to a subset. /// Returns NaN if data is empty or if any entry is NaN. /// Null-entries are ignored. /// /// The full population data. public static double PopulationStandardDeviation(this IEnumerable population) { return StreamingStatistics.PopulationStandardDeviation(population.Where(d => d.HasValue).Select(d => d.Value)); } /// /// Estimates the unbiased population skewness from the provided samples. /// Uses a normalizer (Bessel's correction; type 2). /// Returns NaN if data has less than three entries or if any entry is NaN. /// /// A subset of samples, sampled from the full population. public static double Skewness(this IEnumerable samples) { return new RunningStatistics(samples).Skewness; } /// /// Estimates the unbiased population skewness from the provided samples. /// Uses a normalizer (Bessel's correction; type 2). /// Returns NaN if data has less than three entries or if any entry is NaN. /// Null-entries are ignored. /// /// A subset of samples, sampled from the full population. public static double Skewness(this IEnumerable samples) { return new RunningStatistics(samples.Where(d => d.HasValue).Select(d => d.Value)).Skewness; } /// /// Evaluates the skewness from the full population. /// Does not use a normalizer and would thus be biased if applied to a subset (type 1). /// Returns NaN if data has less than two entries or if any entry is NaN. /// /// The full population data. public static double PopulationSkewness(this IEnumerable population) { return new RunningStatistics(population).PopulationSkewness; } /// /// Evaluates the skewness from the full population. /// Does not use a normalizer and would thus be biased if applied to a subset (type 1). /// Returns NaN if data has less than two entries or if any entry is NaN. /// Null-entries are ignored. /// /// The full population data. public static double PopulationSkewness(this IEnumerable population) { return new RunningStatistics(population.Where(d => d.HasValue).Select(d => d.Value)).PopulationSkewness; } /// /// Estimates the unbiased population kurtosis from the provided samples. /// Uses a normalizer (Bessel's correction; type 2). /// Returns NaN if data has less than four entries or if any entry is NaN. /// /// A subset of samples, sampled from the full population. public static double Kurtosis(this IEnumerable samples) { return new RunningStatistics(samples).Kurtosis; } /// /// Estimates the unbiased population kurtosis from the provided samples. /// Uses a normalizer (Bessel's correction; type 2). /// Returns NaN if data has less than four entries or if any entry is NaN. /// Null-entries are ignored. /// /// A subset of samples, sampled from the full population. public static double Kurtosis(this IEnumerable samples) { return new RunningStatistics(samples.Where(d => d.HasValue).Select(d => d.Value)).Kurtosis; } /// /// Evaluates the kurtosis from the full population. /// Does not use a normalizer and would thus be biased if applied to a subset (type 1). /// Returns NaN if data has less than three entries or if any entry is NaN. /// /// The full population data. public static double PopulationKurtosis(this IEnumerable population) { return new RunningStatistics(population).PopulationKurtosis; } /// /// Evaluates the kurtosis from the full population. /// Does not use a normalizer and would thus be biased if applied to a subset (type 1). /// Returns NaN if data has less than three entries or if any entry is NaN. /// Null-entries are ignored. /// /// The full population data. public static double PopulationKurtosis(this IEnumerable population) { return new RunningStatistics(population.Where(d => d.HasValue).Select(d => d.Value)).PopulationKurtosis; } /// /// Estimates the sample mean and the unbiased population variance from the provided samples. /// On a dataset of size N will use an N-1 normalizer (Bessel's correction). /// Returns NaN for mean if data is empty or if any entry is NaN and NaN for variance if data has less than two entries or if any entry is NaN. /// /// The data to calculate the mean of. /// The mean of the sample. public static Tuple MeanVariance(this IEnumerable samples) { return samples is double[] array ? ArrayStatistics.MeanVariance(array) : StreamingStatistics.MeanVariance(samples); } /// /// Estimates the sample mean and the unbiased population variance from the provided samples. /// On a dataset of size N will use an N-1 normalizer (Bessel's correction). /// Returns NaN for mean if data is empty or if any entry is NaN and NaN for variance if data has less than two entries or if any entry is NaN. /// /// The data to calculate the mean of. /// The mean of the sample. public static Tuple MeanVariance(this IEnumerable samples) { return samples is float[] array ? ArrayStatistics.MeanVariance(array) : StreamingStatistics.MeanVariance(samples); } /// /// Estimates the sample mean and the unbiased population standard deviation from the provided samples. /// On a dataset of size N will use an N-1 normalizer (Bessel's correction). /// Returns NaN for mean if data is empty or if any entry is NaN and NaN for standard deviation if data has less than two entries or if any entry is NaN. /// /// The data to calculate the mean of. /// The mean of the sample. public static Tuple MeanStandardDeviation(this IEnumerable samples) { return samples is double[] array ? ArrayStatistics.MeanStandardDeviation(array) : StreamingStatistics.MeanStandardDeviation(samples); } /// /// Estimates the sample mean and the unbiased population standard deviation from the provided samples. /// On a dataset of size N will use an N-1 normalizer (Bessel's correction). /// Returns NaN for mean if data is empty or if any entry is NaN and NaN for standard deviation if data has less than two entries or if any entry is NaN. /// /// The data to calculate the mean of. /// The mean of the sample. public static Tuple MeanStandardDeviation(this IEnumerable samples) { return samples is float[] array ? ArrayStatistics.MeanStandardDeviation(array) : StreamingStatistics.MeanStandardDeviation(samples); } /// /// Estimates the unbiased population skewness and kurtosis from the provided samples in a single pass. /// Uses a normalizer (Bessel's correction; type 2). /// /// A subset of samples, sampled from the full population. public static Tuple SkewnessKurtosis(this IEnumerable samples) { var stats = new RunningStatistics(samples); return new Tuple(stats.Skewness, stats.Kurtosis); } /// /// Evaluates the skewness and kurtosis from the full population. /// Does not use a normalizer and would thus be biased if applied to a subset (type 1). /// /// The full population data. public static Tuple PopulationSkewnessKurtosis(this IEnumerable population) { var stats = new RunningStatistics(population); return new Tuple(stats.PopulationSkewness, stats.PopulationKurtosis); } /// /// Estimates the unbiased population covariance from the provided samples. /// On a dataset of size N will use an N-1 normalizer (Bessel's correction). /// Returns NaN if data has less than two entries or if any entry is NaN. /// /// A subset of samples, sampled from the full population. /// A subset of samples, sampled from the full population. public static double Covariance(this IEnumerable samples1, IEnumerable samples2) { return samples1 is double[] array1 && samples2 is double[] array2 ? ArrayStatistics.Covariance(array1, array2) : StreamingStatistics.Covariance(samples1, samples2); } /// /// Estimates the unbiased population covariance from the provided samples. /// On a dataset of size N will use an N-1 normalizer (Bessel's correction). /// Returns NaN if data has less than two entries or if any entry is NaN. /// /// A subset of samples, sampled from the full population. /// A subset of samples, sampled from the full population. public static double Covariance(this IEnumerable samples1, IEnumerable samples2) { return samples1 is float[] array1 && samples2 is float[] array2 ? ArrayStatistics.Covariance(array1, array2) : StreamingStatistics.Covariance(samples1, samples2); } /// /// Estimates the unbiased population covariance from the provided samples. /// On a dataset of size N will use an N-1 normalizer (Bessel's correction). /// Returns NaN if data has less than two entries or if any entry is NaN. /// Null-entries are ignored. /// /// A subset of samples, sampled from the full population. /// A subset of samples, sampled from the full population. public static double Covariance(this IEnumerable samples1, IEnumerable samples2) { return StreamingStatistics.Covariance(samples1.Where(d => d.HasValue).Select(d => d.Value), samples2.Where(d => d.HasValue).Select(d => d.Value)); } /// /// Evaluates the population covariance from the provided full populations. /// On a dataset of size N will use an N normalizer and would thus be biased if applied to a subset. /// Returns NaN if data is empty or if any entry is NaN. /// /// The full population data. /// The full population data. public static double PopulationCovariance(this IEnumerable population1, IEnumerable population2) { return population1 is double[] array1 && population2 is double[] array2 ? ArrayStatistics.PopulationCovariance(array1, array2) : StreamingStatistics.PopulationCovariance(population1, population2); } /// /// Evaluates the population covariance from the provided full populations. /// On a dataset of size N will use an N normalizer and would thus be biased if applied to a subset. /// Returns NaN if data is empty or if any entry is NaN. /// /// The full population data. /// The full population data. public static double PopulationCovariance(this IEnumerable population1, IEnumerable population2) { return population1 is float[] array1 && population2 is float[] array2 ? ArrayStatistics.PopulationCovariance(array1, array2) : StreamingStatistics.PopulationCovariance(population1, population2); } /// /// Evaluates the population covariance from the provided full populations. /// On a dataset of size N will use an N normalize and would thus be biased if applied to a subset. /// Returns NaN if data is empty or if any entry is NaN. /// Null-entries are ignored. /// /// The full population data. /// The full population data. public static double PopulationCovariance(this IEnumerable population1, IEnumerable population2) { return StreamingStatistics.PopulationCovariance(population1.Where(d => d.HasValue).Select(d => d.Value), population2.Where(d => d.HasValue).Select(d => d.Value)); } /// /// Evaluates the root mean square (RMS) also known as quadratic mean. /// Returns NaN if data is empty or if any entry is NaN. /// /// The data to calculate the RMS of. public static double RootMeanSquare(this IEnumerable data) { return data is double[] array ? ArrayStatistics.RootMeanSquare(array) : StreamingStatistics.RootMeanSquare(data); } /// /// Evaluates the root mean square (RMS) also known as quadratic mean. /// Returns NaN if data is empty or if any entry is NaN. /// /// The data to calculate the RMS of. public static double RootMeanSquare(this IEnumerable data) { return data is float[] array ? ArrayStatistics.RootMeanSquare(array) : StreamingStatistics.RootMeanSquare(data); } /// /// Evaluates the root mean square (RMS) also known as quadratic mean. /// Returns NaN if data is empty or if any entry is NaN. /// Null-entries are ignored. /// /// The data to calculate the mean of. public static double RootMeanSquare(this IEnumerable data) { return StreamingStatistics.RootMeanSquare(data.Where(d => d.HasValue).Select(d => d.Value)); } /// /// Estimates the sample median from the provided samples (R8). /// /// The data sample sequence. public static double Median(this IEnumerable data) { double[] array = data.ToArray(); return ArrayStatistics.MedianInplace(array); } /// /// Estimates the sample median from the provided samples (R8). /// /// The data sample sequence. public static float Median(this IEnumerable data) { float[] array = data.ToArray(); return ArrayStatistics.MedianInplace(array); } /// /// Estimates the sample median from the provided samples (R8). /// /// The data sample sequence. public static double Median(this IEnumerable data) { double[] array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray(); return ArrayStatistics.MedianInplace(array); } /// /// Estimates the tau-th quantile from the provided samples. /// The tau-th quantile is the data value where the cumulative distribution /// function crosses tau. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. /// Quantile selector, between 0.0 and 1.0 (inclusive). public static double Quantile(this IEnumerable data, double tau) { double[] array = data.ToArray(); return ArrayStatistics.QuantileInplace(array, tau); } /// /// Estimates the tau-th quantile from the provided samples. /// The tau-th quantile is the data value where the cumulative distribution /// function crosses tau. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. /// Quantile selector, between 0.0 and 1.0 (inclusive). public static float Quantile(this IEnumerable data, double tau) { float[] array = data.ToArray(); return ArrayStatistics.QuantileInplace(array, tau); } /// /// Estimates the tau-th quantile from the provided samples. /// The tau-th quantile is the data value where the cumulative distribution /// function crosses tau. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. /// Quantile selector, between 0.0 and 1.0 (inclusive). public static double Quantile(this IEnumerable data, double tau) { double[] array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray(); return ArrayStatistics.QuantileInplace(array, tau); } /// /// Estimates the tau-th quantile from the provided samples. /// The tau-th quantile is the data value where the cumulative distribution /// function crosses tau. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. public static Func QuantileFunc(this IEnumerable data) { double[] array = data.ToArray(); Array.Sort(array); return tau => SortedArrayStatistics.Quantile(array, tau); } /// /// Estimates the tau-th quantile from the provided samples. /// The tau-th quantile is the data value where the cumulative distribution /// function crosses tau. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. public static Func QuantileFunc(this IEnumerable data) { float[] array = data.ToArray(); Array.Sort(array); return tau => SortedArrayStatistics.Quantile(array, tau); } /// /// Estimates the tau-th quantile from the provided samples. /// The tau-th quantile is the data value where the cumulative distribution /// function crosses tau. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. public static Func QuantileFunc(this IEnumerable data) { double[] array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray(); Array.Sort(array); return tau => SortedArrayStatistics.Quantile(array, tau); } /// /// 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. /// /// The data sample sequence. /// Quantile selector, between 0.0 and 1.0 (inclusive). /// Quantile definition, to choose what product/definition it should be consistent with public static double QuantileCustom(this IEnumerable data, double tau, QuantileDefinition definition) { double[] array = data.ToArray(); return ArrayStatistics.QuantileCustomInplace(array, tau, definition); } /// /// 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. /// /// The data sample sequence. /// Quantile selector, between 0.0 and 1.0 (inclusive). /// Quantile definition, to choose what product/definition it should be consistent with public static float QuantileCustom(this IEnumerable data, double tau, QuantileDefinition definition) { float[] array = data.ToArray(); return ArrayStatistics.QuantileCustomInplace(array, tau, definition); } /// /// 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. /// /// The data sample sequence. /// Quantile selector, between 0.0 and 1.0 (inclusive). /// Quantile definition, to choose what product/definition it should be consistent with public static double QuantileCustom(this IEnumerable data, double tau, QuantileDefinition definition) { double[] array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray(); return ArrayStatistics.QuantileCustomInplace(array, tau, definition); } /// /// 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. /// /// The data sample sequence. /// Quantile definition, to choose what product/definition it should be consistent with public static Func QuantileCustomFunc(this IEnumerable data, QuantileDefinition definition) { double[] array = data.ToArray(); Array.Sort(array); return tau => SortedArrayStatistics.QuantileCustom(array, tau, definition); } /// /// 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. /// /// The data sample sequence. /// Quantile definition, to choose what product/definition it should be consistent with public static Func QuantileCustomFunc(this IEnumerable data, QuantileDefinition definition) { float[] array = data.ToArray(); Array.Sort(array); return tau => SortedArrayStatistics.QuantileCustom(array, tau, definition); } /// /// 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. /// /// The data sample sequence. /// Quantile definition, to choose what product/definition it should be consistent with public static Func QuantileCustomFunc(this IEnumerable data, QuantileDefinition definition) { double[] array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray(); Array.Sort(array); return tau => SortedArrayStatistics.QuantileCustom(array, tau, definition); } /// /// Estimates the p-Percentile value from the provided samples. /// If a non-integer Percentile is needed, use Quantile instead. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. /// Percentile selector, between 0 and 100 (inclusive). public static double Percentile(this IEnumerable data, int p) { double[] array = data.ToArray(); return ArrayStatistics.PercentileInplace(array, p); } /// /// Estimates the p-Percentile value from the provided samples. /// If a non-integer Percentile is needed, use Quantile instead. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. /// Percentile selector, between 0 and 100 (inclusive). public static float Percentile(this IEnumerable data, int p) { float[] array = data.ToArray(); return ArrayStatistics.PercentileInplace(array, p); } /// /// Estimates the p-Percentile value from the provided samples. /// If a non-integer Percentile is needed, use Quantile instead. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. /// Percentile selector, between 0 and 100 (inclusive). public static double Percentile(this IEnumerable data, int p) { double[] array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray(); return ArrayStatistics.PercentileInplace(array, p); } /// /// Estimates the p-Percentile value from the provided samples. /// If a non-integer Percentile is needed, use Quantile instead. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. public static Func PercentileFunc(this IEnumerable data) { double[] array = data.ToArray(); Array.Sort(array); return p => SortedArrayStatistics.Percentile(array, p); } /// /// Estimates the p-Percentile value from the provided samples. /// If a non-integer Percentile is needed, use Quantile instead. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. public static Func PercentileFunc(this IEnumerable data) { float[] array = data.ToArray(); Array.Sort(array); return p => SortedArrayStatistics.Percentile(array, p); } /// /// Estimates the p-Percentile value from the provided samples. /// If a non-integer Percentile is needed, use Quantile instead. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. public static Func PercentileFunc(this IEnumerable data) { double[] array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray(); Array.Sort(array); return p => SortedArrayStatistics.Percentile(array, p); } /// /// Estimates the first quartile value from the provided samples. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. public static double LowerQuartile(this IEnumerable data) { double[] array = data.ToArray(); return ArrayStatistics.LowerQuartileInplace(array); } /// /// Estimates the first quartile value from the provided samples. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. public static float LowerQuartile(this IEnumerable data) { float[] array = data.ToArray(); return ArrayStatistics.LowerQuartileInplace(array); } /// /// Estimates the first quartile value from the provided samples. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. public static double LowerQuartile(this IEnumerable data) { double[] array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray(); return ArrayStatistics.LowerQuartileInplace(array); } /// /// Estimates the third quartile value from the provided samples. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. public static double UpperQuartile(this IEnumerable data) { double[] array = data.ToArray(); return ArrayStatistics.UpperQuartileInplace(array); } /// /// Estimates the third quartile value from the provided samples. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. public static float UpperQuartile(this IEnumerable data) { float[] array = data.ToArray(); return ArrayStatistics.UpperQuartileInplace(array); } /// /// Estimates the third quartile value from the provided samples. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. public static double UpperQuartile(this IEnumerable data) { double[] array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray(); return ArrayStatistics.UpperQuartileInplace(array); } /// /// Estimates the inter-quartile range from the provided samples. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. public static double InterquartileRange(this IEnumerable data) { double[] array = data.ToArray(); return ArrayStatistics.InterquartileRangeInplace(array); } /// /// Estimates the inter-quartile range from the provided samples. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. public static float InterquartileRange(this IEnumerable data) { float[] array = data.ToArray(); return ArrayStatistics.InterquartileRangeInplace(array); } /// /// Estimates the inter-quartile range from the provided samples. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. public static double InterquartileRange(this IEnumerable data) { double[] array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray(); return ArrayStatistics.InterquartileRangeInplace(array); } /// /// Estimates {min, lower-quantile, median, upper-quantile, max} from the provided samples. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. public static double[] FiveNumberSummary(this IEnumerable data) { double[] array = data.ToArray(); return ArrayStatistics.FiveNumberSummaryInplace(array); } /// /// Estimates {min, lower-quantile, median, upper-quantile, max} from the provided samples. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. public static float[] FiveNumberSummary(this IEnumerable data) { float[] array = data.ToArray(); return ArrayStatistics.FiveNumberSummaryInplace(array); } /// /// Estimates {min, lower-quantile, median, upper-quantile, max} from the provided samples. /// Approximately median-unbiased regardless of the sample distribution (R8). /// /// The data sample sequence. public static double[] FiveNumberSummary(this IEnumerable data) { double[] array = data.Where(d => d.HasValue).Select(d => d.Value).ToArray(); return ArrayStatistics.FiveNumberSummaryInplace(array); } /// /// Returns the order statistic (order 1..N) from the provided samples. /// /// The data sample sequence. /// One-based order of the statistic, must be between 1 and N (inclusive). public static double OrderStatistic(IEnumerable data, int order) { double[] array = data.ToArray(); return ArrayStatistics.OrderStatisticInplace(array, order); } /// /// Returns the order statistic (order 1..N) from the provided samples. /// /// The data sample sequence. /// One-based order of the statistic, must be between 1 and N (inclusive). public static float OrderStatistic(IEnumerable data, int order) { float[] array = data.ToArray(); return ArrayStatistics.OrderStatisticInplace(array, order); } /// /// Returns the order statistic (order 1..N) from the provided samples. /// /// The data sample sequence. public static Func OrderStatisticFunc(IEnumerable data) { double[] array = data.ToArray(); Array.Sort(array); return order => SortedArrayStatistics.OrderStatistic(array, order); } /// /// Returns the order statistic (order 1..N) from the provided samples. /// /// The data sample sequence. public static Func OrderStatisticFunc(IEnumerable data) { float[] array = data.ToArray(); Array.Sort(array); return order => SortedArrayStatistics.OrderStatistic(array, order); } /// /// Evaluates the rank of each entry of the provided samples. /// The rank definition can be specified to be compatible /// with an existing system. /// /// The data sample sequence. /// Rank definition, to choose how ties should be handled and what product/definition it should be consistent with public static double[] Ranks(this IEnumerable data, RankDefinition definition = RankDefinition.Default) { double[] array = data.ToArray(); return ArrayStatistics.RanksInplace(array, definition); } /// /// Evaluates the rank of each entry of the provided samples. /// The rank definition can be specified to be compatible /// with an existing system. /// /// The data sample sequence. /// Rank definition, to choose how ties should be handled and what product/definition it should be consistent with public static float[] Ranks(this IEnumerable data, RankDefinition definition = RankDefinition.Default) { float[] array = data.ToArray(); return ArrayStatistics.RanksInplace(array, definition); } /// /// Evaluates the rank of each entry of the provided samples. /// The rank definition can be specified to be compatible /// with an existing system. /// /// The data sample sequence. /// Rank definition, to choose how ties should be handled and what product/definition it should be consistent with public static double[] Ranks(this IEnumerable data, RankDefinition definition = RankDefinition.Default) { return Ranks(data.Where(d => d.HasValue).Select(d => d.Value), definition); } /// /// Estimates the quantile tau 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. /// /// The data sample sequence. /// Quantile value. /// Rank definition, to choose how ties should be handled and what product/definition it should be consistent with public static double QuantileRank(this IEnumerable data, double x, RankDefinition definition = RankDefinition.Default) { double[] array = data.ToArray(); Array.Sort(array); return SortedArrayStatistics.QuantileRank(array, x, definition); } /// /// Estimates the quantile tau 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. /// /// The data sample sequence. /// Quantile value. /// Rank definition, to choose how ties should be handled and what product/definition it should be consistent with public static double QuantileRank(this IEnumerable data, float x, RankDefinition definition = RankDefinition.Default) { float[] array = data.ToArray(); Array.Sort(array); return SortedArrayStatistics.QuantileRank(array, x, definition); } /// /// Estimates the quantile tau 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. /// /// The data sample sequence. /// Quantile value. /// Rank definition, to choose how ties should be handled and what product/definition it should be consistent with public static double QuantileRank(this IEnumerable data, double x, RankDefinition definition = RankDefinition.Default) { return QuantileRank(data.Where(d => d.HasValue).Select(d => d.Value), x, definition); } /// /// Estimates the quantile tau 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. /// /// The data sample sequence. /// Rank definition, to choose how ties should be handled and what product/definition it should be consistent with public static Func QuantileRankFunc(this IEnumerable data, RankDefinition definition = RankDefinition.Default) { double[] array = data.ToArray(); Array.Sort(array); return x => SortedArrayStatistics.QuantileRank(array, x, definition); } /// /// Estimates the quantile tau 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. /// /// The data sample sequence. /// Rank definition, to choose how ties should be handled and what product/definition it should be consistent with public static Func QuantileRankFunc(this IEnumerable data, RankDefinition definition = RankDefinition.Default) { float[] array = data.ToArray(); Array.Sort(array); return x => SortedArrayStatistics.QuantileRank(array, x, definition); } /// /// Estimates the quantile tau 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. /// /// The data sample sequence. /// Rank definition, to choose how ties should be handled and what product/definition it should be consistent with public static Func QuantileRankFunc(this IEnumerable data, RankDefinition definition = RankDefinition.Default) { return QuantileRankFunc(data.Where(d => d.HasValue).Select(d => d.Value), definition); } /// /// Estimates the empirical cumulative distribution function (CDF) at x from the provided samples. /// /// The data sample sequence. /// The value where to estimate the CDF at. public static double EmpiricalCDF(this IEnumerable data, double x) { double[] array = data.ToArray(); Array.Sort(array); return SortedArrayStatistics.EmpiricalCDF(array, x); } /// /// Estimates the empirical cumulative distribution function (CDF) at x from the provided samples. /// /// The data sample sequence. /// The value where to estimate the CDF at. public static double EmpiricalCDF(this IEnumerable data, float x) { float[] array = data.ToArray(); Array.Sort(array); return SortedArrayStatistics.EmpiricalCDF(array, x); } /// /// Estimates the empirical cumulative distribution function (CDF) at x from the provided samples. /// /// The data sample sequence. /// The value where to estimate the CDF at. public static double EmpiricalCDF(this IEnumerable data, double x) { return EmpiricalCDF(data.Where(d => d.HasValue).Select(d => d.Value), x); } /// /// Estimates the empirical cumulative distribution function (CDF) at x from the provided samples. /// /// The data sample sequence. public static Func EmpiricalCDFFunc(this IEnumerable data) { double[] array = data.ToArray(); Array.Sort(array); return x => SortedArrayStatistics.EmpiricalCDF(array, x); } /// /// Estimates the empirical cumulative distribution function (CDF) at x from the provided samples. /// /// The data sample sequence. public static Func EmpiricalCDFFunc(this IEnumerable data) { float[] array = data.ToArray(); Array.Sort(array); return x => SortedArrayStatistics.EmpiricalCDF(array, x); } /// /// Estimates the empirical cumulative distribution function (CDF) at x from the provided samples. /// /// The data sample sequence. public static Func EmpiricalCDFFunc(this IEnumerable data) { return EmpiricalCDFFunc(data.Where(d => d.HasValue).Select(d => d.Value)); } /// /// Estimates the empirical inverse CDF at tau from the provided samples. /// /// The data sample sequence. /// Quantile selector, between 0.0 and 1.0 (inclusive). public static double EmpiricalInvCDF(this IEnumerable data, double tau) { double[] array = data.ToArray(); return ArrayStatistics.QuantileCustomInplace(array, tau, QuantileDefinition.EmpiricalInvCDF); } /// /// Estimates the empirical inverse CDF at tau from the provided samples. /// /// The data sample sequence. /// Quantile selector, between 0.0 and 1.0 (inclusive). public static float EmpiricalInvCDF(this IEnumerable data, double tau) { float[] array = data.ToArray(); return ArrayStatistics.QuantileCustomInplace(array, tau, QuantileDefinition.EmpiricalInvCDF); } /// /// Estimates the empirical inverse CDF at tau from the provided samples. /// /// The data sample sequence. /// Quantile selector, between 0.0 and 1.0 (inclusive). public static double EmpiricalInvCDF(this IEnumerable data, double tau) { return EmpiricalInvCDF(data.Where(d => d.HasValue).Select(d => d.Value), tau); } /// /// Estimates the empirical inverse CDF at tau from the provided samples. /// /// The data sample sequence. public static Func EmpiricalInvCDFFunc(this IEnumerable data) { double[] array = data.ToArray(); Array.Sort(array); return tau => SortedArrayStatistics.QuantileCustom(array, tau, QuantileDefinition.EmpiricalInvCDF); } /// /// Estimates the empirical inverse CDF at tau from the provided samples. /// /// The data sample sequence. public static Func EmpiricalInvCDFFunc(this IEnumerable data) { float[] array = data.ToArray(); Array.Sort(array); return tau => SortedArrayStatistics.QuantileCustom(array, tau, QuantileDefinition.EmpiricalInvCDF); } /// /// Estimates the empirical inverse CDF at tau from the provided samples. /// /// The data sample sequence. public static Func EmpiricalInvCDFFunc(this IEnumerable data) { return EmpiricalInvCDFFunc(data.Where(d => d.HasValue).Select(d => d.Value)); } /// /// Calculates the entropy of a stream of double values in bits. /// Returns NaN if any of the values in the stream are NaN. /// /// The data sample sequence. public static double Entropy(IEnumerable data) { return StreamingStatistics.Entropy(data); } /// /// Calculates the entropy of a stream of double values in bits. /// Returns NaN if any of the values in the stream are NaN. /// Null-entries are ignored. /// /// The data sample sequence. public static double Entropy(IEnumerable data) { return StreamingStatistics.Entropy(data.Where(d => d.HasValue).Select(d => d.Value)); } /// /// Evaluates the sample mean over a moving window, for each samples. /// Returns NaN if no data is empty or if any entry is NaN. /// /// The sample stream to calculate the mean of. /// The number of last samples to consider. public static IEnumerable MovingAverage(this IEnumerable samples, int windowSize) { var movingStatistics = new MovingStatistics(windowSize); return samples.Select(sample => { movingStatistics.Push(sample); return movingStatistics.Mean; }); } } }