From f6823c038f993eea41ea09a14256aace03c3ddc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Wed, 30 May 2018 14:01:38 +0200 Subject: [PATCH] [[apps/regression] Fix regression (now compiles) --- apps/regression/calculation_controller.cpp | 53 ++++++++++------- apps/regression/calculation_controller.h | 6 +- .../regression/go_to_parameter_controller.cpp | 6 +- apps/regression/graph_controller.cpp | 57 ++++++++++--------- apps/regression/graph_controller.h | 2 + apps/regression/store.cpp | 4 +- apps/regression/store.h | 4 +- apps/regression/store_controller.cpp | 8 +-- 8 files changed, 79 insertions(+), 61 deletions(-) diff --git a/apps/regression/calculation_controller.cpp b/apps/regression/calculation_controller.cpp index 065d0e8fc..170391962 100644 --- a/apps/regression/calculation_controller.cpp +++ b/apps/regression/calculation_controller.cpp @@ -121,12 +121,8 @@ void CalculationController::willDisplayCellAtLocation(HighlightCell * cell, int EvenOddCell * myCell = (EvenOddCell *)cell; myCell->setEven(j%2 == 0); myCell->setHighlighted(i == selectedColumn() && j == selectedRow()); - if (j == 0 && i > 0) { - EvenOddDoubleBufferTextCell * myCell = (EvenOddDoubleBufferTextCell *)cell; - myCell->setFirstText("x"); - myCell->setSecondText("y"); - return; - } + + // Calculation title if (i == 0) { if (j == numberOfRows()-1) { EvenOddExpressionCell * myCell = (EvenOddExpressionCell *)cell; @@ -143,11 +139,25 @@ void CalculationController::willDisplayCellAtLocation(HighlightCell * cell, int myCell->setMessage(titles[j-1]); return; } + + int seriesNumber = i - 1;; + assert(i >= 0 && seriesNumber < FloatPairStore::k_numberOfSeries); + + // Coordinate and series title + if (j == 0 && i > 0) { + EvenOddDoubleBufferTextCell * myCell = (EvenOddDoubleBufferTextCell *)cell; + char buffer[] = {'x', static_cast('0' + seriesNumber), 0}; + myCell->setFirstText(buffer); + buffer[0] = 'y'; + myCell->setSecondText(buffer); + return; + } + + // Calculation cell if (i == 1 && j > 0 && j <= k_totalNumberOfDoubleBufferRows) { - ArgCalculPointer calculationMethods[k_totalNumberOfDoubleBufferRows] = {&Store::meanOfColumn, &Store::sumOfColumn, - &Store::squaredValueSumOfColumn, &Store::standardDeviationOfColumn, &Store::varianceOfColumn}; - double calculation1 = (m_store->*calculationMethods[j-1])(0); - double calculation2 = (m_store->*calculationMethods[j-1])(1); + ArgCalculPointer calculationMethods[k_totalNumberOfDoubleBufferRows] = {&Store::meanOfColumn, &Store::sumOfColumn, &Store::squaredValueSumOfColumn, &Store::standardDeviationOfColumn, &Store::varianceOfColumn}; + double calculation1 = (m_store->*calculationMethods[j-1])(seriesNumber, 0); + double calculation2 = (m_store->*calculationMethods[j-1])(seriesNumber, 1); EvenOddDoubleBufferTextCell * myCell = (EvenOddDoubleBufferTextCell *)cell; char buffer[PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)]; PrintFloat::convertFloatToText(calculation1, buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits); @@ -163,9 +173,8 @@ void CalculationController::willDisplayCellAtLocation(HighlightCell * cell, int } if (i == 1 && j > k_totalNumberOfDoubleBufferRows) { assert(j != 9); - CalculPointer calculationMethods[k_totalNumberOfRows-k_totalNumberOfDoubleBufferRows] = {&Store::doubleCastedNumberOfPairsOfSeries, &Store::covariance, - &Store::columnProductSum, nullptr, &Store::slope, &Store::yIntercept, &Store::correlationCoefficient, &Store::squaredCorrelationCoefficient}; - double calculation = (m_store->*calculationMethods[j-k_totalNumberOfDoubleBufferRows-1])(); + CalculPointer calculationMethods[k_totalNumberOfRows-k_totalNumberOfDoubleBufferRows] = {&Store::doubleCastedNumberOfPairsOfSeries, &Store::covariance, &Store::columnProductSum, nullptr, &Store::slope, &Store::yIntercept, &Store::correlationCoefficient, &Store::squaredCorrelationCoefficient}; + double calculation = (m_store->*calculationMethods[j-k_totalNumberOfDoubleBufferRows-1])(seriesNumber); EvenOddBufferTextCell * myCell = (EvenOddBufferTextCell *)cell; char buffer[PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)]; PrintFloat::convertFloatToText(calculation, buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits); @@ -197,12 +206,12 @@ HighlightCell * CalculationController::reusableCell(int index, int type) { return m_columnTitleCell; } if (type == 3) { - assert(index < k_totalNumberOfDoubleBufferRows); + assert(index < k_numberOfDoubleCalculationCells); assert(m_doubleCalculationCells[index] != nullptr); return m_doubleCalculationCells[index]; } - assert(index < k_totalNumberOfRows-k_totalNumberOfDoubleBufferRows); - assert(m_calculationCells[index] != nullptr); + assert(index < k_numberOfCalculationCells); + assert(m_calculationCells[index] != nullptr); return m_calculationCells[index]; } @@ -217,9 +226,9 @@ int CalculationController::reusableCellCount(int type) { return 1; } if (type == 3) { - return k_totalNumberOfDoubleBufferRows; + return k_numberOfDoubleCalculationCells; } - return k_totalNumberOfRows-k_totalNumberOfDoubleBufferRows; + return k_numberOfCalculationCells; } int CalculationController::typeAtLocation(int i, int j) { @@ -252,12 +261,12 @@ View * CalculationController::loadView() { for (int i = 0; i < k_maxNumberOfDisplayableRows; i++) { m_titleCells[i] = new EvenOddMessageTextCell(KDText::FontSize::Small); } - for (int i = 0; i < k_totalNumberOfDoubleBufferRows; i++) { + for (int i = 0; i < k_numberOfDoubleCalculationCells; i++) { m_doubleCalculationCells[i] = new EvenOddDoubleBufferTextCell(); m_doubleCalculationCells[i]->setTextColor(Palette::GreyDark); m_doubleCalculationCells[i]->setParentResponder(tableView); } - for (int i = 0; i < k_totalNumberOfRows-k_totalNumberOfDoubleBufferRows;i++) { + for (int i = 0; i < k_numberOfCalculationCells;i++) { m_calculationCells[i] = new EvenOddBufferTextCell(KDText::FontSize::Small); m_calculationCells[i]->setTextColor(Palette::GreyDark); } @@ -269,11 +278,11 @@ void CalculationController::unloadView(View * view) { m_r2TitleCell = nullptr; delete m_columnTitleCell; m_columnTitleCell = nullptr; - for (int i = 0; i < k_totalNumberOfDoubleBufferRows; i++) { + for (int i = 0; i < k_numberOfDoubleCalculationCells; i++) { delete m_doubleCalculationCells[i]; m_doubleCalculationCells[i] = nullptr; } - for (int i = 0; i < k_totalNumberOfRows-k_totalNumberOfDoubleBufferRows;i++) { + for (int i = 0; i < k_numberOfCalculationCells;i++) { delete m_calculationCells[i]; m_calculationCells[i] = nullptr; } diff --git a/apps/regression/calculation_controller.h b/apps/regression/calculation_controller.h index 2de5133d3..b0ff8d8a0 100644 --- a/apps/regression/calculation_controller.h +++ b/apps/regression/calculation_controller.h @@ -43,14 +43,16 @@ private: constexpr static int k_totalNumberOfColumns = 2; constexpr static int k_maxNumberOfDisplayableRows = 11; constexpr static int k_totalNumberOfDoubleBufferRows = 5; + constexpr static int k_numberOfDoubleCalculationCells = Store::k_numberOfSeries * k_totalNumberOfDoubleBufferRows; + constexpr static int k_numberOfCalculationCells = Store::k_numberOfSeries * k_totalNumberOfRows - k_numberOfDoubleCalculationCells; static constexpr KDCoordinate k_cellHeight = 25; static constexpr KDCoordinate k_cellWidth = Ion::Display::Width/2 - Metric::CommonRightMargin/2 - Metric::CommonLeftMargin/2; EvenOddMessageTextCell * m_titleCells[k_maxNumberOfDisplayableRows]; EvenOddExpressionCell * m_r2TitleCell; Poincare::ExpressionLayout * m_r2Layout; EvenOddDoubleBufferTextCell * m_columnTitleCell; - EvenOddDoubleBufferTextCell * m_doubleCalculationCells[k_totalNumberOfDoubleBufferRows]; - EvenOddBufferTextCell * m_calculationCells[k_totalNumberOfRows-k_totalNumberOfDoubleBufferRows]; + EvenOddDoubleBufferTextCell * m_doubleCalculationCells[k_numberOfDoubleCalculationCells]; + EvenOddBufferTextCell * m_calculationCells[k_numberOfCalculationCells]; Store * m_store; }; diff --git a/apps/regression/go_to_parameter_controller.cpp b/apps/regression/go_to_parameter_controller.cpp index 0d521b97f..2b71431a1 100644 --- a/apps/regression/go_to_parameter_controller.cpp +++ b/apps/regression/go_to_parameter_controller.cpp @@ -43,16 +43,16 @@ bool GoToParameterController::setParameterAtIndex(int parameterIndex, double f) app()->displayWarning(I18n::Message::ForbiddenValue); return false; } - double x = m_store->xValueForYValue(f); + double x = m_store->xValueForYValue(m_graphController->selectedSeries(), f); if (m_xPrediction) { - x = m_store->yValueForXValue(f); + x = m_store->yValueForXValue(m_graphController->selectedSeries(), f); } if (std::fabs(x) > k_maxDisplayableFloat) { app()->displayWarning(I18n::Message::ForbiddenValue); return false; } if (std::isnan(x)) { - if (m_store->slope() < DBL_EPSILON && f == m_store->yIntercept()) { + if (m_store->slope(m_graphController->selectedSeries()) < DBL_EPSILON && f == m_store->yIntercept(m_graphController->selectedSeries())) { m_graphController->selectRegressionCurve(); m_cursor->moveTo(m_cursor->x(), f); return true; diff --git a/apps/regression/graph_controller.cpp b/apps/regression/graph_controller.cpp index 7abbd9416..625942ebf 100644 --- a/apps/regression/graph_controller.cpp +++ b/apps/regression/graph_controller.cpp @@ -16,7 +16,8 @@ GraphController::GraphController(Responder * parentResponder, ButtonRowControlle m_store(store), m_initialisationParameterController(this, m_store), m_predictionParameterController(this, m_store, m_cursor, this), - m_selectedDotIndex(selectedDotIndex) + m_selectedDotIndex(selectedDotIndex), + m_selectedSeries(0) // TODO -1 { m_store->setCursor(m_cursor); } @@ -76,7 +77,7 @@ void GraphController::reloadBannerView() { int legendLength = strlen(legend); strlcpy(buffer, legend, legendLength+1); numberOfChar += legendLength; - if (*m_selectedDotIndex == m_store->numberOfPairs()) { + if (*m_selectedDotIndex == m_store->numberOfPairsOfSeries(m_selectedSeries)) { legend = I18n::translate(I18n::Message::MeanDot); legendLength = strlen(legend); strlcpy(buffer+numberOfChar, legend, legendLength+1); @@ -99,10 +100,10 @@ void GraphController::reloadBannerView() { legend = "x="; double x = m_cursor->x(); // Display a specific legend if the mean dot is selected - if (*m_selectedDotIndex == m_store->numberOfPairs()) { + if (*m_selectedDotIndex == m_store->numberOfPairsOfSeries(m_selectedSeries)) { constexpr static char legX[] = {Ion::Charset::XBar, '=', 0}; legend = legX; - x = m_store->meanOfColumn(0); + x = m_store->meanOfColumn(m_selectedSeries, 0); } legendLength = strlen(legend); strlcpy(buffer, legend, legendLength+1); @@ -117,10 +118,10 @@ void GraphController::reloadBannerView() { numberOfChar = 0; legend = "y="; double y = m_cursor->y(); - if (*m_selectedDotIndex == m_store->numberOfPairs()) { + if (*m_selectedDotIndex == m_store->numberOfPairsOfSeries(m_selectedSeries)) { constexpr static char legY[] = {Ion::Charset::YBar, '=', 0}; legend = legY; - y = m_store->meanOfColumn(1); + y = m_store->meanOfColumn(m_selectedSeries, 1); } legendLength = strlen(legend); strlcpy(buffer, legend, legendLength+1); @@ -134,7 +135,7 @@ void GraphController::reloadBannerView() { numberOfChar = 0; legend = " a="; - double slope = m_store->slope(); + double slope = m_store->slope(m_selectedSeries); legendLength = strlen(legend); strlcpy(buffer, legend, legendLength+1); numberOfChar += legendLength; @@ -147,7 +148,7 @@ void GraphController::reloadBannerView() { numberOfChar = 0; legend = " b="; - double yIntercept = m_store->yIntercept(); + double yIntercept = m_store->yIntercept(m_selectedSeries); legendLength = strlen(legend); strlcpy(buffer, legend, legendLength+1); numberOfChar += legendLength; @@ -160,7 +161,7 @@ void GraphController::reloadBannerView() { numberOfChar = 0; legend = " r="; - double r = m_store->correlationCoefficient(); + double r = m_store->correlationCoefficient(m_selectedSeries); legendLength = strlen(legend); strlcpy(buffer, legend, legendLength+1); numberOfChar += legendLength; @@ -173,7 +174,7 @@ void GraphController::reloadBannerView() { numberOfChar = 0; legend = " r2="; - double r2 = m_store->squaredCorrelationCoefficient(); + double r2 = m_store->squaredCorrelationCoefficient(m_selectedSeries); legendLength = strlen(legend); strlcpy(buffer, legend, legendLength+1); numberOfChar += legendLength; @@ -190,25 +191,26 @@ void GraphController::initRangeParameters() { } void GraphController::initCursorParameters() { - double x = m_store->meanOfColumn(0); - double y = m_store->meanOfColumn(1); + assert(m_selectedSeries >= 0); + double x = m_store->meanOfColumn(m_selectedSeries, 0); + double y = m_store->meanOfColumn(m_selectedSeries, 1); m_cursor->moveTo(x, y); m_store->panToMakePointVisible(x, y, k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio); - *m_selectedDotIndex = m_store->numberOfPairs(); + *m_selectedDotIndex = m_store->numberOfPairsOfSeries(m_selectedSeries); } bool GraphController::moveCursorHorizontally(int direction) { if (*m_selectedDotIndex >= 0) { - int dotSelected = m_store->nextDot(direction, *m_selectedDotIndex); - if (dotSelected >= 0 && dotSelected < m_store->numberOfPairs()) { + int dotSelected = m_store->nextDot(m_selectedSeries, direction, *m_selectedDotIndex); + if (dotSelected >= 0 && dotSelected < m_store->numberOfPairsOfSeries(m_selectedSeries)) { *m_selectedDotIndex = dotSelected; - m_cursor->moveTo(m_store->get(0, *m_selectedDotIndex), m_store->get(1, *m_selectedDotIndex)); + m_cursor->moveTo(m_store->get(m_selectedSeries, 0, *m_selectedDotIndex), m_store->get(m_selectedSeries, 1, *m_selectedDotIndex)); m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio); return true; } - if (dotSelected == m_store->numberOfPairs()) { + if (dotSelected == m_store->numberOfPairsOfSeries(m_selectedSeries)) { *m_selectedDotIndex = dotSelected; - m_cursor->moveTo(m_store->meanOfColumn(0), m_store->meanOfColumn(1)); + m_cursor->moveTo(m_store->meanOfColumn(m_selectedSeries, 0), m_store->meanOfColumn(m_selectedSeries, 1)); m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio); return true; } @@ -216,14 +218,14 @@ bool GraphController::moveCursorHorizontally(int direction) { } double x = direction > 0 ? m_cursor->x() + m_store->xGridUnit()/k_numberOfCursorStepsInGradUnit : m_cursor->x() - m_store->xGridUnit()/k_numberOfCursorStepsInGradUnit; - double y = m_store->yValueForXValue(x); + double y = m_store->yValueForXValue(m_selectedSeries, x); m_cursor->moveTo(x, y); m_store->panToMakePointVisible(x, y, k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio); return true; } bool GraphController::moveCursorVertically(int direction) { - double yRegressionCurve = m_store->yValueForXValue(m_cursor->x()); + double yRegressionCurve = m_store->yValueForXValue(m_selectedSeries, m_cursor->x()); if (*m_selectedDotIndex >= 0) { if ((yRegressionCurve - m_cursor->y() > 0) == (direction > 0)) { selectRegressionCurve(); @@ -234,17 +236,18 @@ bool GraphController::moveCursorVertically(int direction) { return false; } } else { - int dotSelected = m_store->closestVerticalDot(direction, m_cursor->x()); - if (dotSelected >= 0 && dotSelected <= m_store->numberOfPairs()) { + int selectedSeries = -1; + int dotSelected = m_store->closestVerticalDot(direction, m_cursor->x(), &selectedSeries); + if (dotSelected >= 0 && dotSelected <= m_store->numberOfPairsOfSeries(selectedSeries)) { m_view.setCursorView(&m_crossCursorView); - if (dotSelected == m_store->numberOfPairs()) { - *m_selectedDotIndex = dotSelected; - m_cursor->moveTo(m_store->meanOfColumn(0), m_store->meanOfColumn(1)); + m_selectedSeries = selectedSeries; + *m_selectedDotIndex = dotSelected; + if (dotSelected == m_store->numberOfPairsOfSeries(m_selectedSeries)) { + m_cursor->moveTo(m_store->meanOfColumn(m_selectedSeries, 0), m_store->meanOfColumn(m_selectedSeries, 1)); m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio); return true; } - *m_selectedDotIndex = dotSelected; - m_cursor->moveTo(m_store->get(0, *m_selectedDotIndex), m_store->get(1, *m_selectedDotIndex)); + m_cursor->moveTo(m_store->get(m_selectedSeries, 0, *m_selectedDotIndex), m_store->get(m_selectedSeries, 1, *m_selectedDotIndex)); m_store->panToMakePointVisible(m_cursor->x(), m_cursor->y(), k_cursorTopMarginRatio, k_cursorRightMarginRatio, k_cursorBottomMarginRatio, k_cursorLeftMarginRatio); return true; } diff --git a/apps/regression/graph_controller.h b/apps/regression/graph_controller.h index 234e5dd19..4d582b009 100644 --- a/apps/regression/graph_controller.h +++ b/apps/regression/graph_controller.h @@ -23,6 +23,7 @@ public: I18n::Message emptyMessage() override; void viewWillAppear() override; void selectRegressionCurve(); + int selectedSeries() const { return m_selectedSeries; } private: constexpr static float k_cursorTopMarginRatio = 0.07f; // (cursorHeight/2)/graphViewHeight constexpr static float k_cursorBottomMarginRatio = 0.3f; // (cursorHeight/2+bannerHeigh)/graphViewHeight @@ -49,6 +50,7 @@ private: /* The selectedDotIndex is -1 when no dot is selected, m_numberOfPairs when * the mean dot is selected and the dot index otherwise */ int * m_selectedDotIndex; + int m_selectedSeries; // TODO store in the Snapshot }; } diff --git a/apps/regression/store.cpp b/apps/regression/store.cpp index 7cfb5adbe..44d286b43 100644 --- a/apps/regression/store.cpp +++ b/apps/regression/store.cpp @@ -19,7 +19,7 @@ Store::Store() : /* Dots */ -int Store::closestVerticalDot(int direction, float x) { +int Store::closestVerticalDot(int direction, float x, int * nextSeries) { float nextX = INFINITY; float nextY = INFINITY; int selectedDot = -1; @@ -39,6 +39,7 @@ int Store::closestVerticalDot(int direction, float x) { nextX = m_data[series][0][index]; nextY = m_data[series][1][index]; selectedDot = index; + *nextSeries = series; } } } @@ -51,6 +52,7 @@ int Store::closestVerticalDot(int direction, float x) { ((meanY - yValueForXValue(series, meanX) >= 0) == (direction > 0))) { if (nextX != meanX || ((nextY - meanY >= 0) == (direction > 0))) { selectedDot = numberOfPairsOfSeries(series); + *nextSeries = series; } } diff --git a/apps/regression/store.h b/apps/regression/store.h index 25a5b41e9..8dc09ab9f 100644 --- a/apps/regression/store.h +++ b/apps/regression/store.h @@ -13,7 +13,7 @@ public: // Dots /* Return the closest dot to abscissa x above the regression curve if * direction > 0, below otherwise */ - int closestVerticalDot(int direction, float x); + int closestVerticalDot(int direction, float x, int * nextSeries); /* Return the closest dot to given dot, on the right if direction > 0, * on the left otherwise */ int nextDot(int series, int direction, int dot); @@ -51,7 +51,7 @@ private: }; typedef double (Store::*ArgCalculPointer)(int, int) const; -typedef double (Store::*CalculPointer)(); +typedef double (Store::*CalculPointer)(int) const; typedef void (Store::*RangeMethodPointer)(); } diff --git a/apps/regression/store_controller.cpp b/apps/regression/store_controller.cpp index 280689011..fec8d8569 100644 --- a/apps/regression/store_controller.cpp +++ b/apps/regression/store_controller.cpp @@ -16,12 +16,12 @@ StoreController::StoreController(Responder * parentResponder, Store * store, But Shared::StoreController(parentResponder, store, header), m_titleCells{} { - for (int i = 0; i < k_numberOfSeries; i++) { + for (int i = 0; i < Store::k_numberOfSeries; i++) { /* If the index is too big, the layout creation should take into account the * possibility of a two-digits index. */ - assert(k_numberOfSeries < 10); - m_titleLayout[k_numberOfColumnsPerSeries*i] = new HorizontalLayout(new CharLayout('X', KDText::FontSize::Small), new VerticalOffsetLayout(new CharLayout('0'+ i, KDText::FontSize::Small), VerticalOffsetLayout::Type::Subscript, false), false); - m_titleLayout[k_numberOfColumnsPerSeries*i+1] = new HorizontalLayout(new CharLayout('Y', KDText::FontSize::Small), new VerticalOffsetLayout(new CharLayout('0' + i, KDText::FontSize::Small), VerticalOffsetLayout::Type::Subscript, false), false); + assert(Store::k_numberOfSeries < 10); + m_titleLayout[Store::k_numberOfColumnsPerSeries*i] = new HorizontalLayout(new CharLayout('X', KDText::FontSize::Small), new VerticalOffsetLayout(new CharLayout('0'+ i, KDText::FontSize::Small), VerticalOffsetLayout::Type::Subscript, false), false); + m_titleLayout[Store::k_numberOfColumnsPerSeries*i+1] = new HorizontalLayout(new CharLayout('Y', KDText::FontSize::Small), new VerticalOffsetLayout(new CharLayout('0' + i, KDText::FontSize::Small), VerticalOffsetLayout::Type::Subscript, false), false); } }