<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def landweber(op, x, rhs, niter, omega=None, projection=None, callback=None):
 r"""Optimized implementation of Landweber's method. Solves the inverse problem:: A(x) = rhs Parameters op : `Operator` Operator in the inverse problem. ``op.derivative(x).adjoint`` must be well-defined for ``x`` in the operator domain. x : ``op.domain`` element Element 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. rhs : ``op.range`` element Right-hand side of the equation defining the inverse problem. niter : int Number of iterations. omega : positive float, optional Relaxation parameter in the iteration. Default: ``1 / op.norm(estimate=True) ** 2`` projection : callable, optional Function that can be used to modify the iterates in each iteration, for example enforcing positivity. The function should take one argument and modify it in-place. callback : callable, optional Object executing code per iteration, e.g. plotting each iterate. Notes ----- This method calculates an approximate least-squares solution of the inverse problem of the first kind .. math:: \mathcal{A} (x) = y, for a given :math:`y\in \mathcal{Y}`, i.e. an approximate solution :math:`x^*` to .. math:: \min_{x\in \mathcal{X}} \| \mathcal{A}(x) - y \|_{\mathcal{Y}}^2 for a (Frechet-) differentiable operator :math:`\mathcal{A}: \mathcal{X} \to \mathcal{Y}` between Hilbert spaces :math:`\mathcal{X}` and :math:`\mathcal{Y}`. The method starts from an initial guess :math:`x_0` and uses the iteration .. math:: x_{k+1} = x_k - \omega \ \partial \mathcal{A}(x)^* (\mathcal{A}(x_k) - y), where :math:`\partial \mathcal{A}(x)` is the Frechet derivative of :math:`\mathcal{A}` at :math:`x` and :math:`\omega` is a relaxation parameter. For linear problems, a choice :math:`0 < \omega < 2/\lVert \mathcal{A}^2\rVert` guarantees convergence, where :math:`\lVert\mathcal{A}\rVert` stands for the operator norm of :math:`\mathcal{A}`. Users may also optionally provide a projection to project each iterate onto some subset. For example enforcing positivity. This implementation uses a minimum amount of memory copies by applying re-usable temporaries and in-place evaluation. The method is also described in a `Wikipedia article <https://en.wikipedia.org/wiki/Landweber_iteration>`_. """

    # TODO: add a book reference

    if x not in op.domain:
        raise TypeError('`x` {!r} is not in the domain of `op` {!r}'
                        ''.format(x, op.domain))

    if omega is None:
        omega = 1 / op.norm(estimate=True) ** 2

    # Reusable temporaries
    tmp_ran = op.range.element()
    tmp_dom = op.domain.element()

    for _ in range(niter):
        op(x, out=tmp_ran)
        tmp_ran -= rhs
        op.derivative(x).adjoint(tmp_ran, out=tmp_dom)
        x.lincomb(1, x, -omega, tmp_dom)

        if projection is not None:
            projection(x)

        if callback is not None:
            callback(x)