// The coefficients for the constraints are passed to the glpk
// functions with a sparse representation.
+ // ** GLPK USES INDEXES STARTING AT 1, NOT 0. **
+
int nb_coeffs = nb_points * _nb_clusters + nb_points * _nb_clusters;
int *coeff_row = new int[nb_coeffs + 1];
glp_add_cols(lp, nb_points * _nb_clusters);
// The constraints (A) will be expressed by putting directly bounds
- // on the column variables. So we need one row per (B) constraint,
- // and one per (C) constraint.
+ // on the variables (i.e. one per column). So we need one row per
+ // (B) constraint, and one per (C) constraint.
glp_add_rows(lp, nb_points + _nb_clusters * nb_classes);
for(int n = 1; n <= nb_points; n++) {
int col = n + nb_points * (k - 1);
- // The LP weight on this association coefficient for the global
- // loss is the normalized distance of that sample to the
- // centroid of that cluster
+ // The LP weight on the gammas for the global loss is the
+ // normalized distance of that sample to the centroid of that
+ // cluster
glp_set_obj_coef(lp, col, distance_to_centroid(points[n-1], k-1));
}
}
- // The (B) constraints: for each point, the sum of its association
- // coefficients is equal to 1.0
+ // The (B) constraints: for each point, the sum of its gamma is
+ // equal to 1.0
for(int n = 1; n <= nb_points; n++) {
int row = n;
glp_set_row_bnds(lp, row, GLP_FX, 1.0, 1.0);
- }
-
- for(int n = 1; n <= nb_points; n++) {
for(int k = 1; k <= _nb_clusters; k++) {
- int row = n;
coeff_row[n_coeff] = row;
coeff_col[n_coeff] = nb_points * (k - 1) + n;
coeff_wgt[n_coeff] = 1.0;
}
// The (C) constraints: 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
+ // gammas for this cluster and this class is equal to the number of
+ // sample of that class, divided by the number of clusters
for(int k = 1; k <= _nb_clusters; k++) {
for(int c = 1; c <= nb_classes; c++) {
int row = nb_points + (k - 1) * nb_classes + c;
scalar_t tau = nb_samples_per_class[c-1] / scalar_t(_nb_clusters);
glp_set_row_bnds(lp, row, GLP_FX, tau, tau);
- }
- }
-
- for(int k = 1; k <= _nb_clusters; k++) {
- for(int c = 1; c <= nb_classes; c++) {
- int row = nb_points + (k - 1) * nb_classes + c;
for(int n = 1; n <= nb_points; n++) {
if(labels[n-1] == c - 1) {
coeff_row[n_coeff] = row;