From 06d71047765814b3190cd4d9019d9bbfd5538a8f Mon Sep 17 00:00:00 2001 From: Hugo Saint-Vignes Date: Wed, 25 Nov 2020 12:41:05 +0100 Subject: [PATCH] [apps/regression] Improve initial coefficient value Change-Id: I2026b8de7e031f7e22921be2def800fa71d7a4e4 --- apps/regression/model/trigonometric_model.cpp | 12 ++++++++++++ apps/regression/store.h | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/regression/model/trigonometric_model.cpp b/apps/regression/model/trigonometric_model.cpp index 37d9f225d..ec094e2bc 100644 --- a/apps/regression/model/trigonometric_model.cpp +++ b/apps/regression/model/trigonometric_model.cpp @@ -86,6 +86,18 @@ void TrigonometricModel::specializedInitCoefficientsForFit(double * modelCoeffic modelCoefficients[0] = 3.0*store->standardDeviationOfColumn(series, 1); // Init the "y delta" coefficient modelCoefficients[k_numberOfCoefficients - 1] = store->meanOfColumn(series, 1); + // Init the b coefficient + double rangeX = store->maxValueOfColumn(series, 0) - store->minValueOfColumn(series, 0); + if (rangeX > 0) { + /* b/2π represents the frequency of the sine (in radians). Instead of + * initializing it to 0, we use the inverse of X series' range as an order + * of magnitude for it. It can help avoiding a regression that overfits the + * data with a very high frequency. This period also depends on the + * angleUnit. We take it into account so that it doesn't impact the result + * (although coefficients b and c depends on the angleUnit). */ + double radian = toRadians(Poincare::Preferences::sharedPreferences()->angleUnit()); + modelCoefficients[1] = (2.0 * M_PI / radian) / rangeX; + } } Expression TrigonometricModel::expression(double * modelCoefficients) { diff --git a/apps/regression/store.h b/apps/regression/store.h index ddcb5dd43..41c1a057a 100644 --- a/apps/regression/store.h +++ b/apps/regression/store.h @@ -73,12 +73,12 @@ public: double yValueForXValue(int series, double x, Poincare::Context * globalContext); double xValueForYValue(int series, double y, Poincare::Context * globalContext); double correlationCoefficient(int series) const; // R + float maxValueOfColumn(int series, int i) const; //TODO LEA why float ? + float minValueOfColumn(int series, int i) const; //TODO LEA why float ? private: double computeDeterminationCoefficient(int series, Poincare::Context * globalContext); constexpr static float k_displayHorizontalMarginRatio = 0.05f; void resetMemoization(); - float maxValueOfColumn(int series, int i) const; //TODO LEA why float ? - float minValueOfColumn(int series, int i) const; //TODO LEA why float ? Model * regressionModel(int index); uint32_t m_seriesChecksum[k_numberOfSeries]; Model::Type m_regressionTypes[k_numberOfSeries];