def map(self, X): """ Maps X (configuration or trajectory) to reference structure by permuting identical particles """ X = ensure_traj(X) Y = X.copy() C = distance_matrix_squared(np.tile(self.xref[:, self.ip_indices], (X.shape[0], 1)), X[:, self.ip_indices]) for i in range(C.shape[0]): # for each configuration _, col_assignment = linear_sum_assignment(C[i]) assignment_components = [self.dim*col_assignment+i for i in range(self.dim)] col_assignment = np.vstack(assignment_components).T.flatten() Y[i, self.ip_indices] = X[i, self.ip_indices[col_assignment]] return Y
def is_permuted(self, X): """ Returns True for permuted configurations """ X = ensure_traj(X) C = distance_matrix_squared(np.tile(self.xref[:, self.ip_indices], (X.shape[0], 1)), X[:, self.ip_indices]) isP = np.zeros(X.shape[0], dtype=bool) for i in range(C.shape[0]): # for each configuration _, col_assignment = linear_sum_assignment(C[i]) assignment_components = [self.dim*col_assignment+i for i in range(self.dim)] col_assignment = np.vstack(assignment_components).T.flatten() if not np.all(col_assignment == np.arange(col_assignment.size)): isP[i] = True return isP
def _distance_squared_matrix(self, crd1, crd2): return distance_matrix_squared(crd1, crd2, dim=2)