def R_op(self, inputs, eval_points):
        """Apply the adjoint of the Jacobian at ``inputs`` to ``eval_points``.

        This is the symbolic counterpart of ODL's ::

            op.derivative(x).adjoint(v)

        See `grad` for its usage.

        Parameters
        ----------
        inputs : 1-element list of `theano.tensor.var.TensorVariable`
            Symbolic input to the gradient, the point at which the
            Jacobian is computed.
        eval_points : 1-element list of `theano.tensor.var.TensorVariable`
            Symbolic input to the adjoint of the Jacobian, i.e., the
            variable to which the Jacobian adjoint should be applied.

        Returns
        -------
        outputs : 1-element list of `theano.tensor.var.TensorVariable`
            Symbolic result of the application of the Jacobian adjoint.
            It uses a wrapper class ``OdlDerivativeAdjointAsTheanoROp``
            for ``(x, v) --> op.derivative(x).adjoint(v)``.
        """
        # ODL weights spaces, Theano does not. We need to handle this
        try:
            dom_weight = self.operator.domain.weighting.const
        except AttributeError:
            dom_weight = 1.0

        try:
            ran_weight = self.operator.range.weighting.const
        except AttributeError:
            ran_weight = 1.0

        scale = dom_weight / ran_weight

        op = self

        class TheanoJacobianAdjoint(theano.Op):

            __props__ = ()

            """Wrap ``op.derivative(x).adjoint(v)`` into a Theano Op.

            This Op has two inputs, ``x`` and ``v``, where ``x``
            is the point at which the Jacobian is taken, and ``v`` the
            tensor to which its adjoint is applied. There is only one output,
            which is of the same type as ``v`` (and ``x``).
            """

            def make_node(self, x, v):
                """Create a node for the computation graph."""
                x = theano.tensor.as_tensor_variable(x)
                v = theano.tensor.as_tensor_variable(v)
                return theano.Apply(self, [x, v], [x.type()])

            def perform(self, node, inputs_storage, output_storage):
                """Evaluate this node's computation.

                This method computes ::

                    op.derivative(x).adjoint(v)
                """
                x = inputs_storage[0]
                v = inputs_storage[1]
                out = output_storage[0]
                out[0] = np.asarray(op.operator.derivative(x).adjoint(v))
                if scale != 1.0:
                    out[0] *= scale

            def infer_shape(self, node, input_shapes):
                """Return a list of output shapes based on ``input_shapes``."""
                # Need to convert to native to avoid error in theano from
                # future.int
                return [tuple(native(si) for si in op.operator.domain.shape)]

        r_op = TheanoJacobianAdjoint()
        r_op_apply = r_op(inputs[0], eval_points[0])
        return [r_op_apply]
Apply the adjoint of the Jacobian at ``inputs`` to ``eval_points``.

        This is the symbolic counterpart of ODL's ::

            op.derivative(x).adjoint(v)

        See `grad` for its usage.

        Parameters
        ----------
        inputs : 1-element list of `theano.tensor.var.TensorVariable`
            Symbolic input to the gradient, the point at which the
            Jacobian is computed.
        eval_points : 1-element list of `theano.tensor.var.TensorVariable`
            Symbolic input to the adjoint of the Jacobian, i.e., the
            variable to which the Jacobian adjoint should be applied.

        Returns
        -------
        outputs : 1-element list of `theano.tensor.var.TensorVariable`
            Symbolic result of the application of the Jacobian adjoint.
            It uses a wrapper class ``OdlDerivativeAdjointAsTheanoROp``
            for ``(x, v) --> op.derivative(x).adjoint(v)``.