def spatial_vfield_gradient(self, i):
        if self.alpha == 0:
            return ZeroOperator(self.space, range=self.vf_space)
        else:
            functional = self
            i -= self.N
            if i == self.N - 1:
                return ZeroOperator(self.space, self.vf_space)
            else:

                class VfieldDerivative(Operator):
                    def __init__(self):
                        super(VfieldDerivative,
                              self).__init__(functional.space,
                                             functional.vf_space)

                    def _call(self, x, out):
                        xim = x[:functional.N]
                        xvf = x[functional.N:]
                        res = functional.residual(xim[i + 1], xim[i], xvf[i])
                        dhuber = functional.huber.gradient(res)
                        tmp = functional.tau * functional.grad(
                            xim[i + 1]) * dhuber
                        tmp *= functional.alpha
                        out.assign(tmp)

                return VfieldDerivative()
    def spatial_vfield_gradient(self, i):
        functional = self
        i -= self.N
        if i == self.N - 1:
            return ZeroOperator(self.space, self.vf_space)
        else:

            class VfieldDerivative(Operator):
                def __init__(self):
                    super(VfieldDerivative,
                          self).__init__(functional.space, functional.vf_space)

                def _call(self, x, out):
                    xim = x[:functional.N]
                    ret = functional.grad(xim[i + 1]) * functional.lagr_mult[i]
                    out.assign(ret)

            return VfieldDerivative()
    def spatial_image_gradient(self, i):
        if self.alpha[i] == 0:
            return ZeroOperator(self.space, range=self.image_space)
        else:
            functional = self

            class auxOperator(Operator):
                def __init__(self):
                    super(auxOperator, self).__init__(functional.space,
                                                      functional.image_space)

                def _call(self, x, out):
                    xim = x[:functional.N]
                    xi = xim[i]
                    ret = functional.alpha[i] * (
                        functional.forward.adjoint *
                        (functional.forward -
                         ConstantOperator(functional.data[i])))(xi)
                    out.assign(ret)

            return auxOperator()
Ejemplo n.º 4
0
    def __getitem__(self, index):
        """Get sub-operator by index.

        Parameters
        ----------
        index : int or tuple of int
            A pair of integers given as (row, col).

        Returns
        -------
        suboperator : `ReductionOperator`, `Operator` or ``0``
            If index is an integer, return the row given by the index.

            If index is a tuple, it must have two elements.
            if there is an operator at ``(row, col)``,  the operator is
            returned, otherwise ``0``.

        Examples
        --------
        >>> r3 = odl.rn(3)
        >>> pspace = odl.ProductSpace(r3, r3)
        >>> I = odl.IdentityOperator(r3)
        >>> prod_op = ProductSpaceOperator([[0, I],
        ...                                 [0, 0]],
        ...                                domain=pspace, range=pspace)
        >>> prod_op[0, 0]
        0
        >>> prod_op[0, 1]
        IdentityOperator(rn(3))
        >>> prod_op[1, 0]
        0
        >>> prod_op[1, 1]
        0

        By accessing single indices, a row is extracted as a
        `ReductionOperator`:

        >>> prod_op[0]
        ReductionOperator(ZeroOperator(rn(3)), IdentityOperator(rn(3)))
        """
        if isinstance(index, tuple):
            row, col = index

            linear_index = np.flatnonzero((self.ops.row == row)
                                          & (self.ops.col == col))
            if linear_index.size == 0:
                return 0
            else:
                return self.ops.data[int(linear_index)]
        else:
            index = int(index)

            ops = [None] * len(self.domain)
            for op, col, row in zip(self.ops.data, self.ops.col, self.ops.row):
                if row == index:
                    ops[col] = op

            for i in range(len(self.domain)):
                if ops[i] is None:
                    ops[i] = ZeroOperator(self.domain[i])

            return ReductionOperator(*ops)
    def spatial_image_gradient(self, i):
        if self.alpha == 0:
            return ZeroOperator(self.space, range=self.image_space)
        else:
            functional = self
            if i == 0:

                class FirstImageDerivative(Operator):
                    def __init__(self):
                        super(FirstImageDerivative,
                              self).__init__(functional.space,
                                             functional.image_space)

                    def _call(self, x, out):
                        xim = x[:functional.N]
                        xvf = x[functional.N:]
                        res = -functional.huber.gradient(
                            functional.residual(xim[1], xim[0], xvf[0]))
                        res *= functional.alpha
                        out.assign(res)

                return FirstImageDerivative()

            if i == self.N - 1:

                class LastImageDerivative(Operator):
                    def __init__(self):
                        super(LastImageDerivative,
                              self).__init__(functional.space,
                                             functional.image_space)

                    def _call(self, x, out):
                        xim = x[:functional.N]
                        xvf = x[functional.N:]
                        res = functional.residual(xim[-1], xim[-2], xvf[-2])
                        dhuber = functional.huber.gradient(res)
                        P = PointwiseInner(functional.vf_space, xvf[-2])
                        tmp = dhuber - functional.tau * (
                            P(functional.grad(dhuber)) -
                            functional.grad.adjoint(xvf[-2]) * dhuber)
                        tmp *= functional.alpha
                        out.assign(tmp)

                return LastImageDerivative()

            if 0 < i < self.N - 1:

                class IntermediateImageDerivative(Operator):
                    def __init__(self):
                        super(IntermediateImageDerivative,
                              self).__init__(functional.space,
                                             functional.image_space)

                    def _call(self, x, out):
                        xim = x[:functional.N]
                        xvf = x[functional.N:]
                        resi = functional.residual(xim[i], xim[i - 1],
                                                   xvf[i - 1])
                        resii = functional.residual(xim[i + 1], xim[i], xvf[i])
                        dhuberi = functional.huber.gradient(resi)
                        dhuberii = functional.huber.gradient(resii)
                        P = PointwiseInner(functional.vf_space, xvf[i - 1])
                        tmp = dhuberi - functional.tau * (
                            P(functional.grad(dhuberi)) -
                            functional.grad.adjoint(xvf[i - 1]) * dhuberi)
                        tmp -= dhuberii
                        tmp *= functional.alpha
                        out.assign(tmp)

                return IntermediateImageDerivative()

            else:
                raise ValueError('time index out of range')
 def spatial_vfield_gradient(self, i):
     i -= self.N
     return ZeroOperator(self.space, range=self.vf_space)