Repository: scipy/scipy
File: scipy/stats/_morestats.py (Python)

Code before:

@xp_capabilities(np_only=True)
@_axis_nan_policy_factory(AnsariResult, n_samples=2)
def ansari(x, y, alternative='two-sided', *, axis=0):
    """Perform the Ansari-Bradley test for equal scale parameters.

    The Ansari-Bradley test ([1]_, [2]_) is a non-parametric test
    for the equality of the scale parameter of the distributions
    from which two samples were drawn. The null hypothesis states that
    the ratio of the scale of the distribution underlying `x` to the scale
    of the distribution underlying `y` is 1.

    Parameters
    ----------
    x, y : array_like
        Arrays of sample data.
    alternative : {'two-sided', 'less', 'greater'}, optional
        Defines the alternative hypothesis. Default is 'two-sided'.
        The following options are available:

        * 'two-sided': the ratio of scales is not equal to 1.
        * 'less': the ratio of scales is less than 1.
        * 'greater': the ratio of scales is greater than 1.

        .. versionadded:: 1.7.0
    axis : int or tuple of ints, default: None
        If an int or tuple of ints, the axis or axes of the input along which
        to compute the statistic. The statistic of each axis-slice (e.g. row)
        of the input will appear in a corresponding element of the output.
        If ``None``, the input will be raveled before computing the statistic.

    Returns
    -------
    statistic : float
        The Ansari-Bradley test statistic.
    pvalue : float
        The p-value of the hypothesis test.

    See Also
    --------
    fligner : A non-parametric test for the equality of k variances
    mood : A non-parametric test for the equality of two scale parameters

    Notes
    -----
    The p-value given is exact when the sample sizes are both less than
    55 and there are no ties, otherwise a normal approximation for the
    p-value is used.

    References
    ----------

Review comment (suggestion):
```suggestion
    axis : int or tuple of ints, default: 0
```

Code after:
            self.freqs = a1.astype(np.float64)
            self.total = self.freqs.sum()  # could calculate from m and n
            # probability mass is self.freqs / self.total;

    def pmf(self, k, n, m):
        """Probability mass function."""
        self._recalc(n, m)
        # The convention here is that PMF at k = 12.5 is the same as at k = 12,
        # -> use `floor` in case of ties.
        ind = np.floor(k - self.astart).astype(int)
        return self.freqs[ind] / self.total

    def cdf(self, k, n, m):
        """Cumulative distribution function."""
        self._recalc(n, m)
        # Null distribution derived without considering ties is
        # approximate. Round down to avoid Type I error.
        ind = np.ceil(k - self.astart).astype(int)
        return self.freqs[:ind+1].sum() / self.total

    def sf(self, k, n, m):
        """Survival function."""
        self._recalc(n, m)
        # Null distribution derived without considering ties is
        # approximate. Round down to avoid Type I error.
        ind = np.floor(k - self.astart).astype(int)
        return self.freqs[ind:].sum() / self.total


# Maintain state for faster repeat calls to ansari w/ method='exact'
# _ABW() is calculated once per thread and stored as an attribute on
# this thread-local variable inside ansari().
_abw_state = threading.local()


@xp_capabilities(np_only=True)
@_axis_nan_policy_factory(AnsariResult, n_samples=2)
def ansari(x, y, alternative='two-sided', *, axis=0):
    """Perform the Ansari-Bradley test for equal scale parameters.

    The Ansari-Bradley test ([1]_, [2]_) is a non-parametric test
    for the equality of the scale parameter of the distributions
    from which two samples were drawn. The null hypothesis states that
    the ratio of the scale of the distribution underlying `x` to the scale
    of the distribution underlying `y` is 1.

    Parameters
    ----------
    x, y : array_like
        Arrays of sample data.
    alternative : {'two-sided', 'less', 'greater'}, optional