Beispiel #1
0
def test_random_bs():
    nTests = 100
    aFile = 'Archive/A.txt'
    maxL = 1e-3
    nCols = 100000

    for i in range(nTests):
        print('Test ' + str(i))
        bFile = 'fakes/b' + str(i) + '.txt'
        xFile = 'fakes/x' + str(i) + '.txt'
        (A,b) = l.read_data(aFile, bFile)
        (x, L, reason, nIters, aLists, b, aSparse) = l.lsqr(aFile, bFile, nCols, verbose = False)
        myCost = l.cost(l.difference_vector(A, x, b))
        if myCost > maxL:
            print('Error in file ' + str(i))
Beispiel #2
0
def test_lsqr():
    aFile = 'Archive/A.txt'
    bFile = 'Archive/b.txt'
    nCols = 100000
    aTol = 1e-6
    bTol = 1e-7
    verbose = False
    maxIter = None
    (x, L, reason, nIters, aLists, b,
     aSparse) = l.lsqr(aFile, bFile, nCols, aTol, bTol, verbose, maxIter)
    success = len(x) == nCols
    if not success:
        print('ERROR!!! in LSQR')
        print(len(x))
        print(nCols)
        print(reason)
Beispiel #3
0
def smooth(boundary_list, cocycle_list):
    dimension = max((max(d[1], d[2]) for d in boundary_list))
    dimension += 1

    # NB: D is a coboundary matrix; 1 and 2 below are transposed
    D = spmatrix([d[0] for d in boundary_list], [d[2] for d in boundary_list],
                 [d[1] for d in boundary_list], (dimension, dimension))

    z = spmatrix([zz[0] for zz in cocycle_list],
                 [zz[1] for zz in cocycle_list], [0 for zz in cocycle_list],
                 (dimension, 1))

    v1 = D * z
    # print "D^2 is zero:", not bool(D*D)
    # print "D*z is zero:", not bool(v1)
    z = matrix(z)

    def Dfun(x, y, trans='N'):
        if trans == 'N':
            copy(D * x, y)
        elif trans == 'T':
            copy(D.T * x, y)
        else:
            assert False, "Unexpected trans parameter"

    tol = 1e-10
    show = False
    maxit = None
    solution = lsqr(Dfun,
                    matrix(z),
                    show=show,
                    atol=tol,
                    btol=tol,
                    itnlim=maxit)

    v = z - D * solution[0]

    # print sum(v**2)
    # assert sum((D*v)**2) < tol and sum((D.T*v)**2) < tol, "Expected a harmonic cocycle"
    if not (sum((D * v)**2) < tol and sum((D.T * v)**2) < tol):
        print "Expected a harmonic cocycle:", sum((D * v)**2), sum(
            (D.T * v)**2)

    return solution[0], v
Beispiel #4
0
def smooth(boundary_list, cocycle_list):
    dimension = max((max(d[1], d[2]) for d in boundary_list))
    dimension += 1

    # NB: D is a coboundary matrix; 1 and 2 below are transposed

    D = spmatrix([d[0] for d in boundary_list],
                 [d[2] for d in boundary_list],
                 [d[1] for d in boundary_list], (dimension, dimension))   


    z = spmatrix([zz[0] for zz in cocycle_list],
                 [zz[1] for zz in cocycle_list],
                 [0     for zz in cocycle_list], (dimension, 1))

    v1 = D * z
    # print "D^2 is zero:", not bool(D*D)
    # print "D*z is zero:", not bool(v1)

    z = matrix(z)

    def Dfun(x,y,trans = 'N'):
        if trans == 'N':
            copy(D * x, y)
        elif trans == 'T':
            copy(D.T * x, y)
        else:
            assert False, "Unexpected trans parameter"

    tol = 1e-10
    show = False
    maxit = None
    solution = lsqr(Dfun, matrix(z), show = show, atol = tol, btol = tol, itnlim = maxit)
    
    v = z - D*solution[0]

    # print sum(v**2)
    # assert sum((D*v)**2) < tol and sum((D.T*v)**2) < tol, "Expected a harmonic cocycle"
    if not (sum((D*v)**2) < tol and sum((D.T*v)**2) < tol):
        print "Expected a harmonic cocycle:", sum((D*v)**2), sum((D.T*v)**2) 

    return solution[0], v
Beispiel #5
0
def solve(images,
          tf_matrices,
          scale,
          x0=None,
          tol=1e-10,
          iter_lim=None,
          damp=1e-1,
          method='CG',
          operator='bilinear',
          norm=1,
          standard_form=False):
    """Super-resolve a set of low-resolution images by solving
    a large, sparse set of linear equations.

    This method approximates the camera with a downsampling operator,
    using bilinear or polygon interpolation.  The LSQR method is used
    to solve the equation :math:`A\mathbf{x} = b` where :math:`A` is
    the downsampling operator, :math:`\mathbf{x}` is the
    high-resolution estimate (flattened in raster scan/
    lexicographic order), and :math:`\mathbf{b}` is a stacked vector
    of all the low-resolution images.

    Parameters
    ----------
    images : list of ndarrays
        Low-resolution input frames.
    tf_matrices : list of (3, 3) ndarrays
        Transformation matrices that relate all low-resolution frames
        to a reference low-resolution frame (usually ``images[0]``).
    scale : float
        The resolution of the output image is `scale` times the resolution
        of the input images.
    x0 : ndarray, optional
        Initial guess of HR image.
    damp : float, optional
        If an initial guess is provided, `damp` specifies how much that
        estimate is weighed in the entire process.  A larger value of
        `damp` results in a solution closer to `x0`, whereas a smaller
        version of `damp` yields a solution closer to the solution
        obtained without any initial estimate.
    method : {'CG', 'LSQR', 'descent', 'L-BFGS-B'}
        Whether to use conjugate gradients, least-squares, gradient descent
        or L-BFGS-B to determine the solution.
    operator : {'bilinear', 'polygon'}
        The camera model is approximated as an interpolation process.  The
        bilinear interpolation operator only works well for zoom ratios < 2.
    norm : {1, 2}
        Whether to use the L1 or L2 norm to measure errors between images.
    standard_form : bool
        Whether to convert the matrix operator to standard form before
        processing.

    Returns
    -------
    HR : ndarray
        High-resolution estimate.

    """
    assert len(images) == len(tf_matrices)

    HH = [H.copy() for H in tf_matrices]
    HH_scaled = []
    scale = float(scale)
    for H in HH:
        HS = np.array([[scale, 0, 0], [0, scale, 0], [0, 0, 1]])

        HH_scaled.append(np.linalg.inv(np.dot(HS, H)))

    HH = HH_scaled
    oshape = np.floor(np.array(images[0].shape) * scale)
    LR_shape = images[0].shape

    print "Constructing camera operator (%s)..." % operator
    if operator == 'bilinear':
        op = bilinear(oshape[0], oshape[1], HH, *LR_shape, boundary=0)
    elif operator == 'polygon':
        sub_ops = []
        for H in HH:
            sub_ops.append(
                poly_interp_op(oshape[0],
                               oshape[1],
                               H,
                               *LR_shape,
                               search_win=round(scale) * 2 + 1))
        op = sparse.vstack(sub_ops, format='csr')
    else:
        raise ValueError('Invalid operator requested (%s).' % operator)

##  Visualise mapping of frames
##
##     import matplotlib.pyplot as plt
##     P = np.prod(LR_shape)
##     img = (op * x0.flat).reshape(LR_shape)
##     plt.subplot(1, 4, 1)
##     plt.imshow(x0, cmap=plt.cm.gray)
##     plt.title('x0')
##     plt.subplot(1, 4, 2)
##     plt.imshow(images[0], cmap=plt.cm.gray)
##     plt.title('LR frame')
##     plt.subplot(1, 4, 3)
##     plt.imshow(img, cmap=plt.cm.gray)
##     plt.title('LR image Ax0')
##     plt.subplot(1, 4, 4)
##     plt.imshow(images[0] - img, cmap=plt.cm.gray)
##     plt.title('diff images[0] - Ax')
##     plt.show()

    if standard_form:
        print "Bringing matrix to standard form..."
        P = ordering.standard_form(op)
        op = P * op

    k = len(images)
    M = np.prod(LR_shape)
    b = np.empty(k * M)
    for i in range(k):
        b[i * M:(i + 1) * M] = images[i].flat

    if standard_form:
        b = P * b

    atol = btol = conlim = tol
    show = True

    # Error and gradient functions, used in conjugate gradient optimisation
    def sr_func(x, norm=norm):
        return (np.linalg.norm(op * x - b, norm) ** 2 + \
                damp * np.linalg.norm(x - x0.flat, norm) ** 2)

    def sr_gradient(x, norm=norm):
        # Careful! Mixture of sparse and dense operators.
        #Axb = op * x - b
        #nrm_sq = np.dot(Axb, Axb) # Dense
        #Axbop = (op.T * Axb).T # Sparse
        #return nrm_sq * Axbop
        Axb = op * x - b
        L = len(x)
        if norm == 1:
            xmx0 = x - x0.flat
            term1 = np.linalg.norm(Axb, 1) * np.sign(Axb.T) * op
            term2 = damp * np.linalg.norm(xmx0, 1) * np.sign(xmx0.flat)
        elif norm == 2:
            term1 = (Axb.T * op)
            term2 = damp * (x - x0.flat)
        else:
            raise ValueError('Invalid norm for error measure (%s).' % norm)

        return 2 * (term1 + term2)

    print "Super resolving..."

    ## Conjugate Gradient Optimisation
    if method == 'CG':

        x, fopt, f_calls, gcalls, warnflag = \
           opt.fmin_cg(sr_func, x0, fprime=sr_gradient, gtol=0,
                       disp=True, maxiter=iter_lim, full_output=True)

    elif method == 'LSQR':

        ## LSQR Optimisation
        ##
        x0 = x0.flat
        b = b - op * x0
        x, istop, itn, r1norm, r2norm, anorm, acond, arnorm, xnorm, var = \
          lsqr(op, b, atol=atol, btol=btol,
               conlim=conlim, damp=damp, show=show, iter_lim=iter_lim)
        x = x0 + x

    elif method == 'descent':

        ## Steepest Descent Optimisation
        ##
        x = np.array(x0, copy=True).reshape(np.prod(x0.shape))
        for i in range(50):
            print(op.T * ((op * x) - b)).shape
            print "Gradient descent step %d" % i
            x += damp * -1 * (op.T * ((op * x) - b))
            # Could add prior: + lam * (x - x0.flat))


## L-BFGS-B
    elif method == 'L-BFGS-B':
        x, f, d = opt.fmin_l_bfgs_b(sr_func, x0.flat, fprime=sr_gradient)
        print "L-BFGS-B converged after %d function calls." % d['funcalls']
        print "Final function value:", f
        print "Reason for termination:", d['task']

    elif method == 'direct':
        x = sparse.linalg.spsolve(op, b)

    else:
        raise ValueError('Invalid method (%s) specified.' % method)

    return x.reshape(oshape.astype(int))
Beispiel #6
0
def solve(images, tf_matrices, scale, x0=None,
          tol=1e-10, iter_lim=None, damp=1e-1,
          method='CG', operator='bilinear', norm=1,
          standard_form=False):
    """Super-resolve a set of low-resolution images by solving
    a large, sparse set of linear equations.

    This method approximates the camera with a downsampling operator,
    using bilinear or polygon interpolation.  The LSQR method is used
    to solve the equation :math:`A\mathbf{x} = b` where :math:`A` is
    the downsampling operator, :math:`\mathbf{x}` is the
    high-resolution estimate (flattened in raster scan/
    lexicographic order), and :math:`\mathbf{b}` is a stacked vector
    of all the low-resolution images.

    Parameters
    ----------
    images : list of ndarrays
        Low-resolution input frames.
    tf_matrices : list of (3, 3) ndarrays
        Transformation matrices that relate all low-resolution frames
        to a reference low-resolution frame (usually ``images[0]``).
    scale : float
        The resolution of the output image is `scale` times the resolution
        of the input images.
    x0 : ndarray, optional
        Initial guess of HR image.
    damp : float, optional
        If an initial guess is provided, `damp` specifies how much that
        estimate is weighed in the entire process.  A larger value of
        `damp` results in a solution closer to `x0`, whereas a smaller
        version of `damp` yields a solution closer to the solution
        obtained without any initial estimate.
    method : {'CG', 'LSQR', 'descent', 'L-BFGS-B'}
        Whether to use conjugate gradients, least-squares, gradient descent
        or L-BFGS-B to determine the solution.
    operator : {'bilinear', 'polygon'}
        The camera model is approximated as an interpolation process.  The
        bilinear interpolation operator only works well for zoom ratios < 2.
    norm : {1, 2}
        Whether to use the L1 or L2 norm to measure errors between images.
    standard_form : bool
        Whether to convert the matrix operator to standard form before
        processing.

    Returns
    -------
    HR : ndarray
        High-resolution estimate.

    """
    assert len(images) == len(tf_matrices)

    HH = [H.copy() for H in tf_matrices]
    HH_scaled = []
    scale = float(scale)
    for H in HH:
        HS = np.array([[scale, 0,         0],
                       [0,       scale,   0],
                       [0,       0,       1]])

        HH_scaled.append(np.linalg.inv(np.dot(HS, H)))

    HH = HH_scaled
    oshape = np.floor(np.array(images[0].shape) * scale)
    LR_shape = images[0].shape

    print "Constructing camera operator (%s)..." % operator
    if operator == 'bilinear':
        op = bilinear(oshape[0], oshape[1], HH, *LR_shape, boundary=0)
    elif operator == 'polygon':
        sub_ops = []
        for H in HH:
            sub_ops.append(poly_interp_op(oshape[0], oshape[1],
                                          H, *LR_shape,
                                          search_win=round(scale) * 2 + 1))
        op = sparse.vstack(sub_ops, format='csr')
    else:
        raise ValueError('Invalid operator requested (%s).' % operator)


##  Visualise mapping of frames
##
##     import matplotlib.pyplot as plt
##     P = np.prod(LR_shape)
##     img = (op * x0.flat).reshape(LR_shape)
##     plt.subplot(1, 4, 1)
##     plt.imshow(x0, cmap=plt.cm.gray)
##     plt.title('x0')
##     plt.subplot(1, 4, 2)
##     plt.imshow(images[0], cmap=plt.cm.gray)
##     plt.title('LR frame')
##     plt.subplot(1, 4, 3)
##     plt.imshow(img, cmap=plt.cm.gray)
##     plt.title('LR image Ax0')
##     plt.subplot(1, 4, 4)
##     plt.imshow(images[0] - img, cmap=plt.cm.gray)
##     plt.title('diff images[0] - Ax')
##     plt.show()

    if standard_form:
        print "Bringing matrix to standard form..."
        P = ordering.standard_form(op)
        op = P * op

    k = len(images)
    M = np.prod(LR_shape)
    b = np.empty(k * M)
    for i in range(k):
        b[i * M:(i + 1) * M] = images[i].flat

    if standard_form:
        b = P * b

    atol = btol = conlim = tol
    show = True

    # Construct the prior
    opT = op.T
    opT_sum1 = opT.sum(axis=1).flatten() + 0.00001 # add small bias to avoid division by zero
    opTb = opT.dot(b)
    x0 = opTb / opT_sum1 

    #return x0.reshape(oshape)

    # Error and gradient functions, used in conjugate gradient optimisation
    def sr_func(x, norm=norm):
        return (np.linalg.norm(op * x - b, norm) ** 2 + \
                damp * np.linalg.norm(x - x0.flat, norm) ** 2)

    def sr_gradient(x, norm=norm):
        # Careful! Mixture of sparse and dense operators.
        #Axb = op * x - b
        #nrm_sq = np.dot(Axb, Axb) # Dense
        #Axbop = (op.T * Axb).T # Sparse
        #return nrm_sq * Axbop
        Axb = op * x - b
        L = len(x)
        if norm == 1:
            xmx0 = x - x0.flat
            term1 = np.linalg.norm(Axb, 1) * np.sign(Axb.T) * op
            term2 = damp * np.linalg.norm(xmx0, 1) * np.sign(xmx0.flat)
        elif norm == 2:
            term1 = (Axb.T * op)
            term2 = damp * (x - x0.flat)
        else:
            raise ValueError('Invalid norm for error measure (%s).' % norm)

        return 2 * (term1 + term2)

    print "Super resolving..."

## Conjugate Gradient Optimisation
    if method == 'CG':

        x, fopt, f_calls, gcalls, warnflag = \
           opt.fmin_cg(sr_func, x0, fprime=sr_gradient, gtol=0,
                       disp=True, maxiter=iter_lim, full_output=True)

    elif method == 'LSQR':

## LSQR Optimisation
##
        x0 = x0.flat
        b = b - op * x0
        x, istop, itn, r1norm, r2norm, anorm, acond, arnorm, xnorm, var = \
          lsqr(op, b, atol=atol, btol=btol,
               conlim=conlim, damp=damp, show=show, iter_lim=iter_lim)
        x = x0 + x

    elif method == 'descent':

## Steepest Descent Optimisation
##
        x = np.array(x0, copy=True).reshape(np.prod(x0.shape))
        for i in range(50):
            print (op.T * ((op * x) - b)).shape
            print "Gradient descent step %d" % i
            x += damp * -1 * (op.T * ((op * x) - b))
            # Could add prior: + lam * (x - x0.flat))

## L-BFGS-B
    elif method == 'L-BFGS-B':
        x, f, d = opt.fmin_l_bfgs_b(sr_func, x0.flat, fprime=sr_gradient)
        print "L-BFGS-B converged after %d function calls." % d['funcalls']
        print "Final function value:", f
        print "Reason for termination:", d['task']

    elif method == 'direct':
        x = sparse.linalg.spsolve(op, b)

    else:
        raise ValueError('Invalid method (%s) specified.' % method)

    return x.reshape(oshape)
Beispiel #7
0
def yaw_solve(yaw_image, yaw, scale,
          tol=1e-10, iter_lim=None, damp=1e-1,
          method='CG', norm=2):
    """Super-resolve a nonzero yaw image by solving
    a large, sparse set of linear equations.

    This method approximates the camera with a downsampling operator,
    using polygon interpolation.  The LSQR method is used
    to solve the equation :math:`A\mathbf{x} = b` where :math:`A` is
    the downsampling operator, :math:`\mathbf{x}` is the
    high-resolution estimate (flattened in raster scan/
    lexicographic order), and :math:`\mathbf{b}` is a vector
    of all the yaw_image pixels.

    Parameters
    ----------
    yaw_image : ndarray
        Nonzero yaw input frame.
    tf_matrix : (3, 3) ndarray
        Transformation matrix that relates all yaw_image pixels 
        to a reference high-resolution frame.
    scale : float
        The resolution of the output image is `scale` times the resolution
        of the input images.
    damp : float, optional
        If an initial guess is provided, `damp` specifies how much that
        estimate is weighed in the entire process.  A larger value of
        `damp` results in a solution closer to `x0`, whereas a smaller
        version of `damp` yields a solution closer to the solution
        obtained without any initial estimate.
    method : {'CG', 'LSQR', 'descent', 'L-BFGS-B'}
        Whether to use conjugate gradients, least-squares, gradient descent
        or L-BFGS-B to determine the solution.
    norm : {1, 2}
        Whether to use the L1 or L2 norm to measure errors between images.

    Returns
    -------
    HR : ndarray
        High-resolution estimate.

    """

    ishape = yaw_image.shape
    oshape = yaw_image.shape

    print "Constructing camera operator..."
    op = poly_interp_op_yaw(oshape[0], oshape[1], ishape[0], ishape[1], yaw, scale, search_win=round(scale) * 2 + 1)

    #dop = op.todense()
    #dsDebug = gdal.GetDriverByName("GTIFF").Create('/tmp/debug.tif', opd.shape[1], opd.shape[0], 1, gdal.GDT_Float32)
    #dsDebug.GetRasterBand(1).WriteArray(opd)
    #dsDebug.FlushCache()

    M = np.prod(ishape)
    b = yaw_image.flat

    atol = btol = conlim = tol
    show = True
    
    # Construct the prior
    opT = op.T
    opT_sum1 = opT.sum(axis=1).flatten() + 0.00001 # add small bias to avoid division by zero
    opTb = opT.dot(b)
    x0 = opTb / opT_sum1 
    #return x0.reshape(oshape)

    # Error and gradient functions, used in conjugate gradient optimisation
    def sr_func(x, norm=norm):
        return (np.linalg.norm(op * x - b, norm) ** 2 + \
                damp * np.linalg.norm(x - x0.flat, norm) ** 2)

    def sr_gradient(x, norm=norm):
        # Careful! Mixture of sparse and dense operators.
        #Axb = op * x - b
        #nrm_sq = np.dot(Axb, Axb) # Dense
        #Axbop = (op.T * Axb).T # Sparse
        #return nrm_sq * Axbop
        Axb = op * x - b
        L = len(x)
        if norm == 1:
            xmx0 = x - x0.flat
            term1 = np.linalg.norm(Axb, 1) * np.sign(Axb.T) * op
            term2 = damp * np.linalg.norm(xmx0, 1) * np.sign(xmx0.flat)
        elif norm == 2:
            term1 = (Axb.T * op)
            term2 = damp * (x - x0.flat)
        else:
            raise ValueError('Invalid norm for error measure (%s).' % norm)

        return 2 * (term1 + term2)

    print "Super resolving..."

## Conjugate Gradient Optimisation
    if method == 'CG':

        x, fopt, f_calls, gcalls, warnflag = \
           opt.fmin_cg(sr_func, x0, fprime=sr_gradient, gtol=0,
                       disp=True, maxiter=iter_lim, full_output=True)

    elif method == 'LSQR':

## LSQR Optimisation
##
        x0 = x0.flat
        b = b - op * x0
        x, istop, itn, r1norm, r2norm, anorm, acond, arnorm, xnorm, var = \
          lsqr(op, b, atol=atol, btol=btol,
               conlim=conlim, damp=damp, show=show, iter_lim=iter_lim)
        x = x0 + x

    elif method == 'descent':

## Steepest Descent Optimisation
##
        x = np.array(x0, copy=True).reshape(np.prod(x0.shape))
        for i in range(50):
            print (op.T * ((op * x) - b)).shape
            print "Gradient descent step %d" % i
            x += damp * -1 * (op.T * ((op * x) - b))
            # Could add prior: + lam * (x - x0.flat))

## L-BFGS-B
    elif method == 'L-BFGS-B':
        x, f, d = opt.fmin_l_bfgs_b(sr_func, x0.flat, fprime=sr_gradient)
        print "L-BFGS-B converged after %d function calls." % d['funcalls']
        print "Final function value:", f
        print "Reason for termination:", d['task']

    elif method == 'direct':
        x = sparse.linalg.spsolve(op, b)

    else:
        raise ValueError('Invalid method (%s) specified.' % method)

    return x.reshape(oshape), x0.reshape(oshape)
Beispiel #8
0
def yaw_solve(yaw_image,
              yaw,
              scale,
              tol=1e-10,
              iter_lim=None,
              damp=1e-1,
              method='CG',
              norm=2):
    """Super-resolve a nonzero yaw image by solving
    a large, sparse set of linear equations.

    This method approximates the camera with a downsampling operator,
    using polygon interpolation.  The LSQR method is used
    to solve the equation :math:`A\mathbf{x} = b` where :math:`A` is
    the downsampling operator, :math:`\mathbf{x}` is the
    high-resolution estimate (flattened in raster scan/
    lexicographic order), and :math:`\mathbf{b}` is a vector
    of all the yaw_image pixels.

    Parameters
    ----------
    yaw_image : ndarray
        Nonzero yaw input frame.
    tf_matrix : (3, 3) ndarray
        Transformation matrix that relates all yaw_image pixels 
        to a reference high-resolution frame.
    scale : float
        The resolution of the output image is `scale` times the resolution
        of the input images.
    damp : float, optional
        If an initial guess is provided, `damp` specifies how much that
        estimate is weighed in the entire process.  A larger value of
        `damp` results in a solution closer to `x0`, whereas a smaller
        version of `damp` yields a solution closer to the solution
        obtained without any initial estimate.
    method : {'CG', 'LSQR', 'descent', 'L-BFGS-B'}
        Whether to use conjugate gradients, least-squares, gradient descent
        or L-BFGS-B to determine the solution.
    norm : {1, 2}
        Whether to use the L1 or L2 norm to measure errors between images.

    Returns
    -------
    HR : ndarray
        High-resolution estimate.

    """

    ishape = yaw_image.shape
    oshape = yaw_image.shape

    print "Constructing camera operator..."
    op = poly_interp_op_yaw(oshape[0],
                            oshape[1],
                            ishape[0],
                            ishape[1],
                            yaw,
                            scale,
                            search_win=round(scale) * 2 + 1)

    #dop = op.todense()
    #dsDebug = gdal.GetDriverByName("GTIFF").Create('/tmp/debug.tif', opd.shape[1], opd.shape[0], 1, gdal.GDT_Float32)
    #dsDebug.GetRasterBand(1).WriteArray(opd)
    #dsDebug.FlushCache()

    M = np.prod(ishape)
    b = yaw_image.flat

    atol = btol = conlim = tol
    show = True

    # Construct the prior
    opT = op.T
    opT_sum1 = opT.sum(
        axis=1).flatten() + 0.00001  # add small bias to avoid division by zero
    opTb = opT.dot(b)
    x0 = opTb / opT_sum1

    #return x0.reshape(oshape)

    # Error and gradient functions, used in conjugate gradient optimisation
    def sr_func(x, norm=norm):
        return (np.linalg.norm(op * x - b, norm) ** 2 + \
                damp * np.linalg.norm(x - x0.flat, norm) ** 2)

    def sr_gradient(x, norm=norm):
        # Careful! Mixture of sparse and dense operators.
        #Axb = op * x - b
        #nrm_sq = np.dot(Axb, Axb) # Dense
        #Axbop = (op.T * Axb).T # Sparse
        #return nrm_sq * Axbop
        Axb = op * x - b
        L = len(x)
        if norm == 1:
            xmx0 = x - x0.flat
            term1 = np.linalg.norm(Axb, 1) * np.sign(Axb.T) * op
            term2 = damp * np.linalg.norm(xmx0, 1) * np.sign(xmx0.flat)
        elif norm == 2:
            term1 = (Axb.T * op)
            term2 = damp * (x - x0.flat)
        else:
            raise ValueError('Invalid norm for error measure (%s).' % norm)

        return 2 * (term1 + term2)

    print "Super resolving..."

    ## Conjugate Gradient Optimisation
    if method == 'CG':

        x, fopt, f_calls, gcalls, warnflag = \
           opt.fmin_cg(sr_func, x0, fprime=sr_gradient, gtol=0,
                       disp=True, maxiter=iter_lim, full_output=True)

    elif method == 'LSQR':

        ## LSQR Optimisation
        ##
        x0 = x0.flat
        b = b - op * x0
        x, istop, itn, r1norm, r2norm, anorm, acond, arnorm, xnorm, var = \
          lsqr(op, b, atol=atol, btol=btol,
               conlim=conlim, damp=damp, show=show, iter_lim=iter_lim)
        x = x0 + x

    elif method == 'descent':

        ## Steepest Descent Optimisation
        ##
        x = np.array(x0, copy=True).reshape(np.prod(x0.shape))
        for i in range(50):
            print(op.T * ((op * x) - b)).shape
            print "Gradient descent step %d" % i
            x += damp * -1 * (op.T * ((op * x) - b))
            # Could add prior: + lam * (x - x0.flat))


## L-BFGS-B
    elif method == 'L-BFGS-B':
        x, f, d = opt.fmin_l_bfgs_b(sr_func, x0.flat, fprime=sr_gradient)
        print "L-BFGS-B converged after %d function calls." % d['funcalls']
        print "Final function value:", f
        print "Reason for termination:", d['task']

    elif method == 'direct':
        x = sparse.linalg.spsolve(op, b)

    else:
        raise ValueError('Invalid method (%s) specified.' % method)

    return x.reshape(oshape), x0.reshape(oshape)
Beispiel #9
0
def smooth(filtration, cocycle):
    from cvxopt import spmatrix, matrix
    from cvxopt.blas import copy
    from lsqr import lsqr

    coefficient = []
    coface_indices = []
    face_indices = []
    for i, s in enumerate(filtration):
        if s.dimension() > 2: continue

        c = 1
        for sb in s.boundary:
            j = filtration(sb)
            coefficient.append(c)
            coface_indices.append(i)
            face_indices.append(j)
            c *= -1

    # Cocycle can be larger than D; we implicitly project it down
    cocycle_max = max(zz[1] for zz in cocycle)

    # D is a coboundary matrix
    dimension = max(max(coface_indices), max(face_indices), cocycle_max) + 1

    D = spmatrix(coefficient, coface_indices, face_indices,
                 (dimension, dimension))
    z = spmatrix([zz[0] for zz in cocycle], [zz[1] for zz in cocycle],
                 [0 for zz in cocycle], (dimension, 1))

    v1 = D * z
    if bool(D * D):
        raise Exception('D^2 is not 0')
    if bool(v1):
        raise Exception('Expected a cocycle as input')
    z = matrix(z)

    def Dfun(x, y, trans='N'):
        if trans == 'N':
            copy(D * x, y)
        elif trans == 'T':
            copy(D.T * x, y)
        else:
            assert False, "Unexpected trans parameter"

    tol = 1e-10
    show = False
    maxit = None
    solution = lsqr(Dfun,
                    matrix(z),
                    show=False,
                    atol=tol,
                    btol=tol,
                    itnlim=maxit)

    z_smooth = z - D * solution[0]

    # print sum(z_smooth**2)
    # assert sum((D*z_smooth)**2) < tol and sum((D.T*z_smooth)**2) < tol, "Expected a harmonic cocycle"
    if not (sum((D * z_smooth)**2) < tol and sum((D.T * z_smooth)**2) < tol):
        raise Exception("Expected a harmonic cocycle: %f %f" % (sum(
            (D * z_smooth)**2), sum((D.T * z_smooth)**2)))

    values = []
    vertices = ((i, s) for (i, s) in enumerate(filtration)
                if s.dimension() == 0)
    for i, s in vertices:
        v = [v for v in s.vertices][0]
        if v >= len(values):
            values.extend((None for i in range(len(values), v + 1)))
        values[v] = solution[0][i]

    return values
Beispiel #10
0
def smooth(filtration, cocycle):
    from    cvxopt          import spmatrix, matrix
    from    cvxopt.blas     import copy
    from    lsqr            import lsqr

    coefficient = []
    coface_indices = []
    face_indices = []
    for i,s in enumerate(filtration):
        if s.dimension() > 2: continue

        c = 1
        for sb in s.boundary:
            j = filtration(sb)
            coefficient.append(c)
            coface_indices.append(i)
            face_indices.append(j)
            c *= -1

    # Cocycle can be larger than D; we implicitly project it down
    cocycle_max = max(zz[1] for zz in cocycle)

    # D is a coboundary matrix
    dimension = max(max(coface_indices), max(face_indices), cocycle_max) + 1
    D = spmatrix(coefficient, coface_indices, face_indices, (dimension, dimension))

    z = spmatrix([zz[0] for zz in cocycle],
                 [zz[1] for zz in cocycle],
                 [0     for zz in cocycle], (dimension, 1))

    v1 = D * z
    if bool(D*D):
        raise Exception('D^2 is not 0')
    if bool(v1):
        raise Exception('Expected a cocycle as input')
    z = matrix(z)

    def Dfun(x,y,trans = 'N'):
        if trans == 'N':
            copy(D * x, y)
        elif trans == 'T':
            copy(D.T * x, y)
        else:
            assert False, "Unexpected trans parameter"

    tol = 1e-10
    show = False
    maxit = None
    solution = lsqr(Dfun, matrix(z), show = show, atol = tol, btol = tol, itnlim = maxit)

    z_smooth = z - D*solution[0]

    # print sum(z_smooth**2)
    # assert sum((D*z_smooth)**2) < tol and sum((D.T*z_smooth)**2) < tol, "Expected a harmonic cocycle"
    if not (sum((D*z_smooth)**2) < tol and sum((D.T*z_smooth)**2) < tol):
        raise Exception("Expected a harmonic cocycle: %f %f" % (sum((D*z_smooth)**2), sum((D.T*z_smooth)**2)))

    values = []
    vertices = ((i,s) for (i,s) in enumerate(filtration) if s.dimension() == 0)
    for i,s in vertices:
        v = [v for v in s.vertices][0]
        if v >= len(values):
            values.extend((None for i in xrange(len(values), v+1)))
        values[v] = solution[0][i]

    return values