QGIS API Documentation  2.12.0-Lyon
qgsstatisticalsummary.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsstatisticalsummary.cpp
3  --------------------------------------
4  Date : May 2015
5  Copyright : (C) 2015 by Nyall Dawson
6  Email : nyall dot dawson at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsstatisticalsummary.h"
17 #include <limits>
18 #include <qmath.h>
19 #include <QString>
20 #include <QObject>
21 
23  : mStatistics( stats )
24 {
25  reset();
26 }
27 
29 {
30 
31 }
32 
34 {
35  mCount = 0;
36  mSum = 0;
37  mMean = 0;
38  mMedian = 0;
41  mStdev = 0;
42  mSampleStdev = 0;
43  mMinority = 0;
44  mMajority = 0;
45  mFirstQuartile = 0;
46  mThirdQuartile = 0;
47  mValueCount.clear();
48 }
49 
51 {
52  reset();
53 
54  Q_FOREACH ( double value, values )
55  {
56  mCount++;
57  mSum += value;
58  mMin = qMin( mMin, value );
59  mMax = qMax( mMax, value );
60 
61  if ( mStatistics & QgsStatisticalSummary::Majority || mStatistics & QgsStatisticalSummary::Minority || mStatistics & QgsStatisticalSummary::Variety )
62  mValueCount.insert( value, mValueCount.value( value, 0 ) + 1 );
63  }
64 
65  if ( mCount == 0 )
66  return;
67 
68  mMean = mSum / mCount;
69 
70  if ( mStatistics & QgsStatisticalSummary::StDev || mStatistics & QgsStatisticalSummary::StDevSample )
71  {
72  double sumSquared = 0;
73  Q_FOREACH ( double value, values )
74  {
75  double diff = value - mMean;
76  sumSquared += diff * diff;
77  }
78  mStdev = qPow( sumSquared / values.count(), 0.5 );
79  mSampleStdev = qPow( sumSquared / ( values.count() - 1 ), 0.5 );
80  }
81 
82  QList<double> sorted;
83  if ( mStatistics & QgsStatisticalSummary::Median
87  {
88  sorted = values;
89  qSort( sorted.begin(), sorted.end() );
90  bool even = ( mCount % 2 ) < 1;
91  if ( even )
92  {
93  mMedian = ( sorted[mCount / 2 - 1] + sorted[mCount / 2] ) / 2.0;
94  }
95  else //odd
96  {
97  mMedian = sorted[( mCount + 1 ) / 2 - 1];
98  }
99  }
100 
101  if ( mStatistics & QgsStatisticalSummary::FirstQuartile
102  || mStatistics & QgsStatisticalSummary::InterQuartileRange )
103  {
104  if (( mCount % 2 ) < 1 )
105  {
106  int halfCount = mCount / 2;
107  bool even = ( halfCount % 2 ) < 1;
108  if ( even )
109  {
110  mFirstQuartile = ( sorted[halfCount / 2 - 1] + sorted[halfCount / 2] ) / 2.0;
111  }
112  else //odd
113  {
114  mFirstQuartile = sorted[( halfCount + 1 ) / 2 - 1];
115  }
116  }
117  else
118  {
119  int halfCount = mCount / 2 + 1;
120  bool even = ( halfCount % 2 ) < 1;
121  if ( even )
122  {
123  mFirstQuartile = ( sorted[halfCount / 2 - 1] + sorted[halfCount / 2] ) / 2.0;
124  }
125  else //odd
126  {
127  mFirstQuartile = sorted[( halfCount + 1 ) / 2 - 1];
128  }
129  }
130  }
131 
132  if ( mStatistics & QgsStatisticalSummary::ThirdQuartile
133  || mStatistics & QgsStatisticalSummary::InterQuartileRange )
134  {
135  if (( mCount % 2 ) < 1 )
136  {
137  int halfCount = mCount / 2;
138  bool even = ( halfCount % 2 ) < 1;
139  if ( even )
140  {
141  mThirdQuartile = ( sorted[ halfCount + halfCount / 2 - 1] + sorted[ halfCount + halfCount / 2] ) / 2.0;
142  }
143  else //odd
144  {
145  mThirdQuartile = sorted[( halfCount + 1 ) / 2 - 1 + halfCount ];
146  }
147  }
148  else
149  {
150  int halfCount = mCount / 2 + 1;
151  bool even = ( halfCount % 2 ) < 1;
152  if ( even )
153  {
154  mThirdQuartile = ( sorted[ halfCount + halfCount / 2 - 2 ] + sorted[ halfCount + halfCount / 2 - 1 ] ) / 2.0;
155  }
156  else //odd
157  {
158  mThirdQuartile = sorted[( halfCount + 1 ) / 2 - 2 + halfCount ];
159  }
160  }
161  }
162 
163  if ( mStatistics & QgsStatisticalSummary::Minority || mStatistics & QgsStatisticalSummary::Majority )
164  {
165  QList<int> valueCounts = mValueCount.values();
166  qSort( valueCounts.begin(), valueCounts.end() );
167  if ( mStatistics & QgsStatisticalSummary::Minority )
168  {
169  mMinority = mValueCount.key( valueCounts.first() );
170  }
171  if ( mStatistics & QgsStatisticalSummary::Majority )
172  {
173  mMajority = mValueCount.key( valueCounts.last() );
174  }
175  }
176 
177 }
178 
180 {
181  switch ( stat )
182  {
183  case Count:
184  return mCount;
185  case Sum:
186  return mSum;
187  case Mean:
188  return mMean;
189  case Median:
190  return mMedian;
191  case StDev:
192  return mStdev;
193  case StDevSample:
194  return mSampleStdev;
195  case Min:
196  return mMin;
197  case Max:
198  return mMax;
199  case Range:
200  return mMax - mMin;
201  case Minority:
202  return mMinority;
203  case Majority:
204  return mMajority;
205  case Variety:
206  return mValueCount.count();
207  case FirstQuartile:
208  return mFirstQuartile;
209  case ThirdQuartile:
210  return mThirdQuartile;
211  case InterQuartileRange:
212  return mThirdQuartile - mFirstQuartile;
213  case All:
214  return 0;
215  }
216  return 0;
217 }
218 
220 {
221  switch ( statistic )
222  {
223  case Count:
224  return QObject::tr( "Count" );
225  case Sum:
226  return QObject::tr( "Sum" );
227  case Mean:
228  return QObject::tr( "Mean" );
229  case Median:
230  return QObject::tr( "Median" );
231  case StDev:
232  return QObject::tr( "St dev (pop)" );
233  case StDevSample:
234  return QObject::tr( "St dev (sample)" );
235  case Min:
236  return QObject::tr( "Minimum" );
237  case Max:
238  return QObject::tr( "Maximum" );
239  case Range:
240  return QObject::tr( "Range" );
241  case Minority:
242  return QObject::tr( "Minority" );
243  case Majority:
244  return QObject::tr( "Majority" );
245  case Variety:
246  return QObject::tr( "Variety" );
247  case FirstQuartile:
248  return QObject::tr( "Q1" );
249  case ThirdQuartile:
250  return QObject::tr( "Q3" );
251  case InterQuartileRange:
252  return QObject::tr( "IQR" );
253  case All:
254  return QString();
255  }
256  return QString();
257 }
258 
void reset()
Resets the calculated values.
QList< T > values() const
Statistic
Enumeration of flags that specify statistics to be calculated.
Variety (count of distinct) values.
Sample standard deviation of values.
void clear()
QString tr(const char *sourceText, const char *disambiguation, int n)
double ANALYSIS_EXPORT max(double x, double y)
Returns the maximum of two doubles or the first argument if both are equal.
int count(const T &value) const
double statistic(Statistic stat) const
Returns the value of a specified statistic.
QgsStatisticalSummary(const QgsStatisticalSummary::Statistics &stats=Statistics(0))
Constructor for QgsStatisticalSummary.
static QString displayName(Statistic statistic)
Returns the friendly display name for a statistic.
T & first()
iterator end()
const Key key(const T &value) const
T & last()
void calculate(const QList< double > &values)
Calculates summary statistics for a list of values.
iterator insert(const Key &key, const T &value)
Standard deviation of values.
int count(const Key &key) const
iterator begin()
Range of values (max - min)
const T value(const Key &key) const