Example #1
0
/*
 * Update the cost after swapping current medoid m with non-medoid n
 * Distance to closest medoid, closest medoid index are updated.
 */
static double pam_swap_cost(pam_partition p, size_t m, size_t n)
{
  double cost = 0.0;
  size_t i, cl;
  gsl_vector_view col;

  /* Update for each column */
  for (i = 0; i < p->M->size2; i++) {
    cl = gsl_vector_ulong_get(p->cl_index, i);

    /* If closest to medoid being removed, find new closest medoid */
    if (cl == m) {
      col = gsl_matrix_column(p->M, i);
      gsl_vector_masked_min_index(&(col.vector), p->in_set,
                                        &cl,
                                        gsl_vector_ptr(p->cl_dist,
                                                             i));
      gsl_vector_ulong_set(p->cl_index, i, cl);
    } else {
      /* Check if the new medoid is closer than the old */
      assert(gsl_vector_get(p->cl_dist, i) ==
             gsl_matrix_get(p->M,
                                  gsl_vector_ulong_get(p->cl_index, i), i));
      if (gsl_matrix_get(p->M, n, i) <
          gsl_vector_get(p->cl_dist, i)) {
        gsl_vector_set(p->cl_dist, i,
                             gsl_matrix_get(p->M, n, i));
        gsl_vector_ulong_set(p->cl_index, i, n);
      }
    }
    cost += gsl_vector_get(p->cl_dist, i);
  }

  return cost;
}
Example #2
0
/* Set the closest medoid, distance to closest medoid for column i */
static void pam_find_closest_medoid_index(pam_partition p, size_t i)
{
  size_t index;
  double min;
  gsl_vector_view col;

  min = FLT_MAX;
  col = gsl_matrix_column(p->M, i);
  gsl_vector_masked_min_index(&(col.vector), p->in_set, &index,
                                    &min);

  assert(min < FLT_MAX);

  gsl_vector_ulong_set(p->cl_index, i, index);
  gsl_vector_set(p->cl_dist, i, min);
}
Example #3
0
static void
dvine_select_order(dml_vine_t *vine,
                   const gsl_matrix *data,
                   dml_vine_weight_t weight,
                   dml_measure_t ***measure_matrix,
                   const gsl_rng *rng)
{
    int n = (int) vine->dim;
    double **weight_matrix;
    size_t selected_node;
    gsl_vector_ulong *tour;
    gsl_vector_short *in_tour;
    double selected_cost, current_cost;
    size_t current_pos = 0, selected_pos = 0; // Initialized to avoid GCC warnings.
    double dik, dkj, dij;
    size_t i, j;
    int cut_index;

    // Compute the weights. The weights are minimized.
    weight_matrix = g_malloc_n(n, sizeof(double *));
    for (size_t i = 0; i < n; i++) {
        weight_matrix[i] = g_malloc_n(n, sizeof(double));
        for (size_t j = 0; j < i; j++) {
            switch (weight) {
            case DML_VINE_WEIGHT_TAU:
                weight_matrix[i][j] = 1
                        - fabs(dml_measure_tau_coef(measure_matrix[i][j]));
                break;
            case DML_VINE_WEIGHT_CVM:
                weight_matrix[i][j] = measure_matrix[i][j]->x->size
                        - dml_measure_cvm_stat(measure_matrix[i][j]);
                break;
            default:
                weight_matrix[i][j] = 0;
                break;
            }
            weight_matrix[j][i] = weight_matrix[i][j];
        }
    }

    // Compute an approximate solution for the TSP instance using the
    // Cheapest insertion heuristic. The dummy node has index n.
    tour = gsl_vector_ulong_alloc(n + 1);
    in_tour = gsl_vector_short_alloc(n + 1);
    gsl_vector_short_set_all(in_tour, FALSE);

    for (size_t node_count = 0; node_count < n + 1; node_count++) {
        // Select the node to be inserted.
        if (node_count == 0) {
            // Initial node (randomly selected).
            selected_node = floor((n + 1) * gsl_rng_uniform(rng));
            gsl_vector_ulong_set(tour, node_count, selected_node);
            gsl_vector_short_set(in_tour, selected_node, TRUE);
        } else {
            selected_cost = GSL_DBL_MAX;

            // Rest of the nodes. Choose the nodes with the minimal insertion cost.
            for (size_t k = 0; k < n + 1; k++) {
                if (!gsl_vector_short_get(in_tour, k)) {
                    if (node_count == 1) {
                        i = gsl_vector_ulong_get(tour, 0);
                        current_cost = (i == n || k == n) ? 0: weight_matrix[i][k];
                        current_pos = 0;
                    } else {
                        current_cost = GSL_DBL_MAX;
                        for (size_t pos = 0; pos < node_count - 1; pos++) {
                            i = gsl_vector_ulong_get(tour, pos);
                            j = gsl_vector_ulong_get(tour, pos + 1);
                            dik = (i == n || k == n) ? 0: weight_matrix[i][k];
                            dkj = (k == n || j == n) ? 0: weight_matrix[k][j];
                            dij = (i == n || j == n) ? 0: weight_matrix[i][j];

                            if (dik + dkj + dij < current_cost) {
                                current_cost = dik + dkj + dij;
                                current_pos = pos;
                            }
                        }
                    }

                    // Check the last position.
                    i = gsl_vector_ulong_get(tour, node_count - 1);
                    j = gsl_vector_ulong_get(tour, 0);
                    dik = (i == n || k == n) ? 0: weight_matrix[i][k];
                    dkj = (k == n || j == n) ? 0: weight_matrix[k][j];
                    dij = (i == n || j == n) ? 0: weight_matrix[i][j];

                    if (dik + dkj + dij < current_cost) {
                        current_cost = dik + dkj + dij;
                        current_pos = node_count - 1;
                    }

                    if (current_cost < selected_cost) {
                        selected_node = k;
                        selected_cost = current_cost;
                        selected_pos = current_pos;
                    }

                }
            }

            // Add the selected node to the tour.
            for (size_t pos = selected_pos; pos < node_count; pos++) {
                i = gsl_vector_ulong_get(tour, pos + 1);
                if (pos == selected_pos) {
                    gsl_vector_ulong_set(tour, pos + 1, selected_node);
                } else {
                    gsl_vector_ulong_set(tour, pos + 1, j);
                }
                j = i;
            }
            gsl_vector_short_set(in_tour, selected_node, TRUE);
        }
    }

    // Cut the tour at the dummy node.
    cut_index = -1;
    for (int i = 0; i < n + 1; i++) {
        if (cut_index >= 0) {
            vine->order[i - cut_index - 1] = gsl_vector_ulong_get(tour, i);
        } else if (gsl_vector_ulong_get(tour, i) == n) {
            cut_index = i;
        }
    }
    for (int i = 0; i < cut_index; i++) {
        vine->order[n - cut_index + i] = gsl_vector_ulong_get(tour, i);
    }

    gsl_vector_ulong_free(tour);
    gsl_vector_short_free(in_tour);
    for (size_t i = 0; i < n; i++) {
        g_free(weight_matrix[i]);
    }
    g_free(weight_matrix);
}