def connectivity_to_weights(mknn: sparse.csr.csr_matrix, axis: int = 1) -> sparse.lil_matrix: """Convert a binary connectivity matrix to weights ready to be multiplied to smooth a data matrix """ if type(mknn) is not sparse.csr.csr_matrix: mknn = mknn.tocsr() return mknn.multiply(1. / sparse.csr_matrix.sum(mknn, axis=axis))
def sp_coo2torch_coo(M: sp.csr.csr_matrix) -> torch.sparse: """ :param M: :return: """ if isinstance(M, sp.csr_matrix): M = M.tocoo() M = torch.sparse.FloatTensor(torch.LongTensor(np.vstack((M.row, M.col))), torch.FloatTensor(M.data), torch.Size(M.shape)) return M
def calculate_field(od_mat: sp.csr.csr_matrix, grid_width: int, nb_trajecs: int = None) -> Tuple[np.array, np.array]: """Calculate the field at each location (origin) where it is non-zero. Parameters ---------- od_mat : csr_matrix The orgin-destination (OD) matrix to use as input. grid_width : int The width of the grid in the level. nb_trajecs : int or None, optional If provided, normalise the field by dividing by this number. Returns ------- Xs : np.array The coordinates of the non-zero entries of the field. Fs : np.array The entries of the field. """ i, j = od_mat.nonzero() r_origin = np.vstack((i % grid_width, i // grid_width)).T r_destination = np.vstack((j % grid_width, j // grid_width)).T u_vec = r_destination - r_origin u_vec = u_vec / np.linalg.norm(u_vec, axis=1)[:, np.newaxis] weighted_vec = u_vec * np.asarray(od_mat[i, j]).T # We sum the vectors grouped by origin using counts of unique elements _, idx_uniq, counts = np.unique(i, return_index=True, return_counts=True) c = np.cumsum(counts) # the end index of each group nb_locations = len(idx_uniq) Xs = r_origin[idx_uniq] # The position at which the field is non-zero Fs = np.zeros((nb_locations, 2)) # Pre-allocate memory for the field start = 0 for k, end in enumerate(c): Fs[k] += weighted_vec[start:end].sum(axis=0) start = end if nb_trajecs: Fs /= nb_trajecs return Xs, Fs
def reduce_matrix(square_mat: sp.csr.csr_matrix, return_index: bool = False) -> sp.csr.csr_matrix: """Remove all rows and columns that are simultaneously empty. Parameters ---------- square_mat : csr_matrix Input matrix. return_index : bool If True, also return the indices of `square_mat` that were kept. Returns ------- reduced_mat : sp.csr_matrix A square matrix that has the zero rows and columns removed. idx : np.array, optional The index of the rows and columns that were kept """ i, j = square_mat.nonzero() idx = sorted(set(i).union(set(j))) # sorted converts to list reduced_mat = square_mat[idx, :][:, idx] return (reduced_mat, idx) if return_index else reduced_mat
def make_mutual(knn: sparse.csr.csr_matrix) -> sparse.coo_matrix: """Removes edges between neighbours that are not mutual """ return knn.minimum(knn.T)