Skip to content

Commit a4443dc

Browse files
Madhav2310Smit-createczgdp1807
authored
geometric_mean, harmonic_mean expanded for i64, f64 data types (#956)
Co-authored-by: Smit Lunagariya <smitlunagariya.mat18@itbhu.ac.in> Co-authored-by: Gagandeep Singh <gdp.1807@gmail.com>
1 parent fc36f29 commit a4443dc

File tree

2 files changed

+103
-145
lines changed

2 files changed

+103
-145
lines changed

integration_tests/test_statistics.py

Lines changed: 19 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from statistics import (mean, fmean, geometric_mean, harmonic_mean,
2-
variance, stdev, covariance, correlation)
2+
variance, stdev)
33
from ltypes import i32, f64, i64
44

55
eps: f64
@@ -45,13 +45,31 @@ def test_geometric_mean():
4545
k = geometric_mean(c)
4646
assert abs(k - 1.8171205928321397) < eps
4747

48+
d: list[f64]
49+
d = [1.1, 3.4, 17.982, 11.8]
50+
l: f64
51+
l = geometric_mean(d)
52+
assert abs(l - 5.307596520524432) < eps
53+
4854
def test_harmonic_mean():
4955
c: list[i32]
5056
c = [9,2,46]
5157
k: f64
5258
k = harmonic_mean(c)
5359
assert abs(k - 4.740458015267175) < eps
5460

61+
d: list[i32]
62+
d = [9, 0, 46]
63+
l: f64
64+
l = harmonic_mean(d)
65+
assert l == 0.0
66+
67+
e: list[f64]
68+
e = [1.1, 3.4, 17.982, 11.8]
69+
f: f64
70+
f = harmonic_mean(e)
71+
assert abs(f - 2.977152988015106) < eps
72+
5573

5674
def test_variance():
5775
a: list[i32]
@@ -66,47 +84,6 @@ def test_variance():
6684
k = variance(b)
6785
assert abs(k - 0.40924) < eps
6886

69-
def test_covariance():
70-
a: list[i32]
71-
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
72-
b: list[i32]
73-
b = [1, 2, 3, 1, 2, 3, 1, 2, 3]
74-
j: f64
75-
j = covariance(a,b)
76-
assert abs(j - 0.75) < eps
77-
78-
c: list[f64]
79-
c = [2.74, 1.23, 2.63, 2.22, 3.0, 1.98]
80-
d: list[f64]
81-
d = [9.4, 1.23, 2.63, 22.4, 1.9, 13.98]
82-
k: f64
83-
k = covariance(c,d)
84-
assert abs(k + 0.24955999999999934) < eps
85-
86-
def test_correlation():
87-
a: list[i32]
88-
a = [11, 2, 7, 4, 15, 6, 10, 8, 9, 1, 11, 5, 13, 6, 15]
89-
b: list[i32]
90-
b = [2, 5, 17, 6, 10, 8, 13, 4, 6, 9, 11, 2, 5, 4, 7]
91-
92-
j: f64
93-
j = correlation(a,b)
94-
assert abs(j - 0.11521487988958108) < eps
95-
96-
c: list[i32]
97-
c = [1, 2, 3, 4, 5, 6, 7, 8, 9]
98-
d: list[i32]
99-
d = [9, 8, 7, 6, 5, 4, 3, 2, 1]
100-
101-
k: f64
102-
k = correlation(c,c)
103-
assert k == 1.0
104-
105-
l: f64
106-
l = correlation(c,d)
107-
assert l == -1.0
108-
109-
11087
def test_stdev():
11188
a: list[i32]
11289
a = [1, 2, 3, 4, 5]
@@ -128,7 +105,5 @@ def check():
128105
test_fmean()
129106
test_variance()
130107
test_stdev()
131-
test_covariance()
132-
test_correlation()
133108

134109
check()

src/runtime/statistics.py

Lines changed: 84 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def fmean(x: list[f32]) -> f64:
102102
"""
103103
return mean(x)
104104

105-
105+
@overload
106106
def geometric_mean(x: list[i32]) -> f64:
107107
"""
108108
Returns the geometric mean of a data sequence of numbers
@@ -115,11 +115,51 @@ def geometric_mean(x: list[i32]) -> f64:
115115
i: i32
116116

117117
for i in range(k):
118+
if x[i] <= 0:
119+
raise Exception("geometric mean requires a non-empty dataset containing positive numbers")
120+
product *= float(x[i])
121+
122+
return product**(1/k)
123+
124+
@overload
125+
def geometric_mean(x: list[i64]) -> f64:
126+
"""
127+
Returns the geometric mean of a data sequence of numbers
128+
"""
129+
k: i32 = len(x)
130+
if k == 0:
131+
return 0.0
132+
product: f64
133+
product = 1.0
134+
i: i32
135+
136+
for i in range(k):
137+
if x[i] <= 0:
138+
raise Exception("geometric mean requires a non-empty dataset containing positive numbers")
118139
product *= float(x[i])
119140

120141
return product ** (1 / k)
121142

143+
@overload
144+
def geometric_mean(x: list[f64]) -> f64:
145+
"""
146+
Returns the geometric mean of a data sequence of numbers
147+
"""
148+
k: i32 = len(x)
149+
if k == 0:
150+
return 0.0
151+
product: f64
152+
product = 1.0
153+
i: i32
154+
155+
for i in range(k):
156+
if x[i] <= 0.0:
157+
raise Exception("geometric mean requires a non-empty dataset containing positive numbers")
158+
product *= x[i]
159+
160+
return product**(1/k)
122161

162+
@overload
123163
def harmonic_mean(x: list[i32]) -> f64:
124164
"""
125165
Returns the harmonic mean of a data sequence of numbers
@@ -134,6 +174,49 @@ def harmonic_mean(x: list[i32]) -> f64:
134174
for i in range(k):
135175
if x[i] == 0:
136176
return 0.0
177+
if x[i] < 0.0:
178+
raise Exception("Harmonic mean does not support negative values")
179+
sum += 1 / x[i]
180+
181+
return float(k/sum)
182+
183+
@overload
184+
def harmonic_mean(x: list[i64]) -> f64:
185+
"""
186+
Returns the harmonic mean of a data sequence of numbers
187+
"""
188+
k: i32 = len(x)
189+
if k == 0:
190+
return 0.0
191+
sum: f64
192+
sum = 0.0
193+
i: i32
194+
195+
for i in range(k):
196+
if x[i] == 0:
197+
return 0.0
198+
if x[i] < 0 :
199+
raise Exception("Harmonic mean does not support negative values")
200+
sum += 1 / x[i]
201+
return k/sum
202+
203+
@overload
204+
def harmonic_mean(x: list[f64]) -> f64:
205+
"""
206+
Returns the harmonic mean of a data sequence of numbers
207+
"""
208+
k: i32 = len(x)
209+
if k == 0:
210+
return 0.0
211+
sum: f64
212+
sum = 0.0
213+
i: i32
214+
215+
for i in range(k):
216+
if x[i] == 0.0:
217+
return 0.0
218+
if x[i] < 0.0:
219+
raise Exception("Harmonic mean does not support negative values")
137220
sum += 1 / x[i]
138221

139222
return k / sum
@@ -189,103 +272,3 @@ def stdev(x: list[i32]) -> f64:
189272
"""
190273
return variance(x)**0.5
191274

192-
@overload
193-
def covariance(x: list[i32], y: list[i32]) -> f64:
194-
"""
195-
Returns the covariance of a data sequence of numbers
196-
"""
197-
n: i32 = len(x)
198-
m: i32 = len(y)
199-
if (n < 2 or m < 2) or n != m:
200-
raise Exception("Both inputs must be of the same length (no less than two)")
201-
xmean: f64 = mean(x)
202-
ymean: f64 = mean(y)
203-
num: f64
204-
num = 0.0
205-
i: i32
206-
for i in range(n):
207-
num += (x[i] - xmean) * (y[i] - ymean)
208-
return num / (n-1)
209-
210-
@overload
211-
def covariance(x: list[f64], y: list[f64]) -> f64:
212-
"""
213-
Returns the covariance of a data sequence of numbers
214-
"""
215-
n: i32 = len(x)
216-
m: i32 = len(y)
217-
if (n < 2 or m < 2) or n != m:
218-
raise Exception("Both inputs must be of the same length (no less than two)")
219-
xmean: f64 = mean(x)
220-
ymean: f64 = mean(y)
221-
num: f64
222-
num = 0.0
223-
i: i32
224-
for i in range(n):
225-
num += (x[i] - xmean) * (y[i] - ymean)
226-
return num / (n-1)
227-
228-
@overload
229-
def correlation(x: list[i32], y: list[i32]) -> f64:
230-
"""
231-
Return the Pearson's correlation coefficient for two inputs.
232-
"""
233-
n: i32 = len(x)
234-
m: i32 = len(y)
235-
if n != m:
236-
raise Exception("correlation requires that both inputs have same number of data points")
237-
if n < 2:
238-
raise Exception("correlation requires at least two data points")
239-
xmean: f64 = mean(x)
240-
ymean: f64 = mean(y)
241-
242-
sxy: f64 = 0.0
243-
i: i32
244-
for i in range(n):
245-
sxy += (x[i] - xmean) * (y[i] - ymean)
246-
247-
sxx: f64 = 0.0
248-
j: i32
249-
for j in range(n):
250-
sxx += (x[j] - xmean) ** 2
251-
252-
syy: f64 = 0.0
253-
k: i32
254-
for k in range(n):
255-
syy += (y[k] - ymean) ** 2
256-
if sqrt(sxx * syy) == 0:
257-
raise Exception('at least one of the inputs is constant')
258-
return sxy / sqrt(sxx * syy)
259-
260-
@overload
261-
def correlation(x: list[f64], y: list[f64]) -> f64:
262-
"""
263-
Return the Pearson's correlation coefficient for two inputs.
264-
"""
265-
n: i32 = len(x)
266-
m: i32 = len(y)
267-
if n != m:
268-
raise Exception("correlation requires that both inputs have same number of data points")
269-
if n < 2:
270-
raise Exception("correlation requires at least two data points")
271-
xmean: f64 = mean(x)
272-
ymean: f64 = mean(y)
273-
274-
sxy: f64 = 0.0
275-
i: i32
276-
for i in range(n):
277-
sxy += (x[i] - xmean) * (y[i] - ymean)
278-
279-
sxx: f64 = 0.0
280-
j: i32
281-
for j in range(n):
282-
sxx += (x[j] - xmean) ** 2
283-
284-
syy: f64 = 0.0
285-
k: i32
286-
for k in range(n):
287-
syy += (y[k] - ymean) ** 2
288-
if sqrt(sxx * syy) == 0:
289-
raise Exception('at least one of the inputs is constant')
290-
return sxy / sqrt(sxx * syy)
291-

0 commit comments

Comments
 (0)