9#ifndef FUZZY_PARTITION_H
10#define FUZZY_PARTITION_H
17#include "zip_range.hpp"
18#include <boost/numeric/ublas/io.hpp>
19#include <boost/numeric/ublas/matrix.hpp>
20#include <boost/numeric/ublas/matrix_proxy.hpp>
21#include <boost/numeric/ublas/vector.hpp>
23#include "RestrictedGrowthString.hpp"
28bool operator==(
const boost::numeric::ublas::matrix<T> &m,
const boost::numeric::ublas::matrix<T> &n);
32template <
typename E>
class FuzzyPartition;
34template <
typename E> std::ostream &operator<<(std::ostream &os,
const FuzzyPartition<E> &fuzzy_partition);
54 using matrix_type = boost::numeric::ublas::matrix<double>;
55 using vector_type = boost::numeric::ublas::vector<double>;
58 using element_type = Element;
59 using cluster_type =
unsigned int;
66 FuzzyPartition(std::map<element_type, std::vector<double>>
const &coefficients)
67 : m_elements(retrieve_elements(coefficients)), m_clusters(retrieve_clusters(coefficients)),
68 m_membership_coefficients(build_coefficients_matrix(coefficients))
70 assert(m_membership_coefficients.size2() == m_elements.size());
71 assert(m_membership_coefficients.size1() == coefficients.cbegin()->second.size());
72 check_coefficients_validty();
90 return m_elements.size();
96 return m_clusters.size();
105 auto costs = this->weighted_bipartite_graph(other);
106 auto best_assignment = hungarian_algorithm_resolution(costs);
107 return (compute_solution_cost(best_assignment, costs));
113 assert(rgs.size() == this->nClusters());
114 matrix_type new_coefficients(rgs.nBlocks(), this->nElements(), 0);
116 for (
unsigned int i = 0; i < m_membership_coefficients.size1(); ++i)
118 for (
unsigned int j = 0; j < m_membership_coefficients.size2(); ++j)
120 new_coefficients(rgs.at(i), j) += m_membership_coefficients(i, j);
123 m_membership_coefficients.swap(new_coefficients);
124 std::set<cluster_type> c;
125 for (
unsigned int i = 0; i < rgs.nBlocks(); ++i)
130 check_coefficients_validty();
138 bool is_equal = this->m_elements == other.m_elements &&
139 this->m_membership_coefficients == other.m_membership_coefficients &&
140 this->m_clusters == other.m_clusters;
146 std::set<element_type> m_elements;
147 std::set<cluster_type> m_clusters;
148 matrix_type m_membership_coefficients;
154 using namespace boost::numeric::ublas;
157 for (
unsigned int i = 0; i < this->
nClusters(); ++i)
159 matrix_row<const matrix<double>> v(m_membership_coefficients, i);
161 for (
unsigned int j = 0; j < other.
nClusters(); ++j)
163 matrix_row<const matrix<double>> w(other.m_membership_coefficients, j);
164 costs(i, j) = compute_cost(v, w);
170 template <
typename V,
typename W>
double compute_cost(V
const &v, W
const &w)
const
172 assert(v.size() == w.size());
174 std::vector<double> distances;
176 for (
auto &&t : zip_range(v, w))
178 distances.push_back(std::abs(boost::get<0>(t) - boost::get<1>(t)));
181 return std::accumulate(distances.begin(), distances.end(), 0.0);
184 template <
typename T> Matrix<T> hungarian_algorithm_resolution(Matrix<T> costs)
const
191 template <
typename T>
double compute_solution_cost(Matrix<T>
const &solution, Matrix<T>
const &costs)
const
193 double total_cost = 0.0;
194 for (
unsigned int i = 0; i < solution.rows(); ++i)
197 for (
unsigned int j = 0; j < solution.columns(); ++j)
199 if (solution(i, j) == 0)
202 total_cost += costs(i, j);
205 assert(row_matches == 0 || row_matches == 1);
210 std::set<element_type> retrieve_elements(std::map<element_type, std::vector<double>>
const &coefficients)
const
212 std::set<element_type> elems;
213 for (
auto const &it : coefficients)
215 elems.insert(it.first);
220 std::set<cluster_type> retrieve_clusters(std::map<element_type, std::vector<double>>
const &coefficients)
const
223 unsigned int s = coefficients.begin()->second.size();
224 for (
unsigned int i = 0; i < s; ++i)
231 matrix_type build_coefficients_matrix(std::map<element_type, std::vector<double>>
const &coefficients)
234 unsigned int n_rows = coefficients.begin()->second.size();
235 unsigned int n_cols = coefficients.size();
237 for (
auto const &it : coefficients)
239 assert(it.second.size() == n_rows);
242 matrix_type m(n_rows, n_cols, 0);
247 for (
auto const &it1 : coefficients)
249 for (
auto const &it2 : it1.second)
260 void check_coefficients_validty()
263 for (
unsigned int j = 0; j < m_membership_coefficients.size2(); ++j)
265 for (
unsigned int i = 0; i < m_membership_coefficients.size1(); ++i)
267 sum += m_membership_coefficients(i, j);
277std::ostream &operator<<(std::ostream &os,
280 os << fuzzy_partition.m_membership_coefficients;
285bool operator==(
const boost::numeric::ublas::matrix<T> &m,
const boost::numeric::ublas::matrix<T> &n)
287 bool returnValue = (m.size1() == n.size1()) && (m.size2() == n.size2());
291 for (
unsigned int i = 0; returnValue && i < m.size1(); ++i)
293 for (
unsigned int j = 0; returnValue && j < m.size2(); ++j)
295 returnValue &= m(i, j) == n(i, j);
Clusters are implicitly defined because of cluster merging (what would make unique IDs complicated to...
Definition FuzzyPartition.hpp:53
size_t nElements() const
Returns the number of elements (columns) of the fuzzy partition (matrix)
Definition FuzzyPartition.hpp:88
FuzzyPartition(std::map< element_type, std::vector< double > > const &coefficients)
Construct the fuzz partition with given coefficients.
Definition FuzzyPartition.hpp:66
bool operator==(FuzzyPartition< element_type > const &other) const
Comparison operator, returning true if two partitions have equal elements set and membership coeffice...
Definition FuzzyPartition.hpp:136
const std::set< element_type > & elements() const
Return the elements of the fuzzy partition.
Definition FuzzyPartition.hpp:76
size_t nClusters() const
Returns the number of clusters (lines) of the fuzzy partition (matrix)
Definition FuzzyPartition.hpp:94
FuzzyPartition & merge_clusters(RestrictedGrowthString const &rgs)
Modifies the object, merging clusters (summing lines) according to a restricted growth string object.
Definition FuzzyPartition.hpp:111
const std::set< cluster_type > & clusters() const
Return the clusters indices.
Definition FuzzyPartition.hpp:82
double fuzzy_transfer_distance(FuzzyPartition const &other) const
Compute the fuzzy transfer distance between two fuzzy partition.
Definition FuzzyPartition.hpp:102
Definition RestrictedGrowthString.hpp:19
auto operator==(const C1 &c1, const C2 &c2)
GridCoordinates are equality comparable.
Definition coordinates.hpp:39
Summary statistics based on spatial partition of coalescent trees.
Definition polymorphism.hpp:28