def slow_coord_to_index(target,lens): """ Slow but simple way of converting coords to indices Uses C-style indexing; this means the last coordinate changes most freqently. For an (P,Q,R) matrix: 0 0 0 -> 0 0 0 1 -> 1 0 0 2 -> 2 ... p q r -> r + R*q + (R*Q)*p """ assert is_vect(target) assert is_int(target) assert is_vect(lens) assert is_int(target) assert target.shape == lens.shape (D,) = lens.shape idx = 0 mult = 1 for d in xrange(D-1,-1,-1): idx += mult * target[d] mult *= lens[d] return idx
def even_slower_coord_to_index(target,lens): assert is_vect(target) assert is_int(target) assert is_vect(lens) assert is_int(target) assert target.shape == lens.shape N = np.prod(lens) C = np.reshape(np.arange(N),lens) # Should be row-major ordering idx = tuple(target.astype(np.integer)) return C[idx]
def indices_to_coords(self,indices): # Converts indices to coordinates assert is_vect(indices) assert is_int(indices) (N,) = indices.shape D = len(self.coef) # Does the hard work raw_coords = np.empty((N,D)) res = indices for d in xrange(D): (coord,res) = divmod(res,self.coef[d]) raw_coords[:,d] = coord # OOB indices mapped to NAN oob_mask = self.are_indices_oob(indices) raw_coords[oob_mask,:] = np.nan oob_indices = self.indices_to_oob_indices(indices,oob_mask) oob = OutOfBounds() oob.build_from_oob_indices(oob_indices,D) coords = Coordinates(raw_coords,oob) assert coords.check() return coords
def build_from_points(self,grid,points): assert is_mat(points) (N,D) = points.shape self.dim = D self.num = N self.shape = (N,D) low = grid.get_lower_boundary() high = grid.get_upper_boundary() # What boundary is violated; # -1 lower boundary, # +1 upper boundary U = sps.csc_matrix(points > high,dtype=np.integer) L = sps.csc_matrix(points < row_vect(low),dtype=np.integer) self.data = U - L # Mask of same self.mask = np.zeros(N,dtype=bool) oob_rows = self.data.nonzero()[0] self.mask[oob_rows] = True assert isinstance(self.mask,np.ndarray) assert (N,) == self.mask.shape # Sanity check assert np.all(self.mask == grid.are_points_oob(points)) # Pre-offset oob node or cell indices self.indices = self.find_oob_index() assert is_vect(self.indices) assert np.all(np.isnan(self.indices) == ~self.mask) assert self.check()
def indices_to_oob_indices(self,indices,oob_mask=None): assert is_vect(indices) assert is_int(indices) # Identify oob indices if oob_mask is None: oob_mask = self.are_indices_oob(indices) assert is_vect(oob_mask) assert oob_mask.shape == indices.shape # Subtract offset, so least oob index is 0 oob_indices = indices - self.get_num_spatial_nodes() # Nan-out any normal index location oob_indices[~oob_mask] = np.nan return oob_indices
def cell_indices_to_mid_points(self,cell_indices): assert is_vect(cell_indices) low_points = cell_indices_to_low_points(self,cell_indices) mid_points = low_points + row_vect(0.5 * self.delta) assert is_mat(mid_points) assert mid_points.shape[0] == cell_indices.shape[0] return mid_points
def cell_indices_to_vertex_indices(self,cell_indices): assert is_vect(cell_indices) cell_coords = self.cell_indexer.indices_to_coords(cell_indices) assert isinstance(cell_coords,Coordinates) vertex_indices = self.cell_coords_to_vertex_indices(cell_coords) assert is_mat(vertex_indices) # (N x 2**D) matrix return vertex_indices
def cell_indices_to_low_points(self,cell_indices): assert is_vect(cell_indices) cell_coords = self.cell_indexer.indices_to_coords(cell_indices) assert isinstance(cell_coords,Coordinates) assert cell_coords.check() low_points = self.cell_coords_to_low_points(cell_coords) assert is_mat(low_points) assert cell_coords.shape == low_points.shape return low_points
def points_to_cell_indices(self,points): assert is_mat(points) (N,D) = points.shape cell_coords = self.points_to_cell_coords(points) assert isinstance(cell_coords,Coordinates) assert (N,D) == cell_coords.shape cell_indices = self.cell_indexer.coords_to_indices(cell_coords) assert is_vect(cell_indices) assert (N,) == cell_indices.shape return cell_indices
def check(self): assert isinstance(self.data,sps.spmatrix) assert is_vect(self.mask) assert is_vect(self.indices) (N,D) = self.shape assert N == self.num assert D == self.dim assert (N,D) == self.data.shape assert (N,) == self.mask.shape assert (N,) == self.indices.shape nz_rows = np.unique(self.data.nonzero()[0]) assert np.all(self.mask[nz_rows]) assert np.all(np.isnan(self.indices) == ~self.mask) assert not np.any(np.isnan(self.indices[self.mask])) assert np.all(np.isnan(self.indices[~self.mask])) assert np.all(self.indices[self.mask] >= 0) assert np.all(self.indices[self.mask] < 2*D) return True
def node_indices_to_node_points(self,node_indices): assert is_vect(node_indices) (N,) = node_indices.shape node_coords = self.node_indexer.indices_to_coords(node_indices) assert isinstance(node_coords,Coordinates) oob = node_coords.oob C = node_coords.coords assert np.all(np.isnan(C[oob.mask,:])) node_points = row_vect(self.lower_bound) + C * row_vect(self.delta) assert is_mat(node_points) assert np.all(np.isnan(node_points[oob.mask,:])) assert node_coords.shape == node_points.shape return node_points
def build_from_oob_indices(self,indices,D): """ Indices should be np.nan if not oob. Max spatial index should be already subtracted off, so indices should be integers in [0,2*D). """ assert is_vect(indices) assert is_int(indices) # ignore nan oob_mask = ~np.isnan(indices) assert not np.any(indices[oob_mask] < 0) assert not np.any(indices[oob_mask] >= 2*D) (N,) = indices.shape self.dim = D self.num = N self.shape = (N,D) self.mask = oob_mask # Binary mask self.indices = np.empty(N) self.indices.fill(np.nan) self.indices[oob_mask] = indices[oob_mask] # Cache of the indices # Go through the non nan indices, unpack into data data = sps.lil_matrix((N,D),dtype=np.integer) for d in xrange(D): # Even indices mask = (self.indices == 2*d) data[mask,d] = -1 # Odd indices mask = (self.indices == 2*d+1) data[mask,d] = 1 self.data = data.tocsc() assert self.check()