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

Code before:
    ...     @property
    ...     def __make_distribution_version__(self):
    ...         return "1.16.0"
    ...
    ...     @property
    ...     def parameters(self):
    ...         return {'a': {'endpoints': (0, np.inf),
    ...                       'inclusive': (False, False)},
    ...                 'b': {'endpoints': ('a', np.inf),
    ...                       'inclusive': (False, False)}}
    ...
    ...     @property
    ...     def support(self):
    ...         return {'endpoints': ('a', 'b'), 'inclusive': (True, True)}
    ...
    ...     def pdf(self, x, a, b):
    ...         return 1 / (x * (np.log(b)- np.log(a)))
    >>>
    >>> MyLogUniform = stats.make_distribution(MyLogUniform())
    >>> Y = MyLogUniform(a=1.0, b=3.0)
    >>> np.isclose(Y.cdf(2.), X.cdf(2.))
    np.True_

    Create a custom distribution with variable support.

    >>> class MyGenExtreme:
    ...     @property
    ...     def __make_distribution_version__(self):
    ...         return "1.16.0"
    ...
    ...     @property
    ...     def parameters(self):
    ...         return {"c": {}, "mu": {}, "sigma": (0, np.inf)}
    ...
    ...     @property
    ...     def support(self):
    ...         def left(*, c, mu, sigma):
    ...             c, mu, sigma = np.broadcast_arrays(c, mu, sigma)
    ...             result = np.empty_like(c)
    ...             result[c >= 0] = -np.inf
    ...             result[c < 0] = mu[c < 0] + sigma[c < 0] / c[c < 0]
    ...             return result[()]
    ...
    ...         def right(*, c, mu, sigma):
    ...             c, mu, sigma = np.broadcast_arrays(c, mu, sigma)
    ...             result = np.empty_like(c)
    ...             result[c <= 0] = np.inf
    ...             result[c > 0] = mu[c > 0] + sigma[c > 0] / c[c > 0]
    ...             return result[()]
    ...
    ...     def pdf(self, x, *, c, mu, sigma):

Review comment (performance):
I was hoping to use a more concise example so the complexity of this particular distribution is not mistaken for inherent complexity of adding variable support. Did you *want* to show this particular example? If not, you've already gone through the trouble of writing this, so would you like me to choose and implement a different example, or would you do that? 

Code after:
    ...     def __make_distribution_version__(self):
    ...         return "1.16.0"
    ...
    ...     @property
    ...     def parameters(self):
    ...         return {'a': {'endpoints': (0, np.inf),
    ...                       'inclusive': (False, False)},
    ...                 'b': {'endpoints': ('a', np.inf),
    ...                       'inclusive': (False, False)}}
    ...
    ...     @property
    ...     def support(self):
    ...         return {'endpoints': ('a', 'b'), 'inclusive': (True, True)}
    ...
    ...     def pdf(self, x, a, b):
    ...         return 1 / (x * (np.log(b)- np.log(a)))
    >>>
    >>> MyLogUniform = stats.make_distribution(MyLogUniform())
    >>> Y = MyLogUniform(a=1.0, b=3.0)
    >>> np.isclose(Y.cdf(2.), X.cdf(2.))
    np.True_

    Create a custom distribution with variable support.

    >>> class MyUniformCube:
    ...     @property
    ...     def __make_distribution_version__(self):
    ...         return "1.16.0"
    ...
    ...     @property
    ...     def parameters(self):
    ...         return {"a": (-np.inf, np.inf), 
    ...                 "b": {'endpoints':('a', np.inf), 'inclusive':(True, False)}}
    ...
    ...     @property
    ...     def support(self):
    ...         def left(*, a, b):
    ...             return a**3
    ...
    ...         def right(*, a, b):
    ...             return b**3
    ...         return (left, right)
    ...
    ...     def pdf(self, x, *, a, b):
    ...         return 1 / (3*(b - a)*np.cbrt(x)**2)
    ...
    ...     def cdf(self, x, *, a, b):
    ...         return (np.cbrt(x) - a) / (b - a)
    >>>
    >>> MyUniformCube = stats.make_distribution(MyUniformCube())
    >>> X = MyUniformCube(a=-2, b=2)