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

Code before:
    .. [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
        def sf_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(

Review comment (refactor):
From https://github.com/scipy/scipy/issues/24551#issuecomment-3882803949:

> The existing methods can be renamed without other modification

Unless there is a benefit to modifying these, let's return them to what they were to simplify review:

```suggestion
            exparg = invK * (0.5 * invK - x)
            return exparg + _norm_logcdf(x - invK) - np.log(K)
```

Please make the equivalent adjustments below.

Code after:
    .. [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):
            return _norm_cdf(-x) + 0.5 * np.exp(-0.5 * x ** 2) * sc.erfcx(u)
        def sf_default(x, K, u):
            invK = 1.0 / K
            expval = invK * (0.5 * invK - x)
            logprod = expval + _norm_logcdf(x - invK)