123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace ScottPlot.Statistics
- {
- /// <summary>
- /// This module holds an array of values and provides popultation statistics (mean, median, standard deviation, etc)
- /// </summary>
- public class Population
- {
- public double[] values { get; private set; }
- public double[] sortedValues { get; private set; }
- public double min { get; private set; }
- public double max { get; private set; }
- public double median { get; private set; }
- public double sum { get; private set; }
- public int count { get; private set; }
- public double mean { get; private set; }
- public double stDev { get; private set; }
- public double plus3stDev { get; private set; }
- public double minus3stDev { get; private set; }
- public double plus2stDev { get; private set; }
- public double minus2stDev { get; private set; }
- public double stdErr { get; private set; }
- public double Q1 { get; private set; }
- public double Q3 { get; private set; }
- public double IQR { get; private set; }
- public double[] lowOutliers { get; private set; }
- public double[] highOutliers { get; private set; }
- public double maxNonOutlier { get; private set; }
- public double minNonOutlier { get; private set; }
- public int n { get { return values.Length; } }
- public double span { get { return sortedValues.Last() - sortedValues.First(); } }
- /// <summary>
- /// Generate random values with a normal distribution
- /// </summary>
- public Population(Random rand, int pointCount, double mean = .5, double stdDev = .5)
- {
- values = DataGen.RandomNormal(rand, pointCount, mean, stdDev);
- Recalculate();
- }
- /// <summary>
- /// Calculate population stats from the given array of values
- /// </summary>
- public Population(double[] values)
- {
- if (values is null)
- throw new ArgumentException("values cannot be null");
- this.values = values;
- Recalculate();
- }
- [Obsolete("This constructor overload is deprecated. Please remove the fullAnalysis argument.")]
- public Population(double[] values, bool fullAnalysis = true)
- {
- if (values is null)
- throw new ArgumentException("values cannot be null");
- this.values = values;
- if (fullAnalysis)
- Recalculate();
- }
- public void Recalculate()
- {
- count = values.Length;
- int QSize = (int)Math.Floor(count / 4.0);
- sortedValues = new double[count];
- Array.Copy(values, 0, sortedValues, 0, count);
- Array.Sort(sortedValues);
- min = sortedValues.First();
- max = sortedValues.Last();
- median = sortedValues[count / 2];
- Q1 = sortedValues[QSize];
- Q3 = sortedValues[sortedValues.Length - QSize - 1];
- IQR = Q3 - Q1;
- double lowerBoundary = Q1 - 1.5 * IQR;
- double upperBoundary = Q3 + 1.5 * IQR;
- int minNonOutlierIndex = 0;
- int maxNonOutlierIndex = 0;
- for (int i = 0; i < sortedValues.Length; i++)
- {
- if (sortedValues[i] < lowerBoundary)
- {
- }
- else
- {
- minNonOutlierIndex = i;
- break;
- }
- }
- for (int i = sortedValues.Length - 1; i >= 0; i--)
- {
- if (sortedValues[i] > upperBoundary)
- {
- }
- else
- {
- maxNonOutlierIndex = i;
- break;
- }
- }
- lowOutliers = new double[minNonOutlierIndex];
- highOutliers = new double[sortedValues.Length - maxNonOutlierIndex - 1];
- Array.Copy(sortedValues, 0, lowOutliers, 0, lowOutliers.Length);
- Array.Copy(sortedValues, maxNonOutlierIndex + 1, highOutliers, 0, highOutliers.Length);
- minNonOutlier = sortedValues[minNonOutlierIndex];
- maxNonOutlier = sortedValues[maxNonOutlierIndex];
- sum = values.Sum();
- mean = sum / count;
- double sumVariancesSquared = 0;
- for (int i = 0; i < values.Length; i++)
- {
- double pointVariance = Math.Abs(mean - values[i]);
- double pointVarianceSquared = Math.Pow(pointVariance, 2);
- sumVariancesSquared += pointVarianceSquared;
- }
- double meanVarianceSquared = sumVariancesSquared / values.Length;
- stDev = Math.Sqrt(meanVarianceSquared);
- plus2stDev = mean + stDev * 2;
- minus2stDev = mean - stDev * 2;
- plus3stDev = mean + stDev * 3;
- minus3stDev = mean - stDev * 3;
- stdErr = stDev / Math.Sqrt(count);
- }
- public double[] GetDistribution(double[] xs, bool normalize)
- {
- double[] ys = new double[xs.Length];
- for (int i = 0; i < xs.Length; i++)
- ys[i] = Math.Exp(-.5 * Math.Pow((xs[i] - mean) / stDev, 2));
- if (normalize)
- {
- double sum = ys.Sum();
- for (int i = 0; i < ys.Length; i++)
- ys[i] /= sum;
- }
- return ys;
- }
- }
- }
|