examples/cohomology/cocycle.py
author Dmitriy Morozov <dmitriy@mrzv.org>
Mon Jul 25 23:21:29 2011 -0700 (10 months ago)
branchdev
changeset 244 66235db8d8b7
parent 1866d81d6ae7a3b
permissions -rwxr-xr-x
Added cohomology/candidates counter to i/t/cohomology-persistence.hpp
dmitriy@138
     1
#!/usr/bin/env python
dmitriy@138
     2
dmitriy@138
     3
from    cvxopt          import spmatrix, matrix
dmitriy@138
     4
from    cvxopt.blas     import copy
dmitriy@138
     5
from    lsqr            import lsqr
dmitriy@138
     6
from    sys             import argv, exit
dmitriy@138
     7
import  os.path
dmitriy@138
     8
dmitriy@186
     9
def smooth(boundary_list, cocycle_list):
dmitriy@138
    10
    dimension = max((max(d[1], d[2]) for d in boundary_list))
dmitriy@138
    11
    dimension += 1
dmitriy@138
    12
dmitriy@138
    13
    # NB: D is a coboundary matrix; 1 and 2 below are transposed
dmitriy@138
    14
    D = spmatrix([d[0] for d in boundary_list],
dmitriy@138
    15
                 [d[2] for d in boundary_list],
dmitriy@138
    16
                 [d[1] for d in boundary_list], (dimension, dimension))
dmitriy@138
    17
dmitriy@138
    18
           
dmitriy@138
    19
    z = spmatrix([zz[0] for zz in cocycle_list],
dmitriy@138
    20
                 [zz[1] for zz in cocycle_list],
dmitriy@138
    21
                 [0     for zz in cocycle_list], (dimension, 1))
dmitriy@138
    22
dmitriy@138
    23
    v1 = D * z
dmitriy@138
    24
    # print "D^2 is zero:", not bool(D*D)
dmitriy@138
    25
    # print "D*z is zero:", not bool(v1)
dmitriy@138
    26
    z = matrix(z)
dmitriy@138
    27
dmitriy@138
    28
    def Dfun(x,y,trans = 'N'):
dmitriy@138
    29
        if trans == 'N':
dmitriy@138
    30
            copy(D * x, y)
dmitriy@138
    31
        elif trans == 'T':
dmitriy@138
    32
            copy(D.T * x, y)
dmitriy@138
    33
        else:
dmitriy@138
    34
            assert False, "Unexpected trans parameter"
dmitriy@138
    35
dmitriy@138
    36
    tol = 1e-10
dmitriy@138
    37
    show = False
dmitriy@138
    38
    maxit = None
dmitriy@138
    39
    solution = lsqr(Dfun, matrix(z), show = show, atol = tol, btol = tol, itnlim = maxit)
dmitriy@138
    40
    
dmitriy@138
    41
    v = z - D*solution[0]
dmitriy@138
    42
dmitriy@138
    43
    # print sum(v**2)
dmitriy@138
    44
    # assert sum((D*v)**2) < tol and sum((D.T*v)**2) < tol, "Expected a harmonic cocycle"
dmitriy@138
    45
    if not (sum((D*v)**2) < tol and sum((D.T*v)**2) < tol):
dmitriy@138
    46
        print "Expected a harmonic cocycle:", sum((D*v)**2), sum((D.T*v)**2) 
dmitriy@138
    47
dmitriy@190
    48
    return solution[0], v
dmitriy@186
    49
dmitriy@186
    50
dmitriy@186
    51
def vertex_values(solution, vertices):
dmitriy@138
    52
    values = [None]*len(vertices)
dmitriy@165
    53
    for i,v in vertices:
dmitriy@186
    54
        values[v] = solution[i]
dmitriy@138
    55
    return values
dmitriy@186
    56
    
dmitriy@138
    57
dmitriy@146
    58
def read_list_file(filename):
dmitriy@146
    59
    list = []
dmitriy@146
    60
    with open(filename) as fp:
dmitriy@146
    61
        for line in fp.xreadlines():
dmitriy@146
    62
            if line.startswith('#'): continue
dmitriy@146
    63
            list.append(map(int, line.split()))
dmitriy@146
    64
    return list
dmitriy@146
    65
dmitriy@146
    66
dmitriy@138
    67
if __name__ == '__main__':
dmitriy@138
    68
    if len(argv) < 4:
dmitriy@138
    69
        print "Usage: %s BOUNDARY COCYCLE VERTEXMAP" % argv[0]
dmitriy@138
    70
        exit()
dmitriy@138
    71
dmitriy@138
    72
    boundary_filename = argv[1]
dmitriy@138
    73
    cocycle_filename = argv[2]
dmitriy@138
    74
    vertexmap_filename = argv[3]
dmitriy@146
    75
dmitriy@146
    76
    boundary_list = read_list_file(boundary_filename)
dmitriy@146
    77
    cocycle_list = read_list_file(cocycle_filename)
dmitriy@146
    78
    vertexmap_list = read_list_file(vertexmap_filename)
dmitriy@146
    79
dmitriy@190
    80
    solution, v = smooth(boundary_list, cocycle_list)
dmitriy@186
    81
    values = vertex_values(solution, vertexmap_list)
dmitriy@138
    82
dmitriy@138
    83
    outfn = os.path.splitext(cocycle_filename)[0] + '.val'
dmitriy@138
    84
    with open(outfn, 'w') as f:
dmitriy@138
    85
        for i,v in enumerate(values):
dmitriy@138
    86
            f.write('%d %f\n' % (i,v))