mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[apps] Multiple data series in FloatPairStore
This commit is contained in:
@@ -32,34 +32,34 @@ void Store::setBarWidth(double barWidth) {
|
||||
}
|
||||
}
|
||||
|
||||
double Store::heightOfBarAtIndex(int index) {
|
||||
return sumOfValuesBetween(startOfBarAtIndex(index), endOfBarAtIndex(index));
|
||||
double Store::heightOfBarAtIndex(int series, int index) {
|
||||
return sumOfValuesBetween(startOfBarAtIndex(series, index), endOfBarAtIndex(series, index));
|
||||
}
|
||||
|
||||
double Store::heightOfBarAtValue(double value) {
|
||||
double Store::heightOfBarAtValue(int series, double value) {
|
||||
double width = barWidth();
|
||||
int barNumber = std::floor((value - m_firstDrawnBarAbscissa)/width);
|
||||
double lowerBound = m_firstDrawnBarAbscissa + barNumber*width;
|
||||
double upperBound = m_firstDrawnBarAbscissa + (barNumber+1)*width;
|
||||
return sumOfValuesBetween(lowerBound, upperBound);
|
||||
return sumOfValuesBetween(series, lowerBound, upperBound);
|
||||
}
|
||||
|
||||
double Store::startOfBarAtIndex(int index) {
|
||||
double firstBarAbscissa = m_firstDrawnBarAbscissa + m_barWidth*std::floor((minValue()- m_firstDrawnBarAbscissa)/m_barWidth);
|
||||
double Store::startOfBarAtIndex(int series, int index) {
|
||||
double firstBarAbscissa = m_firstDrawnBarAbscissa + m_barWidth*std::floor((minValue(series)- m_firstDrawnBarAbscissa)/m_barWidth);
|
||||
return firstBarAbscissa + index * m_barWidth;
|
||||
}
|
||||
|
||||
double Store::endOfBarAtIndex(int index) {
|
||||
return startOfBarAtIndex(index+1);
|
||||
double Store::endOfBarAtIndex(int series, int index) {
|
||||
return startOfBarAtIndex(series, index+1);
|
||||
}
|
||||
|
||||
double Store::numberOfBars() {
|
||||
double firstBarAbscissa = m_firstDrawnBarAbscissa + m_barWidth*std::floor((minValue()- m_firstDrawnBarAbscissa)/m_barWidth);
|
||||
return std::ceil((maxValue() - firstBarAbscissa)/m_barWidth)+1;
|
||||
double Store::numberOfBars(int series) {
|
||||
double firstBarAbscissa = m_firstDrawnBarAbscissa + m_barWidth*std::floor((minValue(series)- m_firstDrawnBarAbscissa)/m_barWidth);
|
||||
return std::ceil((maxValue(series) - firstBarAbscissa)/m_barWidth)+1;
|
||||
}
|
||||
|
||||
bool Store::scrollToSelectedBarIndex(int index) {
|
||||
float startSelectedBar = startOfBarAtIndex(index);
|
||||
bool Store::scrollToSelectedBarIndex(int series, int index) {
|
||||
float startSelectedBar = startOfBarAtIndex(series, index);
|
||||
float windowRange = m_xMax - m_xMin;
|
||||
float range = windowRange/(1+k_displayLeftMarginRatio+k_displayRightMarginRatio);
|
||||
if (m_xMin + k_displayLeftMarginRatio*range > startSelectedBar) {
|
||||
@@ -67,7 +67,7 @@ bool Store::scrollToSelectedBarIndex(int index) {
|
||||
m_xMax = m_xMin + windowRange;
|
||||
return true;
|
||||
}
|
||||
float endSelectedBar = endOfBarAtIndex(index);
|
||||
float endSelectedBar = endOfBarAtIndex(series, index);
|
||||
if (endSelectedBar > m_xMax - k_displayRightMarginRatio*range) {
|
||||
m_xMax = endSelectedBar + k_displayRightMarginRatio*range;
|
||||
m_xMin = m_xMax - windowRange;
|
||||
@@ -78,124 +78,124 @@ bool Store::scrollToSelectedBarIndex(int index) {
|
||||
|
||||
/* Calculation */
|
||||
|
||||
double Store::sumOfOccurrences() {
|
||||
return sumOfColumn(1);
|
||||
double Store::sumOfOccurrences(int series) {
|
||||
return sumOfColumn(series, 1);
|
||||
}
|
||||
|
||||
double Store::maxValue() {
|
||||
double Store::maxValue(int series) {
|
||||
double max = -DBL_MAX;
|
||||
for (int k = 0; k < m_numberOfPairs; k++) {
|
||||
if (m_data[0][k] > max && m_data[1][k] > 0) {
|
||||
max = m_data[0][k];
|
||||
if (m_data[series][0][k] > max && m_data[series][1][k] > 0) {
|
||||
max = m_data[series][0][k];
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
double Store::minValue() {
|
||||
double Store::minValue(int series) {
|
||||
double min = DBL_MAX;
|
||||
for (int k = 0; k < m_numberOfPairs; k++) {
|
||||
if (m_data[0][k] < min && m_data[1][k] > 0) {
|
||||
min = m_data[0][k];
|
||||
if (m_data[series][0][k] < min && m_data[series][1][k] > 0) {
|
||||
min = m_data[series][0][k];
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
double Store::range() {
|
||||
return maxValue()-minValue();
|
||||
double Store::range(int series) {
|
||||
return maxValue(series)-minValue(series);
|
||||
}
|
||||
|
||||
double Store::mean() {
|
||||
return sum()/sumOfOccurrences();
|
||||
double Store::mean(int series) {
|
||||
return sum(series)/sumOfOccurrences(series);
|
||||
}
|
||||
|
||||
double Store::variance() {
|
||||
double m = mean();
|
||||
return squaredValueSum()/sumOfOccurrences() - m*m;
|
||||
double Store::variance(int series) {
|
||||
double m = mean(series);
|
||||
return squaredValueSum(series)/sumOfOccurrences(series) - m*m;
|
||||
}
|
||||
|
||||
double Store::standardDeviation() {
|
||||
return std::sqrt(variance());
|
||||
double Store::standardDeviation(int series) {
|
||||
return std::sqrt(variance(series));
|
||||
}
|
||||
|
||||
double Store::sampleStandardDeviation() {
|
||||
double n = sumOfOccurrences();
|
||||
double Store::sampleStandardDeviation(int series) {
|
||||
double n = sumOfOccurrences(series);
|
||||
double s = std::sqrt(n/(n-1.0));
|
||||
return s*standardDeviation();
|
||||
return s*standardDeviation(series);
|
||||
}
|
||||
|
||||
double Store::firstQuartile() {
|
||||
int firstQuartileIndex = std::ceil(sumOfOccurrences()/4);
|
||||
return sortedElementNumber(firstQuartileIndex);
|
||||
double Store::firstQuartile(int series) {
|
||||
int firstQuartileIndex = std::ceil(sumOfOccurrences(series)/4);
|
||||
return sortedElementNumber(series, firstQuartileIndex);
|
||||
}
|
||||
|
||||
double Store::thirdQuartile() {
|
||||
int thirdQuartileIndex = std::ceil(3*sumOfOccurrences()/4);
|
||||
return sortedElementNumber(thirdQuartileIndex);
|
||||
double Store::thirdQuartile(int series) {
|
||||
int thirdQuartileIndex = std::ceil(3*sumOfOccurrences(series)/4);
|
||||
return sortedElementNumber(series, thirdQuartileIndex);
|
||||
}
|
||||
|
||||
double Store::quartileRange() {
|
||||
double Store::quartileRange(int series) {
|
||||
return thirdQuartile()-firstQuartile();
|
||||
}
|
||||
|
||||
double Store::median() {
|
||||
int total = sumOfOccurrences();
|
||||
double Store::median(int series) {
|
||||
int total = sumOfOccurrences(series);
|
||||
int halfTotal = total/2;
|
||||
int totalMod2 = total - 2*halfTotal;
|
||||
if (totalMod2 == 0) {
|
||||
double minusMedian = sortedElementNumber(halfTotal);
|
||||
double maxMedian = sortedElementNumber(halfTotal+1);
|
||||
double minusMedian = sortedElementNumber(series, halfTotal);
|
||||
double maxMedian = sortedElementNumber(series, halfTotal+1);
|
||||
return (minusMedian+maxMedian)/2.0;
|
||||
} else {
|
||||
return sortedElementNumber(halfTotal+1);
|
||||
return sortedElementNumber(series, halfTotal+1);
|
||||
}
|
||||
}
|
||||
|
||||
double Store::sum() {
|
||||
double Store::sum(int series) {
|
||||
double result = 0;
|
||||
for (int k = 0; k < m_numberOfPairs; k++) {
|
||||
result += m_data[0][k]*m_data[1][k];
|
||||
result += m_data[series][0][k]*m_data[series][1][k];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
double Store::squaredValueSum() {
|
||||
double Store::squaredValueSum(int series) {
|
||||
double result = 0;
|
||||
for (int k = 0; k < m_numberOfPairs; k++) {
|
||||
result += m_data[0][k]*m_data[0][k]*m_data[1][k];
|
||||
result += m_data[series][0][k]*m_data[series][0][k]*m_data[series][1][k];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* private methods */
|
||||
/* Private methods */
|
||||
|
||||
double Store::defaultValue(int i, int j) {
|
||||
return i == 0 ? FloatPairStore::defaultValue(i, j) : 1.0;
|
||||
double Store::defaultValue(int series, int i, int j) {
|
||||
return i == 0 ? FloatPairStore::defaultValue(series, i, j) : 1.0;
|
||||
}
|
||||
|
||||
double Store::sumOfValuesBetween(double x1, double x2) {
|
||||
double result = 0;
|
||||
for (int k = 0; k < m_numberOfPairs; k++) {
|
||||
if (m_data[0][k] < x2 && x1 <= m_data[0][k]) {
|
||||
result += m_data[1][k];
|
||||
for (int k = 0; k < m_numberOfPairs[series]; k++) {
|
||||
if (m_data[series][0][k] < x2 && x1 <= m_data[series][0][k]) {
|
||||
result += m_data[series][1][k];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
double Store::sortedElementNumber(int k) {
|
||||
double Store::sortedElementNumber(int series, int k) {
|
||||
// TODO: use an other algorithm (ex quickselect) to avoid quadratic complexity
|
||||
double bufferValues[m_numberOfPairs];
|
||||
memcpy(bufferValues, m_data[0], m_numberOfPairs*sizeof(double));
|
||||
double bufferValues[m_numberOfPairs[series]];
|
||||
memcpy(bufferValues, m_data[series][0], m_numberOfPairs[series]*sizeof(double));
|
||||
int sortedElementIndex = 0;
|
||||
double cumulatedSize = 0.0;
|
||||
while (cumulatedSize < k) {
|
||||
sortedElementIndex = minIndex(bufferValues, m_numberOfPairs);
|
||||
sortedElementIndex = minIndex(bufferValues, m_numberOfPairs[series]);
|
||||
bufferValues[sortedElementIndex] = DBL_MAX;
|
||||
cumulatedSize += m_data[1][sortedElementIndex];
|
||||
cumulatedSize += m_data[series][1][sortedElementIndex];
|
||||
}
|
||||
return m_data[0][sortedElementIndex];
|
||||
return m_data[series][0][sortedElementIndex];
|
||||
}
|
||||
|
||||
int Store::minIndex(double * bufferValues, int bufferLength) {
|
||||
|
||||
Reference in New Issue
Block a user