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

Code before:

    .. versionadded:: 0.16.0

    References
    ----------
    .. [1] Exponentially modified Gaussian distribution, Wikipedia,
           https://en.wikipedia.org/wiki/Exponentially_modified_Gaussian_distribution

    %(example)s

    """
    def _shape_info(self):
        return [_ShapeInfo("K", False, (0, np.inf), (False, False))]

    def _rvs(self, K, size=None, random_state=None):
        expval = random_state.standard_exponential(size) * K
        gval = random_state.standard_normal(size)
        return expval + gval

    def _pdf(self, x, K):
        return np.exp(self._logpdf(x, K))

    def _logpdf(self, x, K):
        u = (-x + 1.0 / K) / np.sqrt(2)
        def logpdf_nonnegative_u(x, K):
            erfcx_term = np.log(sc.erfcx((-x + 1.0 / K) / np.sqrt(2)))
            return -np.log(2) - 0.5 * (x ** 2) - np.log(K) + erfcx_term
        def logpdf_negative_u(x, K):
            invK = 1.0 / K
            exparg = invK * (-x + 0.5 * invK)
            return -np.log(K) + exparg + _norm_logcdf(x - invK)
        return xpx.apply_where(
            u >= 0, (x, K), logpdf_nonnegative_u, logpdf_negative_u)

    def _cdf(self, x, K):
        u = (-x + 1.0 / K) / np.sqrt(2)
        def cdf_nonnegative_u(x, K):
            eterm = sc.erfcx((-x + 1.0 / K) / np.sqrt(2))
            return _norm_cdf(x) - 0.5 * np.exp(-0.5 * x ** 2) * eterm 
        def cdf_negative_u(x, K):
            invK = 1.0 / K
            logprod = invK * (0.5 * invK - x) + _norm_logcdf(x - invK)
            return _norm_cdf(x) - np.exp(logprod)
        return xpx.apply_where(
            u >= 0, (x, K), cdf_nonnegative_u, cdf_negative_u)

    def _sf(self, x, K):
        u = (-x + 1.0 / K) / np.sqrt(2)
        def sf_nonnegative_u(x, K):
            eterm = sc.erfcx((-x + 1.0 / K) / np.sqrt(2))    
            return _norm_cdf(-x) + 0.5 * np.exp(-0.5 * x ** 2) * eterm

Review comment (refactor):
```suggestion
            erfcx_term = np.log(sc.erfcx(u))
```
Right? So to simplify the expression and avoid redundant calculation, please accept `u` as another argument of the `logpdf_` functions, and include `u` as another one of the `args` in `apply_where`.

Please make the equivalent adjustments below.

Code after:

    .. versionadded:: 0.16.0

    References
    ----------
    .. [1] Exponentially modified Gaussian distribution, Wikipedia,
           https://en.wikipedia.org/wiki/Exponentially_modified_Gaussian_distribution

    %(example)s

    """
    def _shape_info(self):
        return [_ShapeInfo("K", False, (0, np.inf), (False, False))]

    def _rvs(self, K, size=None, random_state=None):
        expval = random_state.standard_exponential(size) * K
        gval = random_state.standard_normal(size)
        return expval + gval

    def _pdf(self, x, K):
        return np.exp(self._logpdf(x, K))

    def _logpdf(self, x, K):
        u = (-x + 1.0 / K) / np.sqrt(2)
        def logpdf_erfcx(x, K, u):
            erfcx_term = np.log(sc.erfcx(u))
            return -np.log(2) - 0.5 * (x ** 2) - np.log(K) + erfcx_term
        def logpdf_default(x, K, u):
            invK = 1.0 / K
            exparg = invK * (-x + 0.5 * invK)
            return exparg + _norm_logcdf(x - invK) - np.log(K)
        use_erfcx = np.logical_and(u >= 0, K < 1)
        return xpx.apply_where(
            use_erfcx, (x, K, u), logpdf_erfcx, logpdf_default)

    def _cdf(self, x, K):
        u = (-x + 1.0 / K) / np.sqrt(2)
        def cdf_erfcx(x, K, u):
            return _norm_cdf(x) - 0.5 * np.exp(-0.5 * x ** 2) * sc.erfcx(u)
        def cdf_default(x, K, u):
            invK = 1.0 / K
            expval = invK * (0.5 * invK - x)
            logprod = expval + _norm_logcdf(x - invK)
            return _norm_cdf(x) - np.exp(logprod)
        use_erfcx = np.logical_and(u >= 0, K < 1)
        return xpx.apply_where(
            use_erfcx, (x, K, u), cdf_erfcx, cdf_default)

    def _sf(self, x, K):
        u = (-x + 1.0 / K) / np.sqrt(2)
        def sf_erfcx(x, K, u):