def derivative(self, x):
        Ax = self(x)
        tmp = self.range.element()

        scale0 = self.range.zero()
        scale1 = self.range.zero()
        for I, E in zip(self.spectrum, self.energies):
            tmp.lincomb(1, Ax, -mu0(E), x[0])
            tmp.lincomb(1, tmp, -mu1(E), x[1])
            tmp.ufunc.exp(out=tmp)
            scale0.lincomb(1, scale0, I * mu0(E), tmp)
            scale1.lincomb(1, scale1, I * mu1(E), tmp)

        return odl.ReductionOperator(odl.MultiplyOperator(scale0),
                                     odl.MultiplyOperator(scale1))
Exemple #2
0
def functional(request):
    """functional with optimum 0 at 0."""
    name = request.param

    if name == 'l2_squared':
        space = odl.rn(3)
        return odl.solvers.L2NormSquared(space)
    elif name == 'l2_squared_scaled':
        space = odl.uniform_discr(0, 1, 3)
        scaling = odl.MultiplyOperator(space.element([1, 2, 3]), domain=space)
        return odl.solvers.L2NormSquared(space) * scaling
    elif name == 'quadratic_form':
        space = odl.rn(3)
        # Symmetric and diagonally dominant matrix
        matrix = odl.MatrixOperator([[7.0, 1, 2], [1, 5, -3], [2, -3, 8]])
        vector = space.element([1, 2, 3])

        # Calibrate so that functional is zero in optimal point
        constant = 1 / 4 * vector.inner(matrix.inverse(vector))

        return odl.solvers.QuadraticForm(operator=matrix,
                                         vector=vector,
                                         constant=constant)
    elif name == 'rosenbrock':
        # Moderately ill-behaved rosenbrock functional.
        rosenbrock = odl.solvers.RosenbrockFunctional(odl.rn(2), scale=2)

        # Center at zero
        return rosenbrock.translated([-1, -1])
    else:
        assert False
Exemple #3
0
    def proximal(self, sigma):
        if self.domain.is_rn:
            mult = self.support
        else:
            mult = self.domain.element()
            mult.real = self.support
            mult.imag = self.support

        return odl.MultiplyOperator(domain=self.domain, range=self.domain,
                                    multiplicand=mult)
def gradient(space,
             sinfo=None,
             mode=None,
             gamma=1,
             eta=1e-2,
             show_sinfo=False,
             prefix=None):

    grad = odl.Gradient(space, method='forward', pad_mode='symmetric')

    if sinfo is not None:
        if mode == 'direction':
            norm = odl.PointwiseNorm(grad.range)
            grad_sinfo = grad(sinfo)
            ngrad_sinfo = norm(grad_sinfo)

            for i in range(len(grad_sinfo)):
                grad_sinfo[i] /= ngrad_sinfo.ufuncs.max()

            ngrad_sinfo = norm(grad_sinfo)
            ngrad_sinfo_eta = np.sqrt(ngrad_sinfo**2 + eta**2)

            xi = grad.range.element([g / ngrad_sinfo_eta
                                     for g in grad_sinfo])  # UGLY

            Id = odl.operator.IdentityOperator(grad.range)
            xiT = odl.PointwiseInner(grad.range, xi)
            xixiT = odl.BroadcastOperator(*[x * xiT for x in xi])

            grad = (Id - gamma * xixiT) * grad

            if show_sinfo:
                misc.save_image(ngrad_sinfo, prefix + '_sinfo_norm')
                misc.save_vfield(xi.asarray(), filename=prefix + '_sinfo_xi')
                misc.save_vfield_cmap(filename=prefix + '_sinfo_xi_cmap')

        elif mode == 'location':
            norm = odl.PointwiseNorm(grad.range)
            ngrad_sinfo = norm(grad(sinfo))
            ngrad_sinfo /= ngrad_sinfo.ufuncs.max()

            w = eta / np.sqrt(ngrad_sinfo**2 + eta**2)
            grad = odl.DiagonalOperator(odl.MultiplyOperator(w), 2) * grad

            if show_sinfo:
                misc.save_image(ngrad_sinfo, prefix + '_sinfo_norm')
                misc.save_image(w, prefix + '_w')

        else:
            grad = None

    return grad
Exemple #5
0
def functional(request):
    """functional with optimum 0 at 0."""
    name = request.param

    # TODO: quadratic (#606) functionals

    if name == 'l2_squared':
        space = odl.rn(3)
        return odl.solvers.L2NormSquared(space)
    elif name == 'l2_squared_scaled':
        space = odl.uniform_discr(0, 1, 3)
        scaling = odl.MultiplyOperator(space.element([1, 2, 3]), domain=space)
        return odl.solvers.L2NormSquared(space) * scaling
    elif name == 'rosenbrock':
        # Moderately ill-behaved rosenbrock functional.
        rosenbrock = odl.solvers.RosenbrockFunctional(odl.rn(2), scale=2)

        # Center at zero
        return rosenbrock.translated([-1, -1])
    else:
        assert False
Exemple #6
0
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

mat_sqrt_inv = inverse_sqrt_matrix(crlb)


re = ray_trafo.range.element
W = odl.ProductSpaceOperator([[odl.MultiplyOperator(re(mat_sqrt_inv[0, 0])), odl.MultiplyOperator(re(mat_sqrt_inv[0, 1]))],
                              [odl.MultiplyOperator(re(mat_sqrt_inv[1, 0])), odl.MultiplyOperator(re(mat_sqrt_inv[1, 1]))]])

op = W * A

rhs = W(data)

data_discrepancy = odl.solvers.L2NormSquared(A.range).translated(rhs)

l1_norm = odl.solvers.L1Norm(space)
huber = 2.5 * odl.solvers.MoreauEnvelope(l1_norm, sigma=0.01)

my_op = MyOperatorTrace(domain=grad_vec.range, range=space, linear=False)

spc_cov_matrix = [[1, -c],
                  [-c, 1]]
Exemple #7
0
def reconstruct_filter(op: odl.Operator,
                       p,
                       u,
                       niter=10,
                       mask=None,
                       fn_filter=None,
                       clip=(None, None)):
    """
    Iterative reconstruction based on
       R.F. Mudde, Time-resolved X-ray tomography of a fluidized bed

    input
       op - projection matrix or linear projection operator
       p - sinogram
       u - initial iterate
       options.niter - max iterations
               mask - image mask as array with same size as u
               beta - regularization parameter for median filter in [0,1]
               bounds - box constraints on values of u: [min,max]

     output
       u - final iterate
    """
    ones = op.range.element(np.ones(op.range.shape))
    C = odl.MultiplyOperator(np.divide(1, op.adjoint(ones)))

    ones = op.domain.element(np.ones(op.domain.shape))
    R = odl.MultiplyOperator(np.divide(1, op(ones)))

    if mask is not None:
        M = odl.MultiplyOperator(op.domain.element(mask),
                                 domain=op.domain,
                                 range=op.domain)
    else:
        M = odl.IdentityOperator(op.domain)

    for _ in range(niter):
        # SART update
        # v = u + C(M.adjoint(op.adjoint(R(p - op(M(u))))))

        # u += C*M.T*op.T*R*(p - op*M*u)
        u2 = M(u)

        v = op(u2)
        np.subtract(p, v, out=v.data)
        R(v, out=v)
        w = op.adjoint(v)
        M.adjoint(w, out=w)  # adjoint of a diagonal...
        C(w, out=w)
        np.add(u, w, out=u.data)

        # import matplotlib.pyplot as plt
        # plt.ion()
        # plt.figure(29234)
        # plt.imshow(v.data)
        # plt.pause(.2)

        # box constraints
        if clip != (None, None):
            np.clip(u.data, *clip, out=u.data)

        # correction step (median filter)
        if fn_filter is not None:
            u.data[:] = fn_filter(u.data)
grad = odl.Gradient(space)
grad_vec = odl.DiagonalOperator(grad, 2)

cross_terms = True
c = 0.0

if not cross_terms:
    crlb[1, 0, ...] = 0
    crlb[0, 1, ...] = 0

mat_sqrt_inv = inverse_sqrt_matrix(crlb)

re = ray_trafo.range.element
W = odl.ProductSpaceOperator([[
    odl.MultiplyOperator(re(mat_sqrt_inv[0, 0])),
    odl.MultiplyOperator(re(mat_sqrt_inv[0, 1]))
],
                              [
                                  odl.MultiplyOperator(re(mat_sqrt_inv[1, 0])),
                                  odl.MultiplyOperator(re(mat_sqrt_inv[1, 1]))
                              ]])

mat_sqrt_inv_hat = mat_sqrt_inv.mean(axis=(2, 3))
mat_sqrt_inv_hat_inv = np.linalg.inv(mat_sqrt_inv_hat)

I = odl.IdentityOperator(space)
precon = odl.ProductSpaceOperator(np.multiply(mat_sqrt_inv_hat_inv, I))
precon_inv = odl.ProductSpaceOperator(np.multiply(mat_sqrt_inv_hat, I))

op = W * A
Exemple #9
0
        for j in range(I):
            convj = conv((x - c[j])**2)
            summand += np.power(convi / convj, 1.0 / (m - 1.0))
        mu[i] = 1.0 / summand
        conv_adj_mu_pow_m[i] = conv.adjoint(np.power(mu[i], m))

    # Update c
    for i in range(I):
        dividend = ones.inner(conv_adj_mu_pow_m[i] * x)
        divisor = ones.inner(conv_adj_mu_pow_m[i])
        c[i] = dividend / divisor

    # Update x

    # construct operator
    diag = odl.MultiplyOperator(sum(conv_adj_mu_pow_m[i] for i in range(I)))
    op = scaling - lam2 * lap + diag

    # define right hand side
    rhs = scaling(y) - lam2 * lap(y) + sum(c[i] * conv_adj_mu_pow_m[i]
                                           for i in range(I))

    # solve using CG
    odl.solvers.conjugate_gradient(op, x, rhs, niter=256)

    # Display partial results
    callback(y - x)
    print(c)

# display final results
Exemple #10
0
x_thresholded = threshold_op(x)
x_thresholded.show('Initial thresholded guess')

callback1 = odl.solvers.CallbackShow()
callback2 = odl.solvers.CallbackShow()

for i in range(50):
    print('Itertion {}'.format(i))
    x_edge = edge_op(x_thresholded)
    callback1(x_edge)

    # Random part of DART
    x_edge = np.maximum(
        x_edge, np.float32(np.random.uniform(size=reco_space.shape) > 0.95))

    free_op = odl.MultiplyOperator(x_edge)
    fix_op = odl.MultiplyOperator(1 - x_edge)

    free_data = data - (ray_trafo * fix_op)(x_thresholded)

    op = ray_trafo * free_op

    x_tmp = free_op(x)
    odl.solvers.conjugate_gradient_normal(op, x_tmp, free_data, niter=30)

    x_tmp += fix_op(x_thresholded)

    x = convolution(x_tmp)
    x_thresholded = threshold_op(x)
    callback2(x_thresholded)