Decorator function for instantiating stochastic variables. Usages:

    Medium:

        @stochastic
        def A(value = ., parent_name = .,  ...):
            return foo(value, parent_name, ...)

        @stochastic(trace=trace_object)
        def A(value = ., parent_name = .,  ...):
            return foo(value, parent_name, ...)

    Long:

        @stochastic
        def A(value = ., parent_name = .,  ...):

            def logp(value, parent_name, ...):
                return foo(value, parent_name, ...)

            def random(parent_name, ...):
                return bar(parent_name, ...)


        @stochastic(trace=trace_object)
        def A(value = ., parent_name = .,  ...):

            def logp(value, parent_name, ...):
                return foo(value, parent_name, ...)

            def random(parent_name, ...):
                return bar(parent_name, ...)

    where foo() computes the log-probability of the variable A
    conditional on its value and its parents' values, and bar()
    generates a random value from A's distribution conditional on
    its parents' values.

    :SeeAlso:
      Stochastic, Deterministic, deterministic, data, Potential, potential, Model,
      distributions

def stochastic(__func__=None, __class__=Stochastic,
               binary=False, discrete=False, **kwds):
    """
    Decorator function for instantiating stochastic variables. Usages:

    Medium:

        @stochastic
        def A(value = ., parent_name = .,  ...):
            return foo(value, parent_name, ...)

        @stochastic(trace=trace_object)
        def A(value = ., parent_name = .,  ...):
            return foo(value, parent_name, ...)

    Long:

        @stochastic
        def A(value = ., parent_name = .,  ...):

            def logp(value, parent_name, ...):
                return foo(value, parent_name, ...)

            def random(parent_name, ...):
                return bar(parent_name, ...)


        @stochastic(trace=trace_object)
        def A(value = ., parent_name = .,  ...):

            def logp(value, parent_name, ...):
                return foo(value, parent_name, ...)

            def random(parent_name, ...):
                return bar(parent_name, ...)

    where foo() computes the log-probability of the variable A
    conditional on its value and its parents' values, and bar()
    generates a random value from A's distribution conditional on
    its parents' values.

    :SeeAlso:
      Stochastic, Deterministic, deterministic, data, Potential, potential, Model,
      distributions
    """

    def instantiate_p(__func__):
        value, parents = _extract(__func__, kwds, keys, 'Stochastic')
        return __class__(value=value, parents=parents, **kwds)

    keys = ['logp', 'random', 'rseed']

    instantiate_p.kwds = kwds

    if __func__:
        return instantiate_p(__func__)

    return instantiate_p