def test_d_one_triangle(self): #sorted test v,e = matrix([[0,0],[1,0],[0,1]]),matrix([[0,1,2]]) sc = simplicial_complex((v,e)) assert_equal(sc[0].d.shape,(3,3)) #d0 row = sc[1].simplex_to_index[simplex((0,1))] assert_equal(sc[0].d[row,0],-1) assert_equal(sc[0].d[row,1], 1) row = sc[1].simplex_to_index[simplex((1,2))] assert_equal(sc[0].d[row,1],-1) assert_equal(sc[0].d[row,2], 1) row = sc[1].simplex_to_index[simplex((0,2))] assert_equal(sc[0].d[row,0],-1) assert_equal(sc[0].d[row,2], 1) #d1 col = sc[1].simplex_to_index[simplex((0,1))] assert_equal(sc[1].d[0,col], 1) col = sc[1].simplex_to_index[simplex((0,2))] assert_equal(sc[1].d[0,col],-1) col = sc[1].simplex_to_index[simplex((1,2))] assert_equal(sc[1].d[0,col], 1) #reversed test v,e = matrix([[0,0],[1,0],[0,1]]),matrix([[0,2,1]]) sc = simplicial_complex((v,e)) assert_equal(sc[0].d.shape,(3,3)) #d0 row = sc[1].simplex_to_index[simplex((0,1))] assert_equal(sc[0].d[row,0],-1) assert_equal(sc[0].d[row,1], 1) row = sc[1].simplex_to_index[simplex((1,2))] assert_equal(sc[0].d[row,1],-1) assert_equal(sc[0].d[row,2], 1) row = sc[1].simplex_to_index[simplex((0,2))] assert_equal(sc[0].d[row,0],-1) assert_equal(sc[0].d[row,2], 1) #d1 col = sc[1].simplex_to_index[simplex((0,1))] assert_equal(sc[1].d[0,col],-1) col = sc[1].simplex_to_index[simplex((0,2))] assert_equal(sc[1].d[0,col], 1) col = sc[1].simplex_to_index[simplex((1,2))] assert_equal(sc[1].d[0,col],-1)
def test_d_in_1d(self): #sorted test v,e = matrix([[0],[1]]),matrix([[0,1]]) sc = simplicial_complex((v,e)) assert_equal(sc[0].d.shape,(1,2)) assert_equal(sc[0].d[0,0],-1) assert_equal(sc[0].d[0,1], 1) #reversed test v,e = matrix([[0],[1]]),matrix([[1,0]]) sc = simplicial_complex((v,e)) assert_equal(sc[0].d.shape,(1,2)) assert_equal(sc[0].d[0,0], 1) assert_equal(sc[0].d[0,1],-1)
def test_boundary(): """check boundary operators (assumes correct faces)""" for mesh in meshes.itervalues(): sc = simplicial_complex(mesh) assert_equal(sc[0].boundary.shape, (1, sc[0].simplices.shape[0])) assert_equal(sc[0].boundary.nnz, 0) for face_data, cell_data in zip(sc[:-1], sc[1:]): B = cell_data.boundary assert_equal(B.shape, (face_data.num_simplices, cell_data.num_simplices)) assert_equal(B.nnz, cell_data.num_simplices * (cell_data.dim + 1)) for row, parity in zip(cell_data.simplices, cell_data.simplex_parity): s = simplex(row) s_index = cell_data.simplex_to_index[s] for f in s.boundary(): f_index = face_data.simplex_to_index[f] assert_equal(B[f_index, s_index], (-1)**(f.parity ^ int(parity)))
def test_simple(self): V = array([[0,0],[1,0],[0,1]]) S = array([[0,1,2]]) sc = simplicial_complex((V,S)) rows,cols = massmatrix_rowcols(sc,0) assert_equal(rows,array([0,0,0,1,1,1,2,2,2])) assert_equal(cols,array([0,1,2,0,1,2,0,1,2])) rows,cols = massmatrix_rowcols(sc,1) edges = [simplex(x) for x in combinations(range(3),2)] edge0 = sc[1].simplex_to_index[edges[0]] edge1 = sc[1].simplex_to_index[edges[1]] edge2 = sc[1].simplex_to_index[edges[2]] assert_equal(rows,array([edge0,edge0,edge0,edge1,edge1,edge1,edge2,edge2,edge2])) assert_equal(cols,array([edge0,edge1,edge2,edge0,edge1,edge2,edge0,edge1,edge2])) rows,cols = massmatrix_rowcols(sc,2) assert_equal(rows,array([0])) assert_equal(cols,array([0]))
def test_simple(self): V = array([[0, 0], [1, 0], [0, 1]]) S = array([[0, 1, 2]]) sc = simplicial_complex((V, S)) rows, cols = massmatrix_rowcols(sc, 0) assert_equal(rows, array([0, 0, 0, 1, 1, 1, 2, 2, 2])) assert_equal(cols, array([0, 1, 2, 0, 1, 2, 0, 1, 2])) rows, cols = massmatrix_rowcols(sc, 1) edges = [simplex(x) for x in combinations(range(3), 2)] edge0 = sc[1].simplex_to_index[edges[0]] edge1 = sc[1].simplex_to_index[edges[1]] edge2 = sc[1].simplex_to_index[edges[2]] assert_equal( rows, array([ edge0, edge0, edge0, edge1, edge1, edge1, edge2, edge2, edge2 ])) assert_equal( cols, array([ edge0, edge1, edge2, edge0, edge1, edge2, edge0, edge1, edge2 ])) rows, cols = massmatrix_rowcols(sc, 2) assert_equal(rows, array([0])) assert_equal(cols, array([0]))
def test_exactness(): for mesh in meshes.itervalues(): sc = simplicial_complex(mesh) cmplx = sc.chain_complex() for B1, B2 in zip(cmplx[:-1], cmplx[1:]): assert_equal((B1 * B2).nnz, 0)
def test_exactness(): for mesh in meshes.itervalues(): sc = simplicial_complex(mesh) cmplx = sc.chain_complex() for B1,B2 in zip(cmplx[:-1],cmplx[1:]): assert_equal((B1*B2).nnz,0)
def test_laplacian(self): """Check that Laplace-Beltrami and Laplace-DeRham agree for 0-forms This makes sure that d() and star() work in the -1 and N+1 cases """ for case in all_cases: sc = simplicial_complex(case) f = sc.get_cochain_basis(0) assert_equal((laplace_beltrami(f) - laplace_derham(f)).v.nnz, 0)
def test_dual_d(self): for case in all_cases: sc = simplicial_complex(case) N = sc.complex_dimension() for p in range(sc.complex_dimension()): df = d(sc.get_cochain_basis(p, is_primal=False)) assert_equal( (df.v - (-1)**p*sc[N-p].boundary).nnz, 0) # test exactness assert_equal(d(df).v.nnz,0)
def test_d(self): for case in all_cases: sc = simplicial_complex(case) N = sc.complex_dimension() for p in range(sc.complex_dimension()): df = d(sc.get_cochain_basis(p)) assert_equal( (df.v - sc[p].d).nnz, 0) # test exactness assert_equal(d(df).v.nnz,0)
def test_star(self): for case in all_cases: sc = simplicial_complex(case) N = sc.complex_dimension() for p in range(N): if not (sc[p].dual_volume > 0).all(): continue #skip non-wellcentered result = star(star(sc.get_cochain_basis(p))).v expected = (-1)**(p*(N - p)) * sparse.identity(sc[p].num_simplices) assert_almost_equal(result.todense(),expected.todense())
def test_faces(): """check whether faces are correct""" for mesh in meshes.itervalues(): sc = simplicial_complex(mesh) for face_data,cell_data in zip(sc[:-1],sc[1:]): #compute all faces and store in a set boundary_set = set() for row in cell_data.simplices: boundary_set.update(simplex(row).boundary()) face_set = set([simplex(row) for row in face_data.simplices]) assert_equal(boundary_set, face_set)
def test_faces(): """check whether faces are correct""" for mesh in meshes.itervalues(): sc = simplicial_complex(mesh) for face_data, cell_data in zip(sc[:-1], sc[1:]): #compute all faces and store in a set boundary_set = set() for row in cell_data.simplices: boundary_set.update(simplex(row).boundary()) face_set = set([simplex(row) for row in face_data.simplices]) assert_equal(boundary_set, face_set)
def test_all(self): for k,v,s,o,expected in self.cases: sc = simplicial_complex((v,s)) M = whitney_innerproduct(sc,k) M = M.todense() #Permute the matrix to coincide with the ordering of the known matrix permute = [sc[k].simplex_to_index[simplex(x)] for x in o] M = M[permute,:][:,permute] assert_almost_equal(M,expected) #check whether matrix is S.P.D. self.assert_(alltrue(isreal(eigvals(M)))) self.assert_(min(real(eigvals(M))) >= 0) assert_almost_equal(M,M.T)
def test_all(self): for k, v, s, o, expected in self.cases: sc = simplicial_complex((v, s)) M = whitney_innerproduct(sc, k) M = M.todense() #Permute the matrix to coincide with the ordering of the known matrix permute = [sc[k].simplex_to_index[simplex(x)] for x in o] M = M[permute, :][:, permute] assert_almost_equal(M, expected) #check whether matrix is S.P.D. self.assert_(alltrue(isreal(eigvals(M)))) self.assert_(min(real(eigvals(M))) >= 0) assert_almost_equal(M, M.T)
def test_three_edges(): V = array([[0],[1],[2],[3]]) S = array([[0,1],[1,2],[2,3]]) sc = simplicial_complex((V,S)) f0 = sc.get_cochain(0) assert_equal(f0.complex,sc) assert_equal(f0.k,0) assert_equal(f0.is_primal,True) assert_equal(f0.v,array([0,0,0,0])) f0.v[:] = 10 f1 = d(f0) assert_equal(f1.complex,sc) assert_equal(f1.k,1) assert_equal(f1.is_primal,True) assert_equal(f1.v,array([0,0,0]))
def test_get_set(): V = array([[0,0],[1,0],[0.5,sqrt(3.0)/2.0]]) S = array([[0,1,2]]) sc = simplicial_complex((V,S)) c0 = sc.get_cochain(0) assert_equal(c0[0],0) assert_equal(c0[0],0) assert_equal(c0[0],0) c0[simplex([0],parity=0)] = 10 c0[simplex([1],parity=0)] = 20 c0[simplex([2],parity=1)] = 30 assert_equal(c0[simplex([0],parity=0)],10) assert_equal(c0[simplex([1],parity=1)],-20) assert_equal(c0[simplex([2],parity=1)],30) assert_equal(c0[0],10) assert_equal(c0[1],20) assert_equal(c0[2],-30)
def test_boundary(): """check boundary operators (assumes correct faces)""" for mesh in meshes.itervalues(): sc = simplicial_complex(mesh) assert_equal(sc[0].boundary.shape,(1,sc[0].simplices.shape[0])) assert_equal(sc[0].boundary.nnz,0) for face_data,cell_data in zip(sc[:-1],sc[1:]): B = cell_data.boundary assert_equal(B.shape,(face_data.num_simplices,cell_data.num_simplices)) assert_equal(B.nnz,cell_data.num_simplices*(cell_data.dim+1)) for row,parity in zip(cell_data.simplices,cell_data.simplex_parity): s = simplex(row) s_index = cell_data.simplex_to_index[s] for f in s.boundary(): f_index = face_data.simplex_to_index[f] assert_equal(B[f_index,s_index],(-1)**(f.parity ^ int(parity)))
def test_d_two_triangles(self): v,e = matrix([[0,0],[1,0],[0,1],[1,1]]),matrix([[1,3,2],[2,0,1]]) sc = simplicial_complex((v,e)) assert_equal(sc[0].d.shape,(5,4)) assert_equal(sc[1].d.shape,(2,5)) #d0 edge01 = sc[1].simplex_to_index[simplex((0,1))] edge02 = sc[1].simplex_to_index[simplex((0,2))] edge12 = sc[1].simplex_to_index[simplex((1,2))] edge13 = sc[1].simplex_to_index[simplex((1,3))] edge23 = sc[1].simplex_to_index[simplex((2,3))] assert_equal(sc[0].d[edge01,0],-1) assert_equal(sc[0].d[edge01,1], 1) assert_equal(sc[0].d[edge02,0],-1) assert_equal(sc[0].d[edge02,2], 1) assert_equal(sc[0].d[edge12,1],-1) assert_equal(sc[0].d[edge12,2], 1) assert_equal(sc[0].d[edge13,1],-1) assert_equal(sc[0].d[edge13,3], 1) assert_equal(sc[0].d[edge23,2],-1) assert_equal(sc[0].d[edge23,3], 1) assert_equal(sc[1].d[1,edge01], 1) assert_equal(sc[1].d[1,edge12], 1) assert_equal(sc[1].d[1,edge02],-1) assert_equal(sc[1].d[0,edge23],-1) assert_equal(sc[1].d[0,edge12],-1) assert_equal(sc[1].d[0,edge13], 1)
def test_d_two_tets(self): """ Check d0,d1,d2 for a mesh with two tets """ v,e = matrix([[0,0,0],[1,0,0],[0,1,0],[0,0,1],[1,1,1]]),matrix([[0,1,2,3],[1,2,3,4]]) sc = simplicial_complex((v,e)) assert_equal(sc[0].d.shape,(9,5)) assert_equal(sc[1].d.shape,(7,9)) assert_equal(sc[2].d.shape,(2,7)) #d0 edge01 = sc[1].simplex_to_index[simplex((0,1))] edge02 = sc[1].simplex_to_index[simplex((0,2))] edge03 = sc[1].simplex_to_index[simplex((0,3))] edge12 = sc[1].simplex_to_index[simplex((1,2))] edge13 = sc[1].simplex_to_index[simplex((1,3))] edge23 = sc[1].simplex_to_index[simplex((2,3))] edge14 = sc[1].simplex_to_index[simplex((1,4))] edge24 = sc[1].simplex_to_index[simplex((2,4))] edge34 = sc[1].simplex_to_index[simplex((3,4))] assert_equal(sc[0].d[edge01,0],-1) assert_equal(sc[0].d[edge01,1], 1) assert_equal(sc[0].d[edge02,0],-1) assert_equal(sc[0].d[edge02,2], 1) assert_equal(sc[0].d[edge03,0],-1) assert_equal(sc[0].d[edge03,3], 1) assert_equal(sc[0].d[edge12,1],-1) assert_equal(sc[0].d[edge12,2], 1) assert_equal(sc[0].d[edge13,1],-1) assert_equal(sc[0].d[edge13,3], 1) assert_equal(sc[0].d[edge23,2],-1) assert_equal(sc[0].d[edge23,3], 1) assert_equal(sc[0].d[edge14,1],-1) assert_equal(sc[0].d[edge14,4], 1) assert_equal(sc[0].d[edge24,2],-1) assert_equal(sc[0].d[edge24,4], 1) assert_equal(sc[0].d[edge34,3],-1) assert_equal(sc[0].d[edge34,4], 1) face123 = sc[2].simplex_to_index[simplex((1,2,3))] face023 = sc[2].simplex_to_index[simplex((0,2,3))] face013 = sc[2].simplex_to_index[simplex((0,1,3))] face012 = sc[2].simplex_to_index[simplex((0,1,2))] face124 = sc[2].simplex_to_index[simplex((1,2,4))] face134 = sc[2].simplex_to_index[simplex((1,3,4))] face234 = sc[2].simplex_to_index[simplex((2,3,4))] #d1 assert_equal(sc[1].d[face012,edge12], 1) assert_equal(sc[1].d[face012,edge02],-1) assert_equal(sc[1].d[face012,edge01], 1) assert_equal(sc[1].d[face023,edge23], 1) assert_equal(sc[1].d[face023,edge03],-1) assert_equal(sc[1].d[face023,edge02], 1) assert_equal(sc[1].d[face013,edge13], 1) assert_equal(sc[1].d[face013,edge03],-1) assert_equal(sc[1].d[face013,edge01], 1) assert_equal(sc[1].d[face012,edge12], 1) assert_equal(sc[1].d[face012,edge02],-1) assert_equal(sc[1].d[face012,edge12], 1) assert_equal(sc[1].d[face124,edge24], 1) assert_equal(sc[1].d[face124,edge14],-1) assert_equal(sc[1].d[face124,edge12], 1) assert_equal(sc[1].d[face134,edge34], 1) assert_equal(sc[1].d[face134,edge14],-1) assert_equal(sc[1].d[face134,edge13], 1) assert_equal(sc[1].d[face234,edge34], 1) assert_equal(sc[1].d[face234,edge24],-1) assert_equal(sc[1].d[face234,edge23], 1) #d2 assert_equal(sc[2].d[0,face123], 1) assert_equal(sc[2].d[0,face023],-1) assert_equal(sc[2].d[0,face013], 1) assert_equal(sc[2].d[0,face012],-1) assert_equal(sc[2].d[1,face234], 1) assert_equal(sc[2].d[1,face134],-1) assert_equal(sc[2].d[1,face124], 1) assert_equal(sc[2].d[1,face123],-1)
def test_hodge_star(self): """Test the hodge * operator""" regular_cases = [] #Unit line segment regular_cases.append((matrix([[0],[1]]),matrix([[0,1]]),[1,1],[0.5,1])) #One regular triangle, edge length 1 regular_cases.append((matrix([[0,0],[1,0],[0.5,sqrt(3.0)/2.0]]),matrix([[0,1,2]]), [1, 1, sqrt(3.0)/4.0],\ [sqrt(3.0)/12.0,sqrt(3.0)/6.0,1])) # One regular tet, edge length sqrt(2) regular_cases.append((matrix([[0, 0, 0], [0, 1, 1], [1, 0, 1], [1, 1, 0]]),matrix([[0,1,2,3]]),\ [1, sqrt(2.0),sqrt(3.0/4.0), 1.0/3.0],[1.0/12.0,sqrt(2.0)/12.0,sqrt(3.0/36.0),1])) for v,e,primal,dual in regular_cases: sc = simplicial_complex((v,e)) for dim in range(sc.complex_dimension() + 1): (n,m) = sc[dim].star.shape for i in range(n): assert_almost_equal( sc[dim].star[i,i], dual[dim]/primal[dim] ) multi_cases = [] #two line segments multi_cases.append((matrix([[0],[1],[2]]),matrix([[0,1],[1,2]]), \ [([0],0.5),([1],1.0),([2],0.5),([0,1],1),([1,2],1)])) #three line segments multi_cases.append((matrix([[0],[1],[2],[3]]),matrix([[0,1],[1,2],[2,3]]), \ [([0],0.5),([1],1.0),([2],1),([3],0.5),([0,1],1),([1,2],1),([2,3],1)])) #two triangles multi_cases.append((matrix([[0,0],[1.0,0],[0.5,sqrt(3.0)/2.0],[1.5,sqrt(3.0)/2.0]]), \ matrix([[0,1,2],[1,3,2]]), \ [([0],sqrt(3.0)/12.0),([1],2*sqrt(3.0)/12.0),([2],2*sqrt(3.0)/12.0), ([3],sqrt(3.0)/12.0), \ ([0,1],sqrt(3.0)/6.0),([0,2],sqrt(3.0)/6.0),([1,2],2*sqrt(3.0)/6.0),([1,3],sqrt(3.0)/6.0), \ ([2,3],sqrt(3.0)/6.0),([0,1,2],4.0/sqrt(3.0)),([1,2,3],4.0/sqrt(3.0))])) #three triangles multi_cases.append((matrix([[0,0],[1.0,0],[0.5,sqrt(3.0)/2.0],[1.5,sqrt(3.0)/2.0],[2,0]]), \ matrix([[0,1,2],[1,3,2],[1,4,3]]), \ [([0],sqrt(3.0)/12.0),([1],3*sqrt(3.0)/12.0),([2],2*sqrt(3.0)/12.0), ([3],2*sqrt(3.0)/12.0), \ ([4],sqrt(3.0)/12.0),([0,1],sqrt(3.0)/6.0),([0,2],sqrt(3.0)/6.0),([1,2],2*sqrt(3.0)/6.0), ([1,3],2*sqrt(3.0)/6.0), ([1,4],sqrt(3.0)/6.0),([3,4],sqrt(3.0)/6.0),\ ([2,3],sqrt(3.0)/6.0),([0,1,2],4.0/sqrt(3.0)),([1,2,3],4.0/sqrt(3.0)),([1,4,3],4.0/sqrt(3.0))])) for v,e,t_list in multi_cases: sc = simplicial_complex((v,e)) for s,ratio in t_list: data = sc[len(s)-1] index = data.simplex_to_index[simplex(s)] assert_almost_equal(ratio,data.star[index,index]) #use the same multi_cases, but add dimensions and translate the vertices #TODO rotate also random.seed(0) for v,e,t_list in multi_cases: (rows,cols) = v.shape v = concatenate([v,zeros((rows,4))],1) v += rand(1,cols +4) #translate sc = simplicial_complex((v,e)) for s,ratio in t_list: data = sc[len(s)-1] index = data.simplex_to_index[simplex(s)] assert_almost_equal(ratio,data.star[index,index]) #Test sign of dual star, check that: ** = -1 ^(k (n-k)) for v,e,t_list in multi_cases: sc = simplicial_complex((v,e)) for dim,data in enumerate(sc): n = sc.complex_dimension() k = dim assert_almost_equal((data.star * data.star_inv).todense(), \ ((-1)**(k*(n-k))*sparse.identity(data.num_simplices)).todense())
def test_d_one_tet(self): v,e = matrix([[0,0,0],[1,0,0],[0,1,0],[0,0,1]]),matrix([[3,2,1,0]]) sc = simplicial_complex((v,e)) assert_equal(sc[0].d.shape,(6,4)) assert_equal(sc[1].d.shape,(4,6)) assert_equal(sc[2].d.shape,(1,4)) #d0 edge01 = sc[1].simplex_to_index[simplex((0,1))] edge02 = sc[1].simplex_to_index[simplex((0,2))] edge03 = sc[1].simplex_to_index[simplex((0,3))] edge12 = sc[1].simplex_to_index[simplex((1,2))] edge13 = sc[1].simplex_to_index[simplex((1,3))] edge23 = sc[1].simplex_to_index[simplex((2,3))] assert_equal(sc[0].d[edge01,0],-1) assert_equal(sc[0].d[edge01,1], 1) assert_equal(sc[0].d[edge02,0],-1) assert_equal(sc[0].d[edge02,2], 1) assert_equal(sc[0].d[edge03,0],-1) assert_equal(sc[0].d[edge03,3], 1) assert_equal(sc[0].d[edge12,1],-1) assert_equal(sc[0].d[edge12,2], 1) assert_equal(sc[0].d[edge13,1],-1) assert_equal(sc[0].d[edge13,3], 1) assert_equal(sc[0].d[edge23,2],-1) assert_equal(sc[0].d[edge23,3], 1) face123 = sc[2].simplex_to_index[simplex((1,2,3))] face023 = sc[2].simplex_to_index[simplex((0,2,3))] face013 = sc[2].simplex_to_index[simplex((0,1,3))] face012 = sc[2].simplex_to_index[simplex((0,1,2))] #d1 assert_equal(sc[1].d[face012,edge12], 1) assert_equal(sc[1].d[face012,edge02],-1) assert_equal(sc[1].d[face012,edge01], 1) assert_equal(sc[1].d[face023,edge23], 1) assert_equal(sc[1].d[face023,edge03],-1) assert_equal(sc[1].d[face023,edge02], 1) assert_equal(sc[1].d[face013,edge13], 1) assert_equal(sc[1].d[face013,edge03],-1) assert_equal(sc[1].d[face013,edge01], 1) assert_equal(sc[1].d[face012,edge12], 1) assert_equal(sc[1].d[face012,edge02],-1) assert_equal(sc[1].d[face012,edge12], 1) #d2 assert_equal(sc[2].d[0,face123], 1) assert_equal(sc[2].d[0,face023],-1) assert_equal(sc[2].d[0,face013], 1) assert_equal(sc[2].d[0,face012],-1)