Called by pfunc to convert NumPy ufuncs to deterministic factories.

def pufunc(func):
    """
    Called by pfunc to convert NumPy ufuncs to deterministic factories.
    """
    def dtrm_generator(*args):
        if len(args) != func.nin:
            raise ValueError('invalid number of arguments')
        name = func.__name__ + '(' + '_'.join(
            [str(arg) for arg in list(args)]) + ')'
        doc_str = 'A deterministic returning %s(%s)' % (
            func.__name__,
            ', '.join([str(arg) for arg in args]))
        parents = {}
        for i in xrange(func.nin):
            parents['in%i' % i] = args[i]

        def wrapper(**kwargs):
            return func(*[kwargs['in%i' % i] for i in xrange(func.nin)])
        return pm.Deterministic(
            wrapper, doc_str, name, parents, trace=False, plot=False)
    dtrm_generator.__name__ = func.__name__ + '_deterministic_generator'
    dtrm_generator.__doc__ = """
Deterministic-generating wrapper for %s. Original docstring:
%s

%s
    """ % (func.__name__, '_' * 60, func.__doc__)
    return dtrm_generator