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

Code before:
    for :math:`k \in \{0, 1, \dots, n\}`, :math:`0 \leq p \leq 1`

    `binom` takes :math:`n` and :math:`p` as shape parameters,
    where :math:`p` is the probability of a single success
    and :math:`1-p` is the probability of a single failure.

    This distribution uses routines from the Boost Math C++ library for
    the computation of the ``pmf``, ``cdf``, ``sf``, ``ppf`` and ``isf``
    methods. [1]_

    %(after_notes)s

    References
    ----------
    .. [1] The Boost Developers. "Boost C++ Libraries". https://www.boost.org/.

    %(example)s
    """
    def _shape_info(self):
        return [_ShapeInfo("n", True, (0, np.inf), (True, False)),
                _ShapeInfo("p", False, (0, 1), (True, True))]

    def _rvs(self, n, p, size=None, random_state=None):
        if not np.all(n == np.floor(n)):
            raise ValueError("`n` must be integral.")
        return random_state.binomial(np.asarray(n, dtype=np.int64), p, size)

    def _argcheck(self, n, p):
        return (n >= 0) & _isintegral(n) & (p >= 0) & (p <= 1)

    def _get_support(self, n, p):
        return self.a, n

    def _logpmf(self, x, n, p):
        k = floor(x)
        combiln = (gamln(n+1) - (gamln(k+1) + gamln(n-k+1)))
        return combiln + special.xlogy(k, p) + special.xlog1py(n-k, -p)

    def _pmf(self, x, n, p):
        # binom.pmf(k) = choose(n, k) * p**k * (1-p)**(n-k)
        return scu._binom_pmf(x, n, p)

    def _cdf(self, x, n, p):
        k = floor(x)
        return scu._binom_cdf(k, n, p)

    def _sf(self, x, n, p):
        k = floor(x)
        return scu._binom_sf(k, n, p)

    def _isf(self, x, n, p):

Review comment (bug):
Without this dtype conversion, I get failures because NumPy won't convert floats to ints.
With this conversion, I get a failure in CI on 32-bit because NumPy won't convert int64 to int32. 
Should I take advantage of NumPy's flexibility with dtype specifications and just set `dtype=int`?

Code after:
    for :math:`k \in \{0, 1, \dots, n\}`, :math:`0 \leq p \leq 1`

    `binom` takes :math:`n` and :math:`p` as shape parameters,
    where :math:`p` is the probability of a single success
    and :math:`1-p` is the probability of a single failure.

    This distribution uses routines from the Boost Math C++ library for
    the computation of the ``pmf``, ``cdf``, ``sf``, ``ppf`` and ``isf``
    methods. [1]_

    %(after_notes)s

    References
    ----------
    .. [1] The Boost Developers. "Boost C++ Libraries". https://www.boost.org/.

    %(example)s
    """
    def _shape_info(self):
        return [_ShapeInfo("n", True, (0, np.inf), (True, False)),
                _ShapeInfo("p", False, (0, 1), (True, True))]

    def _rvs(self, n, p, size=None, random_state=None):
        if not np.all(n == np.floor(n)):
            raise ValueError("`n` must be integral.")
        return random_state.binomial(np.asarray(n, dtype=int), p, size)

    def _argcheck(self, n, p):
        return (n >= 0) & _isintegral(n) & (p >= 0) & (p <= 1)

    def _get_support(self, n, p):
        return self.a, n

    def _logpmf(self, x, n, p):
        k = floor(x)
        combiln = (gamln(n+1) - (gamln(k+1) + gamln(n-k+1)))
        return combiln + special.xlogy(k, p) + special.xlog1py(n-k, -p)

    def _pmf(self, x, n, p):
        # binom.pmf(k) = choose(n, k) * p**k * (1-p)**(n-k)
        return scu._binom_pmf(x, n, p)

    def _cdf(self, x, n, p):
        k = floor(x)
        return scu._binom_cdf(k, n, p)

    def _sf(self, x, n, p):
        k = floor(x)
        return scu._binom_sf(k, n, p)

    def _isf(self, x, n, p):