From dff6672fb3c7eda03cb1de39a14b58a1c1d10089 Mon Sep 17 00:00:00 2001 From: Madhav2310 Date: Sun, 21 Aug 2022 05:04:48 +0530 Subject: [PATCH 1/2] Linear Regression function implemented --- src/runtime/statistics.py | 78 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/src/runtime/statistics.py b/src/runtime/statistics.py index 961c731404..f9a5808ae4 100644 --- a/src/runtime/statistics.py +++ b/src/runtime/statistics.py @@ -322,3 +322,81 @@ def pstdev(x: list[i32]) -> f64: """ return pvariance(x)**0.5 + +@overload +def linear_regression(x: list[i32], y: list[i32]) -> tuple[f64, f64]: + + """ + Returns the slope and intercept of simple linear regression + parameters estimated using ordinary least squares. + + """ + n: i32 = len(x) + if len(y) != n: + raise Exception('linear regression requires that both inputs have same number of data points') + if n < 2: + raise Exception('linear regression requires at least two data points') + xmean: f64 = mean(x) + ymean: f64 = mean(y) + + sxy: f64 = 0.0 + i: i32 + for i in range(n): + sxy += (x[i] - xmean) * (y[i] - ymean) + + sxx: f64 = 0.0 + j: i32 + for j in range(n): + sxx += (x[j] - xmean) ** 2 + + slope: f64 + + if sxx == 0: + raise Exception('x is constant') + else: + slope = sxy / sxx + + intercept: f64 = ymean - slope * xmean + + LinReg: tuple[f64, f64] = (slope, intercept) + + return LinReg + +@overload +def linear_regression(x: list[f64], y: list[f64]) -> tuple[f64, f64]: + + """ + Returns the slope and intercept of simple linear regression + parameters estimated using ordinary least squares. + + """ + n: i32 = len(x) + if len(y) != n: + raise Exception('linear regression requires that both inputs have same number of data points') + if n < 2: + raise Exception('linear regression requires at least two data points') + xmean: f64 = mean(x) + ymean: f64 = mean(y) + + sxy: f64 = 0.0 + i: i32 + for i in range(n): + sxy += (x[i] - xmean) * (y[i] - ymean) + + sxx: f64 = 0.0 + j: i32 + for j in range(n): + sxx += (x[j] - xmean) ** 2 + + slope: f64 + + if sxx == 0: + raise Exception('x is constant') + else: + slope = sxy / sxx + + intercept: f64 = ymean - slope * xmean + + LinReg: tuple[f64, f64] = (slope, intercept) + + return LinReg From c16f9492db4c5b689133bb7e074276f899c81468 Mon Sep 17 00:00:00 2001 From: Smit-create Date: Mon, 29 Aug 2022 16:32:32 +0530 Subject: [PATCH 2/2] Add tests Co-Authored-By: Madhav --- integration_tests/test_statistics.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/integration_tests/test_statistics.py b/integration_tests/test_statistics.py index 4228072418..25f15893fb 100644 --- a/integration_tests/test_statistics.py +++ b/integration_tests/test_statistics.py @@ -1,4 +1,5 @@ -from statistics import (mean, fmean, geometric_mean, harmonic_mean, variance, stdev, pvariance, pstdev) +from statistics import (mean, fmean, geometric_mean, harmonic_mean, variance, + stdev, pvariance, pstdev, linear_regression) from ltypes import i32, f64, i64, f32 eps: f64 @@ -122,6 +123,30 @@ def test_pstdev(): k = pstdev(b) assert abs(k - 0.37537181567080935) < eps +def test_linear_regression(): + c: list[f64] + c = [2.74, 1.23, 2.63, 2.22, 3.0, 1.98] + d: list[f64] + d = [9.4, 1.23, 2.63, 22.4, 1.9, 13.98] + + slope: f64 + intercept: f64 + slope, intercept = linear_regression(c, d) + + assert abs(slope + 0.6098133124816717) < eps + assert abs(intercept - 9.992570618707845) < eps + + a: list[i32] + b: list[i32] + a = [12, 24, 2, 1, 43, 53, 23] + b = [2, 13, 14, 63, 49, 7, 3] + + slope, intercept = linear_regression(a, b) + + assert abs(slope + 0.18514007308160782) < eps + assert abs(intercept - 25.750304506699152) < eps + + def check(): test_mean() test_geometric_mean() @@ -131,5 +156,6 @@ def check(): test_stdev() test_pvariance() test_pstdev() + test_linear_regression() check()