Repository: numpy/numpy
File: numpy/lib/_function_base_impl.py (Python)

Code before:
    if weights is not None:
        if method != "inverted_cdf":
            msg = ("Only method 'inverted_cdf' supports weights. "
                   f"Got: {method}.")
            raise ValueError(msg)
        if axis is not None:
            axis = _nx.normalize_axis_tuple(axis, a.ndim, argname="axis")
        weights = _weights_are_valid(weights=weights, a=a, axis=axis)
        if weights.dtype != object:
            if np.any(np.isinf(weights)):
                raise ValueError("Weights must be finite.")
            elif np.any(np.isnan(weights)):
                raise ValueError("At least one weight is nan.")
        # Since np.isinf and np.isnan do not work in dtype object arrays
        # Also, dtpye object arrays with np.nan in them break <, > and == opperators
        # This specific handling had to be done (Can be improved)   
        elif weights.dtype == object:
            for w in weights: 
                if np.isnan(w):
                    raise ValueError("At least one weight is nan.")
                if np.isinf(w):
                    raise ValueError("Weights must be finite.")
                
        if np.any(weights < 0):
            raise ValueError("Weights must be non-negative.")
        elif np.all(weights == 0):
            raise ValueError("At least one weight must be non-zero.")
        

    return _quantile_unchecked(
        a, q, axis, out, overwrite_input, method, keepdims, weights)


def _quantile_unchecked(a,
                        q,
                        axis=None,
                        out=None,
                        overwrite_input=False,
                        method="linear",
                        keepdims=False,
                        weights=None):
    """Assumes that q is in [0, 1], and is an ndarray"""
    return _ureduce(a,
                    func=_quantile_ureduce_func,
                    q=q,
                    weights=weights,
                    keepdims=keepdims,
                    axis=axis,
                    out=out,
                    overwrite_input=overwrite_input,
                    method=method)

Review comment (suggestion):
Here again we could ensure the common case remains fast by doing:
```
if np.any(weights <= 0):
    raise ValueError("weights must be non-negative and cannot be all zero.")
    # or, more explicit error messages,
    if np.all(weights == 0):
        raise ValueError("At least one weight must be non-zero.")
    else:
        raise ValueError("Weights must be non-negative.")
```

Code after:
        A constant used to correct the index computed.
    beta : float
        A constant used to correct the index computed.

    alpha and beta values depend on the chosen method
    (see quantile documentation)

    Reference:
    Hyndman&Fan paper "Sample Quantiles in Statistical Packages",
    DOI: 10.1080/00031305.1996.10473566
    """
    return n * quantiles + (
            alpha + quantiles * (1 - alpha - beta)
    ) - 1


def _get_gamma(virtual_indexes, previous_indexes, method, dtype):
    """
    Compute gamma (a.k.a 'm' or 'weight') for the linear interpolation
    of quantiles.

    virtual_indexes : array_like
        The indexes where the percentile is supposed to be found in the sorted
        sample.
    previous_indexes : array_like
        The floor values of virtual_indexes.
    method : dict
        The interpolation method chosen, which may have a specific rule
        modifying gamma.

    gamma is usually the fractional part of virtual_indexes but can be modified
    by the interpolation method.
    """
    gamma = np.asanyarray(virtual_indexes - previous_indexes)
    gamma = method["fix_gamma"](gamma, virtual_indexes)
    # Ensure both that we have an array, and that we keep the dtype
    # (which may have been matched to the input array).
    return np.asanyarray(gamma, dtype=dtype)


def _lerp(a, b, t, out=None):
    """
    Compute the linear interpolation weighted by gamma on each point of
    two same shape array.

    a : array_like
        Left bound.
    b : array_like
        Right bound.
    t : array_like
        The interpolation weight.