From 31c5e8106f2ab59384fb1b3874b2252668335ac1 Mon Sep 17 00:00:00 2001 From: Maziar Veyskarami <maziar.veyskarami@iws.uni-stuttgart.de> Date: Thu, 15 Apr 2021 11:15:03 +0200 Subject: [PATCH] [common] add a function for linear regression in math.hh --- dumux/common/math.hh | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/dumux/common/math.hh b/dumux/common/math.hh index 08abfd48e3..2b8679b189 100644 --- a/dumux/common/math.hh +++ b/dumux/common/math.hh @@ -25,6 +25,7 @@ #define DUMUX_MATH_HH #include <algorithm> +#include <numeric> #include <cmath> #include <utility> @@ -881,6 +882,44 @@ vtmv(const Dune::DenseVector<V1>& v1, return m*(v1*v2); } +/*! + * \ingroup Common + * \brief Returns the [intercept, slope] of the regression line + * fitted to a set of (x, y) data points. + * + * Note: We use least-square regression method to find + * the regression line. + * + * \param x x-values of the data set + * \param y y-values of the data set + */ +template <class Scalar> +std::array<Scalar, 2> linearRegression(const std::vector<Scalar>& x, + const std::vector<Scalar>& y) +{ + if (x.size() != y.size()) + DUNE_THROW(Dune::InvalidStateException, "x and y array must have the same length."); + + const Scalar averageX = std::accumulate(x.begin(), x.end(), 0.0)/x.size(); + const Scalar averageY = std::accumulate(y.begin(), y.end(), 0.0)/y.size(); + + // calculate temporary variables necessary for slope computation + const Scalar numerator = std::inner_product( + x.begin(), x.end(), y.begin(), 0.0, std::plus<Scalar>(), + [&](auto xx, auto yy) { return (xx - averageX) * (yy - averageY); } + ); + const Scalar denominator = std::inner_product( + x.begin(), x.end(), x.begin(), 0.0, std::plus<Scalar>(), + [&](auto xx, auto yy) { return (xx - averageX) * (yy - averageX); } + ); + + // compute slope and intercept of the regression line + const Scalar slope = numerator / denominator; + const Scalar intercept = averageY - slope * averageX; + + return {intercept, slope}; +} + } // end namespace Dumux #endif -- GitLab