Skip to content

Commit 174c325

Browse files
Statistics funcs cov (#2)
* naive numpy.cov implementation * del statistics_tests * add statics_tests * throw errors in np.cov
1 parent 8983189 commit 174c325

File tree

8 files changed

+1046
-3
lines changed

8 files changed

+1046
-3
lines changed

dpnp/backend_statistics.pyx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,44 @@ from dpnp.dpnp_utils cimport checker_throw_type_error, normalize_axis
3838

3939

4040
__all__ += [
41+
"dpnp_cov",
4142
"dpnp_mean"
4243
]
4344

4445

46+
cpdef dparray dpnp_cov(dparray array1):
47+
# behaviour of original numpy
48+
if array1.ndim > 2:
49+
raise ValueError("array has more than 2 dimensions")
50+
51+
if array1.ndim < 2:
52+
raise NotImplementedError
53+
54+
# numpy provide result as float64 for any input type
55+
cdef dparray mean = dparray(array1.shape[0], dtype=numpy.float64)
56+
cdef dparray X = dparray(array1.shape, dtype=numpy.float64)
57+
58+
# mean(array1, axis=1) #################################
59+
# dpmp.mean throws: 'dpnp.dparray.dparray' object is not callable
60+
for i in range(array1.shape[0]):
61+
sum = 0.0
62+
for j in range(array1.shape[1]):
63+
sum += array1[i, j]
64+
mean[i] = sum / array1.shape[1]
65+
########################################################
66+
#X = array1 - mean[:, None]
67+
#X = array1 - mean[:, numpy.newaxis]
68+
#X = array1 - mean.reshape((array1.shape[0], 1))
69+
for i in range(array1.shape[0]):
70+
for j in range(array1.shape[1]):
71+
X[i, j] = array1[i, j] - mean[i]
72+
########################################################
73+
Y = X.transpose()
74+
res = dpnp_matmul(X, Y) / (array1.shape[1] - 1)
75+
76+
return res
77+
78+
4579
cpdef dparray dpnp_mean(dparray a, axis):
4680
cdef dparray_shape_type shape_a = a.shape
4781
cdef long size_a = a.size

dpnp/dpnp_iface_statistics.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,37 @@
4747
from dpnp.dpnp_utils import checker_throw_value_error, use_origin_backend
4848

4949
__all__ = [
50+
'cov',
5051
'mean'
5152
]
5253

5354

55+
def cov(in_array1, y=None, rowvar=True, bias=False, ddof=None, fweights=None, aweights=None):
56+
"""
57+
Estimate a covariance matrix, given data and weights.
58+
"""
59+
60+
is_dparray1 = isinstance(in_array1, dparray)
61+
62+
if (not use_origin_backend(in_array1) and is_dparray1):
63+
if y is not None:
64+
checker_throw_value_error("cov", "y", type(y), None)
65+
if rowvar is not True:
66+
checker_throw_value_error("cov", "rowvar", rowvar, True)
67+
if bias is not False:
68+
checker_throw_value_error("cov", "bias", bias, False)
69+
if ddof is not None:
70+
checker_throw_value_error("cov", "ddof", type(ddof), None)
71+
if fweights is not None:
72+
checker_throw_value_error("cov", "fweights", type(fweights), None)
73+
if aweights is not None:
74+
checker_throw_value_error("cov", "aweights", type(aweights), None)
75+
76+
return dpnp_cov(in_array1)
77+
78+
return numpy.cov(in_array1)
79+
80+
5481
def mean(a, axis=None):
5582
"""
5683
Compute the arithmetic mean along the specified axis.
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
import unittest
2+
3+
import numpy
4+
import pytest
5+
6+
import dpnp as cupy
7+
from tests.third_party.cupy import testing
8+
9+
10+
@testing.gpu
11+
class TestCorrcoef(unittest.TestCase):
12+
13+
@testing.for_all_dtypes()
14+
@testing.numpy_cupy_allclose()
15+
def test_corrcoef(self, xp, dtype):
16+
a = testing.shaped_arange((2, 3), xp, dtype)
17+
return xp.corrcoef(a)
18+
19+
@testing.for_all_dtypes()
20+
@testing.numpy_cupy_allclose()
21+
def test_corrcoef_diag_exception(self, xp, dtype):
22+
a = testing.shaped_arange((1, 3), xp, dtype)
23+
return xp.corrcoef(a)
24+
25+
@testing.for_all_dtypes()
26+
@testing.numpy_cupy_allclose()
27+
def test_corrcoef_y(self, xp, dtype):
28+
a = testing.shaped_arange((2, 3), xp, dtype)
29+
y = testing.shaped_arange((2, 3), xp, dtype)
30+
return xp.corrcoef(a, y=y)
31+
32+
@testing.for_all_dtypes()
33+
@testing.numpy_cupy_allclose()
34+
def test_corrcoef_rowvar(self, xp, dtype):
35+
a = testing.shaped_arange((2, 3), xp, dtype)
36+
y = testing.shaped_arange((2, 3), xp, dtype)
37+
return xp.corrcoef(a, y=y, rowvar=False)
38+
39+
40+
@testing.gpu
41+
class TestCov(unittest.TestCase):
42+
43+
def generate_input(self, a_shape, y_shape, xp, dtype):
44+
a = testing.shaped_arange(a_shape, xp, dtype)
45+
y = None
46+
if y_shape is not None:
47+
y = testing.shaped_arange(y_shape, xp, dtype)
48+
return a, y
49+
50+
@testing.for_all_dtypes()
51+
@testing.numpy_cupy_allclose()
52+
def check(self, a_shape, y_shape=None, rowvar=True, bias=False,
53+
ddof=None, xp=None, dtype=None):
54+
a, y = self.generate_input(a_shape, y_shape, xp, dtype)
55+
return xp.cov(a, y, rowvar, bias, ddof)
56+
57+
@testing.for_all_dtypes()
58+
@testing.numpy_cupy_allclose()
59+
def check_warns(self, a_shape, y_shape=None, rowvar=True, bias=False,
60+
ddof=None, xp=None, dtype=None):
61+
with testing.assert_warns(RuntimeWarning):
62+
a, y = self.generate_input(a_shape, y_shape, xp, dtype)
63+
return xp.cov(a, y, rowvar, bias, ddof)
64+
65+
@testing.for_all_dtypes()
66+
def check_raises(self, a_shape, y_shape=None, rowvar=True, bias=False,
67+
ddof=None, dtype=None):
68+
for xp in (numpy, cupy):
69+
a, y = self.generate_input(a_shape, y_shape, xp, dtype)
70+
with pytest.raises(ValueError):
71+
xp.cov(a, y, rowvar, bias, ddof)
72+
73+
def test_cov(self):
74+
self.check((2, 3))
75+
self.check((2,), (2,))
76+
self.check((1, 3), (1, 3), rowvar=False)
77+
self.check((2, 3), (2, 3), rowvar=False)
78+
self.check((2, 3), bias=True)
79+
self.check((2, 3), ddof=2)
80+
81+
def test_cov_warns(self):
82+
self.check_warns((2, 3), ddof=3)
83+
self.check_warns((2, 3), ddof=4)
84+
85+
def test_cov_raises(self):
86+
self.check_raises((2, 3), ddof=1.2)
87+
self.check_raises((3, 4, 2))
88+
self.check_raises((2, 3), (3, 4, 2))
89+
90+
def test_cov_empty(self):
91+
self.check((0, 1))
92+
93+
94+
@testing.gpu
95+
@testing.parameterize(*testing.product({
96+
'mode': ['valid', 'same', 'full'],
97+
'shape1': [(5,), (6,), (20,), (21,)],
98+
'shape2': [(5,), (6,), (20,), (21,)],
99+
}))
100+
class TestCorrelateShapeCombination(unittest.TestCase):
101+
102+
@testing.for_all_dtypes(no_float16=True)
103+
@testing.numpy_cupy_allclose(rtol=1e-4)
104+
def test_correlate(self, xp, dtype):
105+
a = testing.shaped_arange(self.shape1, xp, dtype)
106+
b = testing.shaped_arange(self.shape2, xp, dtype)
107+
return xp.correlate(a, b, mode=self.mode)
108+
109+
110+
@testing.gpu
111+
@testing.parameterize(*testing.product({
112+
'mode': ['valid', 'full', 'same']
113+
}))
114+
class TestCorrelate(unittest.TestCase):
115+
116+
@testing.for_all_dtypes()
117+
@testing.numpy_cupy_allclose(rtol=1e-5)
118+
def test_correlate_non_contiguous(self, xp, dtype):
119+
a = testing.shaped_arange((300,), xp, dtype)
120+
b = testing.shaped_arange((100,), xp, dtype)
121+
return xp.correlate(a[::200], b[10::70], mode=self.mode)
122+
123+
@testing.for_all_dtypes(no_float16=True)
124+
@testing.numpy_cupy_allclose(rtol=1e-4)
125+
def test_correlate_large_non_contiguous(self, xp, dtype):
126+
a = testing.shaped_arange((10000,), xp, dtype)
127+
b = testing.shaped_arange((1000,), xp, dtype)
128+
return xp.correlate(a[200::], b[10::700], mode=self.mode)
129+
130+
@testing.for_all_dtypes_combination(names=['dtype1', 'dtype2'])
131+
@testing.numpy_cupy_allclose(rtol=1e-2)
132+
def test_correlate_diff_types(self, xp, dtype1, dtype2):
133+
a = testing.shaped_random((200,), xp, dtype1)
134+
b = testing.shaped_random((100,), xp, dtype2)
135+
return xp.correlate(a, b, mode=self.mode)
136+
137+
138+
@testing.gpu
139+
@testing.parameterize(*testing.product({
140+
'mode': ['valid', 'same', 'full']
141+
}))
142+
class TestCorrelateInvalid(unittest.TestCase):
143+
144+
@testing.with_requires('numpy>=1.18')
145+
@testing.for_all_dtypes()
146+
def test_correlate_empty(self, dtype):
147+
for xp in (numpy, cupy):
148+
a = xp.zeros((0,), dtype)
149+
with pytest.raises(ValueError):
150+
xp.correlate(a, a, mode=self.mode)
151+
152+
@testing.for_all_dtypes()
153+
def test_correlate_ndim(self, dtype):
154+
for xp in (numpy, cupy):
155+
a = testing.shaped_arange((5, 10, 2), xp, dtype)
156+
b = testing.shaped_arange((3, 4, 4), xp, dtype)
157+
with pytest.raises(ValueError):
158+
xp.correlate(a, b, mode=self.mode)
159+
160+
@testing.for_all_dtypes()
161+
def test_correlate_zero_dim(self, dtype):
162+
for xp in (numpy, cupy):
163+
a = testing.shaped_arange((), xp, dtype)
164+
b = testing.shaped_arange((1,), xp, dtype)
165+
with pytest.raises(ValueError):
166+
xp.correlate(a, b, mode=self.mode)

0 commit comments

Comments
 (0)