Skip to content

Commit 5e7baa0

Browse files
Apply review comments
1 parent c695999 commit 5e7baa0

File tree

6 files changed

+149
-76
lines changed

6 files changed

+149
-76
lines changed

dpnp/dpnp_iface_statistics.py

Lines changed: 120 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@
3737
3838
"""
3939

40-
import warnings
41-
4240
import dpctl.tensor as dpt
4341
import numpy
4442
from dpctl.tensor._numpy_helper import (
@@ -363,50 +361,7 @@ def bincount(x1, weights=None, minlength=0):
363361
return call_origin(numpy.bincount, x1, weights=weights, minlength=minlength)
364362

365363

366-
def correlate(x1, x2, mode="valid"):
367-
"""
368-
Cross-correlation of two 1-dimensional sequences.
369-
370-
For full documentation refer to :obj:`numpy.correlate`.
371-
372-
Limitations
373-
-----------
374-
Input arrays are supported as :obj:`dpnp.ndarray`.
375-
Size and shape of input arrays are supported to be equal.
376-
Parameter `mode` is supported only with default value ``"valid"``.
377-
Otherwise the function will be executed sequentially on CPU.
378-
Input array data types are limited by supported DPNP :ref:`Data types`.
379-
380-
See Also
381-
--------
382-
:obj:`dpnp.convolve` : Discrete, linear convolution of
383-
two one-dimensional sequences.
384-
385-
Examples
386-
--------
387-
>>> import dpnp as np
388-
>>> x = np.correlate([1, 2, 3], [0, 1, 0.5])
389-
>>> [i for i in x]
390-
[3.5]
391-
392-
"""
393-
394-
x1_desc = dpnp.get_dpnp_descriptor(x1, copy_when_nondefault_queue=False)
395-
x2_desc = dpnp.get_dpnp_descriptor(x2, copy_when_nondefault_queue=False)
396-
if x1_desc and x2_desc:
397-
if x1_desc.size != x2_desc.size or x1_desc.size == 0:
398-
pass
399-
elif x1_desc.shape != x2_desc.shape:
400-
pass
401-
elif mode != "valid":
402-
pass
403-
else:
404-
return dpnp_correlate(x1_desc, x2_desc).get_pyobj()
405-
406-
return call_origin(numpy.correlate, x1, x2, mode=mode)
407-
408-
409-
def corrcoef(x, y=None, rowvar=True, bias=None, ddof=None, *, dtype=None):
364+
def corrcoef(x, y=None, rowvar=True, *, dtype=None):
410365
"""
411366
Return Pearson product-moment correlation coefficients.
412367
@@ -418,20 +373,19 @@ def corrcoef(x, y=None, rowvar=True, bias=None, ddof=None, *, dtype=None):
418373
A 1-D or 2-D array containing multiple variables and observations.
419374
Each row of `x` represents a variable, and each column a single
420375
observation of all those variables. Also see `rowvar` below.
421-
y : {dpnp.ndarray, usm_ndarray}, optional
376+
y : {None, dpnp.ndarray, usm_ndarray}, optional
422377
An additional set of variables and observations. `y` has the same
423378
shape as `x`.
379+
Default: ``None``.
424380
rowvar : {bool}, optional
425-
If `rowvar` is True (default), then each row represents a
426-
variable, with observations in the columns. Otherwise, the relationship
381+
If `rowvar` is ``True``, then each row represents a variable,
382+
with observations in the columns. Otherwise, the relationship
427383
is transposed: each column represents a variable, while the rows
428384
contain observations.
429-
bias : {None}, optional
430-
Has no effect, do not use.
431-
ddof : {None}, optional
432-
Has no effect, do not use.
433-
dtype : data-type, optional
385+
Default: ``True``.
386+
dtype : {None, dtype}, optional
434387
Data-type of the result.
388+
Default: ``None``.
435389
436390
Returns
437391
-------
@@ -441,25 +395,84 @@ def corrcoef(x, y=None, rowvar=True, bias=None, ddof=None, *, dtype=None):
441395
See Also
442396
--------
443397
:obj:`dpnp.cov` : Covariance matrix.
398+
399+
Examples
400+
--------
401+
In this example we generate two random arrays, ``xarr`` and ``yarr``, and
402+
compute the row-wise and column-wise Pearson correlation coefficients,
403+
``R``. Since ``rowvar`` is true by default, we first find the row-wise
404+
Pearson correlation coefficients between the variables of ``xarr``.
405+
406+
>>> import dpnp as np
407+
>>> np.random.seed(123)
408+
>>> xarr = np.random.rand(3, 3).astype(np.float32)
409+
>>> xarr
410+
array([[7.2858386e-17, 2.2066992e-02, 3.9520904e-01],
411+
[4.8012391e-01, 5.9377134e-01, 4.5147297e-01],
412+
[9.0728188e-01, 9.9387854e-01, 5.8399546e-01]], dtype=float32)
413+
>>> R1 = np.corrcoef(xarr)
414+
>>> R1
415+
array([[ 0.99999994, -0.6173796 , -0.9685411 ],
416+
[-0.6173796 , 1. , 0.7937219 ],
417+
[-0.9685411 , 0.7937219 , 0.9999999 ]], dtype=float32)
418+
419+
If we add another set of variables and observations ``yarr``, we can
420+
compute the row-wise Pearson correlation coefficients between the
421+
variables in ``xarr`` and ``yarr``.
422+
423+
>>> yarr = np.random.rand(3, 3).astype(np.float32)
424+
>>> yarr
425+
array([[0.17615308, 0.65354985, 0.15716429],
426+
[0.09373496, 0.2123185 , 0.84086883],
427+
[0.9011005 , 0.45206687, 0.00225109]], dtype=float32)
428+
>>> R2 = np.corrcoef(xarr, yarr)
429+
>>> R2
430+
array([[ 0.99999994, -0.6173796 , -0.968541 , -0.48613155, 0.9951523 ,
431+
-0.8900264 ],
432+
[-0.6173796 , 1. , 0.7937219 , 0.9875833 , -0.53702235,
433+
0.19083664],
434+
[-0.968541 , 0.7937219 , 0.9999999 , 0.6883078 , -0.9393724 ,
435+
0.74857277],
436+
[-0.48613152, 0.9875833 , 0.6883078 , 0.9999999 , -0.39783284,
437+
0.0342579 ],
438+
[ 0.9951523 , -0.53702235, -0.9393725 , -0.39783284, 0.99999994,
439+
-0.9305482 ],
440+
[-0.89002645, 0.19083665, 0.7485727 , 0.0342579 , -0.9305482 ,
441+
1. ]], dtype=float32)
442+
443+
Finally if we use the option ``rowvar=False``, the columns are now
444+
being treated as the variables and we will find the column-wise Pearson
445+
correlation coefficients between variables in ``xarr`` and ``yarr``.
446+
447+
>>> R3 = np.corrcoef(xarr, yarr, rowvar=False)
448+
>>> R3
449+
array([[ 1. , 0.9724453 , -0.9909503 , 0.8104691 , -0.46436927,
450+
-0.1643624 ],
451+
[ 0.9724453 , 1. , -0.9949381 , 0.6515728 , -0.6580445 ,
452+
0.07012729],
453+
[-0.99095035, -0.994938 , 1. , -0.72450536, 0.5790461 ,
454+
0.03047091],
455+
[ 0.8104691 , 0.65157276, -0.72450536, 1. , 0.14243561,
456+
-0.71102554],
457+
[-0.4643693 , -0.6580445 , 0.57904613, 0.1424356 , 0.99999994,
458+
-0.79727215],
459+
[-0.1643624 , 0.07012729, 0.03047091, -0.7110255 , -0.7972722 ,
460+
0.99999994]], dtype=float32)
444461
"""
445-
if bias is not None or ddof is not None:
446-
warnings.warn(
447-
"bias and ddof have no effect and are deprecated",
448-
DeprecationWarning,
449-
stacklevel=2,
450-
)
451462

452463
out = dpnp.cov(x, y, rowvar, dtype=dtype)
453-
try:
454-
d = dpnp.diag(out)
455-
except ValueError:
464+
if out.ndim == 0:
465+
# scalar covariance
466+
# nan if incorrect value (nan, inf, 0), 1 otherwise
456467
return out / out
457468

469+
d = dpnp.diag(out)
470+
458471
stddev = dpnp.sqrt(d.real)
459472
out /= stddev[:, None]
460473
out /= stddev[None, :]
461474

462-
# Clip real and imaginary parts to [-1, 1]. This does not guarantee
475+
# Clip real and imaginary parts to [-1, 1]. This does not guarantee
463476
# abs(a[i,j]) <= 1 for complex arrays, but is the best we can do without
464477
# excessive work.
465478
dpnp.clip(out.real, -1, 1, out=out.real)
@@ -469,6 +482,49 @@ def corrcoef(x, y=None, rowvar=True, bias=None, ddof=None, *, dtype=None):
469482
return out
470483

471484

485+
def correlate(x1, x2, mode="valid"):
486+
"""
487+
Cross-correlation of two 1-dimensional sequences.
488+
489+
For full documentation refer to :obj:`numpy.correlate`.
490+
491+
Limitations
492+
-----------
493+
Input arrays are supported as :obj:`dpnp.ndarray`.
494+
Size and shape of input arrays are supported to be equal.
495+
Parameter `mode` is supported only with default value ``"valid"``.
496+
Otherwise the function will be executed sequentially on CPU.
497+
Input array data types are limited by supported DPNP :ref:`Data types`.
498+
499+
See Also
500+
--------
501+
:obj:`dpnp.convolve` : Discrete, linear convolution of
502+
two one-dimensional sequences.
503+
504+
Examples
505+
--------
506+
>>> import dpnp as np
507+
>>> x = np.correlate([1, 2, 3], [0, 1, 0.5])
508+
>>> [i for i in x]
509+
[3.5]
510+
511+
"""
512+
513+
x1_desc = dpnp.get_dpnp_descriptor(x1, copy_when_nondefault_queue=False)
514+
x2_desc = dpnp.get_dpnp_descriptor(x2, copy_when_nondefault_queue=False)
515+
if x1_desc and x2_desc:
516+
if x1_desc.size != x2_desc.size or x1_desc.size == 0:
517+
pass
518+
elif x1_desc.shape != x2_desc.shape:
519+
pass
520+
elif mode != "valid":
521+
pass
522+
else:
523+
return dpnp_correlate(x1_desc, x2_desc).get_pyobj()
524+
525+
return call_origin(numpy.correlate, x1, x2, mode=mode)
526+
527+
472528
def cov(
473529
m,
474530
y=None,

tests/skipped_tests.tbl

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -310,11 +310,6 @@ tests/third_party/cupy/random_tests/test_sample.py::TestRandomIntegers2::test_bo
310310
tests/third_party/cupy/random_tests/test_sample.py::TestRandomIntegers2::test_goodness_of_fit
311311
tests/third_party/cupy/random_tests/test_sample.py::TestRandomIntegers2::test_goodness_of_fit_2
312312

313-
tests/third_party/cupy/statistics_tests/test_correlation.py::TestCorrcoef::test_corrcoef
314-
tests/third_party/cupy/statistics_tests/test_correlation.py::TestCorrcoef::test_corrcoef_diag_exception
315-
tests/third_party/cupy/statistics_tests/test_correlation.py::TestCorrcoef::test_corrcoef_rowvar
316-
tests/third_party/cupy/statistics_tests/test_correlation.py::TestCorrcoef::test_corrcoef_y
317-
318313
tests/third_party/cupy/statistics_tests/test_order.py::TestOrder::test_percentile_defaults[linear]
319314
tests/third_party/cupy/statistics_tests/test_order.py::TestOrder::test_percentile_defaults[lower]
320315
tests/third_party/cupy/statistics_tests/test_order.py::TestOrder::test_percentile_defaults[higher]

tests/test_statistics.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,10 @@ def test_std_error(self):
574574

575575

576576
class TestCorrcoef:
577-
@pytest.mark.usefixtures("suppress_divide_invalid_numpy_warnings")
577+
@pytest.mark.usefixtures(
578+
"suppress_divide_invalid_numpy_warnings",
579+
"suppress_dof_numpy_warnings",
580+
)
578581
@pytest.mark.parametrize("dtype", get_all_dtypes())
579582
@pytest.mark.parametrize("rowvar", [True, False])
580583
def test_corrcoef(self, dtype, rowvar):
@@ -586,7 +589,11 @@ def test_corrcoef(self, dtype, rowvar):
586589

587590
assert_dtype_allclose(result, expected)
588591

589-
@pytest.mark.usefixtures("suppress_divide_invalid_numpy_warnings")
592+
@pytest.mark.usefixtures(
593+
"suppress_divide_invalid_numpy_warnings",
594+
"suppress_dof_numpy_warnings",
595+
"suppress_mean_empty_slice_numpy_warnings",
596+
)
590597
@pytest.mark.parametrize("shape", [(2, 0), (0, 2)])
591598
def test_corrcoef_empty(self, shape):
592599
dp_array = dpnp.empty(shape, dtype=dpnp.int64)
@@ -608,7 +615,10 @@ def test_corrcoef_dtype(self, dt_in, dt_out):
608615
assert expected.dtype == result.dtype
609616
assert_allclose(result, expected, rtol=1e-6)
610617

611-
@pytest.mark.usefixtures("suppress_divide_invalid_numpy_warnings")
618+
@pytest.mark.usefixtures(
619+
"suppress_divide_invalid_numpy_warnings",
620+
"suppress_dof_numpy_warnings",
621+
)
612622
def test_corrcoef_scalar(self):
613623
dp_array = dpnp.array(5)
614624
np_array = dpnp.asnumpy(dp_array)

tests/test_sycl_queue.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,7 @@ def test_meshgrid(device):
442442
pytest.param("ceil", [-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]),
443443
pytest.param("conjugate", [[1.0 + 1.0j, 0.0], [0.0, 1.0 + 1.0j]]),
444444
pytest.param("copy", [1.0, 2.0, 3.0]),
445+
pytest.param("corrcoef", [[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]]),
445446
pytest.param(
446447
"cos", [-dpnp.pi / 2, -dpnp.pi / 4, 0.0, dpnp.pi / 4, dpnp.pi / 2]
447448
),
@@ -693,6 +694,11 @@ def test_reduce_hypot(device):
693694
pytest.param("append", [1, 2, 3], [4, 5, 6]),
694695
pytest.param("arctan2", [-1, +1, +1, -1], [-1, -1, +1, +1]),
695696
pytest.param("copysign", [0.0, 1.0, 2.0], [-1.0, 0.0, 1.0]),
697+
pytest.param(
698+
"corrcoef",
699+
[[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]],
700+
[[0.7, 0.8, 0.9], [1.0, 1.1, 1.2]],
701+
),
696702
pytest.param("cross", [1.0, 2.0, 3.0], [4.0, 5.0, 6.0]),
697703
pytest.param("digitize", [0.2, 6.4, 3.0], [0.0, 1.0, 2.5, 4.0]),
698704
pytest.param(

tests/test_usm_type.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,7 @@ def test_norm(usm_type, ord, axis):
576576
pytest.param("cbrt", [1, 8, 27]),
577577
pytest.param("ceil", [-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0]),
578578
pytest.param("conjugate", [[1.0 + 1.0j, 0.0], [0.0, 1.0 + 1.0j]]),
579+
pytest.param("corrcoef", [[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]]),
579580
pytest.param(
580581
"cos", [-dp.pi / 2, -dp.pi / 4, 0.0, dp.pi / 4, dp.pi / 2]
581582
),
@@ -685,6 +686,11 @@ def test_1in_1out(func, data, usm_type):
685686
pytest.param("copysign", [0.0, 1.0, 2.0], [-1.0, 0.0, 1.0]),
686687
pytest.param("cross", [1.0, 2.0, 3.0], [4.0, 5.0, 6.0]),
687688
pytest.param("digitize", [0.2, 6.4, 3.0], [0.0, 1.0, 2.5, 4.0]),
689+
pytest.param(
690+
"corrcoef",
691+
[[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]],
692+
[[0.7, 0.8, 0.9], [1.0, 1.1, 1.2]],
693+
),
688694
# dpnp.dot has 3 different implementations based on input arrays dtype
689695
# checking all of them
690696
pytest.param("dot", [3.0, 4.0, 5.0], [1.0, 2.0, 3.0]),

tests/third_party/cupy/statistics_tests/test_correlation.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,26 @@
1212

1313
class TestCorrcoef(unittest.TestCase):
1414
@testing.for_all_dtypes()
15-
@testing.numpy_cupy_allclose(type_check=False)
15+
@testing.numpy_cupy_allclose(type_check=has_support_aspect64())
1616
def test_corrcoef(self, xp, dtype):
1717
a = testing.shaped_arange((2, 3), xp, dtype)
1818
return xp.corrcoef(a)
1919

2020
@testing.for_all_dtypes()
21-
@testing.numpy_cupy_allclose(type_check=False)
21+
@testing.numpy_cupy_allclose(type_check=has_support_aspect64())
2222
def test_corrcoef_diag_exception(self, xp, dtype):
2323
a = testing.shaped_arange((1, 3), xp, dtype)
2424
return xp.corrcoef(a)
2525

2626
@testing.for_all_dtypes()
27-
@testing.numpy_cupy_allclose(type_check=False)
27+
@testing.numpy_cupy_allclose(type_check=has_support_aspect64())
2828
def test_corrcoef_y(self, xp, dtype):
2929
a = testing.shaped_arange((2, 3), xp, dtype)
3030
y = testing.shaped_arange((2, 3), xp, dtype)
3131
return xp.corrcoef(a, y=y)
3232

3333
@testing.for_all_dtypes()
34-
@testing.numpy_cupy_allclose(type_check=False)
34+
@testing.numpy_cupy_allclose(type_check=has_support_aspect64())
3535
def test_corrcoef_rowvar(self, xp, dtype):
3636
a = testing.shaped_arange((2, 3), xp, dtype)
3737
y = testing.shaped_arange((2, 3), xp, dtype)

0 commit comments

Comments
 (0)