def simple_functional(space, fcall=None, grad=None, prox=None, grad_lip=np.nan,
                      convex_conj_fcall=None, convex_conj_grad=None,
                      convex_conj_prox=None, convex_conj_grad_lip=np.nan,
                      linear=False):
    """Simplified interface to create a functional with specific properties.

    Users may specify as many properties as-is needed by the application.

    Parameters
    ----------
    space : `LinearSpace`
        Space that the functional should act on.
    fcall : callable, optional
        Function to evaluate when calling the functional.
    grad : callable or `Operator`, optional
        Gradient operator of the functional.
    prox : `proximal factory`, optional
        Proximal factory for the functional.
    grad_lip : float, optional
        lipschitz constant of the functional.
    convex_conj_fcall : callable, optional
        Function to evaluate when calling the convex conjugate functional.
    convex_conj_grad : callable or `Operator`, optional
        Gradient operator of the convex conjugate functional
    convex_conj_prox : `proximal factory`, optional
        Proximal factory for the convex conjugate functional.
    convex_conj_grad_lip : float, optional
        lipschitz constant of the convex conjugate functional.
    linear : bool, optional
        True if the operator is linear.

    Examples
    --------
    Create squared sum functional on rn:

    >>> def f(x):
    ...     return sum(xi**2 for xi in x)
    >>> def dfdx(x):
    ...     return 2 * x
    >>> space = odl.rn(3)
    >>> func = simple_functional(space, f, grad=dfdx)
    >>> func.domain
    rn(3)
    >>> func.range
    RealNumbers()
    >>> func([1, 2, 3])
    14.0
    >>> func.gradient([1, 2, 3])
    rn(3).element([ 2.,  4.,  6.])
    """
    if grad is not None and not isinstance(grad, Operator):
        grad_in = grad

        class SimpleFunctionalGradient(Operator):

            """Gradient of a `SimpleFunctional`."""

            def _call(self, x):
                """Return ``self(x)``."""
                return grad_in(x)

        grad = SimpleFunctionalGradient(space, space, linear=False)

    if (convex_conj_grad is not None and
            not isinstance(convex_conj_grad, Operator)):
        convex_conj_grad_in = convex_conj_grad

        class SimpleFunctionalConvexConjGradient(Operator):

            """Gradient of the convex conj of a  `SimpleFunctional`."""

            def _call(self, x):
                """Return ``self(x)``."""
                return convex_conj_grad_in(x)

        convex_conj_grad = SimpleFunctionalConvexConjGradient(
            space, space, linear=False)

    class SimpleFunctional(Functional):

        """A simplified functional for examples."""

        def __init__(self):
            """Initialize an instance."""
            super(SimpleFunctional, self).__init__(
                space, linear=linear, grad_lipschitz=grad_lip)

        def _call(self, x):
            """Return ``self(x)``."""
            if fcall is None:
                raise NotImplementedError('call not implemented')
            else:
                return fcall(x)

        @property
        def proximal(self):
            """Return the proximal of the operator."""
            if prox is None:
                raise NotImplementedError('proximal not implemented')
            else:
                return prox

        @property
        def gradient(self):
            """Return the gradient of the operator."""
            if grad is None:
                raise NotImplementedError('gradient not implemented')
            else:
                return grad

        @property
        def convex_conj(self):
            return simple_functional(space, fcall=convex_conj_fcall,
                                     grad=convex_conj_grad,
                                     prox=convex_conj_prox,
                                     grad_lip=convex_conj_grad_lip,
                                     convex_conj_fcall=fcall,
                                     convex_conj_grad=grad,
                                     convex_conj_prox=prox,
                                     convex_conj_grad_lip=grad_lip,
                                     linear=linear)

    return SimpleFunctional()
def simple_functional ( space , fcall = None , grad = None , prox = None , grad_lip = np . nan , convex_conj_fcall = None , convex_conj_grad = None , convex_conj_prox = None , convex_conj_grad_lip = np . nan , linear = False ) : if grad is not None and not isinstance ( grad , Operator ) : grad_in = grad class SimpleFunctionalGradient ( Operator ) : def _call ( self , x ) : return grad_in ( x ) grad = SimpleFunctionalGradient ( space , space , linear = False ) if ( convex_conj_grad is not None and not isinstance ( convex_conj_grad , Operator ) ) : convex_conj_grad_in = convex_conj_grad class SimpleFunctionalConvexConjGradient ( Operator ) : def _call ( self , x ) : return convex_conj_grad_in ( x ) convex_conj_grad = SimpleFunctionalConvexConjGradient ( space , space , linear = False ) class SimpleFunctional ( Functional ) : def __init__ ( self ) : super ( SimpleFunctional , self ) . __init__ ( space , linear = linear , grad_lipschitz = grad_lip ) def _call ( self , x ) : if fcall is None : raise NotImplementedError ( 'call not implemented' ) else : return fcall ( x ) @ property def proximal ( self ) : if prox is None : raise NotImplementedError ( 'proximal not implemented' ) else : return prox @ property def gradient ( self ) : if grad is None : raise NotImplementedError ( 'gradient not implemented' ) else : return grad @ property def convex_conj ( self ) : return simple_functional ( space , fcall = convex_conj_fcall , grad = convex_conj_grad , prox = convex_conj_prox , grad_lip = convex_conj_grad_lip , convex_conj_fcall = fcall , convex_conj_grad = grad , convex_conj_prox = prox , convex_conj_grad_lip = grad_lip , linear = linear ) return SimpleFunctional ( )
Simplified interface to create a functional with specific properties.

    Users may specify as many properties as-is needed by the application.

    Parameters
    ----------
    space : `LinearSpace`
        Space that the functional should act on.
    fcall : callable, optional
        Function to evaluate when calling the functional.
    grad : callable or `Operator`, optional
        Gradient operator of the functional.
    prox : `proximal factory`, optional
        Proximal factory for the functional.
    grad_lip : float, optional
        lipschitz constant of the functional.
    convex_conj_fcall : callable, optional
        Function to evaluate when calling the convex conjugate functional.
    convex_conj_grad : callable or `Operator`, optional
        Gradient operator of the convex conjugate functional
    convex_conj_prox : `proximal factory`, optional
        Proximal factory for the convex conjugate functional.
    convex_conj_grad_lip : float, optional
        lipschitz constant of the convex conjugate functional.
    linear : bool, optional
        True if the operator is linear.

    Examples
    --------
    Create squared sum functional on rn:

    >>> def f(x):
    ...     return sum(xi**2 for xi in x)
    >>> def dfdx(x):
    ...     return 2 * x
    >>> space = odl.rn(3)
    >>> func = simple_functional(space, f, grad=dfdx)
    >>> func.domain
    rn(3)
    >>> func.range
    RealNumbers()
    >>> func([1, 2, 3])
    14.0
    >>> func.gradient([1, 2, 3])
    rn(3).element([ 2.,  4.,  6.])