29 static std::pair<std::vector<size_t>, std::vector<size_t>> affinityPropagation(
const crn::SquareMatrixDouble &s,
double damping,
size_t stable_iters_stop,
size_t max_iter)
31 if ((damping < 0.0) || (damping >= 1.0))
33 if (stable_iters_stop <= 1)
43 auto identical = size_t(0);
44 auto clusters = std::vector<size_t>(N, 0);
45 for (
auto cnt =
size_t(0); cnt < max_iter; ++cnt)
48 for (
auto i =
size_t(0); i < N; ++i)
49 for (
auto k =
size_t(0); k < N; ++k)
51 auto m = -std::numeric_limits<double>::max();
52 for (
auto kp =
size_t(0); kp < N; ++kp)
55 const auto v = a[i][kp] - s[i][kp];
59 r[i][k] = damping * r[i][k] + (1.0 - damping) * (-s[i][k] - m);
62 for (
auto i =
size_t(0); i < N; ++i)
63 for (
auto k =
size_t(0); k < N; ++k)
68 for (
auto ip =
size_t(0); ip < N; ++ip)
71 a[i][k] = damping * a[i][k] + (1.0 - damping) * v;
76 for (
auto ip =
size_t(0); ip < N; ++ip)
77 if ((ip != i) && (ip != k))
79 a[i][k] = damping * a[i][k] + (1.0 - damping) *
crn::Min(0.0, v);
84 auto newclusters = std::vector<size_t>(N, 0);
85 for (
auto i =
size_t(0); i < N; ++i)
88 auto maxval = -std::numeric_limits<double>::max();
89 for (
auto k =
size_t(0); k < N; ++k)
91 const auto val = r[i][k] + a[i][k];
102 if (clusters == newclusters)
106 clusters.swap(newclusters);
109 if (identical >= stable_iters_stop)
113 auto protos = std::vector<size_t>{};
114 for (
auto i =
size_t(0); i < N; ++i)
115 if (clusters[i] == i)
117 return std::make_pair(std::move(protos), std::move(clusters));
130 const auto N = distance_matrix.
GetRows();
133 auto s = distance_matrix;
138 std::sort(vect.begin(), vect.end());
139 diag = vect[(vect.size() + N) / 2];
145 for (
auto tmp =
size_t(0); tmp < N; ++tmp)
149 return affinityPropagation(s, damping, stable_iters_stop, max_iter);
163 auto s = distance_matrix;
164 for (
auto tmp =
size_t(0); tmp < s.
GetRows(); ++tmp)
165 s[tmp][tmp] = preference;
167 return affinityPropagation(s, damping, stable_iters_stop, max_iter);
180 if (distance_matrix.
GetRows() != preference.size())
183 auto s = distance_matrix;
184 for (
auto tmp =
size_t(0); tmp < s.
GetRows(); ++tmp)
185 s[tmp][tmp] = preference[tmp];
187 return affinityPropagation(s, damping, stable_iters_stop, max_iter);
size_t GetRows() const noexcept
Returns the number of rows.
const T & Max(const T &a, const T &b)
Returns the max of two values.
const T & Min(const T &a, const T &b)
Returns the min of two values.
const std::vector< T > & Std() const &noexcept
Square double matrix class.
AProClusters
Strategies to limit the number of classes in affinity propagation.
std::pair< std::vector< size_t >, std::vector< size_t > > AffinityPropagation(const SquareMatrixDouble &distance_matrix, AProClusters nclusters, double damping=0.5, size_t stable_iters_stop=10, size_t max_iter=100)
Computes clusters and their prototypes.