def get_weights(self, comm): rank = comm.Get_rank() size = comm.Get_size() # compute the distance matrix if needed if self.distance_matrix is None: logging.info("distance matrix not provided, computing it...") #idxs_thread = p_index.get_idxs_thread(comm, self.npoints) #npoints_thread = len(idxs_thread) #coords_thread = np.array([self.coords[idx] for idx in idxs_thread]) self.idxs_thread, self.npoints_per_thread, self.offsets_per_thread = p_index.get_idxs_thread( comm, self.npoints) npoints_thread = self.npoints_per_thread[rank] coords_thread = np.array( [self.coords[idx] for idx in self.idxs_thread]) DistanceMatrix = mt.DistanceMatrix(coords_thread, self.coords, metric=self.metric, metric_prms=self.metric_prms) self.distance_matrix = np.vstack( comm.allgather(DistanceMatrix.distance_matrix)) logging.info("distance matrix computed") else: if any(self.distance_matrix.shape[idx] != self.npoints for idx in [0, 1]): logging.error( "distance matrix provided doesn't match the number of coordinates" ) self.sigma = self.initialize_sigma_values(self.sigma, self.ksigma) # invert kernel matrix kernel_matrix = self.fit_function(self.distance_matrix, self.sigma) # perform singular valu decomposition U, s, V = np.linalg.svd(kernel_matrix) sinv = 1 / s # filter noisy singular values values sinv[s < 0.02 * np.max(s)] = 0 inverse_kernel_matrix = np.dot(np.dot(V.T, np.diag(sinv)), U.T) weights = np.dot(inverse_kernel_matrix, self.values) logging.info("kernel matrix inverted") return weights
def run(self): #initialize mpi variables comm = MPI.COMM_WORLD # MPI environment size = comm.Get_size() # number of threads rank = comm.Get_rank() # number of the current thread parser = self.create_arg_parser() args = parser.parse_args() # set argument parser config = ConfigParser.SafeConfigParser() config.read(args.config_file) # set config file parser logging.basicConfig(filename='lsdmap.log', filemode='w', format="%(levelname)s:%(name)s:%(asctime)s: %(message)s", datefmt="%H:%M:%S", level=logging.DEBUG) logging.info('intializing LSDMap with %d processors...' % size) self.initialize(comm, config, args) logging.info('LSDMap initialized') if size > self.npoints: logging.error("number of threads should be less than the number of frames") raise ValueError npoints_thread = self.npoints_per_thread[rank] coords_thread = np.array([self.coords[idx] for idx in self.idxs_thread]) weights_thread = np.array([self.weights[idx] for idx in self.idxs_thread]) if args.dminput is None: # compute the distance matrix DistanceMatrix = mt.DistanceMatrix(coords_thread, self.coords, metric=self.metric, metric_prms=self.metric_prms) distance_matrix_thread = DistanceMatrix.distance_matrix neighbor_matrix_thread, idx_neighbor_matrix_thread = DistanceMatrix.get_neighbor_matrix() logging.info("distance matrix computed") else: # load distance matrix distance_matrix_thread = self.load_distance_matrix(comm,args) neighbor_matrix_thread, idx_neighbor_matrix_thread = mt.get_neighbor_matrix(distance_matrix_thread) logging.info("distance matrix loaded") # compute kth neighbor local scales if needed if self.status_epsilon in ['kneighbor', 'kneighbor_mean']: #epsilon_thread = [] epsilon_threadv = np.zeros(npoints_thread,dtype='float') for idx, line in enumerate(idx_neighbor_matrix_thread): cum_weight = 0 for jdx in line[1:]: cum_weight += self.weights[jdx] if cum_weight >= self.k: break #epsilon_thread.append(distance_matrix_thread[idx,jdx]) epsilon_threadv[idx] = distance_matrix_thread[idx,jdx] self.epsilon = np.zeros(self.npoints, dtype='float') comm.Allgatherv(epsilon_threadv, (self.epsilon, self.npoints_per_thread, self.offsets_per_thread, MPI.DOUBLE)) if self.status_epsilon == 'kneighbor_mean': mean_value_epsilon = np.mean(self.epsilon) # compute the mean value of the local scales self.epsilon = mean_value_epsilon * np.ones(self.npoints) # and set it as the new constant local scale logging.info("kneighbor local scales computed") epsilon_thread = np.array([self.epsilon[idx] for idx in self.idxs_thread]) # compute kernel kernel = self.compute_kernel(comm, npoints_thread, distance_matrix_thread, weights_thread, epsilon_thread) # diagonalize kernel params= p_arpack._ParallelSymmetricArpackParams(comm, kernel, self.neigs) while not params.converged: params.iterate() eigs, evs = params.extract(return_eigenvectors=True) # normalize eigenvectors self.evsu = np.copy(evs) # store unormalized eigenvectors evs /= np.sqrt(self.d_vector[:,np.newaxis]) norm = np.sqrt(np.sum(evs**2, axis=0)) evs /= norm[np.newaxis,:] # store eigenvalues/eigenvectors self.eigs = eigs self.evs = evs logging.info("kernel diagonalized") if rank == 0: self.save(config, args) logging.info("Eigenvalues/eigenvectors saved (.eg/.ev files)") # store nearest neighbors in .nn file if specified via -n option if args.nnfile is not None: logging.info("Saving nearest neighbors") self.save_nneighbors(comm, args, neighbor_matrix, idx_neighbor_matrix, epsilon_thread) if (args.dmfile is not None) and (args.dminput is None): logging.info("Saving distance matrix") self.save_distance_matrix(comm, args, distance_matrix_thread) logging.info("LSDMap computation done")