Creates a new binary special method with left and right versions, such as
        A.__mul__(B) <=> A*B,
        A.__rmul__(B) <=> [B*A if B.__mul__(A) fails]
    for target class. The method is called __op_name__.

def create_rl_bin_method(op_name, klass, jacobians={}):
    """
    Creates a new binary special method with left and right versions, such as
        A.__mul__(B) <=> A*B,
        A.__rmul__(B) <=> [B*A if B.__mul__(A) fails]
    for target class. The method is called __op_name__.
    """
    # Make left and right versions.
    for prefix in ['r', '']:
        # This function will became the methods.
        op_modules = [operator, builtins]
        op_names = [op_name, op_name + '_']

        op_function_base = find_element(
            op_names,
            op_modules,
            error_on_fail=True)
        # many such functions do not take keyword arguments, so we need to wrap
        # them

        def op_function(a, b):
            return op_function_base(a, b)

        def new_method(self, other, prefix=prefix):
            if not check_special_methods():
                raise NotImplementedError(
                    'Special method %s called on %s, but special methods have been disabled. Set pymc.special_methods_available to True to enable them.' %
                    (op_name, str(self)))
            # This code will create one of two Deterministic objects.
            if prefix == 'r':
                parents = {'a': other, 'b': self}

            else:
                parents = {'a': self, 'b': other}
            jacobian_formats = {'a': 'broadcast_operation',
                                'b': 'broadcast_operation'}
            return pm.Deterministic(op_function,
                                    'A Deterministic returning the value of %s(%s,%s)' % (
                                        prefix + op_name, self.__name__, str(
                                            other)),
                                    '(' + '_'.join(
                                        [self.__name__,
                                         prefix + op_name,
                                         str(other)]) + ')',
                                    parents,
                                    trace=False,
                                    plot=False,
                                    jacobians=jacobians,
                                    jacobian_formats=jacobian_formats)
        # Convert the functions into methods for klass.
        new_method.__name__ = '__' + prefix + op_name + '__'
        setattr(
            klass,
            new_method.__name__,
            UnboundMethodType(
                new_method,
                None,
                klass))