9 #ifndef IMPEM2D_HIERARCHICAL_CLUSTERING_H
10 #define IMPEM2D_HIERARCHICAL_CLUSTERING_H
12 #include <IMP/em2d/em2d_config.h>
14 #include <IMP/em2d/internal/clustering_helper.h>
22 #include <cereal/access.hpp>
24 IMPEM2D_BEGIN_NAMESPACE
28 IMPEM2D_DEPRECATED_FUNCTION_DECL(2.26)
30 IMPEM2D_DEPRECATED_FUNCTION_DEF(
31 2.26,
"This function is not used in IMP, and will be removed.");
32 for (
unsigned int i = 0; i < v.size(); ++i) {
33 std::cout << v[i] <<
" , ";
35 std::cout << std::endl;
53 void do_join_clusters(
unsigned int cluster_id1,
unsigned int cluster_id2,
54 double distance_between_clusters);
60 Ints get_cluster_elements(
unsigned int id)
const;
67 Ints get_clusters_below_cutoff(
double cutoff)
const;
70 Ints get_cluster_formed_at_step(
unsigned int step)
const;
73 double get_distance_at_step(
unsigned int step)
const;
75 unsigned int get_id_for_cluster_at_step(
unsigned int step)
const {
76 return step + n_elements_;
94 FloatsList get_linkage_matrix_in_matlab_format()
const;
99 void show(std::ostream &out)
const;
102 void check_step_value(
unsigned int s)
const;
103 unsigned int get_step_from_id(
unsigned int id)
const {
104 return (
id - n_elements_);
108 unsigned int n_elements_;
109 Ints joined_ids1_, joined_ids2_;
110 Floats cluster_distances_;
116 friend class cereal::access;
118 template<
class Archive>
void serialize(Archive &ar) {
119 ar(steps_, n_elements_, joined_ids1_, joined_ids2_,
120 cluster_distances_, clusters_elements_);
140 double operator()(
unsigned int id1,
unsigned int id2,
144 void show(std::ostream &out)
const {
145 out <<
"SingleLinkage";
148 friend class cereal::access;
150 template<
class Archive>
void serialize(Archive &) {}
164 double operator()(
unsigned int id1,
unsigned int id2,
167 void show(std::ostream &out)
const {
168 out <<
"CompleteLinkage";
171 friend class cereal::access;
173 template<
class Archive>
void serialize(Archive &) {}
186 double operator()(
unsigned int id1,
unsigned int id2,
189 void show(std::ostream &out)
const {
190 out <<
"AverageDistanceLinkage";
193 friend class cereal::access;
195 template<
class Archive>
void serialize(Archive &) {}
206 template <
class LinkageFunction>
213 IMP_LOG_TERSE(
"starting hierarchical_agglomerative_clustering " << std::endl);
215 unsigned int N = distances.size();
218 std::vector<internal::list_cluster_id_distance> lists(N);
222 std::vector<bool> active_list(N);
223 std::fill(active_list.begin(), active_list.end(),
true);
225 for (
unsigned int n = 0; n < N; ++n) {
226 for (
unsigned int i = 0; i < N; ++i) {
228 lists[n].push_back(std::make_pair(i, distances[n][i]));
237 LinkageFunction linkage_function;
238 unsigned int steps = N - 1;
240 for (
unsigned int k = 0; k < steps; ++k) {
243 double minimum_distance = std::numeric_limits<double>::max();
246 for (
unsigned int j = 0; j < N; ++j) {
247 if (active_list[j] ==
true) {
249 if (lists[j].front().second < minimum_distance) {
250 minimum_distance = lists[j].front().second;
256 unsigned int l2 = lists[l1].front().first;
257 minimum_distance = lists[l2].front().second;
258 IMP_LOG_TERSE(
"step " << k <<
": joining clusters " << cluster_id[l1]
259 <<
" and " << cluster_id[l2] <<
" to form cluster "
260 << cluster_set.get_id_for_cluster_at_step(k)
261 <<
" distance = " << minimum_distance << std::endl);
264 active_list[l2] =
false;
265 cluster_id[l1] = cluster_set.get_id_for_cluster_at_step(k);
269 for (
unsigned int i = 0; i < N; ++i) {
270 IMP_LOG_TERSE(
"Updating list of distances " << i << std::endl);
271 if (active_list[i] ==
true && i != l1) {
274 lists[i].erase(std::remove_if(lists[i].begin(), lists[i].end(),
275 internal::ListHasDistance(l1, l2)),
278 double dist = linkage_function(cluster_id[l1], cluster_id[i],
279 cluster_set, distances);
280 IMP_LOG_TERSE(
"Distance by linkage function " << dist << std::endl);
281 lists[i].push_back(std::make_pair(l1, dist));
282 lists[l1].push_back(std::make_pair(i, dist));
286 for (
unsigned int i = 0; i < N; ++i) {
287 if (active_list[i] ==
true) {
295 IMPEM2D_END_NAMESPACE
void print_vector(const std::vector< T > &v)
ClusterSet do_hierarchical_agglomerative_clustering(const FloatsList &distances)
Function to perform agglomerative clustering.
Functor for hierarchical clustering based on single linkage.
#define IMP_LOG_TERSE(expr)
Scoring functions for 2D Copyright 2007-2026 IMP Inventors. All rights reserved.
void do_join_clusters(unsigned int cluster_id1, unsigned int cluster_id2, double distance_between_clusters)
join operation
#define IMP_VALUES(Name, PluralName)
Define the type for storing sets of values.
A class to store the clusters generated during hierarchical clustering.
std::ostream & show(Hierarchy h, std::ostream &out=std::cout)
Print the hierarchy using a given decorator to display each node.
Functor for hierarchical clustering based on complete linkage.
Functor for hierarchical clustering based on average-linkage.
Logging and error reporting support.
unsigned int get_number_of_steps() const
Returns the number of steps of clustering recorded.
Comparison of pairs by checking the second element.