odl.Operator.__init__(self, space, space, True) def _call(self, x): result = self.range.zero() for k in range(self.domain.size): for i in range(self.domain.size): for j in range(self.domain[0].size): result[i][j] += self.arr[k][i] * x[k][j] return result @property def adjoint(self): return LamOp(self.domain, self.arr.T) data, geometry, crlb = load_fan_data(return_crlb=True) space = odl.uniform_discr([-129, -129], [129, 129], [400, 400]) ray_trafo = odl.tomo.RayTransform(space, geometry, impl='astra_cuda') A = odl.DiagonalOperator(ray_trafo, 2) grad = odl.Gradient(space) grad_vec = odl.DiagonalOperator(grad, 2) cross_terms = True c = 0.5 if not cross_terms: crlb[1, 0, ...] = 0 crlb[0, 1, ...] = 0
"""Example of reconstruction with the Huber norm. Here, the huber norm is implemented using the moreau envelope, for convenience. The problem is solved using the BFGS quasi-newton method. """ import odl from util import load_data, load_fan_data material = 'water' lam = 4 sigma = 0.005 data, geometry = load_fan_data() space = odl.uniform_discr([-129, -129], [129, 129], [400, 400]) ray_trafo = odl.tomo.RayTransform(space, geometry, impl='astra_cuda') # Data discrepancy if material == 'water': b = ray_trafo.range.element(data[0]) elif material == 'bone': b = ray_trafo.range.element(data[1]) l2 = odl.solvers.L2NormSquared(ray_trafo.range) * (ray_trafo - b) # Create huber norm grad = odl.Gradient(space) l1_norm = odl.solvers.GroupL1Norm(grad.range)