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