<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def mlem(op, x, data, niter, callback=None, **kwargs):
 """Maximum Likelihood Expectation Maximation algorithm. Attempts to solve:: max_x L(x | data) where ``L(x | data)`` is the Poisson likelihood of ``x`` given ``data``. The likelihood depends on the forward operator ``op`` such that (approximately):
: op(x) = data Parameters op : `Operator` Forward operator in the inverse problem. x : ``op.domain`` element Vector to which the result is written. Its initial value is used as starting point of the iteration, and its values are updated in each iteration step. The initial value of ``x`` should be non-negative. data : ``op.range`` `element-like` Right-hand side of the equation defining the inverse problem. niter : int Number of iterations. callback : callable, optional Function called with the current iterate after each iteration. Other Parameters sensitivities : float or ``op.domain`` `element-like`, optional The algorithm contains a ``A^T 1`` term, if this parameter is given, it is replaced by it. Default: ``op.adjoint(op.range.one())`` Notes ----- Given a forward model :math:`A` and data :math:`g`, the algorithm attempts to find an :math:`x` that maximizes: .. math:: P(g | g \text{ is } Poisson(A(x)) \text{ distributed}). The algorithm is explicitly given by: .. math:: x_{n+1} = \frac{x_n}{A^* 1} A^* (g / A(x_n)) See Also -------- osmlem : Ordered subsets MLEM loglikelihood : Function for calculating the logarithm of the likelihood """

    osmlem([op], x, [data], niter=niter, callback=callback,
           **kwargs)