<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def proximal_convex_conj_kl_cross_entropy(space, lam=1, g=None):
 r"""Proximal factory of the convex conj of cross entropy KL divergence. Function returning the proximal factory of the convex conjugate of the functional F, where F is the cross entropy Kullback-Leibler (KL) divergence given by:: F(x) = sum_i (x_i ln(pos(x_i)) - x_i ln(g_i) + g_i - x_i) + ind_P(x) with ``x`` and ``g`` in the linear space ``X``, and ``g`` non-negative. Here, ``pos`` denotes the nonnegative part, and ``ind_P`` is the indicator function for nonnegativity. Parameters space : `TensorSpace` Space X which is the domain of the functional F lam : positive float, optional Scaling factor. g : ``space`` element, optional Data term, positive. If None it is take as the one-element. Returns ------- prox_factory : function Factory for the proximal operator to be initialized. See Also -------- proximal_convex_conj_kl : proximal for related functional Notes ----- The functional is given by the expression .. math:: F(x) = \sum_i (x_i \ln(pos(x_i)) - x_i \ln(g_i) + g_i - x_i) + I_{x \geq 0}(x) The indicator function :math:`I_{x \geq 0}(x)` is used to restrict the domain of :math:`F` such that :math:`F` is defined over whole space :math:`X`. The non-negativity thresholding :math:`pos` is used to define :math:`F` in the real numbers. Note that the functional is not well-defined without a prior g. Hence, if g is omitted this will be interpreted as if g is equal to the one-element. The convex conjugate :math:`F^*` of :math:`F` is .. math:: F^*(p) = \sum_i g_i (exp(p_i) - 1) where :math:`p` is the variable dual to :math:`x`. The proximal operator of the convex conjugate of :math:`F` is .. math:: \mathrm{prox}_{\sigma (\lambda F)^*}(x) = x - \lambda W(\frac{\sigma}{\lambda} g e^{x/\lambda}) where :math:`\sigma` is the step size-like parameter, :math:`\lambda` is the weighting in front of the function :math:`F`, and :math:`W` is the Lambert W function (see, for example, the `Wikipedia article <https://en.wikipedia.org/wiki/Lambert_W_function>`_). For real-valued input x, the Lambert :math:`W` function is defined only for :math:`x \geq -1/e`, and it has two branches for values :math:`-1/e \leq x < 0`. However, for inteneded use-cases, where :math:`\lambda` and :math:`g` are positive, the argument of :math:`W` will always be positive. `Wikipedia article on Kullback Leibler divergence <https://en.wikipedia.org/wiki/Kullback%E2%80%93Leibler_divergence>`_. For further information about the functional, see for example `this article <http://ieeexplore.ieee.org/document/1056144/?arnumber=1056144>`_. The KL cross entropy functional :math:`F`, described above, is related to another functional functional also know as KL divergence. This functional is often used as data discrepancy term in inverse problems, when data is corrupted with Poisson noise. This functional is obtained by changing place of the prior and the variable. See the See Also section. """

    lam = float(lam)

    if g is not None and g not in space:
        raise TypeError('{} is not an element of {}'.format(g, space))

    class ProximalConvexConjKLCrossEntropy(Operator):

        """Proximal operator of conjugate of cross entropy KL divergence."""

        def __init__(self, sigma):
            """Initialize a new instance.

            Parameters
            ----------
            sigma : positive float
            """
            self.sigma = float(sigma)
            super(ProximalConvexConjKLCrossEntropy, self).__init__(
                domain=space, range=space, linear=False)

        def _call(self, x, out):
            """Return ``self(x, out=out)``."""
            # Lazy import to improve `import odl` time
            import scipy.special

            if g is None:
                # If g is None, it is taken as the one element
                # Different branches of lambertw is not an issue, see Notes
                lambw = scipy.special.lambertw(
                    (self.sigma / lam) * np.exp(x / lam))
            else:
                # Different branches of lambertw is not an issue, see Notes
                lambw = scipy.special.lambertw(
                    (self.sigma / lam) * g * np.exp(x / lam))

            if not np.issubsctype(self.domain.dtype, np.complexfloating):
                lambw = lambw.real

            lambw = x.space.element(lambw)

            out.lincomb(1, x, -lam, lambw)

    return ProximalConvexConjKLCrossEntropy