def points_to_basis_dists(self, points): assert is_mat(points) assert is_float(points) (N, D) = points.shape assert D == self.grid.get_dim() G = self.grid # Get indices cell_coords = G.points_to_cell_coords(points) # Get rel distances rel_dist = G.points_to_low_vertex_rel_distance(points, cell_coords) assert (N, D) == rel_dist.shape # Get the vertices vertices = self.grid.cell_coords_to_vertex_indices(cell_coords) assert (N, 2 ** D) == vertices.shape # Calculate multilinear interp weights from distances weights = np.empty((N, 2 ** D)) for (i, bin_vertex) in enumerate(itertools.product([0, 1], repeat=D)): vert_mask = np.array(bin_vertex, dtype=bool) weights[:, i] = np.product(rel_dist[:, vert_mask], axis=1) * np.product( 1.0 - rel_dist[:, ~vert_mask], axis=1 ) point_dist = self.convert_to_sparse_matrix(cell_coords, vertices, weights) return point_dist
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 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 convert_to_sparse_matrix(self, cell_coords, vertices, weights): assert isinstance(cell_coords, Coordinates) assert cell_coords.check() assert is_mat(vertices) assert is_int(vertices) assert is_mat(weights) assert is_float(weights) (N, D) = cell_coords.shape assert vertices.shape == weights.shape assert (N, 2 ** D) == vertices.shape assert D == self.dim oob_mask = cell_coords.oob.mask num_oob = cell_coords.oob.num_oob() num_normal = N - num_oob assert num_oob >= 0 assert num_normal >= 0 normal_idx = np.arange(N)[~oob_mask] oob_idx = np.arange(N)[oob_mask] m = num_normal * (2 ** D) # Space for normal points M = m + num_oob # Add on space for oob nodes cols = np.empty(M) rows = np.empty(M) data = np.empty(M) # Add normal weights cols[:m] = (np.tile(normal_idx, (2 ** D, 1)).T).flatten() rows[:m] = (vertices[~oob_mask, :]).flatten() data[:m] = (weights[~oob_mask, :]).flatten() # Route all oob points to oob node cols[m:] = oob_idx rows[m:] = vertices[oob_mask, 0] data[m:] = np.ones(num_oob) NN = self.grid.get_num_total_nodes() point_dist = sps.coo_matrix((data, (rows, cols)), shape=(NN, N)) point_dist = point_dist.tocsr() point_dist.eliminate_zeros() return point_dist
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 __init__(self,coords,oob): assert is_mat(coords) assert isinstance(oob,OutOfBounds) (N,D) = coords.shape assert oob.dim == D assert oob.num == N self.dim = D self.num = N self.shape = (N,D) self.coords = coords self.oob = oob
def cell_coords_to_low_points(self,cell_coords): assert isinstance(cell_coords,Coordinates) assert self.dim == cell_coords.dim assert cell_coords.check() C = cell_coords.coords oob = cell_coords.oob assert np.all(np.isnan(C[oob.mask,:])) low_points = row_vect(self.lower_bound) + C * row_vect(self.delta) assert is_mat(low_points) assert np.all(np.isnan(low_points[oob.mask,:])) assert cell_coords.shape == low_points.shape return low_points
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 points_to_low_vertex_rel_distance(self,points,cell_coords): assert is_mat(points) assert isinstance(cell_coords,Coordinates) (N,D) = points.shape assert (N,D) == cell_coords.shape low_vertex = self.cell_coords_to_low_points(cell_coords) dist = np.empty((N,D)) for d in xrange(D): dist[:,d] = (points[:,d] - low_vertex[:,d]) / self.delta[d] # OOB -> 0 distance from OOB node dist[cell_coords.oob.mask,:] = 0.0 assert np.all(dist >= 0.0) assert np.all(dist <= 1.0) return dist
def points_to_cell_coords(self,points): """ Figure out where points are. Returns the cell coordinate. """ assert is_mat(points) (N,D) = points.shape assert D == self.dim # Get the OOB info oob = OutOfBounds() oob.build_from_points(self,points) assert oob.check() raw_coords = np.empty((N,D)) for d in xrange(D): (low,high,num_cells) = self.grid_desc[d] # Transform: [low,high) |-> [0,n) transform = num_cells * (points[:,d] - low) / (high - low) transform += self.fuzz raw_coords[:,d] = np.floor(transform).astype(np.integer) # Add a little fuzz to make sure stuff on the boundary is # mapped correctly # Fuzz top boundary to get [low,high] fuzz_mask = np.logical_and(high <= points[:,d], points[:,d] < high + 2*self.fuzz) raw_coords[fuzz_mask,d] = num_cells - 1 # Counts things just a littttle bit greater than last cell # boundary as part of the last cell raw_coords[oob.mask,:] = np.nan assert is_int(raw_coords) coords = Coordinates(raw_coords,oob) assert coords.check() return coords