int dm_swap_cols (matrix_t *m, int cola, int colb) { // swap header permutation_group_t o; int d[2]; dm_create_permutation_group (&o, 2, d); dm_add_to_permutation_group (&o, cola); dm_add_to_permutation_group (&o, colb); dm_permute_cols (m, &o); dm_free_permutation_group (&o); return 0; }
// merge cola and colb, remove colb from the matrix static int merge_cols_ (matrix_t *m, int cola, int colb) { int cols = dm_ncols (m); permutation_group_t o; int d[cols]; int j; // make sure colb > cola if (cola == colb) return -1; if (colb < cola) { // in this case, cola will move 1 col up cola--; } // create permutation dm_create_permutation_group (&o, cols, d); // create proper permutation group for (j = colb; j < cols; j++) { dm_add_to_permutation_group (&o, j); } dm_permute_cols (m, &o); dm_free_permutation_group (&o); // merge the groups (last col in matrix is now colb) merge_group_ (&(m->col_perm), m->col_perm.data[cols - 1].becomes, m->col_perm.data[cola].becomes); // update matrix counts uncount_col_ (m, cols - 1); // remove the last col from the matrix m->cols--; return 0; }
// unmerge the first item in the group of this col and put it right after // this col static int unmerge_col_ (matrix_t *m, int col) { int org_col = m->col_perm.data[col].becomes; int org_group = m->col_perm.data[org_col].group; int next_at = m->col_perm.data[org_group].at; // if this col is ungrouped, return if (org_col == org_group) return 0; // remove this col from the group unmerge_group_ (&(m->col_perm), org_col); int perm_size = m->col_perm.size; permutation_group_t o; int d[perm_size]; int j; // create permutation dm_create_permutation_group (&o, perm_size, d); // create proper permutation group for (j = next_at; j > col; j--) { dm_add_to_permutation_group (&o, j); } dm_permute_cols (m, &o); dm_free_permutation_group (&o); // update matrix counts count_col_ (m, j + 1); // increase matrix size m->cols++; return 0; }
int main (void) { bitvector_t b1; bitvector_t b2; bitvector_create (&b1, 20); user_bitvector_print (&b1); bitvector_set (&b1, 4); user_bitvector_print (&b1); bitvector_copy (&b2, &b1); bitvector_unset (&b1, 4); user_bitvector_print (&b1); user_bitvector_print (&b2); // test is_empty printf ("is_empty b1? %c (should be t)\n", bitvector_is_empty(&b1)?'t':'f'); printf ("is_empty b2? %c (should be f)\n", bitvector_is_empty(&b2)?'t':'f'); // set even/odd bits in b1/b2 for(int i=0; i<20; ++i) { if (i%2) { bitvector_set(&b1,i); } else { bitvector_set(&b2,i); } } // print before union printf ("before union\n"); user_bitvector_print (&b1); user_bitvector_print (&b2); // disjoint? printf ("b1,b2 are disjoint %c (should be t)\n", bitvector_is_disjoint(&b1, &b2)?'t':'f'); printf ("union\n"); bitvector_union(&b1, &b2); // disjoint? printf ("b1,b2 are disjoint %c (should be f)\n", bitvector_is_disjoint(&b1, &b2)?'t':'f'); // print after union user_bitvector_print (&b1); user_bitvector_print (&b2); printf ("intersect\n"); bitvector_intersect(&b1, &b2); // disjoint? printf ("b1,b2 are disjoint %c (should be f)\n", bitvector_is_disjoint(&b1, &b2)?'t':'f'); // print after intersection user_bitvector_print (&b1); user_bitvector_print (&b2); printf ("invert b1\n"); bitvector_invert(&b1); // print after inversion user_bitvector_print (&b1); // disjoint? printf ("b1,b2 are disjoint %c (should be t)\n", bitvector_is_disjoint(&b1, &b2)?'t':'f'); bitvector_free (&b2); bitvector_free (&b1); matrix_t m1; matrix_t m2; dm_create (&m1, 10, 10); print_matrix (&m1); printf ("dm_set(4,4)\n"); dm_set (&m1, 4, 4); print_matrix (&m1); printf ("dm_unset(4,4)\n"); dm_unset (&m1, 4, 4); print_matrix (&m1); printf ("test shift permutation (3,4,5)(6,7)\n"); printf ("before\n"); dm_set (&m1, 3, 3); dm_set (&m1, 4, 4); dm_set (&m1, 5, 5); dm_set (&m1, 6, 6); dm_set (&m1, 7, 7); print_matrix (&m1); printf ("after\n"); // create permutation_group, apply permutation_group_t o1; dm_create_permutation_group (&o1, 2, NULL); dm_add_to_permutation_group (&o1, 3); dm_add_to_permutation_group (&o1, 4); dm_add_to_permutation_group (&o1, 5); dm_close_group (&o1); dm_add_to_permutation_group (&o1, 6); dm_add_to_permutation_group (&o1, 7); dm_permute_cols (&m1, &o1); print_matrix (&m1); dm_free_permutation_group (&o1); printf ("swap cols 6,7\n"); dm_swap_cols (&m1, 6, 7); print_matrix (&m1); printf ("swap rows 6,7\n"); dm_swap_rows (&m1, 6, 7); print_matrix (&m1); printf ("copy\n"); dm_create(&m2, dm_nrows(&m1), dm_ncols(&m1)); dm_copy (&m1, &m2); // TODO: needs some more work print_matrix (&m2); dm_sort_rows (&m1, &min_row_first); print_matrix (&m1); dm_sort_rows (&m1, &max_row_first); print_matrix (&m1); dm_print_perm (&(m1.row_perm)); printf ("to nub rows added & resorted\n"); dm_set (&m1, 7, 3); dm_set (&m1, 8, 4); dm_sort_rows (&m1, &max_row_first); print_matrix (&m1); printf ("flatten \n"); dm_flatten (&m1); print_matrix (&m1); dm_print_perm (&(m1.row_perm)); printf ("nub sorted\n"); //dm_nub_rows (&m1, &eq_rows, NULL); print_matrix (&m1); dm_print_perm (&(m1.row_perm)); /* * printf("again, now to test row order & nub idx\n"); dm_free(&m1); * dm_create(&m1, 10, 10); dm_set(&m1, 0,0); dm_set(&m1, 1,0); * dm_set(&m1, 2,3); dm_set(&m1, 3,3); print_matrix(&m1); * * printf("nub sorted\n"); * * dm_nub_rows(&m1); * * print_matrix(&m1); * * dm_print_perm(&(m1.row_perm)); */ printf ("optimize sorted\n"); dm_set (&m1, 0, 7); dm_set (&m1, 1, 6); dm_set (&m1, 3, 9); printf ("before\n"); print_matrix (&m1); dm_optimize (&m1); printf ("after\n"); print_matrix (&m1); printf ("resorted\n"); dm_sort_rows (&m1, &max_row_first); print_matrix (&m1); /* dm_nub_cols(&m1); dm_ungroup_rows(&m1); dm_ungroup_cols(&m1); print_matrix (&m1); */ // get bitvector from matrix text bitvector_create (&b1, 6); bitvector_create (&b2, 10); printf ("bitvector of row 0\n"); user_bitvector_print (&b2); printf ("bitvector of col 8\n"); user_bitvector_print (&b1); bitvector_free (&b2); bitvector_free (&b1); printf ("count test\n"); for (int i = 0; i < dm_nrows (&m1); i++) printf ("ones in row %d: %d\n", i, dm_ones_in_row (&m1, i)); for (int i = 0; i < dm_ncols (&m1); i++) printf ("ones in col %d: %d\n", i, dm_ones_in_col (&m1, i)); printf ("iterator test\n"); dm_row_iterator_t mx; dm_col_iterator_t my; for (int i = 0; i < dm_nrows (&m1); i++) { printf ("iterator row: %d\n", i); dm_create_row_iterator (&mx, &m1, i); int r; while ((r = dm_row_next (&mx)) != -1) printf (" next: %d\n", r); printf ("\n\n"); } for (int i = 0; i < dm_ncols (&m1); i++) { printf ("iterator col: %d\n", i); dm_create_col_iterator (&my, &m1, i); int r; while ((r = dm_col_next (&my)) != -1) printf (" next: %d\n", r); printf ("\n\n"); } printf ("projection test\n"); int s0[10]; int src[10]; int prj[2]; int tgt[10]; // initialize for (int i = 0; i < 10; i++) { s0[i] = -i; src[i] = i; } // do projection int prj_n = dm_project_vector (&m1, 0, src, prj); // print projection printf ("projection:"); for (int i = 0; i < prj_n; i++) { printf (" %d", prj[i]); } printf ("\n"); printf ("expansion test\n"); // do expansion int exp_n = dm_expand_vector (&m1, 0, s0, prj, tgt); (void)exp_n; // print expansion printf ("expansion:"); for (int i = 0; i < 10; i++) { printf (" %d", tgt[i]); } printf ("\n"); // subsumption printf ("subsumption test:\n"); dm_swap_rows (&m1, 0, 3); dm_swap_rows (&m1, 1, 2); dm_flatten (&m1); print_matrix (&m1); dm_subsume_rows (&m1, &eq_rows, NULL); printf ("after subsumption:\n"); print_matrix (&m1); printf ("\n"); printf ("after ungrouping:\n"); dm_ungroup_rows (&m1); print_matrix (&m1); printf ("\n"); printf ("column sort test:\n"); dm_flatten (&m1); printf ("max col first:\n"); dm_sort_cols (&m1, &max_col_first); print_matrix (&m1); printf ("min col first:\n"); dm_sort_cols (&m1, &min_col_first); print_matrix (&m1); printf ("nub columns test:\n"); dm_set (&m1, 0, 1); dm_set (&m1, 3, 1); dm_set (&m1, 3, 4); dm_set (&m1, 3, 5); dm_sort_cols (&m1, &max_col_first); // dm_flatten(&m1); printf ("max col first:\n"); print_matrix (&m1); //printf ("subsume columns:\n"); //dm_subsume_cols (&m1, &eq_cols, NULL); //dm_subsume_rows (&m1, &eq_rows, NULL); print_matrix (&m1); printf ("column permutation:\n"); dm_print_perm (&(m1.col_perm)); printf ("optimize columns:\n"); dm_optimize (&m1); print_matrix (&m1); //printf ("ungroup columns:\n"); //dm_ungroup_cols (&m1); //print_matrix (&m1); //printf ("all permutations:\n"); //dm_set (&m1, 0, 9); //dm_nub_cols(&m1, &eq_cols, NULL); //print_matrix (&m1); //dm_all_perm (&m1); dm_free (&m2); dm_free (&m1); return 0; }
int dm_optimize (matrix_t *r, matrix_t *mayw, matrix_t *mustw) { HREassert( dm_ncols(r) == dm_ncols(mayw) && dm_nrows(r) == dm_nrows(mayw) && dm_ncols(r) == dm_ncols(mustw) && dm_nrows(r) == dm_nrows(mustw), "matrix sizes do not match"); matrix_t* test = RTmalloc(sizeof(matrix_t)); dm_create(test, dm_nrows(r), dm_ncols(r)); dm_copy(r, test); dm_apply_or(test, mayw); int d_rot[dm_ncols (r)]; permutation_group_t rot; int best_i = 0, best_j = 0, min = cost_ (r, mayw), last_min = 0; int i, j, c, k, d; int firsts[dm_nrows(r)]; int lasts[dm_nrows(r)]; while (last_min != min) { last_min = min; // initialize first and last integers per row for (i=0; i<dm_nrows(r); i++) { firsts[i] = first_(test,i); lasts[i] = last_(test,i); } // find best rotation for (i = 0; i < dm_ncols (r); i++) { for (j = 0; j < dm_ncols (r); j++) { if (i != j) { c=estimate_cost(test,i,j,firsts,lasts); if (c < min) { min = c; best_i = i; best_j = j; } } } } // rotate if (best_i != best_j) { d = best_i < best_j ? 1 : -1; dm_create_permutation_group (&rot, dm_ncols (r), d_rot); for (k = best_i; k != best_j; k += d) dm_add_to_permutation_group (&rot, k); dm_add_to_permutation_group (&rot, best_j); dm_permute_cols (r, &rot); dm_permute_cols (mayw, &rot); dm_permute_cols (mustw, &rot); dm_permute_cols (test, &rot); dm_free_permutation_group (&rot); DMDBG (printf("best rotation: %d-%d, costs %d\n", best_i, best_j, min)); DMDBG (dm_print_combined (stdout, r, mayw, mustw)); best_i = best_j = 0; } } DMDBG (printf ("cost: %d ", cost_ (r, mayw))); dm_free(test); return 0; }
int dm_anneal (matrix_t *r, matrix_t *mayw, matrix_t *mustw) { HREassert( dm_ncols(r) == dm_ncols(mayw) && dm_nrows(r) == dm_nrows(mayw) && dm_ncols(r) == dm_ncols(mustw) && dm_nrows(r) == dm_nrows(mustw), "matrix sizes do not match"); int ncols = dm_ncols(r); double cur_cost = cost_(r, mayw); double temp = INIT_TEMP; srandom(time(NULL)); for (int cool_step = 0; cool_step < COOL_STEPS; cool_step++) { double start_cost = cur_cost; temp *= COOL_FRAC; for (int temp_step = 0; temp_step < TEMP_STEPS; temp_step++) { int i = random() % ncols; int j = random() % ncols; if (i != j) { int d_rot[ncols]; permutation_group_t rot; int d = i < j ? 1 : -1; dm_create_permutation_group(&rot, ncols, d_rot); for (int k = i; k != j; k += d) dm_add_to_permutation_group(&rot, k); dm_add_to_permutation_group(&rot, j); dm_permute_cols(r, &rot); dm_permute_cols(mayw, &rot); dm_permute_cols(mustw, &rot); dm_free_permutation_group(&rot); } double delta = cost_(r, mayw) - cur_cost; if (delta < 0) { cur_cost += delta; } else { double rand = random(); double flip = rand / LONG_MAX; double exp = (-delta / cur_cost) / (K * temp); double merit = pow(E, exp); if (merit > flip) { cur_cost += delta; } else if (i != j) { int d_rot[ncols]; permutation_group_t rot; int d = i < j ? 1 : -1; dm_create_permutation_group(&rot, ncols, d_rot); for (int k = j; k != i; k += -d) dm_add_to_permutation_group(&rot, k); dm_add_to_permutation_group(&rot, i); dm_permute_cols(r, &rot); dm_permute_cols(mayw, &rot); dm_permute_cols(mustw, &rot); dm_free_permutation_group(&rot); } } } if (cur_cost - start_cost < 0.0) temp /= COOL_FRAC; } DMDBG (printf ("cost: %d ", cost_ (r, mayw))); return 0; }