30 #include "density_clustering_mpi.hpp"
33 namespace Clustering {
36 std::vector<std::size_t>
39 ,
const float free_energy_threshold
41 ,
const std::size_t n_rows
42 ,
const std::size_t n_cols
43 ,
const std::vector<std::size_t> initial_clusters
45 ,
const int mpi_n_nodes
46 ,
const int mpi_node_id
50 using namespace Clustering::Density::MPI;
52 std::vector<std::size_t> clustering;
53 bool have_initial_clusters = (initial_clusters.size() == n_rows);
54 if (have_initial_clusters) {
55 clustering = initial_clusters;
57 clustering = std::vector<std::size_t>(n_rows);
62 auto lb = std::upper_bound(fe_sorted.begin(),
66 std::size_t first_frame_above_threshold = (lb - fe_sorted.begin());
75 logger(std::cout) <<
"sigma2: " << sigma2 << std::endl
76 << first_frame_above_threshold <<
" frames with low free energy / high density" << std::endl
77 <<
"first frame above threshold has free energy: "
78 << fe_sorted[first_frame_above_threshold].second << std::endl
79 <<
"merging initial clusters" << std::endl;
84 std::size_t distinct_name = *std::max_element(clustering.begin(), clustering.end());
85 bool neighboring_clusters_merged =
false;
86 std::set<std::size_t> visited_frames = {};
87 if (have_initial_clusters) {
90 for (std::size_t i=0; i < first_frame_above_threshold; ++i) {
91 std::size_t i_original = fe_sorted[i].first;
92 if (initial_clusters[i_original] != 0) {
93 visited_frames.insert(i);
96 logger(std::cout) <<
"# already visited: " << visited_frames.size() << std::endl;
99 while ( ! neighboring_clusters_merged) {
100 neighboring_clusters_merged =
true;
104 logger(std::cout) <<
"initial merge iteration" << std::endl;
108 for (std::size_t i=0; i < first_frame_above_threshold; ++i) {
109 if (visited_frames.count(i) == 0) {
110 visited_frames.insert(i);
117 first_frame_above_threshold,
126 first_frame_above_threshold,
131 std::set<std::size_t> cluster_names;
132 for (
auto j: local_nh) {
133 cluster_names.insert(clustering[fe_sorted[j].first]);
135 if ( ! (cluster_names.size() == 1 && cluster_names.count(0) != 1)) {
136 neighboring_clusters_merged =
false;
138 if (cluster_names.count(0) == 1) {
139 cluster_names.erase(0);
141 std::size_t common_name;
142 if (cluster_names.size() > 0) {
147 common_name = (*cluster_names.begin());
151 common_name = ++distinct_name;
153 for (
auto j: local_nh) {
154 clustering[fe_sorted[j].first] = common_name;
157 #pragma omp parallel for default(none) private(j)\
158 firstprivate(common_name,first_frame_above_threshold,cluster_names) \
159 shared(clustering,fe_sorted)
160 for (j=0; j < first_frame_above_threshold; ++j) {
161 if (cluster_names.count(clustering[fe_sorted[j].first]) == 1) {
162 clustering[fe_sorted[j].first] = common_name;
170 std::set<std::size_t> final_names;
171 for (std::size_t i=0; i < first_frame_above_threshold; ++i) {
172 final_names.insert(clustering[fe_sorted[i].first]);
174 std::map<std::size_t, std::size_t> old_to_new;
176 std::size_t new_name=0;
177 for (
auto name: final_names) {
178 old_to_new[name] = ++new_name;
181 for(
auto& elem: clustering) {
182 elem = old_to_new[elem];
const int MAIN_PROCESS
identify MPI process 0 as main process
double compute_sigma2(const Neighborhood &nh)
Clustering::Tools::Neighborhood Neighborhood
map frame id to neighbors
std::ostream & logger(std::ostream &s)
std::vector< std::size_t > initial_density_clustering(const std::vector< float > &free_energy, const Neighborhood &nh, const float free_energy_threshold, const float *coords, const std::size_t n_rows, const std::size_t n_cols, const std::vector< std::size_t > initial_clusters)
std::vector< FreeEnergy > sorted_free_energies(const std::vector< float > &fe)
std::pair< std::size_t, float > FreeEnergy
matches frame id to free energy
std::set< std::size_t > high_density_neighborhood(const float *coords, const std::size_t n_cols, const std::vector< FreeEnergy > &sorted_fe, const std::size_t i_frame, const std::size_t limit, const float max_dist, const int mpi_n_nodes, const int mpi_node_id)