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()
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)