Numworks Epsilon  1.4.1
Graphing Calculator Operating System
store.cpp
Go to the documentation of this file.
1 #include "store.h"
2 #include <assert.h>
3 #include <float.h>
4 #include <cmath>
5 #include <string.h>
6 #include <ion.h>
7 
8 using namespace Shared;
9 
10 namespace Statistics {
11 
12 Store::Store() :
15  m_barWidth(1.0),
16  m_firstDrawnBarAbscissa(0.0)
17 {
18 }
19 
21  double data[2] = {m_barWidth, m_firstDrawnBarAbscissa};
22  size_t dataLengthInBytes = 2*sizeof(double);
23  assert((dataLengthInBytes & 0x3) == 0); // Assert that dataLengthInBytes is a multiple of 4
24  return Ion::crc32((uint32_t *)data, dataLengthInBytes/sizeof(uint32_t));
25 }
26 
27 /* Histogram bars */
28 
29 double Store::barWidth() {
30  return m_barWidth;
31 }
32 
33 void Store::setBarWidth(double barWidth) {
34  if (barWidth <= 0.0) {
35  return;
36  }
37  m_barWidth = barWidth;
38 }
39 
41  return m_firstDrawnBarAbscissa;
42 }
43 
44 void Store::setFirstDrawnBarAbscissa(double firstBarAbscissa) {
45  m_firstDrawnBarAbscissa = firstBarAbscissa;
46 }
47 
48 double Store::heightOfBarAtIndex(int index) {
49  return sumOfValuesBetween(startOfBarAtIndex(index), endOfBarAtIndex(index));
50 }
51 
52 double Store::heightOfBarAtValue(double value) {
53  double width = barWidth();
54  int barNumber = std::floor((value - m_firstDrawnBarAbscissa)/width);
55  double lowerBound = m_firstDrawnBarAbscissa + barNumber*width;
56  double upperBound = m_firstDrawnBarAbscissa + (barNumber+1)*width;
57  return sumOfValuesBetween(lowerBound, upperBound);
58 }
59 
60 double Store::startOfBarAtIndex(int index) {
61  double firstBarAbscissa = m_firstDrawnBarAbscissa + m_barWidth*std::floor((minValue()- m_firstDrawnBarAbscissa)/m_barWidth);
62  return firstBarAbscissa + index * m_barWidth;
63 }
64 
65 double Store::endOfBarAtIndex(int index) {
66  return startOfBarAtIndex(index+1);
67 }
68 
70  double firstBarAbscissa = m_firstDrawnBarAbscissa + m_barWidth*std::floor((minValue()- m_firstDrawnBarAbscissa)/m_barWidth);
71  return std::ceil((maxValue() - firstBarAbscissa)/m_barWidth)+1;
72 }
73 
75  float startSelectedBar = startOfBarAtIndex(index);
76  float windowRange = m_xMax - m_xMin;
78  if (m_xMin + k_displayLeftMarginRatio*range > startSelectedBar) {
79  m_xMin = startSelectedBar - k_displayLeftMarginRatio*range;
80  m_xMax = m_xMin + windowRange;
81  return true;
82  }
83  float endSelectedBar = endOfBarAtIndex(index);
84  if (endSelectedBar > m_xMax - k_displayRightMarginRatio*range) {
85  m_xMax = endSelectedBar + k_displayRightMarginRatio*range;
86  m_xMin = m_xMax - windowRange;
87  return true;
88  }
89  return false;
90 }
91 
92 /* Calculation */
93 
95  return sumOfColumn(1);
96 }
97 
98 double Store::maxValue() {
99  double max = -DBL_MAX;
100  for (int k = 0; k < m_numberOfPairs; k++) {
101  if (m_data[0][k] > max && m_data[1][k] > 0) {
102  max = m_data[0][k];
103  }
104  }
105  return max;
106 }
107 
108 double Store::minValue() {
109  double min = DBL_MAX;
110  for (int k = 0; k < m_numberOfPairs; k++) {
111  if (m_data[0][k] < min && m_data[1][k] > 0) {
112  min = m_data[0][k];
113  }
114  }
115  return min;
116 }
117 
118 double Store::range() {
119  return maxValue()-minValue();
120 }
121 
122 double Store::mean() {
123  return sum()/sumOfColumn(1);
124 }
125 
126 double Store::variance() {
127  double m = mean();
128  return squaredValueSum()/sumOfColumn(1) - m*m;
129 }
130 
132  return std::sqrt(variance());
133 }
134 
136  double n = sumOfColumn(1);
137  double s = std::sqrt(n/(n-1.0));
138  return s*standardDeviation();
139 }
140 
142  int firstQuartileIndex = std::ceil(sumOfColumn(1)/4);
143  return sortedElementNumber(firstQuartileIndex);
144 }
145 
147  int thirdQuartileIndex = std::ceil(3*sumOfColumn(1)/4);
148  return sortedElementNumber(thirdQuartileIndex);
149 }
150 
152  return thirdQuartile()-firstQuartile();
153 }
154 
155 double Store::median() {
156  int total = sumOfColumn(1);
157  int halfTotal = total/2;
158  int totalMod2 = total - 2*halfTotal;
159  if (totalMod2 == 0) {
160  double minusMedian = sortedElementNumber(halfTotal);
161  double maxMedian = sortedElementNumber(halfTotal+1);
162  return (minusMedian+maxMedian)/2.0;
163  } else {
164  return sortedElementNumber(halfTotal+1);
165  }
166 }
167 
168 double Store::sum() {
169  double result = 0;
170  for (int k = 0; k < m_numberOfPairs; k++) {
171  result += m_data[0][k]*m_data[1][k];
172  }
173  return result;
174 }
175 
177  double result = 0;
178  for (int k = 0; k < m_numberOfPairs; k++) {
179  result += m_data[0][k]*m_data[0][k]*m_data[1][k];
180  }
181  return result;
182 }
183 
184 /* private methods */
185 
186 double Store::defaultValue(int i, int j) {
187  if (i == 0) {
188  return FloatPairStore::defaultValue(i, j);
189  } else {
190  return 1.0;
191  }
192 }
193 
194 double Store::sumOfValuesBetween(double x1, double x2) {
195  int result = 0;
196  for (int k = 0; k < m_numberOfPairs; k++) {
197  if (m_data[0][k] < x2 && x1 <= m_data[0][k]) {
198  result += m_data[1][k];
199  }
200  }
201  return result;
202 }
203 
204 double Store::sortedElementNumber(int k) {
205  // TODO: use an other algorithm (ex quickselect) to avoid quadratic complexity
206  double bufferValues[m_numberOfPairs];
207  memcpy(bufferValues, m_data[0], m_numberOfPairs*sizeof(double));
208  int sortedElementIndex = 0;
209  double cumulatedSize = 0.0;
210  while (cumulatedSize < k) {
211  sortedElementIndex = minIndex(bufferValues, m_numberOfPairs);
212  bufferValues[sortedElementIndex] = DBL_MAX;
213  cumulatedSize += m_data[1][sortedElementIndex];
214  }
215  return m_data[0][sortedElementIndex];
216 }
217 
218 int Store::minIndex(double * bufferValues, int bufferLength) {
219  int index = 0;
220  for (int i = 1; i < bufferLength; i++) {
221  if (bufferValues[index] > bufferValues[i]) {
222  index = i;
223  }
224  }
225  return index;
226 }
227 
228 }
double sumOfOccurrences()
Definition: store.cpp:94
static constexpr float k_displayLeftMarginRatio
Definition: store.h:45
double heightOfBarAtValue(double value)
Definition: store.cpp:52
void setFirstDrawnBarAbscissa(double firstDrawnBarAbscissa)
Definition: store.cpp:44
#define assert(e)
Definition: assert.h:9
def data
Definition: i18n.py:176
uint32_t barChecksum()
Definition: store.cpp:20
static constexpr float k_displayRightMarginRatio
Definition: store.h:43
double maxValue()
Definition: store.cpp:98
double barWidth()
Definition: store.cpp:29
double standardDeviation()
Definition: store.cpp:131
double heightOfBarAtIndex(int index)
Definition: store.cpp:48
double sum()
Definition: store.cpp:168
double firstDrawnBarAbscissa()
Definition: store.cpp:40
double numberOfBars()
Definition: store.cpp:69
double endOfBarAtIndex(int index)
Definition: store.cpp:65
double range()
Definition: store.cpp:118
double minValue()
Definition: store.cpp:108
double median()
Definition: store.cpp:155
#define DBL_MAX
Definition: float.h:9
unsigned int uint32_t
Definition: stdint.h:6
void setBarWidth(double barWidth)
Definition: store.cpp:33
double sampleStandardDeviation()
Definition: store.cpp:135
double firstQuartile()
Definition: store.cpp:141
#define ceil(x)
Definition: math.h:170
double quartileRange()
Definition: store.cpp:151
double m_data[2][k_maxNumberOfPairs]
double thirdQuartile()
Definition: store.cpp:146
uint32_t crc32(const uint32_t *data, size_t length)
Definition: device.cpp:37
double mean()
Definition: store.cpp:122
bool scrollToSelectedBarIndex(int index)
Definition: store.cpp:74
#define floor(x)
Definition: math.h:179
double startOfBarAtIndex(int index)
Definition: store.cpp:60
double squaredValueSum()
Definition: store.cpp:176
#define sqrt(x)
Definition: math.h:196
void * memcpy(void *dst, const void *src, size_t n)
Definition: memcpy.c:3
double variance()
Definition: store.cpp:126