Returns a new class from a distribution.

    :Parameters:
      dtype : numpy dtype
        The dtype values of instances of this class.
      name : string
        Name of the new class.
      parent_names : list of strings
        The labels of the parents of this class.
      parents_default : list
        The default values of parents.
      docstr : string
        The docstring of this class.
      eval : function
        The function for this class.
      jacobians : dictionary of functions
        The dictionary of jacobian functions for the class
      jacobian_formats : dictionary of strings
        A dictionary indicating the format of each jacobian function

def new_deterministic_class(*new_class_args):
    """
    Returns a new class from a distribution.

    :Parameters:
      dtype : numpy dtype
        The dtype values of instances of this class.
      name : string
        Name of the new class.
      parent_names : list of strings
        The labels of the parents of this class.
      parents_default : list
        The default values of parents.
      docstr : string
        The docstring of this class.
      eval : function
        The function for this class.
      jacobians : dictionary of functions
        The dictionary of jacobian functions for the class
      jacobian_formats : dictionary of strings
        A dictionary indicating the format of each jacobian function
    """

    (dtype, name, parent_names, parents_default, docstr,
     eval, jacobians, jacobian_formats) = new_class_args

    class new_class(pm.Deterministic):
        __doc__ = docstr

        def __init__(self, *args, **kwds):
            (dtype, name, parent_names, parents_default, docstr,
             eval, jacobians, jacobian_formats) = new_class_args
            parents = parents_default

            # Figure out what argument names are needed.
            arg_keys = ['parents', 'trace', 'doc', 'debug', 'plot', 'verbose']
            arg_vals = [parents, False, True, None, False, -1]

            arg_dict_out = dict(zip(arg_keys, arg_vals))
            args_needed = parent_names + arg_keys[2:]

            # Sort positional arguments
            for i in xrange(len(args)):
                try:
                    k = args_needed.pop(0)
                    if k in parent_names:
                        parents[k] = args[i]
                    else:
                        arg_dict_out[k] = args[i]
                except:
                    raise ValueError(
                        'Too many positional arguments provided. Arguments for class ' + self.__class__.__name__ + ' are: ' + str(
                            all_args_needed))

            # Sort keyword arguments
            for k in args_needed:
                if k in parent_names:
                    try:
                        parents[k] = kwds.pop(k)
                    except:
                        if k in parents_default:
                            parents[k] = parents_default[k]
                        else:
                            raise ValueError('No value given for parent ' + k)
                elif k in arg_dict_out.keys():
                    try:
                        arg_dict_out[k] = kwds.pop(k)
                    except:
                        pass

            # Remaining unrecognized arguments raise an error.
            if len(kwds) > 0:
                raise TypeError(
                    'Keywords ' + str(
                        kwds.keys(
                        )) + ' not recognized. Arguments recognized are ' + str(
                        args_needed))

            # Call base class initialization method
            if arg_dict_out.pop('debug'):
                pass
            else:
                parent_strs = []
                for key in parents.keys():
                    parent_strs.append(str(key))

                instance_name = name + '(' + ','.join(parent_strs) + ')'

                pm.Deterministic.__init__(
                    self,
                    name=instance_name,
                    eval=eval,
                    jacobians=jacobians,
                    jacobian_formats=jacobian_formats,
                    dtype=dtype,
                    **arg_dict_out)

    new_class.__name__ = name
    new_class.parent_names = parent_names

    return new_class