def calc_grad_theta(self, xmins, xmaxs, As_vectorized, BasMats, pts0, dt, nTimeSteps, nStepsOdeSolver, pts_at_T, grad_per_point, dim_domain, dim_range, nCs, incs): if dim_domain != dim_range: raise ValueError if pts_at_T is None: raise ValueError if len(incs) != dim_domain: raise ValueError(len(incs), dim_domain) if As_vectorized.ndim != 2: raise ValueError(As_vectorized.shape) if As_vectorized.shape[1] != (dim_domain + 1) * dim_domain: raise ValueError(As_vectorized.shape, (dim_domain + 1) * dim_domain) nPts = pts0.shape[0] if not isinstance(pts0, CpuGpuArray): raise TypeError if not isinstance(pts_at_T, CpuGpuArray): raise TypeError # number of threads per block has to be >= than number of cells # if self.nCells <= 128: # threadsPerBlock = 128 if self.nCells <= 256: threadsPerBlock = 256 # threadsPerBlock = 256/4 elif 256 < self.nCells <= 512: threadsPerBlock = 512 elif 512 < self.nCells <= 625: threadsPerBlock = 625 elif 512 < self.nCells <= 1024: threadsPerBlock = 1024 else: raise NotImplementedError nBlocks = int(np.ceil(float(nPts) / float(threadsPerBlock))) if 0: print '(nPts', nPts print 'nBlocks', nBlocks print 'threadsPerBlock = ', threadsPerBlock print d = len(BasMats) if not isinstance(grad_per_point, CpuGpuArray): raise TypeError if grad_per_point.shape != (nPts, dim_range, d): raise ValueError(grad_per_point.shape) if 1: nC0, nC1, nC2, inc_x, inc_y, inc_z = self.parse_nCs_and_incs( dim_domain, incs, nCs) if dim_domain == dim_range: calc_gpu = self.calc_grad_theta_gpu else: raise NotImplementedError if 0: ipshell('hi') 1 / 0 calc_gpu(pts0.gpu, pts_at_T.gpu, drv.In(As_vectorized), BasMats.gpu, grad_per_point.gpu, np.int32(d), self.my_dtype(dt), np.int32(nTimeSteps), np.int32(nStepsOdeSolver), np.int32(nPts), np.int32(nC0), np.int32(nC1), np.int32(nC2), np.float64(inc_x), np.float64(inc_y), np.float64(inc_z), grid=(nBlocks, 1, 1), block=(threadsPerBlock, 1, 1)) return grad_per_point
def calc_ll(self, theta): """ Computes the ll per measurments. """ cpa_space = self.cpa_space src = self.src signal = self.signal params_flow_int = self.params_flow_int transformed = self.transformed sigma_signal = self.sigma_signal ll = self.ll if src.shape[1] != cpa_space.dim_domain: raise ValueError(src.shape) cpa_space.theta2Avees(theta) cpa_space.update_pat() cpa_space.calc_T_inv(pts=src, out=transformed, **params_flow_int) if transformed.shape != src.shape: raise ValueError(transformed.shape, src.shape) if 0: # I think this is irrelevant here. # (it was relevant for the 1d case) scale_pts = src.shape[0] # Assuming we normalized src # to [0,1], # we need to scale it # t0 [0,1,..,num_of_samples+1] transformed.gpu *= scale_pts if self.interp_type_for_ll == 'gpu_linear': resampler(pts_gpu=transformed.gpu, img_gpu=signal.src.gpu, img_wrapped_gpu=signal.transformed.gpu) else: remap_fwd_opencv(pts_inv=transformed, img=signal.src, img_wrapped_fwd=signal.transformed, interp_method=self.interp_type_for_ll) # if signal.dst.shape[1]>1: # raise NotImplementedError("Only 1D signals for now") # plt.figure(17); # signal.transformed.gpu2cpu() # if not signal.transformed.cpu.any(): # raise ValueError('wtf') # plt.subplot(221) # plt.imshow(signal.src.cpu.reshape(256,-1)) # plt.subplot(222) # plt.imshow(signal.transformed.cpu.reshape(256,-1)) # # ipshell('hi') # 2/0 calc_signal_err_per_sample(signal.transformed.gpu, signal.dst.gpu, self.signal.err.gpu) # print np.allclose(signal.transformed.gpu.get()- # signal.dst.gpu.get(), # self.signal.err.gpu.get()) # if self.dim_signal != 1: # raise NotImplementedError calc_ll_per_sample(ll=ll.gpu, err=self.signal.err.gpu, sigma=sigma_signal) if 0: res = -0.5 / (sigma_signal**2) * ( (signal.transformed.gpu - signal.dst.gpu)**2).get() np.allclose(res.ravel(), ll.gpu.get()) ipshell('stop') 1 / 0 # 1/0 # ipshell('stop'); # if any(theta): # 1/0
def create_cont_constraint_mat_separable(H, v1s, v2s, nSides, nConstraints, nC, dim_domain, dim_range, tess): """ L is the matrix that encodes the constraints of the consistent subspace. Its null space space is the sought-after consistent subspace (unless additional constraints are added; e.g., sub-algerba or bdry conditions). """ if dim_domain != 2: raise ValueError if dim_range not in [1, 2]: raise ValueError nHomoCoo = dim_domain + 1 length_Avee = dim_range * nHomoCoo L1 = np.zeros((nConstraints / 2, nC * nHomoCoo)) nPtsInSide = 2 # Since, in 2D, the side is always a line joining 2 pts. # if nSides != nConstraints/(nPtsInSide*dim_domain): # raise ValueError(nSides,nConstraints) if nSides != nConstraints / (nPtsInSide * dim_range): print " print nSides , nConstraints/(nPtsInSide*dim_range):" print nSides, nConstraints / (nPtsInSide * dim_range) ipshell('stop') raise ValueError(nSides, (nConstraints, nPtsInSide, dim_range)) if nSides != H.shape[0]: raise ValueError(nSides, H.shape) # M = nPtsInSide*dim_range M = nPtsInSide if dim_range == 1: raise NotImplementedError for i in range(nSides): v1 = v1s[i] v2 = v2s[i] h = H[i] a, b = h.nonzero()[0] # idx for the relevant As # s stands for start # e stands for end s1 = a * length_Avee e1 = s1 + nHomoCoo s2 = b * length_Avee e2 = s2 + nHomoCoo # Constraint 1: L[i * M, s1:e1] = v1 L[i * M, s2:e2] = -v1 # Constraint 2: L[i * M + 1, s1:e1] = v2 L[i * M + 1, s2:e2] = -v2 elif dim_range == 2: for i in range(nSides): v1 = v1s[i] v2 = v2s[i] if np.allclose(v1, v2): raise ValueError(v1, v2) h = H[i] a, b = h.nonzero()[0] # idx for the relevant As # L1 is acting on columns of the following form: # [ a_1 b_1 c_1 d_1 a_2 b_2 c_2 d_2 ... a_Nc b_Nc c_Nc d_Nc] # s stands for start # e stands for end s1 = a * nHomoCoo e1 = s1 + nHomoCoo s2 = b * nHomoCoo e2 = s2 + nHomoCoo try: # Constraint 1: row = np.zeros(L1.shape[1]) row[s1:e1] = v1 row[s2:e2] = -v1 # x component L1[i * M] = row except: ipshell('fail') raise # Constraint 2: row = np.zeros(L1.shape[1]) row[s1:e1] = v2 row[s2:e2] = -v2 # x component L1[i * M + 1] = row else: raise ValueError(dim_range) return L1
def __init__(self,cpa_space,scale_spatial=1.0/10,scale_value=0.001*1, left_blk_rel_scale=None, right_vec_scale=None): # scale_spatial=0.0 if cpa_space.only_local: raise NotImplementedError('only_local=', cpa_space.only_local) self.scale_spatial = scale_spatial self.scale_value = scale_value if left_blk_rel_scale is None: raise ValueError("You need to pass this argument. 0.5 may be a good value") if right_vec_scale is None: raise ValueError("You need to pass this argument. 0.5 may be a good value") self.left_blk_rel_scale = left_blk_rel_scale self.right_vec_scale = right_vec_scale # Covariance on the joint Lie algebra self.pa_cov = create_joint_algebra_cov(cpa_space, scale_spatial=scale_spatial, scale_value=scale_value, # scale_value=1.0, %FOR DEBUGGING left_blk_rel_scale=left_blk_rel_scale, right_vec_scale=right_vec_scale) # Covariance on the subspace of that Lie algebra self.cpa_cov = self.pa_cov_to_cpa_cov(cpa_space,self.pa_cov) # # self.cpa_cov_debug = self.pa_cov_to_cpa_cov(cpa_space,self.pa_cov*(10**2)) # # C=self.cpa_cov # D=self.cpa_cov_debug # ipshell('hi') # 1/0 # computing inverse if 0: try: self.pa_cov_inv = inv(self.pa_cov) # ipshell("STOP") except: ipshell("Failed to invert") raise else: pass self.cpa_cov_inv = inv(self.cpa_cov) # if cpa_space.dim_domain==2: # if cpa_space.tess=='tri': # nV = len(cpa_space.local_stuff['vert_tess']) # if nV*2 != cpa_space.d: # raise ValueError( nV , cpa_space.d) # if cpa_space.local_stuff: A2v = cpa_space.local_stuff.linop_Avees2velTess B = cpa_space.B # H = A2v.matmat(B.dot(B.T)) H = A2v.matmat(B).dot(B.T) # self.velTess_cpa_cov = H.dot(self.pa_cov).dot(H.T) # self.velTess_cpa_cov_inv = inv(self.velTess_cpa_cov) self.velTess_cov_byB = H.dot(self.pa_cov).dot(H.T) try: self.velTess_cov_byB_inv = inv(self.velTess_cov_byB) except: # self.velTess_cov_byB=None self.velTess_cov_byB_inv=None if 0: self.velTess_cov = create_cov_velTess(cpa_space=cpa_space, scale_spatial=scale_spatial, scale_value = scale_value) self.velTess_cov_inv = inv( self.velTess_cov)
def create_verts_and_H_type_II(self,dim_range): """ This assummes 3D H encodes the n'bors info. """ if self.type != 'II': raise ValueError(self.type) dim_domain=self.dim_domain nC = self.nC cells_multiidx=self.cells_multiidx cells_verts=self.cells_verts_homo_coo # nCx=self.nCx # nCy=self.nCy # nCz=self.nCz if dim_domain !=3: raise ValueError(dim_domain) if dim_range != dim_domain: raise NotImplementedError(dim_range) # if dim_range not in (1,dim_domain): # raise NotImplementedError(dim_range) nbrs = np.zeros((nC,nC)) mi=cells_multiidx # shorter name for i in range(nC): for j in range(nC): if mi[i] == mi[j]: continue else: # pair = (np.abs(mi[i][0]-mi[j][0]), # np.abs(mi[i][1]-mi[j][1])) # if set(pair) == set([0,1]): # nbrs[i,j]=1 triplet = (np.abs(mi[i][0]-mi[j][0]), np.abs(mi[i][1]-mi[j][1]), np.abs(mi[i][2]-mi[j][2])) triplet=np.asarray(triplet) if (triplet==0).sum()==2 and (triplet==1).sum()==1: nbrs[i,j]=1 nSides=nbrs.sum().astype(np.int)/2 # H is larger than we need # but it was easier to code this way. # Later we eliminate the unused rows. H = np.zeros((nC**2,nC)) # H = sparse.lil_matrix((nC**2,nC)) for i in range(nC): for j in range(nC): # k is the index of the row in H. # Most rows won't be used. k = i*nC + j if i < j: continue nbr = nbrs[i,j] if nbr: H[k,i]=-1 H[k,j]=+1 verts1 = [] verts2 = [] verts3 = [] verts4 = [] counter = 0 for h in H: if h.any(): # if h.nnz: # Very annoying: I think there is a bug in the sparse matrix object. # Even after 'todense' it is impossible to flatten it properly. # h = np.asarray(h.todense().tolist()[0]) # Workaround. counter+=4 # Find the vertex pair i = (h==1).nonzero()[0][0] j = (h==-1).nonzero()[0][0] # a = mi[i] # b = mi[j] vi = cells_verts[i] vj = cells_verts[j] vi = self.make_it_hashable(vi) vj = self.make_it_hashable(vj) side = set(vi).intersection(vj) if len(side) != 4: # adjcant boxes share 4 verts ipshell('oops') raise ValueError(len(side),side) try: v1,v2,v3,v4 = np.asarray(list(side)) except: ipshell('hi') raise verts1.append(v1) verts2.append(v2) verts3.append(v3) verts4.append(v4) # if a != (1,1): # continue # print a, ' is a nbr of ',b if counter != nSides*4: raise ValueError(counter,nEdges) # Every side conntect 4 vertices. # At every vertex, all components of the velocity must agree. # nConstraints = nSides*4*dim_domain nConstraints = nSides*4*dim_range verts1 = np.asarray(verts1) verts2 = np.asarray(verts2) verts3 = np.asarray(verts3) verts4 = np.asarray(verts4) H = np.asarray([h for h in H if h.any()]) # H = np.asarray([h for h in H if h.nnz]) # # ipshell('hi') # 1/0 return verts1,verts2,verts3,verts4,H,nSides,nConstraints
def calc_ll(self, theta): """ Computes the ll per measurments. """ cpa_space = self.cpa_space src = self.src signal = self.signal params_flow_int = self.params_flow_int transformed = self.transformed sigma_signal = self.sigma_signal ll = self.ll if src.shape[1] != cpa_space.dim_domain: raise ValueError(src.shape) cpa_space.theta2Avees(theta) cpa_space.update_pat() cpa_space.calc_T_inv(pts=src, out=transformed, **params_flow_int) if transformed.shape != src.shape: raise ValueError(transformed.shape, src.shape) if 0: # I think this is irrelevant here. # (it was relevant for the 1d case) scale_pts = src.shape[0] # Assuming we normalized src # to [0,1], # we need to scale it # t0 [0,1,..,num_of_samples+1] transformed.gpu *= scale_pts if self.interp_type_for_ll == "gpu_linear": resampler(pts_gpu=transformed.gpu, img_gpu=signal.src.gpu, img_wrapped_gpu=signal.transformed.gpu) else: remap_fwd_opencv( pts_inv=transformed, img=signal.src, img_wrapped_fwd=signal.transformed, interp_method=self.interp_type_for_ll, ) # if signal.dst.shape[1]>1: # raise NotImplementedError("Only 1D signals for now") # plt.figure(17); # signal.transformed.gpu2cpu() # if not signal.transformed.cpu.any(): # raise ValueError('wtf') # plt.subplot(221) # plt.imshow(signal.src.cpu.reshape(256,-1)) # plt.subplot(222) # plt.imshow(signal.transformed.cpu.reshape(256,-1)) # # ipshell('hi') # 2/0 calc_signal_err_per_sample(signal.transformed.gpu, signal.dst.gpu, self.signal.err.gpu) # print np.allclose(signal.transformed.gpu.get()- # signal.dst.gpu.get(), # self.signal.err.gpu.get()) # if self.dim_signal != 1: # raise NotImplementedError calc_ll_per_sample(ll=ll.gpu, err=self.signal.err.gpu, sigma=sigma_signal) if 0: res = -0.5 / (sigma_signal ** 2) * ((signal.transformed.gpu - signal.dst.gpu) ** 2).get() np.allclose(res.ravel(), ll.gpu.get()) ipshell("stop") 1 / 0
def create_verts_and_H_type_I(self, dim_range, valid_outside): """ This assummes 2D H encodes the n'bors info. """ if self.type != 'I': raise ValueError(self.type) dim_domain = self.dim_domain nC = self.nC cells_multiidx = self.cells_multiidx cells_verts = self.cells_verts_homo_coo nCx = self.nCx nCy = self.nCy if dim_domain != 2: raise ValueError(dim_domain) if dim_range not in (1, 2): raise NotImplementedError(dim_range) nbrs = np.zeros((nC, nC), dtype=np.bool) if valid_outside: left = np.zeros((nC, nC), np.bool) right = np.zeros((nC, nC), np.bool) top = np.zeros((nC, nC), np.bool) bottom = np.zeros((nC, nC), np.bool) print 'Encoding continuity constraints.' print 'If nC is large, this may take some time.' print 'For a given configuration, however, this is done only once;' print 'the results computed here will be saved and reused the next time' print 'you use the same configuration.' # TODO: Cython # for i in range(nC): if nC > 200 and i % 200 == 0: print i, '/', nC for j in range(nC): # shorter names mi = cells_multiidx[i] mj = cells_multiidx[j] vi = cells_verts[i] vj = cells_verts[j] vi = self.make_it_hashable(vi) vj = self.make_it_hashable(vj) shared_verts = set(vi).intersection(vj) if len(mi) != 3: raise ValueError if len(mj) != 3: raise ValueError if mi == mj: # same cell, nothing to do here continue elif mi[:-1] == mj[:-1]: # Same rect boxs, different triangles s = set([mi[-1], mj[-1]]) if s in [ set([0, 1]), set([1, 2]), set([2, 3]), set([3, 0]) ]: nbrs[i, j] = 1 else: # different rect boxes if valid_outside: # try to deal with the extension if mi[0] == mj[0] == 0: # leftmost col if mi[2] == mj[2] == 3: # left triangle if np.abs(mi[1] - mj[1]) == 1: # adjacent rows nbrs[i, j] = 1 left[i, j] = True continue if mi[0] == mj[0] == nCx - 1: # rightmost col if mi[2] == mj[2] == 1: # right triangle if np.abs(mi[1] - mj[1]) == 1: # adjacent rows nbrs[i, j] = 1 right[i, j] = True continue if mi[1] == mj[1] == 0: # uppermost row if mi[2] == mj[2] == 0: # upper triangle if np.abs(mi[0] - mj[0]) == 1: # adjacent cols nbrs[i, j] = 1 top[i, j] = True continue if mi[1] == mj[1] == nCy - 1: # lowermost row if mi[2] == mj[2] == 2: # lower triangle if np.abs(mi[0] - mj[0]) == 1: # adjacent cols nbrs[i, j] = 1 bottom[i, j] = True continue if set([mi[2], mj[2]]) not in [set([0, 2]), set([1, 3])]: continue pair = (mi[0] - mj[0]), (mi[1] - mj[1]) # Recall the order of triangles is # 0 # 3 1 # 2 # vertical nbr's if pair == (0, 1) and (mi[2], mj[2]) == (0, 2): nbrs[i, j] = 1 elif pair == (0, -1) and (mi[2], mj[2]) == (2, 0): nbrs[i, j] = 1 # horizontal nbr's elif pair == (1, 0) and (mi[2], mj[2]) == (3, 1): nbrs[i, j] = 1 elif pair == (-1, 0) and (mi[2], mj[2]) == (1, 3): nbrs[i, j] = 1 print 'Creating H of size (nC**2,nC)=({},{})'.format(nC**2, nC) try: H = np.zeros((nC**2, nC)) except MemoryError: msg = 'Got MemoryError when trying to call np.zeros((nC**2,nC))' ipshell(msg) raise MemoryError('np.zeros((nC**2,nC))', 'nC={}'.format(nC)) # H = sparse.lil_matrix((nC**2,nC)) for i in range(nC): for j in range(nC): k = i * nC + j if i < j: continue nbr = nbrs[i, j] if nbr: H[k, i] = -1 H[k, j] = +1 # ipshell('save H') # 1/0 verts1 = [] verts2 = [] k = 0 print 'Extracting the vertices' for count, h in enumerate(H): if H.shape[0] > 1000: if count % 100000 == 0: print count, '/', H.shape[0] # ipshell('..') if h.any(): # if h.nnz: # ipshell('STOP') # # Make h dense and flat # h=np.asarray(h.todense()).ravel() i = (h == 1).nonzero()[0][0] j = (h == -1).nonzero()[0][0] mi = cells_multiidx[i] mj = cells_multiidx[j] vi = cells_verts[i] vj = cells_verts[j] vi = self.make_it_hashable(vi) vj = self.make_it_hashable(vj) shared_verts = set(vi).intersection(vj) if len(shared_verts) == 0: continue if len(shared_verts) == 1: # single vertex if any([left[i, j], right[i, j], top[i, j], bottom[i, j]]): # shared_vert is a set that contains a single tuple. v_aux = list(shared_verts)[0] # v_aux is a tuple v_aux = list( v_aux) # Now v_aux is a list (i.e. mutable) if left[i, j] or right[i, j]: v_aux[ 0] -= 10 # Create a new vertex with the same y elif top[i, j] or bottom[i, j]: v_aux[ 1] -= 10 # Create a new vertex with the same x else: raise ValueError("WTF?") v_aux = tuple(v_aux) shared_verts.add(v_aux) # add it to the set # ipshell('hello') # print shared_verts else: # We can skip it since the continuity at this vertex # will be imposed via the edges. continue if len(shared_verts) != 2: ipshell('oops') raise ValueError(len(shared_verts), shared_verts) try: v1, v2 = np.asarray(list(shared_verts)) except: ipshell('oops2') raise k += 2 verts1.append(v1) verts2.append(v2) # if a != (1,1): # continue # print a, ' is a nbr of ',b # nEdges=nbrs.sum().astype(np.int)/2 # if k != nEdges*2: # raise ValueError(k,nEdges) nEdges = k / 2 # Every edge connects 2 vertices. # At every vertex, all components of the velocity must agree. nConstraints = nEdges * 2 * dim_range verts1 = np.asarray(verts1) verts2 = np.asarray(verts2) H = np.asarray([h for h in H if h.any()]) # H = np.asarray([h for h in H if h.nnz]) print 'H is ready' return verts1, verts2, H, nEdges, nConstraints
def __init__(self, cpa_space, scale_spatial=1.0 / 10, scale_value=0.001 * 1, left_blk_rel_scale=None, right_vec_scale=None): # scale_spatial=0.0 if cpa_space.only_local: raise NotImplementedError('only_local=', cpa_space.only_local) self.scale_spatial = scale_spatial self.scale_value = scale_value if left_blk_rel_scale is None: raise ValueError( "You need to pass this argument. 0.5 may be a good value") if right_vec_scale is None: raise ValueError( "You need to pass this argument. 0.5 may be a good value") self.left_blk_rel_scale = left_blk_rel_scale self.right_vec_scale = right_vec_scale # Covariance on the joint Lie algebra self.pa_cov = create_joint_algebra_cov( cpa_space, scale_spatial=scale_spatial, scale_value=scale_value, # scale_value=1.0, %FOR DEBUGGING left_blk_rel_scale=left_blk_rel_scale, right_vec_scale=right_vec_scale) # Covariance on the subspace of that Lie algebra self.cpa_cov = self.pa_cov_to_cpa_cov(cpa_space, self.pa_cov) # # self.cpa_cov_debug = self.pa_cov_to_cpa_cov(cpa_space,self.pa_cov*(10**2)) # # C=self.cpa_cov # D=self.cpa_cov_debug # ipshell('hi') # 1/0 # computing inverse if 0: try: self.pa_cov_inv = inv(self.pa_cov) # ipshell("STOP") except: ipshell("Failed to invert") raise else: pass self.cpa_cov_inv = inv(self.cpa_cov) # if cpa_space.dim_domain==2: # if cpa_space.tess=='tri': # nV = len(cpa_space.local_stuff['vert_tess']) # if nV*2 != cpa_space.d: # raise ValueError( nV , cpa_space.d) # if cpa_space.local_stuff: A2v = cpa_space.local_stuff.linop_Avees2velTess B = cpa_space.B # H = A2v.matmat(B.dot(B.T)) H = A2v.matmat(B).dot(B.T) # self.velTess_cpa_cov = H.dot(self.pa_cov).dot(H.T) # self.velTess_cpa_cov_inv = inv(self.velTess_cpa_cov) self.velTess_cov_byB = H.dot(self.pa_cov).dot(H.T) try: self.velTess_cov_byB_inv = inv(self.velTess_cov_byB) except: # self.velTess_cov_byB=None self.velTess_cov_byB_inv = None if 0: self.velTess_cov = create_cov_velTess( cpa_space=cpa_space, scale_spatial=scale_spatial, scale_value=scale_value) self.velTess_cov_inv = inv(self.velTess_cov)
def create_cont_constraint_mat(N, H, verts, nSides, nConstraints, nC, dim_domain, dim_range, tess): """ L is the matrix that encodes the constraints of the consistent subspace. Its null space space is the sought-after consistent subspace (unless additional constraints are added; e.g., sub-algerba or bdry conditions). """ if dim_domain != N: raise ValueError if dim_range != N: raise NotImplementedError nHomoCoo = dim_domain + 1 # length_Avee = dim_domain*nHomoCoo length_Avee = dim_range * nHomoCoo L = np.zeros((nConstraints, nC * length_Avee)) # if tess == 'II': nPtsInSide = 2**(N - 1) else: raise ValueError # if nSides != nConstraints/(nPtsInSide*dim_domain): # raise ValueError(nSides,nConstraints) if nSides != nConstraints / (nPtsInSide * dim_range): print " print nSides , nConstraints/(nPtsInSide*dim_range):" print nSides, nConstraints / (nPtsInSide * dim_range) ipshell('stop') raise ValueError(nSides, (nConstraints, nPtsInSide, dim_range)) if nSides != H.shape[0]: raise ValueError(nSides, H.shape) M = nPtsInSide * dim_range verts = np.asarray(map(np.asarray, verts)) # verts.shape is (2**(N-1),nSides,N+1)) if verts.shape != (2**(N - 1), nSides, N + 1): raise ValueError(verts.shape) if dim_range == N: # loop over interfaces for i in range(nSides): verts_in_this_side = verts[:, i, :] h = H[i] a, b = h.nonzero()[0] # idx for the relevant As # s stands for start # e stands for end s1 = a * length_Avee e1 = s1 + nHomoCoo s2 = b * length_Avee e2 = s2 + nHomoCoo # loop over vertices in this inter-cell interface for j in range(nPtsInSide): row = np.zeros(L.shape[1]) row[s1:e1] = verts_in_this_side[j] row[s2:e2] = -verts_in_this_side[j] # loop over coordinates in this vertex for coo in range(N): L[i * M + j * N + coo] = np.roll(row, coo * nHomoCoo) else: raise ValueError(dim_range) return L
def create_cont_constraint_mat(H, v1s, v2s, v3s, v4s, nSides, nConstraints, nC, dim_domain, dim_range, tess): """ L is the matrix that encodes the constraints of the consistent subspace. Its null space space is the sought-after consistent subspace (unless additional constraints are added; e.g., sub-algerba or bdry conditions). """ if dim_domain != 3: raise ValueError if dim_range not in [1, 3]: raise ValueError nHomoCoo = dim_domain + 1 # length_Avee = dim_domain*nHomoCoo length_Avee = dim_range * nHomoCoo L = np.zeros((nConstraints, nC * length_Avee)) # if tess == 'II': nPtsInSide = 4 elif tess == 'I': nPtsInSide = 3 # if nSides != nConstraints/(nPtsInSide*dim_domain): # raise ValueError(nSides,nConstraints) if nSides != nConstraints / (nPtsInSide * dim_range): print " print nSides , nConstraints/(nPtsInSide*dim_range):" print nSides, nConstraints / (nPtsInSide * dim_range) ipshell('stop') raise ValueError(nSides, (nConstraints, nPtsInSide, dim_range)) if nSides != H.shape[0]: raise ValueError(nSides, H.shape) M = nPtsInSide * dim_range if dim_range == 1: for i in range(nSides): v1 = v1s[i] v2 = v2s[i] v3 = v3s[i] if tess == 'II': v4 = v4s[i] h = H[i] a, b = h.nonzero()[0] # idx for the relevant As # s stands for start # e stands for end s1 = a * length_Avee e1 = s1 + nHomoCoo s2 = b * length_Avee e2 = s2 + nHomoCoo # Constraint 1: L[i * M, s1:e1] = v1 L[i * M, s2:e2] = -v1 # Constraint 2: # x component L[i * M + 1, s1:e1] = v2 L[i * M + 1, s2:e2] = -v2 # Constraint 3: L[i * M + 2, s1:e1] = v3 L[i * M + 2, s2:e2] = -v3 if tess == 'II': # Constraint 4: L[i * M + 3, s1:e1] = v4 L[i * M + 3, s2:e2] = -v4 elif dim_range == 3: for i in range(nSides): v1 = v1s[i] v2 = v2s[i] v3 = v3s[i] if tess == 'II': v4 = v4s[i] if np.allclose(v1, v2): raise ValueError(v1, v2) if np.allclose(v1, v3): raise ValueError(v1, v3) if np.allclose(v2, v3): raise ValueError(v2, v3) if tess == 'II': if np.allclose(v1, v4): raise ValueError(v1, v4) if np.allclose(v2, v4): raise ValueError(v2, v4) if np.allclose(v3, v4): raise ValueError(v3, v4) h = H[i] a, b = h.nonzero()[0] # idx for the relevant As # s stands for start # e stands for end s1 = a * length_Avee e1 = s1 + nHomoCoo s2 = b * length_Avee e2 = s2 + nHomoCoo # Constraint 1: row = np.zeros(L.shape[1]) row[s1:e1] = v1 row[s2:e2] = -v1 # x component L[i * M] = row # y component L[i * M + 1] = np.roll(row, nHomoCoo) # z component L[i * M + 2] = np.roll(row, 2 * nHomoCoo) # Constraint 2: row = np.zeros(L.shape[1]) row[s1:e1] = v2 row[s2:e2] = -v2 # x component L[i * M + 3] = row # y component L[i * M + 4] = np.roll(row, nHomoCoo) # z component L[i * M + 5] = np.roll(row, nHomoCoo * 2) # Constraint 3: row = np.zeros(L.shape[1]) row[s1:e1] = v3 row[s2:e2] = -v3 # x component L[i * M + 6] = row # y component L[i * M + 7] = np.roll(row, nHomoCoo) # z component L[i * M + 8] = np.roll(row, 2 * nHomoCoo) # ipshell('qqq') # 1/0 if tess == 'II': # Constraint 4: row = np.zeros(L.shape[1]) row[s1:e1] = v4 row[s2:e2] = -v4 # x component L[i * M + 9] = row # y component L[i * M + 10] = np.roll(row, nHomoCoo) # z component L[i * M + 11] = np.roll(row, 2 * nHomoCoo) else: raise ValueError(dim_range) return L
def create_verts_and_H_type_II(self, # nC, cells_multiidx, cells_verts,dim_domain, dim_range): """ This assummes 2D H encodes the n'bors info. """ if self.type != 'II': raise ValueError(self.type) dim_domain=self.dim_domain nC = self.nC cells_multiidx=self.cells_multiidx cells_verts=self.cells_verts_homo_coo # nCx=self.nCx # nCy=self.nCy if dim_domain !=2: raise ValueError(dim_domain) if dim_range not in (1,dim_domain): raise NotImplementedError(dim_range) nbrs = np.zeros((nC,nC)) for i in range(nC): for j in range(nC): # shorter names mi = cells_multiidx[i] mj = cells_multiidx[j] if mi == mj: continue else: pair = (np.abs(mi[0]-mj[0]), np.abs(mi[1]-mj[1])) if set(pair) == set([0,1]): nbrs[i,j]=1 nEdges=nbrs.sum().astype(np.int)/2 H = np.zeros((nC**2,nC)) # H = sparse.lil_matrix((nC**2,nC)) for i in range(nC): for j in range(nC): k = i*nC + j if i < j: continue nbr = nbrs[i,j] if nbr: H[k,i]=-1 H[k,j]=+1 # ipshell('hi') # 1/0 verts1 = [] verts2 = [] k = 0 for h in H: # ipshell('..') if h.any(): # if h.nnz: # Very annoying: I think there is a bug in the sparse matrix object. # Even after 'todense' it is impossible to flatten it properly. # h = np.asarray(h.todense().tolist()[0]) # Workaround. k+=2 i = (h==1).nonzero()[0][0] j = (h==-1).nonzero()[0][0] # if set([i,j])==set([6,9]): # ipshell('debug') # 1/0 # a = mi # b = mj vi = cells_verts[i] vj = cells_verts[j] vi = self.make_it_hashable(vi) vj = self.make_it_hashable(vj) edge = set(vi).intersection(vj) if len(edge) != 2: ipshell('oops') raise ValueError(len(edge),edge) try: v1,v2 = np.asarray(list(edge)) except: ipshell('oops2') raise verts1.append(v1) verts2.append(v2) # if a != (1,1): # continue # print a, ' is a nbr of ',b if k != nEdges*2: raise ValueError(k,nEdges) # Every edge connects 2 vertices. # At every vertex, all components of the velocity must agree. #nConstraints = nEdges*2*dim_domain nConstraints = nEdges*2*dim_range verts1 = np.asarray(verts1) verts2 = np.asarray(verts2) H = np.asarray([h for h in H if h.any()]) # H = np.asarray([h for h in H if h.nnz]) # ipshell('hi') # 1/0 return verts1,verts2,H,nEdges,nConstraints
def create_verts_and_H_type_I(self,dim_range,valid_outside): """ This assummes 2D H encodes the n'bors info. """ if self.type != 'I': raise ValueError(self.type) dim_domain=self.dim_domain nC = self.nC cells_multiidx=self.cells_multiidx cells_verts=self.cells_verts_homo_coo nCx=self.nCx nCy=self.nCy if dim_domain !=2: raise ValueError(dim_domain) if dim_range not in (1,2): raise NotImplementedError(dim_range) nbrs = np.zeros((nC,nC),dtype=np.bool) if valid_outside: left=np.zeros((nC,nC),np.bool) right=np.zeros((nC,nC),np.bool) top=np.zeros((nC,nC),np.bool) bottom=np.zeros((nC,nC),np.bool) print 'Encoding continuity constraints.' print 'If nC is large, this may take some time.' print 'For a given configuration, however, this is done only once;' print 'the results computed here will be saved and reused the next time' print 'you use the same configuration.' # TODO: Cython # for i in range(nC): if nC > 200 and i % 200==0: print i,'/',nC for j in range(nC): # shorter names mi = cells_multiidx[i] mj = cells_multiidx[j] vi = cells_verts[i] vj = cells_verts[j] vi=self.make_it_hashable(vi) vj=self.make_it_hashable(vj) shared_verts = set(vi).intersection(vj) if len(mi)!=3: raise ValueError if len(mj)!=3: raise ValueError if mi == mj: # same cell, nothing to do here continue elif mi[:-1]==mj[:-1]: # Same rect boxs, different triangles s = set([mi[-1],mj[-1]]) if s in [set([0,1]),set([1,2]),set([2,3]),set([3,0])]: nbrs[i,j]=1 else: # different rect boxes if valid_outside: # try to deal with the extension if mi[0]==mj[0]==0: # leftmost col if mi[2]==mj[2]==3: # left triangle if np.abs(mi[1]-mj[1])==1: # adjacent rows nbrs[i,j]=1 left[i,j]=True continue if mi[0]==mj[0]==nCx-1: # rightmost col if mi[2]==mj[2]==1: # right triangle if np.abs(mi[1]-mj[1])==1: # adjacent rows nbrs[i,j]=1 right[i,j]=True continue if mi[1]==mj[1]==0: # uppermost row if mi[2]==mj[2]==0: # upper triangle if np.abs(mi[0]-mj[0])==1: # adjacent cols nbrs[i,j]=1 top[i,j]=True continue if mi[1]==mj[1]==nCy-1: # lowermost row if mi[2]==mj[2]==2: # lower triangle if np.abs(mi[0]-mj[0])==1: # adjacent cols nbrs[i,j]=1 bottom[i,j]=True continue if set([mi[2],mj[2]]) not in [set([0,2]),set([1,3])]: continue pair = (mi[0]-mj[0]),(mi[1]-mj[1]) # Recall the order of triangles is # 0 # 3 1 # 2 # vertical nbr's if pair == (0,1) and (mi[2],mj[2])==(0,2): nbrs[i,j]=1 elif pair == (0,-1) and (mi[2],mj[2])==(2,0): nbrs[i,j]=1 # horizontal nbr's elif pair == (1,0) and (mi[2],mj[2])==(3,1): nbrs[i,j]=1 elif pair == (-1,0) and (mi[2],mj[2])==(1,3): nbrs[i,j]=1 print 'Creating H of size (nC**2,nC)=({},{})'.format(nC**2,nC) try: H = np.zeros((nC**2,nC)) except MemoryError: msg='Got MemoryError when trying to call np.zeros((nC**2,nC))' ipshell(msg) raise MemoryError('np.zeros((nC**2,nC))','nC={}'.format(nC)) # H = sparse.lil_matrix((nC**2,nC)) for i in range(nC): for j in range(nC): k = i*nC + j if i < j: continue nbr = nbrs[i,j] if nbr: H[k,i]=-1 H[k,j]=+1 # ipshell('save H') # 1/0 verts1 = [] verts2 = [] k = 0 print 'Extracting the vertices' for count,h in enumerate(H): if H.shape[0]>1000: if count % 100000 == 0: print count,'/',H.shape[0] # ipshell('..') if h.any(): # if h.nnz: # ipshell('STOP') # # Make h dense and flat # h=np.asarray(h.todense()).ravel() i = (h==1).nonzero()[0][0] j = (h==-1).nonzero()[0][0] mi = cells_multiidx[i] mj = cells_multiidx[j] vi = cells_verts[i] vj = cells_verts[j] vi=self.make_it_hashable(vi) vj=self.make_it_hashable(vj) shared_verts = set(vi).intersection(vj) if len(shared_verts) ==0: continue if len(shared_verts) ==1: # single vertex if any([left[i,j],right[i,j],top[i,j],bottom[i,j]]): # shared_vert is a set that contains a single tuple. v_aux = list(shared_verts)[0] # v_aux is a tuple v_aux = list(v_aux) # Now v_aux is a list (i.e. mutable) if left[i,j] or right[i,j]: v_aux[0]-=10 # Create a new vertex with the same y elif top[i,j] or bottom[i,j]: v_aux[1]-=10 # Create a new vertex with the same x else: raise ValueError("WTF?") v_aux = tuple(v_aux) shared_verts.add(v_aux) # add it to the set # ipshell('hello') # print shared_verts else: # We can skip it since the continuity at this vertex # will be imposed via the edges. continue if len(shared_verts) != 2: ipshell('oops') raise ValueError(len(shared_verts),shared_verts) try: v1,v2 = np.asarray(list(shared_verts)) except: ipshell('oops2') raise k+=2 verts1.append(v1) verts2.append(v2) # if a != (1,1): # continue # print a, ' is a nbr of ',b # nEdges=nbrs.sum().astype(np.int)/2 # if k != nEdges*2: # raise ValueError(k,nEdges) nEdges = k/2 # Every edge connects 2 vertices. # At every vertex, all components of the velocity must agree. nConstraints = nEdges*2*dim_range verts1 = np.asarray(verts1) verts2 = np.asarray(verts2) H = np.asarray([h for h in H if h.any()]) # H = np.asarray([h for h in H if h.nnz]) print 'H is ready' return verts1,verts2,H,nEdges,nConstraints
def create_verts_and_H_type_II(self,dim_range): """ """ dim_domain = self.dim_domain nCs = self.nCs nC = self.nC cells_multiidx=self.cells_multiidx cells_verts=self.cells_verts_homo_coo N = len(nCs) if dim_domain !=N: raise ValueError(dim_domain) nbrs = np.zeros((nC,nC)) mi=cells_multiidx # shorter name for i in range(nC): for j in range(nC): if mi[i] == mi[j]: continue else: t = np.abs(np.asarray(mi[i])-np.asarray(mi[j])) if (t==0).sum()==N-1 and (t==1).sum()==1: nbrs[i,j]=1 nSides=nbrs.sum().astype(np.int)/2 # H is larger than we need # but it was easier to code this way. # Later we eliminate the unused rows. H = np.zeros((nC**2,nC)) # H = sparse.lil_matrix((nC**2,nC)) for i in range(nC): for j in range(nC): # k is the index of the row in H. # Most rows won't be used. k = i*nC + j if i < j: continue nbr = nbrs[i,j] if nbr: H[k,i]=-1 H[k,j]=+1 # verts1 = [] # verts2 = [] # verts3 = [] # verts4 = [] verts = [[] for i in range(2**(N-1))] counter = 0 for h in H: if h.any(): # if h.nnz: # Very annoying: I think there is a bug in the sparse matrix object. # Even after 'todense' it is impossible to flatten it properly. # h = np.asarray(h.todense().tolist()[0]) # Workaround. # update: the sparsity issue was because I used arrays # while the sparse functions want matrices. counter+=2**(N-1) # Find the vertex pair i = (h==1).nonzero()[0][0] j = (h==-1).nonzero()[0][0] vi = cells_verts[i] vj = cells_verts[j] vi=self.make_it_hashable(vi) vj=self.make_it_hashable(vj) side = set(vi).intersection(vj) if len(side) != 2**(N-1): # adjcant boxes share 2**(N-1) verts ipshell('oops') raise ValueError(len(side),side) _verts = np.asarray(list(side)) # try: # # v1,v2,v3,v4 = np.asarray(list(side)) # except: # ipshell('hi') # raise # verts1.append(v1) # verts2.append(v2) # verts3.append(v3) # verts4.append(v4) for i in range(2**(N-1)): verts[i].append(_verts[i]) # if a != (1,1): # continue # print a, ' is a nbr of ',b if counter != nSides*2**(N-1): raise ValueError(counter,nSides) # Every side conntect 2**(N-1) vertices. # At every vertex, all components of the velocity must agree. ############## nConstraints = nSides*2**(N-1)*dim_domain nConstraints = nSides*2**(N-1)*dim_range # # verts1 = np.asarray(verts1) # verts2 = np.asarray(verts2) # verts3 = np.asarray(verts3) # verts4 = np.asarray(verts4) H = np.asarray([h for h in H if h.any()]) # H = np.asarray([h for h in H if h.nnz]) # return verts,H,nSides,nConstraints
def create_verts_and_H_type_I(self, dim_range, valid_outside): """ This assummes 2D H encodes the n'bors info. """ if self.type != 'I': raise ValueError(self.type) dim_domain = self.dim_domain nC = self.nC cells_multiidx = self.cells_multiidx cells_verts = self.cells_verts_homo_coo nCx = self.nCx nCy = self.nCy nCz = self.nCz if valid_outside: raise NotImplementedError('dim_domain =', dim_domain, 'valid_outside =', valid_outside) if dim_domain != 3: raise ValueError(dim_domain) nbrs = np.zeros((nC, nC)) mi = cells_multiidx # shorter name for i in range(nC): for j in range(nC): # shorter names mi = cells_multiidx[i] mj = cells_multiidx[j] # tetrahedron index within the box ti = mi[-1] tj = mj[-1] if len(mi) != 4: raise ValueError(len(mi)) if len(mj) != 4: raise ValueError(len(mj)) vi = cells_verts[i] vj = cells_verts[j] vi = self.make_it_hashable(vi) vj = self.make_it_hashable(vj) if mi == mj: continue elif mi[:-1] == mj[:-1]: # Same rect boxs, different tetrahedra if ti == 0 or tj == 0: if tj == ti: raise ValueError else: nbrs[i, j] = 1 else: # Different boxes if len(set(vi).intersection(vj)) == 3: nbrs[i, j] = 1 nSides = nbrs.sum().astype(np.int) / 2 # H is larger than we need # but it was easier to code this way. # Later we eliminate the unused rows. H = np.zeros((nC**2, nC)) # H = sparse.lil_matrix((nC**2,nC)) for i in range(nC): for j in range(nC): # k is the index of the row in H. # Most rows won't be used. k = i * nC + j if i < j: continue nbr = nbrs[i, j] if nbr: H[k, i] = -1 H[k, j] = +1 verts1 = [] verts2 = [] verts3 = [] verts4 = [] counter = 0 for h in H: if h.any(): # if h.nnz: # Very annoying: I think there is a bug in the sparse matrix object. # Even after 'todense' it is impossible to flatten it properly. # h = np.asarray(h.todense().tolist()[0]) # Workaround. # Find the vertex pair i = (h == 1).nonzero()[0][0] j = (h == -1).nonzero()[0][0] mi = cells_multiidx[i] # for debugging mj = cells_multiidx[j] # for debugging ti = mi[-1] tj = mj[-1] # a = mi # b = mj vi = cells_verts[i] vj = cells_verts[j] vi = self.make_it_hashable(vi) vj = self.make_it_hashable(vj) side = set(vi).intersection(vj) len_side = len(side) if len_side == 3: v1, v2, v3 = np.asarray(list(side)) v4 = None verts1.append(v1) verts2.append(v2) verts3.append(v3) verts4.append(v4) elif len_side == 2: if ti == 0 and tj == 0: # That's ok. Can ignore it: # these should be the two "Central" tetrahedra # of two adjacent cell. continue else: raise ValueError elif len_side == 1: continue # I thinkg this should be ok. # I don't have time now to check this happens only when # it should... TODO else: print('len(side) = ', len(side)) ipshell('wtf') raise ValueError(len(side), side) counter += len_side # if a != (1,1): # continue # print a, ' is a nbr of ',b # Every side connects 3 vertices. nPtsInSide = 3 if counter != nSides * nPtsInSide: ipshell('WTF') raise ValueError(counter, nSides) # At every vertex, all components of the velocity must agree. nConstraints = nSides * nPtsInSide * dim_range verts1 = np.asarray(verts1) verts2 = np.asarray(verts2) verts3 = np.asarray(verts3) verts4 = np.asarray(verts4) H = np.asarray([h for h in H if h.any()]) # H = np.asarray([h for h in H if h.nnz]) # # ipshell('hi') # 1/0 return verts1, verts2, verts3, verts4, H, nSides, nConstraints
def create_verts_and_H_type_II( self, # nC, cells_multiidx, cells_verts,dim_domain, dim_range): """ This assummes 2D H encodes the n'bors info. """ if self.type != 'II': raise ValueError(self.type) dim_domain = self.dim_domain nC = self.nC cells_multiidx = self.cells_multiidx cells_verts = self.cells_verts_homo_coo # nCx=self.nCx # nCy=self.nCy if dim_domain != 2: raise ValueError(dim_domain) if dim_range not in (1, dim_domain): raise NotImplementedError(dim_range) nbrs = np.zeros((nC, nC)) for i in range(nC): for j in range(nC): # shorter names mi = cells_multiidx[i] mj = cells_multiidx[j] if mi == mj: continue else: pair = (np.abs(mi[0] - mj[0]), np.abs(mi[1] - mj[1])) if set(pair) == set([0, 1]): nbrs[i, j] = 1 nEdges = nbrs.sum().astype(np.int) / 2 H = np.zeros((nC**2, nC)) # H = sparse.lil_matrix((nC**2,nC)) for i in range(nC): for j in range(nC): k = i * nC + j if i < j: continue nbr = nbrs[i, j] if nbr: H[k, i] = -1 H[k, j] = +1 # ipshell('hi') # 1/0 verts1 = [] verts2 = [] k = 0 for h in H: # ipshell('..') if h.any(): # if h.nnz: # Very annoying: I think there is a bug in the sparse matrix object. # Even after 'todense' it is impossible to flatten it properly. # h = np.asarray(h.todense().tolist()[0]) # Workaround. k += 2 i = (h == 1).nonzero()[0][0] j = (h == -1).nonzero()[0][0] # if set([i,j])==set([6,9]): # ipshell('debug') # 1/0 # a = mi # b = mj vi = cells_verts[i] vj = cells_verts[j] vi = self.make_it_hashable(vi) vj = self.make_it_hashable(vj) edge = set(vi).intersection(vj) if len(edge) != 2: ipshell('oops') raise ValueError(len(edge), edge) try: v1, v2 = np.asarray(list(edge)) except: ipshell('oops2') raise verts1.append(v1) verts2.append(v2) # if a != (1,1): # continue # print a, ' is a nbr of ',b if k != nEdges * 2: raise ValueError(k, nEdges) # Every edge connects 2 vertices. # At every vertex, all components of the velocity must agree. #nConstraints = nEdges*2*dim_domain nConstraints = nEdges * 2 * dim_range verts1 = np.asarray(verts1) verts2 = np.asarray(verts2) H = np.asarray([h for h in H if h.any()]) # H = np.asarray([h for h in H if h.nnz]) # ipshell('hi') # 1/0 return verts1, verts2, H, nEdges, nConstraints
def create_verts_and_H_type_II(self, dim_range): """ This assummes 3D H encodes the n'bors info. """ if self.type != 'II': raise ValueError(self.type) dim_domain = self.dim_domain nC = self.nC cells_multiidx = self.cells_multiidx cells_verts = self.cells_verts_homo_coo # nCx=self.nCx # nCy=self.nCy # nCz=self.nCz if dim_domain != 3: raise ValueError(dim_domain) if dim_range != dim_domain: raise NotImplementedError(dim_range) # if dim_range not in (1,dim_domain): # raise NotImplementedError(dim_range) nbrs = np.zeros((nC, nC)) mi = cells_multiidx # shorter name for i in range(nC): for j in range(nC): if mi[i] == mi[j]: continue else: # pair = (np.abs(mi[i][0]-mi[j][0]), # np.abs(mi[i][1]-mi[j][1])) # if set(pair) == set([0,1]): # nbrs[i,j]=1 triplet = (np.abs(mi[i][0] - mi[j][0]), np.abs(mi[i][1] - mi[j][1]), np.abs(mi[i][2] - mi[j][2])) triplet = np.asarray(triplet) if (triplet == 0).sum() == 2 and (triplet == 1).sum() == 1: nbrs[i, j] = 1 nSides = nbrs.sum().astype(np.int) / 2 # H is larger than we need # but it was easier to code this way. # Later we eliminate the unused rows. H = np.zeros((nC**2, nC)) # H = sparse.lil_matrix((nC**2,nC)) for i in range(nC): for j in range(nC): # k is the index of the row in H. # Most rows won't be used. k = i * nC + j if i < j: continue nbr = nbrs[i, j] if nbr: H[k, i] = -1 H[k, j] = +1 verts1 = [] verts2 = [] verts3 = [] verts4 = [] counter = 0 for h in H: if h.any(): # if h.nnz: # Very annoying: I think there is a bug in the sparse matrix object. # Even after 'todense' it is impossible to flatten it properly. # h = np.asarray(h.todense().tolist()[0]) # Workaround. counter += 4 # Find the vertex pair i = (h == 1).nonzero()[0][0] j = (h == -1).nonzero()[0][0] # a = mi[i] # b = mi[j] vi = cells_verts[i] vj = cells_verts[j] vi = self.make_it_hashable(vi) vj = self.make_it_hashable(vj) side = set(vi).intersection(vj) if len(side) != 4: # adjcant boxes share 4 verts ipshell('oops') raise ValueError(len(side), side) try: v1, v2, v3, v4 = np.asarray(list(side)) except: ipshell('hi') raise verts1.append(v1) verts2.append(v2) verts3.append(v3) verts4.append(v4) # if a != (1,1): # continue # print a, ' is a nbr of ',b if counter != nSides * 4: raise ValueError(counter, nEdges) # Every side conntect 4 vertices. # At every vertex, all components of the velocity must agree. # nConstraints = nSides*4*dim_domain nConstraints = nSides * 4 * dim_range verts1 = np.asarray(verts1) verts2 = np.asarray(verts2) verts3 = np.asarray(verts3) verts4 = np.asarray(verts4) H = np.asarray([h for h in H if h.any()]) # H = np.asarray([h for h in H if h.nnz]) # # ipshell('hi') # 1/0 return verts1, verts2, verts3, verts4, H, nSides, nConstraints
def create_cont_constraint_mat(H,v1s,v2s,v3s,v4s,nSides,nConstraints,nC, dim_domain,dim_range,tess): """ L is the matrix that encodes the constraints of the consistent subspace. Its null space space is the sought-after consistent subspace (unless additional constraints are added; e.g., sub-algerba or bdry conditions). """ if dim_domain != 3: raise ValueError if dim_range not in [1,3]: raise ValueError nHomoCoo=dim_domain+1 # length_Avee = dim_domain*nHomoCoo length_Avee = dim_range*nHomoCoo L = np.zeros((nConstraints,nC*length_Avee)) # if tess=='II': nPtsInSide = 4 elif tess=='I': nPtsInSide = 3 # if nSides != nConstraints/(nPtsInSide*dim_domain): # raise ValueError(nSides,nConstraints) if nSides != nConstraints/(nPtsInSide*dim_range): print " print nSides , nConstraints/(nPtsInSide*dim_range):" print nSides , nConstraints/(nPtsInSide*dim_range) ipshell('stop') raise ValueError( nSides , (nConstraints,nPtsInSide,dim_range)) if nSides != H.shape[0]: raise ValueError(nSides,H.shape) M = nPtsInSide*dim_range if dim_range == 1: for i in range(nSides): v1 = v1s[i] v2 = v2s[i] v3 = v3s[i] if tess=='II': v4 = v4s[i] h = H[i] a,b = h.nonzero()[0] # idx for the relevant As # s stands for start # e stands for end s1 = a*length_Avee e1 = s1+nHomoCoo s2 = b*length_Avee e2 = s2+nHomoCoo # Constraint 1: L[i*M,s1:e1]= v1 L[i*M,s2:e2]= -v1 # Constraint 2: # x component L[i*M+1,s1:e1]= v2 L[i*M+1,s2:e2]= -v2 # Constraint 3: L[i*M+2,s1:e1]= v3 L[i*M+2,s2:e2]= -v3 if tess=='II': # Constraint 4: L[i*M+3,s1:e1]= v4 L[i*M+3,s2:e2]= -v4 elif dim_range==3: for i in range(nSides): v1 = v1s[i] v2 = v2s[i] v3 = v3s[i] if tess=='II': v4 = v4s[i] if np.allclose(v1,v2): raise ValueError(v1,v2) if np.allclose(v1,v3): raise ValueError(v1,v3) if np.allclose(v2,v3): raise ValueError(v2,v3) if tess=='II': if np.allclose(v1,v4): raise ValueError(v1,v4) if np.allclose(v2,v4): raise ValueError(v2,v4) if np.allclose(v3,v4): raise ValueError(v3,v4) h = H[i] a,b = h.nonzero()[0] # idx for the relevant As # s stands for start # e stands for end s1 = a*length_Avee e1 = s1+nHomoCoo s2 = b*length_Avee e2 = s2+nHomoCoo # Constraint 1: row = np.zeros(L.shape[1]) row[s1:e1]=v1 row[s2:e2]=-v1 # x component L[i*M]=row # y component L[i*M+1]=np.roll(row,nHomoCoo) # z component L[i*M+2]=np.roll(row,2*nHomoCoo) # Constraint 2: row = np.zeros(L.shape[1]) row[s1:e1]=v2 row[s2:e2]=-v2 # x component L[i*M+3]=row # y component L[i*M+4]=np.roll(row,nHomoCoo) # z component L[i*M+5]=np.roll(row,nHomoCoo*2) # Constraint 3: row = np.zeros(L.shape[1]) row[s1:e1]=v3 row[s2:e2]=-v3 # x component L[i*M+6]=row # y component L[i*M+7]=np.roll(row,nHomoCoo) # z component L[i*M+8]=np.roll(row,2*nHomoCoo) # ipshell('qqq') # 1/0 if tess=='II': # Constraint 4: row = np.zeros(L.shape[1]) row[s1:e1]=v4 row[s2:e2]=-v4 # x component L[i*M+9]=row # y component L[i*M+10]=np.roll(row,nHomoCoo) # z component L[i*M+11]=np.roll(row,2*nHomoCoo) else: raise ValueError(dim_range) return L
def create_verts_and_H_type_I(self,dim_range,valid_outside): """ This assummes 2D H encodes the n'bors info. """ if self.type != 'I': raise ValueError(self.type) dim_domain=self.dim_domain nC = self.nC cells_multiidx=self.cells_multiidx cells_verts=self.cells_verts_homo_coo nCx=self.nCx nCy=self.nCy nCz=self.nCz if valid_outside: raise NotImplementedError('dim_domain =',dim_domain, 'valid_outside =',valid_outside) if dim_domain !=3: raise ValueError(dim_domain) nbrs = np.zeros((nC,nC)) mi=cells_multiidx # shorter name for i in range(nC): for j in range(nC): # shorter names mi = cells_multiidx[i] mj = cells_multiidx[j] # tetrahedron index within the box ti = mi[-1] tj = mj[-1] if len(mi)!=4: raise ValueError(len(mi)) if len(mj)!=4: raise ValueError(len(mj)) vi = cells_verts[i] vj = cells_verts[j] vi=self.make_it_hashable(vi) vj=self.make_it_hashable(vj) if mi == mj: continue elif mi[:-1]==mj[:-1]: # Same rect boxs, different tetrahedra if ti==0 or tj==0: if tj==ti: raise ValueError else: nbrs[i,j]=1 else: # Different boxes if len(set(vi).intersection(vj))==3: nbrs[i,j]=1 nSides=nbrs.sum().astype(np.int)/2 # H is larger than we need # but it was easier to code this way. # Later we eliminate the unused rows. H = np.zeros((nC**2,nC)) # H = sparse.lil_matrix((nC**2,nC)) for i in range(nC): for j in range(nC): # k is the index of the row in H. # Most rows won't be used. k = i*nC + j if i < j: continue nbr = nbrs[i,j] if nbr: H[k,i]=-1 H[k,j]=+1 verts1 = [] verts2 = [] verts3 = [] verts4 = [] counter = 0 for h in H: if h.any(): # if h.nnz: # Very annoying: I think there is a bug in the sparse matrix object. # Even after 'todense' it is impossible to flatten it properly. # h = np.asarray(h.todense().tolist()[0]) # Workaround. # Find the vertex pair i = (h==1).nonzero()[0][0] j = (h==-1).nonzero()[0][0] mi = cells_multiidx[i] # for debugging mj = cells_multiidx[j] # for debugging ti = mi[-1] tj = mj[-1] # a = mi # b = mj vi = cells_verts[i] vj = cells_verts[j] vi=self.make_it_hashable(vi) vj=self.make_it_hashable(vj) side = set(vi).intersection(vj) len_side = len(side) if len_side == 3: v1,v2,v3 = np.asarray(list(side)) v4=None verts1.append(v1) verts2.append(v2) verts3.append(v3) verts4.append(v4) elif len_side==2: if ti == 0 and tj == 0: # That's ok. Can ignore it: # these should be the two "Central" tetrahedra # of two adjacent cell. continue else: raise ValueError elif len_side == 1: continue # I thinkg this should be ok. # I don't have time now to check this happens only when # it should... TODO else: print ('len(side) = ',len(side)) ipshell('wtf') raise ValueError(len(side),side) counter+=len_side # if a != (1,1): # continue # print a, ' is a nbr of ',b # Every side connects 3 vertices. nPtsInSide = 3 if counter != nSides*nPtsInSide: ipshell('WTF') raise ValueError(counter,nSides) # At every vertex, all components of the velocity must agree. nConstraints = nSides*nPtsInSide*dim_range verts1 = np.asarray(verts1) verts2 = np.asarray(verts2) verts3 = np.asarray(verts3) verts4 = np.asarray(verts4) H = np.asarray([h for h in H if h.any()]) # H = np.asarray([h for h in H if h.nnz]) # # ipshell('hi') # 1/0 return verts1,verts2,verts3,verts4,H,nSides,nConstraints
def calc_grad_theta(self, xmins, xmaxs, As_vectorized, BasMats, pts0,dt,nTimeSteps, nStepsOdeSolver,pts_at_T, grad_per_point, dim_domain,dim_range, nCs, incs): if dim_domain != dim_range: raise ValueError if pts_at_T is None: raise ValueError if len(incs)!=dim_domain: raise ValueError(len(incs),dim_domain) if As_vectorized.ndim != 2: raise ValueError(As_vectorized.shape) if As_vectorized.shape[1]!= (dim_domain+1)*dim_domain: raise ValueError(As_vectorized.shape,(dim_domain+1)*dim_domain) nPts = pts0.shape[0] if not isinstance(pts0,CpuGpuArray): raise TypeError if not isinstance(pts_at_T,CpuGpuArray): raise TypeError # number of threads per block has to be >= than number of cells # if self.nCells <= 128: # threadsPerBlock = 128 if self.nCells <= 256: threadsPerBlock = 256 # threadsPerBlock = 256/4 elif 256<self.nCells<=512: threadsPerBlock = 512 elif 512<self.nCells<=625: threadsPerBlock=625 elif 512<self.nCells<=1024: threadsPerBlock = 1024 else: raise NotImplementedError nBlocks = int(np.ceil(float(nPts) / float(threadsPerBlock))) if 0: print '(nPts',nPts print 'nBlocks',nBlocks print 'threadsPerBlock = ',threadsPerBlock print d = len(BasMats) if not isinstance(grad_per_point,CpuGpuArray): raise TypeError if grad_per_point.shape != (nPts,dim_range,d): raise ValueError(grad_per_point.shape) if 1: nC0,nC1,nC2,inc_x,inc_y,inc_z = self.parse_nCs_and_incs(dim_domain,incs,nCs) if dim_domain == dim_range: calc_gpu=self.calc_grad_theta_gpu else: raise NotImplementedError if 0: ipshell('hi') 1/0 calc_gpu( pts0.gpu, pts_at_T.gpu, drv.In(As_vectorized), BasMats.gpu, grad_per_point.gpu, np.int32(d), self.my_dtype(dt), np.int32(nTimeSteps), np.int32(nStepsOdeSolver), np.int32(nPts), np.int32(nC0), np.int32(nC1), np.int32(nC2), np.float64(inc_x), np.float64(inc_y), np.float64(inc_z), grid=(nBlocks,1,1), block=(threadsPerBlock,1,1) ) return grad_per_point
def create_cont_constraint_mat_separable(H,v1s,v2s,v3s,v4s,nSides,nConstraints,nC, dim_domain,dim_range,tess): """ L is the matrix that encodes the constraints of the consistent subspace. Its null space space is the sought-after consistent subspace (unless additional constraints are added; e.g., sub-algerba or bdry conditions). """ if dim_domain != 3: raise ValueError if dim_range not in [1,3]: raise ValueError nHomoCoo=dim_domain+1 length_Avee = dim_range*nHomoCoo L1 = np.zeros((nConstraints/3,nC*nHomoCoo)) # if tess=='II': nPtsInSide = 4 elif tess=='I': nPtsInSide = 3 # if nSides != nConstraints/(nPtsInSide*dim_domain): # raise ValueError(nSides,nConstraints) if nSides != nConstraints/(nPtsInSide*dim_range): print " print nSides , nConstraints/(nPtsInSide*dim_range):" print nSides , nConstraints/(nPtsInSide*dim_range) ipshell('stop') raise ValueError( nSides , (nConstraints,nPtsInSide,dim_range)) if nSides != H.shape[0]: raise ValueError(nSides,H.shape) # M = nPtsInSide*dim_range M = nPtsInSide if dim_range == 1: raise NotImplementedError for i in range(nSides): v1 = v1s[i] v2 = v2s[i] v3 = v3s[i] if tess=='II': v4 = v4s[i] h = H[i] a,b = h.nonzero()[0] # idx for the relevant As # s stands for start # e stands for end s1 = a*length_Avee e1 = s1+nHomoCoo s2 = b*length_Avee e2 = s2+nHomoCoo # Constraint 1: L[i*M,s1:e1]= v1 L[i*M,s2:e2]= -v1 # Constraint 2: L[i*M+1,s1:e1]= v2 L[i*M+1,s2:e2]= -v2 # Constraint 3: L[i*M+2,s1:e1]= v3 L[i*M+2,s2:e2]= -v3 if tess=='II': # Constraint 4: L[i*M+3,s1:e1]= v4 L[i*M+3,s2:e2]= -v4 elif dim_range==3: for i in range(nSides): v1 = v1s[i] v2 = v2s[i] v3 = v3s[i] if tess=='II': v4 = v4s[i] if np.allclose(v1,v2): raise ValueError(v1,v2) if np.allclose(v1,v3): raise ValueError(v1,v3) if np.allclose(v2,v3): raise ValueError(v2,v3) if tess=='II': if np.allclose(v1,v4): raise ValueError(v1,v4) if np.allclose(v2,v4): raise ValueError(v2,v4) if np.allclose(v3,v4): raise ValueError(v3,v4) h = H[i] a,b = h.nonzero()[0] # idx for the relevant As # L1 is acting on columns of the following form: # [ a_1 b_1 c_1 d_1 a_2 b_2 c_2 d_2 ... a_Nc b_Nc c_Nc d_Nc] # s stands for start # e stands for end s1 = a*nHomoCoo e1 = s1+nHomoCoo s2 = b*nHomoCoo e2 = s2+nHomoCoo try: # Constraint 1: row = np.zeros(L1.shape[1]) row[s1:e1]=v1 row[s2:e2]=-v1 # x component L1[i*M]=row except: ipshell('fail') raise # Constraint 2: row = np.zeros(L1.shape[1]) row[s1:e1]=v2 row[s2:e2]=-v2 # x component L1[i*M+1]=row # Constraint 3: row = np.zeros(L1.shape[1]) row[s1:e1]=v3 row[s2:e2]=-v3 # x component L1[i*M+2]=row if tess=='II': # Constraint 4: row = np.zeros(L1.shape[1]) row[s1:e1]=v4 row[s2:e2]=-v4 # x component L1[i*M+3]=row else: raise ValueError(dim_range) return L1
def create_cont_constraint_mat(N,H,verts,nSides,nConstraints,nC, dim_domain,dim_range,tess): """ L is the matrix that encodes the constraints of the consistent subspace. Its null space space is the sought-after consistent subspace (unless additional constraints are added; e.g., sub-algerba or bdry conditions). """ if dim_domain != N: raise ValueError if dim_range != N: raise NotImplementedError nHomoCoo=dim_domain+1 # length_Avee = dim_domain*nHomoCoo length_Avee = dim_range*nHomoCoo L = np.zeros((nConstraints,nC*length_Avee)) # if tess=='II': nPtsInSide = 2**(N-1) else: raise ValueError # if nSides != nConstraints/(nPtsInSide*dim_domain): # raise ValueError(nSides,nConstraints) if nSides != nConstraints/(nPtsInSide*dim_range): print " print nSides , nConstraints/(nPtsInSide*dim_range):" print nSides , nConstraints/(nPtsInSide*dim_range) ipshell('stop') raise ValueError( nSides , (nConstraints,nPtsInSide,dim_range)) if nSides != H.shape[0]: raise ValueError(nSides,H.shape) M = nPtsInSide*dim_range verts = np.asarray(map(np.asarray,verts)) # verts.shape is (2**(N-1),nSides,N+1)) if verts.shape != (2**(N-1),nSides,N+1): raise ValueError(verts.shape) if dim_range==N: # loop over interfaces for i in range(nSides): verts_in_this_side = verts[:,i,:] h = H[i] a,b = h.nonzero()[0] # idx for the relevant As # s stands for start # e stands for end s1 = a*length_Avee e1 = s1+nHomoCoo s2 = b*length_Avee e2 = s2+nHomoCoo # loop over vertices in this inter-cell interface for j in range(nPtsInSide): row = np.zeros(L.shape[1]) row[s1:e1]=verts_in_this_side[j] row[s2:e2]=-verts_in_this_side[j] # loop over coordinates in this vertex for coo in range(N): L[i*M+j*N+coo]=np.roll(row,coo*nHomoCoo) else: raise ValueError(dim_range) return L