• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

IntelPython / dpnp / 11943154871

20 Nov 2024 10:54PM UTC coverage: 67.757% (-0.004%) from 67.761%
11943154871

Pull #2189

github

web-flow
Merge 77be4e2ca into ffd3829f6
Pull Request #2189: simplify `dpnp.average` implementation

4365 of 9994 branches covered (43.68%)

Branch coverage included in aggregate %.

17 of 17 new or added lines in 1 file covered. (100.0%)

3 existing lines in 1 file now uncovered.

16399 of 20651 relevant lines covered (79.41%)

20660.42 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.75
/dpnp/dpnp_iface_statistics.py
1
# -*- coding: utf-8 -*-
2
# *****************************************************************************
3
# Copyright (c) 2016-2024, Intel Corporation
4
# All rights reserved.
5
#
6
# Redistribution and use in source and binary forms, with or without
7
# modification, are permitted provided that the following conditions are met:
8
# - Redistributions of source code must retain the above copyright notice,
9
#   this list of conditions and the following disclaimer.
10
# - Redistributions in binary form must reproduce the above copyright notice,
11
#   this list of conditions and the following disclaimer in the documentation
12
#   and/or other materials provided with the distribution.
13
#
14
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24
# THE POSSIBILITY OF SUCH DAMAGE.
25
# *****************************************************************************
26

27
"""
28
Interface of the statistics function of the DPNP
29

30
Notes
31
-----
32
This module is a face or public interface file for the library
33
it contains:
34
 - Interface functions
35
 - documentation for the functions
36
 - The functions parameters check
37

38
"""
39

40
import dpctl.tensor as dpt
1✔
41
import numpy
1✔
42
from dpctl.tensor._numpy_helper import (
1✔
43
    normalize_axis_index,
44
    normalize_axis_tuple,
45
)
46

47
import dpnp
1✔
48

49
# pylint: disable=no-name-in-module
50
from .dpnp_algo import dpnp_correlate
1✔
51
from .dpnp_array import dpnp_array
1✔
52
from .dpnp_utils import call_origin, get_usm_allocations
1✔
53
from .dpnp_utils.dpnp_utils_reduction import dpnp_wrap_reduction_call
1✔
54
from .dpnp_utils.dpnp_utils_statistics import dpnp_cov
1✔
55

56
__all__ = [
1✔
57
    "amax",
58
    "amin",
59
    "average",
60
    "corrcoef",
61
    "correlate",
62
    "cov",
63
    "max",
64
    "mean",
65
    "median",
66
    "min",
67
    "ptp",
68
    "std",
69
    "var",
70
]
71

72

73
def _count_reduce_items(arr, axis, where=True):
1✔
74
    """
75
    Calculates the number of items used in a reduction operation
76
    along the specified axis or axes.
77

78
    Parameters
79
    ----------
80
    arr : {dpnp.ndarray, usm_ndarray}
81
        Input array.
82
    axis : {None, int, tuple of ints}, optional
83
        axis or axes along which the number of items used in a reduction
84
        operation must be counted. If a tuple of unique integers is given,
85
        the items are counted over multiple axes. If ``None``, the variance
86
        is computed over the entire array.
87
        Default: `None`.
88

89
    Returns
90
    -------
91
    out : int
92
        The number of items should be used in a reduction operation.
93

94
    Limitations
95
    -----------
96
    Parameters `where` is only supported with its default value.
97

98
    """
99
    if where is True:
1!
100
        # no boolean mask given, calculate items according to axis
101
        if axis is None:
1✔
102
            axis = tuple(range(arr.ndim))
1✔
103
        elif not isinstance(axis, tuple):
1✔
104
            axis = (axis,)
1✔
105
        items = 1
1✔
106
        for ax in axis:
1✔
107
            items *= arr.shape[normalize_axis_index(ax, arr.ndim)]
1✔
108
        items = dpnp.intp(items)
1✔
109
    else:
110
        raise NotImplementedError(
×
111
            "where keyword argument is only supported with its default value."
112
        )
113
    return items
1✔
114

115

116
def _flatten_array_along_axes(arr, axes_to_flatten):
1✔
117
    """Flatten an array along a specific set of axes."""
118

119
    axes_to_keep = (
1✔
120
        axis for axis in range(arr.ndim) if axis not in axes_to_flatten
121
    )
122

123
    # Move the axes_to_flatten to the front
124
    arr_moved = dpnp.moveaxis(arr, axes_to_flatten, range(len(axes_to_flatten)))
1✔
125

126
    new_shape = (-1,) + tuple(arr.shape[axis] for axis in axes_to_keep)
1✔
127
    flattened_arr = arr_moved.reshape(new_shape)
1✔
128

129
    return flattened_arr
1✔
130

131

132
def _get_comparison_res_dt(a, _dtype, _out):
1✔
133
    """Get a data type used by dpctl for result array in comparison function."""
134

135
    return a.dtype
1✔
136

137

138
def amax(a, axis=None, out=None, keepdims=False, initial=None, where=True):
1✔
139
    """
140
    Return the maximum of an array or maximum along an axis.
141

142
    `amax` is an alias of :obj:`dpnp.max`.
143

144
    See Also
145
    --------
146
    :obj:`dpnp.max` : alias of this function
147
    :obj:`dpnp.ndarray.max` : equivalent method
148

149
    """
150

151
    return max(
1✔
152
        a, axis=axis, out=out, keepdims=keepdims, initial=initial, where=where
153
    )
154

155

156
def amin(a, axis=None, out=None, keepdims=False, initial=None, where=True):
1✔
157
    """
158
    Return the minimum of an array or minimum along an axis.
159

160
    `amin` is an alias of :obj:`dpnp.min`.
161

162
    See Also
163
    --------
164
    :obj:`dpnp.min` : alias of this function
165
    :obj:`dpnp.ndarray.min` : equivalent method
166

167
    """
168

169
    return min(
1✔
170
        a, axis=axis, out=out, keepdims=keepdims, initial=initial, where=where
171
    )
172

173

174
def average(a, axis=None, weights=None, returned=False, *, keepdims=False):
1✔
175
    """
176
    Compute the weighted average along the specified axis.
177

178
    For full documentation refer to :obj:`numpy.average`.
179

180
    Parameters
181
    ----------
182
    a : {dpnp.ndarray, usm_ndarray}
183
        Input array.
184
    axis : {None, int, tuple of ints}, optional
185
        Axis or axes along which the averages must be computed. If
186
        a tuple of unique integers, the averages are computed over multiple
187
        axes. If ``None``, the average is computed over the entire array.
188
        Default: ``None``.
189
    weights : {array_like}, optional
190
        An array of weights associated with the values in `a`. Each value in
191
        `a` contributes to the average according to its associated weight.
192
        The weights array can either be 1-D (in which case its length must be
193
        the size of `a` along the given axis) or of the same shape as `a`.
194
        If `weights=None`, then all data in `a` are assumed to have a
195
        weight equal to one.  The 1-D calculation is::
196

197
            avg = sum(a * weights) / sum(weights)
198

199
        The only constraint on `weights` is that `sum(weights)` must not be 0.
200
    returned : {bool}, optional
201
        If ``True``, the tuple (`average`, `sum_of_weights`) is returned,
202
        otherwise only the average is returned. If `weights=None`,
203
        `sum_of_weights` is equivalent to the number of elements over which
204
        the average is taken.
205
        Default: ``False``.
206
    keepdims : {None, bool}, optional
207
        If ``True``, the reduced axes (dimensions) are included in the result
208
        as singleton dimensions, so that the returned array remains
209
        compatible with the input array according to Array Broadcasting
210
        rules. Otherwise, if ``False``, the reduced axes are not included in
211
        the returned array.
212
        Default: ``False``.
213

214
    Returns
215
    -------
216
    out, [sum_of_weights] : dpnp.ndarray, dpnp.ndarray
217
        Return the average along the specified axis. When `returned` is
218
        ``True``, return a tuple with the average as the first element and
219
        the sum of the weights as the second element. `sum_of_weights` is of
220
        the same type as `out`. The result dtype follows a general pattern.
221
        If `weights` is ``None``, the result dtype will be that of `a` , or
222
        default floating point data type for the device where input array `a`
223
        is allocated. Otherwise, if `weights` is not ``None`` and `a` is
224
        non-integral, the result type will be the type of lowest precision
225
        capable of representing values of both `a` and `weights`. If `a`
226
        happens to be integral, the previous rules still applies but the result
227
        dtype will at least be default floating point data type for the device
228
        where input array `a` is allocated.
229

230
    See Also
231
    --------
232
    :obj:`dpnp.mean` : Compute the arithmetic mean along the specified axis.
233
    :obj:`dpnp.sum` : Sum of array elements over a given axis.
234

235
    Examples
236
    --------
237
    >>> import dpnp as np
238
    >>> data = np.arange(1, 5)
239
    >>> data
240
    array([1, 2, 3, 4])
241
    >>> np.average(data)
242
    array(2.5)
243
    >>> np.average(np.arange(1, 11), weights=np.arange(10, 0, -1))
244
    array(4.0)
245

246
    >>> data = np.arange(6).reshape((3, 2))
247
    >>> data
248
    array([[0, 1],
249
        [2, 3],
250
        [4, 5]])
251
    >>> np.average(data, axis=1, weights=[1./4, 3./4])
252
    array([0.75, 2.75, 4.75])
253
    >>> np.average(data, weights=[1./4, 3./4])
254
    TypeError: Axis must be specified when shapes of a and weights differ.
255

256
    With ``keepdims=True``, the following result has shape (3, 1).
257

258
    >>> np.average(data, axis=1, keepdims=True)
259
    array([[0.5],
260
        [2.5],
261
        [4.5]])
262

263
    >>> a = np.ones(5, dtype=np.float64)
264
    >>> w = np.ones(5, dtype=np.complex64)
265
    >>> avg = np.average(a, weights=w)
266
    >>> print(avg.dtype)
267
    complex128
268

269
    """
270

271
    dpnp.check_supported_arrays_type(a)
1✔
272
    usm_type, exec_q = get_usm_allocations([a, weights])
1✔
273

274
    if weights is None:
1✔
275
        avg = dpnp.mean(a, axis=axis, keepdims=keepdims)
1✔
276
        scl = dpnp.asanyarray(
1✔
277
            avg.dtype.type(a.size / avg.size),
278
            usm_type=usm_type,
279
            sycl_queue=exec_q,
280
        )
281
    else:
282
        wgt = dpnp.asanyarray(weights, usm_type=usm_type, sycl_queue=exec_q)
1✔
283

284
        if not dpnp.issubdtype(a.dtype, dpnp.inexact):
1✔
285
            default_dtype = dpnp.default_float_type(a.device)
1✔
286
            result_dtype = dpnp.result_type(a.dtype, wgt.dtype, default_dtype)
1✔
287
        else:
288
            result_dtype = dpnp.result_type(a.dtype, wgt.dtype)
1✔
289

290
        # Sanity checks
291
        if a.shape != wgt.shape:
1✔
292
            if axis is None:
1✔
293
                raise TypeError(
1✔
294
                    "Axis must be specified when shapes of input array and "
295
                    "weights differ."
296
                )
297
            if wgt.ndim != 1:
1✔
298
                raise TypeError(
1✔
299
                    "1D weights expected when shapes of input array and "
300
                    "weights differ."
301
                )
302
            if wgt.shape[0] != a.shape[axis]:
1✔
303
                raise ValueError(
1✔
304
                    "Length of weights not compatible with specified axis."
305
                )
306

307
            # setup wgt to broadcast along axis
308
            wgt = dpnp.broadcast_to(wgt, (a.ndim - 1) * (1,) + wgt.shape)
1✔
309
            wgt = wgt.swapaxes(-1, axis)
1✔
310

311
        scl = wgt.sum(axis=axis, dtype=result_dtype, keepdims=keepdims)
1✔
312
        if dpnp.any(scl == 0.0):
1✔
313
            raise ZeroDivisionError("Weights sum to zero, can't be normalized")
1✔
314

315
        # result_datatype
316
        avg = (
1✔
317
            dpnp.multiply(a, wgt).sum(
318
                axis=axis, dtype=result_dtype, keepdims=keepdims
319
            )
320
            / scl
321
        )
322

323
    if returned:
1✔
324
        if scl.shape != avg.shape:
1✔
325
            scl = dpnp.broadcast_to(scl, avg.shape).copy()
1✔
326
        return avg, scl
1✔
327
    return avg
1✔
328

329

330
def corrcoef(x, y=None, rowvar=True, *, dtype=None):
1✔
331
    """
332
    Return Pearson product-moment correlation coefficients.
333

334
    For full documentation refer to :obj:`numpy.corrcoef`.
335

336
    Parameters
337
    ----------
338
    x : {dpnp.ndarray, usm_ndarray}
339
        A 1-D or 2-D array containing multiple variables and observations.
340
        Each row of `x` represents a variable, and each column a single
341
        observation of all those variables. Also see `rowvar` below.
342
    y : {None, dpnp.ndarray, usm_ndarray}, optional
343
        An additional set of variables and observations. `y` has the same
344
        shape as `x`.
345
        Default: ``None``.
346
    rowvar : {bool}, optional
347
        If `rowvar` is ``True``, then each row represents a variable,
348
        with observations in the columns. Otherwise, the relationship
349
        is transposed: each column represents a variable, while the rows
350
        contain observations.
351
        Default: ``True``.
352
    dtype : {None, dtype}, optional
353
        Data-type of the result.
354
        Default: ``None``.
355

356
    Returns
357
    -------
358
    R : {dpnp.ndarray}
359
        The correlation coefficient matrix of the variables.
360

361
    See Also
362
    --------
363
    :obj:`dpnp.cov` : Covariance matrix.
364

365
    Examples
366
    --------
367
    In this example we generate two random arrays, ``xarr`` and ``yarr``, and
368
    compute the row-wise and column-wise Pearson correlation coefficients,
369
    ``R``. Since `rowvar` is true by default, we first find the row-wise
370
    Pearson correlation coefficients between the variables of ``xarr``.
371

372
    >>> import dpnp as np
373
    >>> np.random.seed(123)
374
    >>> xarr = np.random.rand(3, 3).astype(np.float32)
375
    >>> xarr
376
    array([[7.2858386e-17, 2.2066992e-02, 3.9520904e-01],
377
           [4.8012391e-01, 5.9377134e-01, 4.5147297e-01],
378
           [9.0728188e-01, 9.9387854e-01, 5.8399546e-01]], dtype=float32)
379
    >>> R1 = np.corrcoef(xarr)
380
    >>> R1
381
    array([[ 0.99999994, -0.6173796 , -0.9685411 ],
382
           [-0.6173796 ,  1.        ,  0.7937219 ],
383
           [-0.9685411 ,  0.7937219 ,  0.9999999 ]], dtype=float32)
384

385
    If we add another set of variables and observations ``yarr``, we can
386
    compute the row-wise Pearson correlation coefficients between the
387
    variables in ``xarr`` and ``yarr``.
388

389
    >>> yarr = np.random.rand(3, 3).astype(np.float32)
390
    >>> yarr
391
    array([[0.17615308, 0.65354985, 0.15716429],
392
           [0.09373496, 0.2123185 , 0.84086883],
393
           [0.9011005 , 0.45206687, 0.00225109]], dtype=float32)
394
    >>> R2 = np.corrcoef(xarr, yarr)
395
    >>> R2
396
    array([[ 0.99999994, -0.6173796 , -0.968541  , -0.48613155,  0.9951523 ,
397
            -0.8900264 ],
398
           [-0.6173796 ,  1.        ,  0.7937219 ,  0.9875833 , -0.53702235,
399
             0.19083664],
400
           [-0.968541  ,  0.7937219 ,  0.9999999 ,  0.6883078 , -0.9393724 ,
401
             0.74857277],
402
           [-0.48613152,  0.9875833 ,  0.6883078 ,  0.9999999 , -0.39783284,
403
             0.0342579 ],
404
           [ 0.9951523 , -0.53702235, -0.9393725 , -0.39783284,  0.99999994,
405
            -0.9305482 ],
406
           [-0.89002645,  0.19083665,  0.7485727 ,  0.0342579 , -0.9305482 ,
407
             1.        ]], dtype=float32)
408

409
    Finally if we use the option ``rowvar=False``, the columns are now
410
    being treated as the variables and we will find the column-wise Pearson
411
    correlation coefficients between variables in ``xarr`` and ``yarr``.
412

413
    >>> R3 = np.corrcoef(xarr, yarr, rowvar=False)
414
    >>> R3
415
    array([[ 1.        ,  0.9724453 , -0.9909503 ,  0.8104691 , -0.46436927,
416
            -0.1643624 ],
417
           [ 0.9724453 ,  1.        , -0.9949381 ,  0.6515728 , -0.6580445 ,
418
             0.07012729],
419
           [-0.99095035, -0.994938  ,  1.        , -0.72450536,  0.5790461 ,
420
             0.03047091],
421
           [ 0.8104691 ,  0.65157276, -0.72450536,  1.        ,  0.14243561,
422
            -0.71102554],
423
           [-0.4643693 , -0.6580445 ,  0.57904613,  0.1424356 ,  0.99999994,
424
            -0.79727215],
425
           [-0.1643624 ,  0.07012729,  0.03047091, -0.7110255 , -0.7972722 ,
426
             0.99999994]], dtype=float32)
427
    """
428

429
    out = dpnp.cov(x, y, rowvar, dtype=dtype)
1✔
430
    if out.ndim == 0:
1✔
431
        # scalar covariance
432
        # nan if incorrect value (nan, inf, 0), 1 otherwise
433
        return out / out
1✔
434

435
    d = dpnp.diag(out)
1✔
436

437
    stddev = dpnp.sqrt(d.real)
1✔
438
    out /= stddev[:, None]
1✔
439
    out /= stddev[None, :]
1✔
440

441
    # Clip real and imaginary parts to [-1, 1]. This does not guarantee
442
    # abs(a[i,j]) <= 1 for complex arrays, but is the best we can do without
443
    # excessive work.
444
    dpnp.clip(out.real, -1, 1, out=out.real)
1✔
445
    if dpnp.iscomplexobj(out):
1✔
446
        dpnp.clip(out.imag, -1, 1, out=out.imag)
1✔
447

448
    return out
1✔
449

450

451
def correlate(x1, x2, mode="valid"):
1✔
452
    """
453
    Cross-correlation of two 1-dimensional sequences.
454

455
    For full documentation refer to :obj:`numpy.correlate`.
456

457
    Limitations
458
    -----------
459
    Input arrays are supported as :obj:`dpnp.ndarray`.
460
    Size and shape of input arrays are supported to be equal.
461
    Parameter `mode` is supported only with default value ``"valid"``.
462
    Otherwise the function will be executed sequentially on CPU.
463
    Input array data types are limited by supported DPNP :ref:`Data types`.
464

465
    See Also
466
    --------
467
    :obj:`dpnp.convolve` : Discrete, linear convolution of
468
                           two one-dimensional sequences.
469

470
    Examples
471
    --------
472
    >>> import dpnp as np
473
    >>> x = np.correlate([1, 2, 3], [0, 1, 0.5])
474
    >>> [i for i in x]
475
    [3.5]
476

477
    """
478

479
    x1_desc = dpnp.get_dpnp_descriptor(x1, copy_when_nondefault_queue=False)
1✔
480
    x2_desc = dpnp.get_dpnp_descriptor(x2, copy_when_nondefault_queue=False)
1✔
481
    if x1_desc and x2_desc:
1!
482
        if x1_desc.size != x2_desc.size or x1_desc.size == 0:
1✔
483
            pass
1✔
484
        elif x1_desc.shape != x2_desc.shape:
1✔
485
            pass
1✔
486
        elif mode != "valid":
1✔
487
            pass
1✔
488
        else:
489
            return dpnp_correlate(x1_desc, x2_desc).get_pyobj()
1✔
490

491
    return call_origin(numpy.correlate, x1, x2, mode=mode)
1✔
492

493

494
def cov(
1✔
495
    m,
496
    y=None,
497
    rowvar=True,
498
    bias=False,
499
    ddof=None,
500
    fweights=None,
501
    aweights=None,
502
    *,
503
    dtype=None,
504
):
505
    """
506
    Estimate a covariance matrix, given data and weights.
507

508
    For full documentation refer to :obj:`numpy.cov`.
509

510
    Returns
511
    -------
512
    out : dpnp.ndarray
513
        The covariance matrix of the variables.
514

515
    Limitations
516
    -----------
517
    Input array ``m`` is supported as :obj:`dpnp.ndarray`.
518
    Dimension of input array ``m`` is limited by ``m.ndim <= 2``.
519
    Size and shape of input arrays are supported to be equal.
520
    Parameter `y` is supported only with default value ``None``.
521
    Parameter `bias` is supported only with default value ``False``.
522
    Parameter `ddof` is supported only with default value ``None``.
523
    Parameter `fweights` is supported only with default value ``None``.
524
    Parameter `aweights` is supported only with default value ``None``.
525
    Otherwise the function will be executed sequentially on CPU.
526
    Input array data types are limited by supported DPNP :ref:`Data types`.
527

528
    See Also
529
    --------
530
    :obj:`dpnp.corrcoef` : Normalized covariance matrix
531

532
    Examples
533
    --------
534
    >>> import dpnp as np
535
    >>> x = np.array([[0, 2], [1, 1], [2, 0]]).T
536
    >>> x.shape
537
    (2, 3)
538
    >>> [i for i in x]
539
    [0, 1, 2, 2, 1, 0]
540
    >>> out = np.cov(x)
541
    >>> out.shape
542
    (2, 2)
543
    >>> [i for i in out]
544
    [1.0, -1.0, -1.0, 1.0]
545

546
    """
547

548
    if not dpnp.is_supported_array_type(m):
1!
UNCOV
549
        pass
×
550
    elif m.ndim > 2:
1✔
551
        pass
1✔
552
    elif bias:
1✔
553
        pass
1✔
554
    elif ddof is not None:
1✔
555
        pass
1✔
556
    elif fweights is not None:
1!
UNCOV
557
        pass
×
558
    elif aweights is not None:
1!
UNCOV
559
        pass
×
560
    else:
561
        return dpnp_cov(m, y=y, rowvar=rowvar, dtype=dtype)
1✔
562

563
    return call_origin(
1✔
564
        numpy.cov, m, y, rowvar, bias, ddof, fweights, aweights, dtype=dtype
565
    )
566

567

568
def max(a, axis=None, out=None, keepdims=False, initial=None, where=True):
1✔
569
    """
570
    Return the maximum of an array or maximum along an axis.
571

572
    For full documentation refer to :obj:`numpy.max`.
573

574
    Parameters
575
    ----------
576
    a : {dpnp.ndarray, usm_ndarray}
577
        Input array.
578
    axis : {None, int or tuple of ints}, optional
579
        Axis or axes along which to operate. By default, flattened input is
580
        used. If this is a tuple of integers, the minimum is selected over
581
        multiple axes, instead of a single axis or all the axes as before.
582
        Default: ``None``.
583
    out : {None, dpnp.ndarray, usm_ndarray}, optional
584
        Alternative output array in which to place the result. Must be of the
585
        same shape and buffer length as the expected output.
586
        Default: ``None``.
587
    keepdims : {None, bool}, optional
588
        If this is set to ``True``, the axes which are reduced are left in the
589
        result as dimensions with size one. With this option, the result will
590
        broadcast correctly against the input array.
591
        Default: ``False``.
592

593
    Returns
594
    -------
595
    out : dpnp.ndarray
596
        Maximum of `a`. If `axis` is ``None``, the result is a zero-dimensional
597
        array. If `axis` is an integer, the result is an array of dimension
598
        ``a.ndim - 1``. If `axis` is a tuple, the result is an array of
599
        dimension ``a.ndim - len(axis)``.
600

601
    Limitations
602
    -----------.
603
    Parameters `where`, and `initial` are only supported with their default
604
    values. Otherwise ``NotImplementedError`` exception will be raised.
605

606
    See Also
607
    --------
608
    :obj:`dpnp.min` : Return the minimum of an array.
609
    :obj:`dpnp.maximum` : Element-wise maximum of two arrays, propagates NaNs.
610
    :obj:`dpnp.fmax` : Element-wise maximum of two arrays, ignores NaNs.
611
    :obj:`dpnp.amax` : The maximum value of an array along a given axis,
612
                       propagates NaNs.
613
    :obj:`dpnp.nanmax` : The maximum value of an array along a given axis,
614
                         ignores NaNs.
615

616
    Examples
617
    --------
618
    >>> import dpnp as np
619
    >>> a = np.arange(4).reshape((2,2))
620
    >>> a
621
    array([[0, 1],
622
           [2, 3]])
623
    >>> np.max(a)
624
    array(3)
625

626
    >>> np.max(a, axis=0)   # Maxima along the first axis
627
    array([2, 3])
628
    >>> np.max(a, axis=1)   # Maxima along the second axis
629
    array([1, 3])
630

631
    >>> b = np.arange(5, dtype=float)
632
    >>> b[2] = np.nan
633
    >>> np.max(b)
634
    array(nan)
635

636
    """
637

638
    dpnp.check_limitations(initial=initial, where=where)
1✔
639
    usm_a = dpnp.get_usm_ndarray(a)
1✔
640

641
    return dpnp_wrap_reduction_call(
1✔
642
        a,
643
        out,
644
        dpt.max,
645
        _get_comparison_res_dt,
646
        usm_a,
647
        axis=axis,
648
        keepdims=keepdims,
649
    )
650

651

652
def mean(a, /, axis=None, dtype=None, out=None, keepdims=False, *, where=True):
1✔
653
    """
654
    Compute the arithmetic mean along the specified axis.
655

656
    For full documentation refer to :obj:`numpy.mean`.
657

658
    Parameters
659
    ----------
660
    a : {dpnp.ndarray, usm_ndarray}
661
        Input array.
662
    axis : {None, int, tuple of ints}, optional
663
        Axis or axes along which the arithmetic means must be computed. If
664
        a tuple of unique integers, the means are computed over multiple
665
        axes. If ``None``, the mean is computed over the entire array.
666
        Default: ``None``.
667
    dtype : {None, dtype}, optional
668
        Type to use in computing the mean. By default, if `a` has a
669
        floating-point data type, the returned array will have
670
        the same data type as `a`.
671
        If `a` has a boolean or integral data type, the returned array
672
        will have the default floating point data type for the device
673
        where input array `a` is allocated.
674
    out : {None, dpnp.ndarray, usm_ndarray}, optional
675
        Alternative output array in which to place the result. It must have
676
        the same shape as the expected output but the type (of the calculated
677
        values) will be cast if necessary.
678
        Default: ``None``.
679
    keepdims : {None, bool}, optional
680
        If ``True``, the reduced axes (dimensions) are included in the result
681
        as singleton dimensions, so that the returned array remains
682
        compatible with the input array according to Array Broadcasting
683
        rules. Otherwise, if ``False``, the reduced axes are not included in
684
        the returned array.
685
        Default: ``False``.
686

687
    Returns
688
    -------
689
    out : dpnp.ndarray
690
        An array containing the arithmetic means along the specified axis(axes).
691
        If the input is a zero-size array, an array containing NaN values is
692
        returned.
693

694
    Limitations
695
    -----------
696
    Parameter `where` is only supported with its default value.
697
    Otherwise ``NotImplementedError`` exception will be raised.
698

699
    See Also
700
    --------
701
    :obj:`dpnp.average` : Weighted average.
702
    :obj:`dpnp.std` : Compute the standard deviation along the specified axis.
703
    :obj:`dpnp.var` : Compute the variance along the specified axis.
704
    :obj:`dpnp.nanmean` : Compute the arithmetic mean along the specified axis,
705
                          ignoring NaNs.
706
    :obj:`dpnp.nanstd` : Compute the standard deviation along
707
                         the specified axis, while ignoring NaNs.
708
    :obj:`dpnp.nanvar` : Compute the variance along the specified axis,
709
                         while ignoring NaNs.
710

711
    Examples
712
    --------
713
    >>> import dpnp as np
714
    >>> a = np.array([[1, 2], [3, 4]])
715
    >>> np.mean(a)
716
    array(2.5)
717
    >>> np.mean(a, axis=0)
718
    array([2., 3.])
719
    >>> np.mean(a, axis=1)
720
    array([1.5, 3.5])
721

722
    """
723

724
    dpnp.check_limitations(where=where)
1✔
725

726
    usm_a = dpnp.get_usm_ndarray(a)
1✔
727
    usm_res = dpt.mean(usm_a, axis=axis, keepdims=keepdims)
1✔
728
    if dtype is not None:
1✔
729
        usm_res = dpt.astype(usm_res, dtype)
1✔
730

731
    return dpnp.get_result_array(usm_res, out, casting="unsafe")
1✔
732

733

734
def median(a, axis=None, out=None, overwrite_input=False, keepdims=False):
1✔
735
    """
736
    Compute the median along the specified axis.
737

738
    For full documentation refer to :obj:`numpy.median`.
739

740
    Parameters
741
    ----------
742
    a : {dpnp.ndarray, usm_ndarray}
743
        Input array.
744
    axis : {None, int, tuple or list of ints}, optional
745
        Axis or axes along which the medians are computed. The default,
746
        ``axis=None``, will compute the median along a flattened version of
747
        the array. If a sequence of axes, the array is first flattened along
748
        the given axes, then the median is computed along the resulting
749
        flattened axis.
750
        Default: ``None``.
751
    out : {None, dpnp.ndarray, usm_ndarray}, optional
752
        Alternative output array in which to place the result. It must have
753
        the same shape as the expected output but the type (of the calculated
754
        values) will be cast if necessary.
755
        Default: ``None``.
756
    overwrite_input : bool, optional
757
       If ``True``, then allow use of memory of input array `a` for
758
       calculations. The input array will be modified by the call to
759
       :obj:`dpnp.median`. This will save memory when you do not need to
760
       preserve the contents of the input array. Treat the input as undefined,
761
       but it will probably be fully or partially sorted.
762
       Default: ``False``.
763
    keepdims : {None, bool}, optional
764
        If ``True``, the reduced axes (dimensions) are included in the result
765
        as singleton dimensions, so that the returned array remains
766
        compatible with the input array according to Array Broadcasting
767
        rules. Otherwise, if ``False``, the reduced axes are not included in
768
        the returned array.
769
        Default: ``False``.
770

771
    Returns
772
    -------
773
    dpnp.median : dpnp.ndarray
774
        A new array holding the result. If `a` has a floating-point data type,
775
        the returned array will have the same data type as `a`. If `a` has a
776
        boolean or integral data type, the returned array will have the
777
        default floating point data type for the device where input array `a`
778
        is allocated.
779

780
    See Also
781
    --------
782
    :obj:`dpnp.mean` : Compute the arithmetic mean along the specified axis.
783
    :obj:`dpnp.percentile` : Compute the q-th percentile of the data
784
                             along the specified axis.
785

786
    Notes
787
    -----
788
    Given a vector ``V`` of length ``N``, the median of ``V`` is the
789
    middle value of a sorted copy of ``V``, ``V_sorted`` - i.e.,
790
    ``V_sorted[(N-1)/2]``, when ``N`` is odd, and the average of the
791
    two middle values of ``V_sorted`` when ``N`` is even.
792

793
    Examples
794
    --------
795
    >>> import dpnp as np
796
    >>> a = np.array([[10, 7, 4], [3, 2, 1]])
797
    >>> a
798
    array([[10,  7,  4],
799
           [ 3,  2,  1]])
800
    >>> np.median(a)
801
    array(3.5)
802

803
    >>> np.median(a, axis=0)
804
    array([6.5, 4.5, 2.5])
805
    >>> np.median(a, axis=1)
806
    array([7.,  2.])
807
    >>> np.median(a, axis=(0, 1))
808
    array(3.5)
809

810
    >>> m = np.median(a, axis=0)
811
    >>> out = np.zeros_like(m)
812
    >>> np.median(a, axis=0, out=m)
813
    array([6.5,  4.5,  2.5])
814
    >>> m
815
    array([6.5,  4.5,  2.5])
816

817
    >>> b = a.copy()
818
    >>> np.median(b, axis=1, overwrite_input=True)
819
    array([7.,  2.])
820
    >>> assert not np.all(a==b)
821
    >>> b = a.copy()
822
    >>> np.median(b, axis=None, overwrite_input=True)
823
    array(3.5)
824
    >>> assert not np.all(a==b)
825

826
    """
827

828
    dpnp.check_supported_arrays_type(a)
1✔
829
    a_ndim = a.ndim
1✔
830
    a_shape = a.shape
1✔
831
    _axis = range(a_ndim) if axis is None else axis
1✔
832
    _axis = normalize_axis_tuple(_axis, a_ndim)
1✔
833

834
    if isinstance(axis, (tuple, list)):
1✔
835
        if len(axis) == 1:
1✔
836
            axis = axis[0]
1✔
837
        else:
838
            # Need to flatten if `axis` is a sequence of axes since `dpnp.sort`
839
            # only accepts integer `axis`
840
            # Note that the output of _flatten_array_along_axes is not
841
            # necessarily a view of the input since `reshape` is used there.
842
            # If this is the case, using overwrite_input is meaningless
843
            a = _flatten_array_along_axes(a, _axis)
1✔
844
            axis = 0
1✔
845

846
    if overwrite_input:
1✔
847
        if axis is None:
1✔
848
            a_sorted = dpnp.ravel(a)
1✔
849
            a_sorted.sort()
1✔
850
        else:
851
            if isinstance(a, dpt.usm_ndarray):
1✔
852
                # dpnp.ndarray.sort only works with dpnp_array
853
                a = dpnp_array._create_from_usm_ndarray(a)
1✔
854
            a.sort(axis=axis)
1✔
855
            a_sorted = a
1✔
856
    else:
857
        a_sorted = dpnp.sort(a, axis=axis)
1✔
858

859
    if axis is None:
1✔
860
        axis = 0
1✔
861
    indexer = [slice(None)] * a_sorted.ndim
1✔
862
    index, remainder = divmod(a_sorted.shape[axis], 2)
1✔
863
    if remainder == 1:
1✔
864
        # index with slice to allow mean (below) to work
865
        indexer[axis] = slice(index, index + 1)
1✔
866
    else:
867
        indexer[axis] = slice(index - 1, index + 1)
1✔
868

869
    # Use `mean` in odd and even case to coerce data type and use `out` array
870
    res = dpnp.mean(a_sorted[tuple(indexer)], axis=axis, out=out)
1✔
871
    nan_mask = dpnp.isnan(a_sorted).any(axis=axis)
1✔
872
    if nan_mask.any():
1✔
873
        res[nan_mask] = dpnp.nan
1✔
874

875
    if keepdims:
1✔
876
        # We can't use dpnp.mean(..., keepdims) and dpnp.any(..., keepdims)
877
        # above because of the reshape hack might have been used in
878
        # `_flatten_array_along_axes` to handle cases when axis is a tuple.
879
        res_shape = list(a_shape)
1✔
880
        for i in _axis:
1✔
881
            res_shape[i] = 1
1✔
882
        res = res.reshape(tuple(res_shape))
1✔
883

884
    return res
1✔
885

886

887
def min(a, axis=None, out=None, keepdims=False, initial=None, where=True):
1✔
888
    """
889
    Return the minimum of an array or maximum along an axis.
890

891
    For full documentation refer to :obj:`numpy.min`.
892

893
    Parameters
894
    ----------
895
    a : {dpnp.ndarray, usm_ndarray}
896
        Input array.
897
    axis : {None, int or tuple of ints}, optional
898
        Axis or axes along which to operate. By default, flattened input is
899
        used. If this is a tuple of integers, the minimum is selected over
900
        multiple axes, instead of a single axis or all the axes as before.
901
        Default: ``None``.
902
    out : {None, dpnp.ndarray, usm_ndarray}, optional
903
        Alternative output array in which to place the result. Must be of the
904
        same shape and buffer length as the expected output.
905
        Default: ``None``.
906
    keepdims : {None, bool}, optional
907
        If this is set to ``True``, the axes which are reduced are left in the
908
        result as dimensions with size one. With this option, the result will
909
        broadcast correctly against the input array.
910
        Default: ``False``.
911

912
    Returns
913
    -------
914
    out : dpnp.ndarray
915
        Minimum of `a`. If `axis` is ``None``, the result is a zero-dimensional
916
        array. If `axis` is an integer, the result is an array of dimension
917
        ``a.ndim - 1``. If `axis` is a tuple, the result is an array of
918
        dimension ``a.ndim - len(axis)``.
919

920
    Limitations
921
    -----------
922
    Parameters `where`, and `initial` are only supported with their default
923
    values. Otherwise ``NotImplementedError`` exception will be raised.
924

925
    See Also
926
    --------
927
    :obj:`dpnp.max` : Return the maximum of an array.
928
    :obj:`dpnp.minimum` : Element-wise minimum of two arrays, propagates NaNs.
929
    :obj:`dpnp.fmin` : Element-wise minimum of two arrays, ignores NaNs.
930
    :obj:`dpnp.amin` : The minimum value of an array along a given axis,
931
                       propagates NaNs.
932
    :obj:`dpnp.nanmin` : The minimum value of an array along a given axis,
933
                         ignores NaNs.
934

935
    Examples
936
    --------
937
    >>> import dpnp as np
938
    >>> a = np.arange(4).reshape((2,2))
939
    >>> a
940
    array([[0, 1],
941
           [2, 3]])
942
    >>> np.min(a)
943
    array(0)
944

945
    >>> np.min(a, axis=0)   # Minima along the first axis
946
    array([0, 1])
947
    >>> np.min(a, axis=1)   # Minima along the second axis
948
    array([0, 2])
949

950
    >>> b = np.arange(5, dtype=float)
951
    >>> b[2] = np.nan
952
    >>> np.min(b)
953
    array(nan)
954

955
    """
956

957
    dpnp.check_limitations(initial=initial, where=where)
1✔
958
    usm_a = dpnp.get_usm_ndarray(a)
1✔
959

960
    return dpnp_wrap_reduction_call(
1✔
961
        a,
962
        out,
963
        dpt.min,
964
        _get_comparison_res_dt,
965
        usm_a,
966
        axis=axis,
967
        keepdims=keepdims,
968
    )
969

970

971
def ptp(
1✔
972
    a,
973
    /,
974
    axis=None,
975
    out=None,
976
    keepdims=False,
977
):
978
    """
979
    Range of values (maximum - minimum) along an axis.
980

981
    For full documentation refer to :obj:`numpy.ptp`.
982

983
    Returns
984
    -------
985
    ptp : dpnp.ndarray
986
        The range of a given array.
987

988
    Limitations
989
    -----------
990
    Input array is supported as :class:`dpnp.dpnp.ndarray` or
991
    :class:`dpctl.tensor.usm_ndarray`.
992

993
    Examples
994
    --------
995
    >>> import dpnp as np
996
    >>> x = np.array([[4, 9, 2, 10],[6, 9, 7, 12]])
997
    >>> np.ptp(x, axis=1)
998
    array([8, 6])
999

1000
    >>> np.ptp(x, axis=0)
1001
    array([2, 0, 5, 2])
1002

1003
    >>> np.ptp(x)
1004
    array(10)
1005

1006
    """
1007

1008
    return dpnp.subtract(
1✔
1009
        dpnp.max(a, axis=axis, keepdims=keepdims, out=out),
1010
        dpnp.min(a, axis=axis, keepdims=keepdims),
1011
        out=out,
1012
    )
1013

1014

1015
def std(
1✔
1016
    a, axis=None, dtype=None, out=None, ddof=0, keepdims=False, *, where=True
1017
):
1018
    """
1019
    Compute the standard deviation along the specified axis.
1020

1021
    For full documentation refer to :obj:`numpy.std`.
1022

1023
    Parameters
1024
    ----------
1025
    a : {dpnp.ndarray, usm_ndarray}
1026
        Input array.
1027
    axis : {None, int, tuple of ints}, optional
1028
        Axis or axes along which the standard deviations must be computed.
1029
        If a tuple of unique integers is given, the standard deviations
1030
        are computed over multiple axes. If ``None``, the standard deviation
1031
        is computed over the entire array.
1032
        Default: ``None``.
1033
    dtype : {None, dtype}, optional
1034
        Type to use in computing the standard deviation. By default,
1035
        if `a` has a floating-point data type, the returned array
1036
        will have the same data type as `a`.
1037
        If `a` has a boolean or integral data type, the returned array
1038
        will have the default floating point data type for the device
1039
        where input array `a` is allocated.
1040
    out : {None, dpnp.ndarray, usm_ndarray}, optional
1041
        Alternative output array in which to place the result. It must have
1042
        the same shape as the expected output but the type (of the calculated
1043
        values) will be cast if necessary.
1044
    ddof : {int, float}, optional
1045
        Means Delta Degrees of Freedom.  The divisor used in calculations
1046
        is ``N - ddof``, where ``N`` corresponds to the total
1047
        number of elements over which the standard deviation is calculated.
1048
        Default: `0.0`.
1049
    keepdims : {None, bool}, optional
1050
        If ``True``, the reduced axes (dimensions) are included in the result
1051
        as singleton dimensions, so that the returned array remains
1052
        compatible with the input array according to Array Broadcasting
1053
        rules. Otherwise, if ``False``, the reduced axes are not included in
1054
        the returned array. Default: ``False``.
1055

1056
    Returns
1057
    -------
1058
    out : dpnp.ndarray
1059
        An array containing the standard deviations. If the standard
1060
        deviation was computed over the entire array, a zero-dimensional
1061
        array is returned.
1062

1063
    Limitations
1064
    -----------
1065
    Parameters `where` is only supported with its default value.
1066
    Otherwise ``NotImplementedError`` exception will be raised.
1067

1068
    Notes
1069
    -----
1070
    Note that, for complex numbers, the absolute value is taken before squaring,
1071
    so that the result is always real and non-negative.
1072

1073
    See Also
1074
    --------
1075
    :obj:`dpnp.ndarray.std` : corresponding function for ndarrays.
1076
    :obj:`dpnp.var` : Compute the variance along the specified axis.
1077
    :obj:`dpnp.mean` : Compute the arithmetic mean along the specified axis.
1078
    :obj:`dpnp.nanmean` : Compute the arithmetic mean along the specified axis,
1079
                          ignoring NaNs.
1080
    :obj:`dpnp.nanstd` : Compute the standard deviation along
1081
                         the specified axis, while ignoring NaNs.
1082
    :obj:`dpnp.nanvar` : Compute the variance along the specified axis,
1083
                         while ignoring NaNs.
1084

1085
    Examples
1086
    --------
1087
    >>> import dpnp as np
1088
    >>> a = np.array([[1, 2], [3, 4]])
1089
    >>> np.std(a)
1090
    array(1.118033988749895)
1091
    >>> np.std(a, axis=0)
1092
    array([1.,  1.])
1093
    >>> np.std(a, axis=1)
1094
    array([0.5,  0.5])
1095

1096
    """
1097

1098
    dpnp.check_supported_arrays_type(a)
1✔
1099
    dpnp.check_limitations(where=where)
1✔
1100

1101
    if not isinstance(ddof, (int, float)):
1✔
1102
        raise TypeError(
1✔
1103
            f"An integer or float is required, but got {type(ddof)}"
1104
        )
1105

1106
    if dpnp.issubdtype(a.dtype, dpnp.complexfloating):
1✔
1107
        result = dpnp.var(
1✔
1108
            a,
1109
            axis=axis,
1110
            dtype=None,
1111
            out=out,
1112
            ddof=ddof,
1113
            keepdims=keepdims,
1114
            where=where,
1115
        )
1116
        dpnp.sqrt(result, out=result)
1✔
1117
    else:
1118
        usm_a = dpnp.get_usm_ndarray(a)
1✔
1119
        usm_res = dpt.std(usm_a, axis=axis, correction=ddof, keepdims=keepdims)
1✔
1120
        result = dpnp.get_result_array(usm_res, out)
1✔
1121

1122
    if dtype is not None and out is None:
1✔
1123
        result = result.astype(dtype, casting="same_kind")
1✔
1124
    return result
1✔
1125

1126

1127
def var(
1✔
1128
    a, axis=None, dtype=None, out=None, ddof=0, keepdims=False, *, where=True
1129
):
1130
    """
1131
    Compute the variance along the specified axis.
1132

1133
    For full documentation refer to :obj:`numpy.var`.
1134

1135
    Parameters
1136
    ----------
1137
    a : {dpnp.ndarray, usm_ndarray}
1138
        Input array.
1139
    axis : {None, int, tuple of ints}, optional
1140
        axis or axes along which the variances must be computed. If a tuple
1141
        of unique integers is given, the variances are computed over multiple
1142
        axes. If ``None``, the variance is computed over the entire array.
1143
        Default: ``None``.
1144
    dtype : {None, dtype}, optional
1145
        Type to use in computing the variance. By default, if `a` has a
1146
        floating-point data type, the returned array will have
1147
        the same data type as `a`.
1148
        If `a` has a boolean or integral data type, the returned array
1149
        will have the default floating point data type for the device
1150
        where input array `a` is allocated.
1151
    out : {None, dpnp.ndarray, usm_ndarray}, optional
1152
        Alternative output array in which to place the result. It must have
1153
        the same shape as the expected output but the type (of the calculated
1154
        values) will be cast if necessary.
1155
    ddof : {int, float}, optional
1156
        Means Delta Degrees of Freedom.  The divisor used in calculations
1157
        is ``N - ddof``, where ``N`` corresponds to the total
1158
        number of elements over which the variance is calculated.
1159
        Default: `0.0`.
1160
    keepdims : {None, bool}, optional
1161
        If ``True``, the reduced axes (dimensions) are included in the result
1162
        as singleton dimensions, so that the returned array remains
1163
        compatible with the input array according to Array Broadcasting
1164
        rules. Otherwise, if ``False``, the reduced axes are not included in
1165
        the returned array. Default: ``False``.
1166

1167
    Returns
1168
    -------
1169
    out : dpnp.ndarray
1170
        An array containing the variances. If the variance was computed
1171
        over the entire array, a zero-dimensional array is returned.
1172

1173
    Limitations
1174
    -----------
1175
    Parameters `where` is only supported with its default value.
1176
    Otherwise ``NotImplementedError`` exception will be raised.
1177

1178
    Notes
1179
    -----
1180
    Note that, for complex numbers, the absolute value is taken before squaring,
1181
    so that the result is always real and non-negative.
1182

1183
    See Also
1184
    --------
1185
    :obj:`dpnp.ndarray.var` : corresponding function for ndarrays.
1186
    :obj:`dpnp.std` : Compute the standard deviation along the specified axis.
1187
    :obj:`dpnp.mean` : Compute the arithmetic mean along the specified axis.
1188
    :obj:`dpnp.nanmean` : Compute the arithmetic mean along the specified axis,
1189
                          ignoring NaNs.
1190
    :obj:`dpnp.nanstd` : Compute the standard deviation along
1191
                         the specified axis, while ignoring NaNs.
1192
    :obj:`dpnp.nanvar` : Compute the variance along the specified axis,
1193
                         while ignoring NaNs.
1194

1195
    Examples
1196
    --------
1197
    >>> import dpnp as np
1198
    >>> a = np.array([[1, 2], [3, 4]])
1199
    >>> np.var(a)
1200
    array(1.25)
1201
    >>> np.var(a, axis=0)
1202
    array([1.,  1.])
1203
    >>> np.var(a, axis=1)
1204
    array([0.25,  0.25])
1205

1206
    """
1207

1208
    dpnp.check_supported_arrays_type(a)
1✔
1209
    dpnp.check_limitations(where=where)
1✔
1210

1211
    if not isinstance(ddof, (int, float)):
1✔
1212
        raise TypeError(
1✔
1213
            f"An integer or float is required, but got {type(ddof)}"
1214
        )
1215

1216
    if dpnp.issubdtype(a.dtype, dpnp.complexfloating):
1✔
1217
        # Note that if dtype is not of inexact type then arrmean
1218
        # will not be either.
1219
        arrmean = dpnp.mean(
1✔
1220
            a, axis=axis, dtype=dtype, keepdims=True, where=where
1221
        )
1222
        x = dpnp.subtract(a, arrmean)
1✔
1223
        x = dpnp.multiply(x, x.conj(), out=x).real
1✔
1224
        result = dpnp.sum(
1✔
1225
            x,
1226
            axis=axis,
1227
            dtype=a.real.dtype,
1228
            out=out,
1229
            keepdims=keepdims,
1230
            where=where,
1231
        )
1232

1233
        cnt = _count_reduce_items(a, axis, where)
1✔
1234
        cnt = numpy.max(cnt - ddof, 0).astype(result.dtype, casting="same_kind")
1✔
1235
        if not cnt:
1✔
1236
            cnt = dpnp.nan
1✔
1237

1238
        dpnp.divide(result, cnt, out=result)
1✔
1239
    else:
1240
        usm_a = dpnp.get_usm_ndarray(a)
1✔
1241
        usm_res = dpt.var(usm_a, axis=axis, correction=ddof, keepdims=keepdims)
1✔
1242
        result = dpnp.get_result_array(usm_res, out)
1✔
1243

1244
    if out is None and dtype is not None:
1✔
1245
        result = result.astype(dtype, casting="same_kind")
1✔
1246
    return result
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc