deallocate_array<scalar_t>(_cluster_var);
}
+scalar_t Clusterer::distance_to_centroid(scalar_t *x, int k) {
+ scalar_t dist = 0;
+ for(int d = 0; d < _dim; d++) {
+ dist += sq(_cluster_means[k][d] - x[d]) / (2 * _cluster_var[k][d]);
+ dist += 0.5 * log(_cluster_var[k][d]);
+ ASSERT(!isnan(dist) && !isinf(dist));
+ }
+ return dist;
+}
+
+void Clusterer::initialize_clusters(int nb_points, scalar_t **points) {
+ int *used = new int[nb_points];
+ for(int k = 0; k < nb_points; k++) { used[k] = 0; }
+ for(int k = 0; k < _nb_clusters; k++) {
+ int l;
+ do { l = int(drand48() * nb_points); } while(used[l]);
+ for(int d = 0; d < _dim; d++) {
+ _cluster_means[k][d] = points[l][d];
+ _cluster_var[k][d] = 1.0;
+ }
+ used[l] = 1;
+ }
+ delete[] used;
+}
+
scalar_t Clusterer::baseline_cluster_association(int nb_points, scalar_t **points,
int nb_classes, int *labels,
scalar_t **gamma) {
for(int n = 0; n < nb_points; n++) {
scalar_t lowest_dist = 0;
for(int k = 0; k < _nb_clusters; k++) {
- scalar_t dist = 0;
-
- for(int d = 0; d < _dim; d++) {
- dist += sq(_cluster_means[k][d] - points[n][d]) / (2 * _cluster_var[k][d]);
- dist += 0.5 * log(_cluster_var[k][d]);
- ASSERT(!isnan(dist) && !isinf(dist));
- }
-
+ scalar_t dist = distance_to_centroid(points[n], k);
if(k == 0 || dist <= lowest_dist) {
lowest_dist = dist;
associated_clusters[n] = k;
for(int k = 1; k <= _nb_clusters; k++) {
for(int n = 1; n <= nb_points; n++) {
int i = n + nb_points * (k - 1);
-
- scalar_t dist = 0;
-
- for(int d = 0; d < _dim; d++) {
- dist += sq(_cluster_means[k-1][d] - points[n-1][d]) / (2 * _cluster_var[k-1][d]);
- dist += 0.5 * log(_cluster_var[k-1][d]);
- }
-
- glp_set_obj_coef(lp, i, dist);
+ glp_set_obj_coef(lp, i, distance_to_centroid(points[n-1], k-1));
glp_set_col_bnds(lp, i, GLP_DB, 0.0, 1.0);
}
}
glp_set_prob_name(lp, "uninformative_lp_cluster_association");
glp_set_obj_dir(lp, GLP_MIN);
- // We have one constraint per points and one per cluster/class
+ // We have one constraint per point and one per cluster/class
glp_add_rows(lp, nb_points + _nb_clusters * nb_classes);
// (A) For each point, the constraint is that the sum of its
- // association coefficients will be equal to 1.0
+ // association coefficients is equal to 1.0
for(int n = 1; n <= nb_points; n++) {
glp_set_row_bnds(lp, n, GLP_FX, 1.0, 1.0);
}
- // (B) For each cluster and each class, the sum of the association
+ // (B) For each pair cluster/class, the sum of the association
// coefficient to this cluster for this class is equal to the number
// of sample of that class, divided by the number of clusters
for(int n = 1; n <= nb_points; n++) {
int r = n + nb_points * (k - 1);
- scalar_t dist = 0;
+ // scalar_t dist = 0;
- for(int d = 0; d < _dim; d++) {
- dist += sq(_cluster_means[k-1][d] - points[n-1][d]) / (2 * _cluster_var[k-1][d]);
- dist += 0.5 * log(_cluster_var[k-1][d]);
- }
+ // for(int d = 0; d < _dim; d++) {
+ // dist += sq(_cluster_means[k-1][d] - points[n-1][d]) / (2 * _cluster_var[k-1][d]);
+ // dist += 0.5 * log(_cluster_var[k-1][d]);
+ // }
- // The LP weight on this association coefficient is the distance
- // (normalized) of that sample to the centroid of that cluster
+ // The LP weight on this association coefficient for the global
+ // loss is the normalized distance of that sample to the
+ // centroid of that cluster
- glp_set_obj_coef(lp, r, dist);
+ glp_set_obj_coef(lp, r, distance_to_centroid(points[n-1], k-1));
// And this association coefficient is in [0,1]
}
}
-void Clusterer::initialize_clusters(int nb_points, scalar_t **points) {
- int *used = new int[nb_points];
- for(int k = 0; k < nb_points; k++) { used[k] = 0; }
- for(int k = 0; k < _nb_clusters; k++) {
- int l;
- do { l = int(drand48() * nb_points); } while(used[l]);
- for(int d = 0; d < _dim; d++) {
- _cluster_means[k][d] = points[l][d];
- _cluster_var[k][d] = 1.0;
- }
- used[l] = 1;
- }
- delete[] used;
-}
-
void Clusterer::train(int mode,
int nb_clusters, int dim,
int nb_points, scalar_t **points,