Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Common/3.3/EnumerableStatisticExtensions.cs @ 8564

Last change on this file since 8564 was 8564, checked in by gkronber, 12 years ago

#1890

  • added an extension to calculate the range of IEnumerable<double>
  • increased the buffer size for the heuristic determination of separator characters in the table file parser (to make it work with files that have more than 1024 bytes in the second line).
File size: 4.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25
26namespace HeuristicLab.Common {
27  public static class EnumerableStatisticExtensions {
28    /// <summary>
29    /// Calculates the median element of the enumeration.
30    /// </summary>
31    /// <param name="values"></param>
32    /// <returns></returns>
33    public static double Median(this IEnumerable<double> values) {
34      // iterate only once
35      double[] valuesArr = values.ToArray();
36      int n = valuesArr.Length;
37      if (n == 0) throw new InvalidOperationException("Enumeration contains no elements.");
38
39      Array.Sort(valuesArr);
40
41      // return the middle element (if n is uneven) or the average of the two middle elements if n is even.
42      if (n % 2 == 1) {
43        return valuesArr[n / 2];
44      } else {
45        return (valuesArr[(n / 2) - 1] + valuesArr[n / 2]) / 2.0;
46      }
47    }
48
49    /// <summary>
50    /// Calculates the range (max - min) of the enumeration.
51    /// </summary>
52    /// <param name="values"></param>
53    /// <returns></returns>
54    public static double Range(this IEnumerable<double> values) {
55      double min = double.PositiveInfinity;
56      double max = double.NegativeInfinity;
57      int i = 0;
58      foreach (var e in values) {
59        if (min > e) min = e;
60        if (max < e) max = e;
61        i++;
62      }
63      if (i <= 2) throw new ArgumentException("The enumerable must contain at least two elements", "values");
64      return max - min;
65    }
66
67
68    /// <summary>
69    /// Calculates the standard deviation of values.
70    /// </summary>
71    /// <param name="values"></param>
72    /// <returns></returns>
73    public static double StandardDeviation(this IEnumerable<double> values) {
74      return Math.Sqrt(Variance(values));
75    }
76
77    /// <summary>
78    /// Calculates the variance of values. (sum (x - x_mean)² / n)
79    /// </summary>
80    /// <param name="values"></param>
81    /// <returns></returns>
82    public static double Variance(this IEnumerable<double> values) {
83      int m_n = 0;
84      double m_oldM = 0.0;
85      double m_newM = 0.0;
86      double m_oldS = 0.0;
87      double m_newS = 0.0;
88      foreach (double x in values) {
89        m_n++;
90        if (m_n == 1) {
91          m_oldM = m_newM = x;
92          m_oldS = 0.0;
93        } else {
94          m_newM = m_oldM + (x - m_oldM) / m_n;
95          m_newS = m_oldS + (x - m_oldM) * (x - m_newM);
96
97          // set up for next iteration
98          m_oldM = m_newM;
99          m_oldS = m_newS;
100        }
101      }
102      return ((m_n > 1) ? m_newS / (m_n - 1) : 0.0);
103    }
104
105    /// <summary>
106    /// Calculates the pth percentile of the values.
107    /// </summary
108    public static double Percentile(this IEnumerable<double> values, double p) {
109      // iterate only once
110      double[] valuesArr = values.ToArray();
111      int n = valuesArr.Length;
112      if (n == 0) throw new InvalidOperationException("Enumeration contains no elements.");
113      if (n == 1) return values.ElementAt(0);
114
115      if (p.IsAlmost(0.0)) return valuesArr[0];
116      if (p.IsAlmost(1.0)) return valuesArr[n - 1];
117
118      double t = p * (n - 1);
119      int index = (int)Math.Floor(t);
120      double percentage = t - index;
121      return valuesArr[index] * (1 - percentage) + valuesArr[index + 1] * percentage;
122    }
123
124    public static IEnumerable<double> LimitToRange(this IEnumerable<double> values, double min, double max) {
125      if (min > max) throw new ArgumentException(string.Format("Minimum {0} is larger than maximum {1}.", min, max));
126      foreach (var x in values) {
127        if (double.IsNaN(x)) yield return (max + min) / 2.0;
128        else if (x < min) yield return min;
129        else if (x > max) yield return max;
130        else yield return x;
131      }
132    }
133  }
134}
Note: See TracBrowser for help on using the repository browser.