diff --git a/infinity/library/src/infinity.c b/infinity/library/src/infinity.c index 8ad2186..60785d9 100644 --- a/infinity/library/src/infinity.c +++ b/infinity/library/src/infinity.c @@ -156,19 +156,6 @@ static int create_cut_from_lfree(const struct Tableau *tableau, log_verbose(" psi[%4d] = %20.12lf %d\n", map->indices[i], value); - if_debug_level - { - time_printf(" q=["); - for(int j = 0; j < nrows; j++) - printf("%25.20lf ", ray[j] * map->ray_scale[i]); - printf("] value=%25.20lf\n", value); - } - - value = fmax(value, 1 / 1024.0); - -// value *= 1.001; -// value = DOUBLE_max(value, 0.001); - cut->indices[i] = map->indices[i]; cut->pi[i] = -value; } @@ -201,11 +188,6 @@ static int filter_model(const struct MultiRowModel *original_model, const struct RayList *original_rays = &original_model->rays; memcpy(f, original_model->f, 2 * sizeof(double)); - for(int i = 0; i < nrows; i++) - { - f[i] = (ceil(f[i] * 128) / 128); - if(f[i] <= 0.01) f[i] = 0; - } r = (double*) malloc(nrows * sizeof(double)); abort_if(!r, "could not allocate r"); @@ -282,11 +264,18 @@ static int append_extra_rays(struct MultiRowModel *model) for(int i = 0; i < nrows; i++) { + int found, index; + double scale; + for(int j = 0; j < nrows; j++) r[j] = (i == j ? e : 0); - LFREE_push_ray(&model->rays, r); + rval = CG_find_ray(&model->rays, r, &found, &scale, &index); + abort_if(rval, "CG_find_ray failed"); + if(!found) LFREE_push_ray(&model->rays, r); for(int j = 0; j < nrows; j++) r[j] = (i == j ? -e : 0); - LFREE_push_ray(&model->rays, r); + rval = CG_find_ray(&model->rays, r, &found, &scale, &index); + abort_if(rval, "CG_find_ray failed"); + if(!found) LFREE_push_ray(&model->rays, r); } if(nrows == 2) @@ -436,24 +425,6 @@ int INFINITY_generate_cut(const struct Tableau *tableau, struct Row *cut) rval = LFREE_init_conv(&lfree, tableau->nrows, max_nrays); abort_if(rval, "LFREE_init_conv failed"); -// if(tableau->nrows == 2) -// rval = INFINITY_2D_generate_lfree(&filtered_model, &lfree); -// else -// rval = INFINITY_ND_generate_lfree(&filtered_model, &lfree); -// -// if(rval) -// { -// rval = ERR_NO_CUT; -// goto CLEANUP; -// } -// -// for(int i = 0; i < filtered_model.rays.nrays; i++) -// { -// double *r = LFREE_get_ray(&filtered_model.rays, i); -// for(int j = 0; j < tableau->nrows; j++) -// r[j] *= lfree.beta[j]; -// } - rval = append_extra_rays(&filtered_model); abort_if(rval, "append_extra_rays failed"); diff --git a/infinity/library/tests/infinity-nd-test.cpp b/infinity/library/tests/infinity-nd-test.cpp index 5fbed5b..f23eb7c 100644 --- a/infinity/library/tests/infinity-nd-test.cpp +++ b/infinity/library/tests/infinity-nd-test.cpp @@ -370,6 +370,53 @@ CLEANUP: if(rval) FAIL(); } +TEST(InfinityNDTest, psi_test_3) +{ + int rval = 0; + + double f[] = { 0.671875, 0.671875 }; + double rays[] = { + -0.007812500000, 0.000000000000, + -0.039062500000, 0.046875000000, + 0.000000000000, 0.046875000000, + 0.046875000000, 0.000000000000, + 0.000000000000, -0.039062500000 + }; + + double beta[] = { + 66.909090909091, + 29.440000000000, + 14.000000000000, + 14.000000000000, + 29.440000000000, + }; + + double q[] = { 0 - f[0], 1 - f[1]}; + + struct ConvLFreeSet lfree; + lfree.f = f; + lfree.beta = beta; + lfree.rays.nrays = 5; + lfree.rays.values = rays; + lfree.nrows = lfree.rays.dim = 2; + + double value; + struct LP lp; + + rval = LP_open(&lp); + abort_if(rval, "LP_open failed"); + + rval = INFINITY_create_psi_lp(&lfree, &lp); + abort_if(rval, "INFINITY_create_psi_lp failed"); + + rval = INFINITY_psi(lfree.nrows, q, 1.0, &lp, &value); + abort_if(rval, "GREDDY_ND_psi failed"); + EXPECT_NEAR(value, 1.0, 1e-6); + +CLEANUP: + if(rval) FAIL(); +} + TEST(InfinityNDTest, generate_cut_test_1) { int rval = 0; diff --git a/infinity/library/tests/infinity-test.cpp b/infinity/library/tests/infinity-test.cpp index 69225a7..4af5aea 100644 --- a/infinity/library/tests/infinity-test.cpp +++ b/infinity/library/tests/infinity-test.cpp @@ -411,6 +411,42 @@ TEST(InfinityTest, generate_cut_test_4) lhs = CG_replace_x(&cut, x); EXPECT_LE(lhs, cut.pi_zero); +CLEANUP: + if (rval) FAIL(); +} + +TEST(InfinityTest, generate_cut_test_5) +{ + int rval = 0; + + // Extracted from instance bell5.pre.mps (MIPLIB 3) + char column_types[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; + double pi0[] = { 1.0000000000, 0.0416666667, -0.0416666667, -0.0416666667, }; + double pi1[] = { 1.0000000000, 0.0416666667, -0.0416666667, -0.0416666667, -0.0416666667, }; + int indices0[] = { 50, 64, 143, 156, }; + int indices1[] = { 49, 63, 64, 142, 155, }; + struct Row row0 = {.nz = 4, .head = 50, .pi_zero = 41.6666666667, .pi = pi0, .indices = indices0 }; + struct Row row1 = {.nz = 5, .head = 49, .pi_zero = 16.6666666667, .pi = pi1, .indices = indices1 }; + struct Row* rows[] = {&row0, &row1, }; + struct Tableau tableau = {.ncols = 169, .nrows = 2, .rows = rows, .column_types = column_types }; + double x[169] = {1.0000000000, 1.0000000000, 1.0000000000, 1.0000000000, 1.0000000000, 0.0000000000, 1.0000000000, 0.0000000000, 0.0000000000, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000, 1.0000000000, 0.0000000000, 11.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 2.0000000000, 38.0000000000, 2.0000000000, 498.0000000000, 125.0000000000, 10.0000000000, 17.0000000000, 41.0000000000, 0.0000000000, 19.0000000000, 0.0000000000, 8318.0000000000, 7494.0000000000, 60.0000000000, 10.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 18.0000000000, 8.0000000000, 16.0000000000, 334.0000000000, 24.0000000000, 792.0000000000, 792.0000000000, 336.0000000000, 336.0000000000, 0.0000000000, 40.0000000000, 166.0000000000, 3000.0000000000, 1632.0000000000, 1392.0000000000, 984.0000000000, 456.0000000000, 456.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 48.0000000000, 900.0000000000, 40.0000000000, 11950.0000000000, 240.0000000000, 408.0000000000, 984.0000000000, 0.0000000000, 456.0000000000, 0.0000000000, -0.0000000000, -0.0000000000, -0.0000000000, -0.0000000000, 1.0000000000, 0.0000000000, 1.0000000000, 1.0000000000, 0.0000000000, 1.0000000000, 1.0000000000, 20.0000000000, 20.0000000000, 20.0000000000, 19.0000000000, 19.0000000000, 0.0000000000, 9.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 20.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 238.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 12.0000000000, 8.0000000000, 2.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0053700000, 0.6917620000, 6.9221320000, 0.0000000000, 0.9966800000, 11.9862220000, 0.7510000000, 0.8495500000, 3.3519300000, 266583.5900000000, }; + + double lhs, s[2]; + struct Row cut; + LP_init_row(&cut, CG_total_nz(&tableau)); + + rval = INFINITY_generate_cut(&tableau, &cut); + abort_if(rval, "INFINITY_generate_cut failed"); + + rval = get_lattice_point(&tableau, x, s); + abort_if(rval, "get_lattice_point failed"); + + for(int i = 0; i < tableau.nrows; i++) + log_debug("s[%d] = %20.12lf\n", i, s[i]); + + lhs = CG_replace_x(&cut, x); + EXPECT_LE(lhs, cut.pi_zero); + CLEANUP: if (rval) FAIL(); } \ No newline at end of file diff --git a/multirow/include/multirow/cg.h b/multirow/include/multirow/cg.h index f345225..7abe1f7 100644 --- a/multirow/include/multirow/cg.h +++ b/multirow/include/multirow/cg.h @@ -116,4 +116,6 @@ int CG_total_nz(const struct Tableau *tableau); double CG_replace_x(const struct Row *row, const double *x); +int CG_print_model(const struct MultiRowModel *model); + #endif //MULTIROW_CG_H diff --git a/multirow/include/multirow/lfree2d.h b/multirow/include/multirow/lfree2d.h index 608cd23..c440b4f 100644 --- a/multirow/include/multirow/lfree2d.h +++ b/multirow/include/multirow/lfree2d.h @@ -40,7 +40,6 @@ struct RayList int dim; }; - struct ConvLFreeSet { double *f; @@ -82,4 +81,6 @@ int LFREE_init_conv(struct ConvLFreeSet *lfree, int dim, int max_nrays); void LFREE_free_conv(struct ConvLFreeSet *lfree); +int LFREE_print_set(const struct ConvLFreeSet *lfree); + #endif //LFREE_2D_H diff --git a/multirow/src/cg.c b/multirow/src/cg.c index 4e3d29c..733c301 100644 --- a/multirow/src/cg.c +++ b/multirow/src/cg.c @@ -1115,4 +1115,32 @@ int CG_total_nz(const struct Tableau *tableau) return total_nz; } +int CG_print_model(const struct MultiRowModel *model) +{ + int rval = 0; + int nrows = model->nrows; + + time_printf(" f = ["); + for (int i = 0; i < nrows; i++) + printf("%20.12lf ", model->f[i]); + printf("]\n"); + + for (int i = 0; i < model->rays.nrays; i++) + { + double *ray = LFREE_get_ray(&model->rays, i); + double norm = 0; + + time_printf("ray[%3d] = [", i); + for (int j = 0; j < nrows; j++) + { + printf("%20.12lf ", ray[j]); + norm += fabs(ray[j]); + } + printf("] norm=%20.12lf \n", norm); + } + +CLEANUP: + return rval; +} + #endif // TEST_SOURCE diff --git a/multirow/src/lfree2d.c b/multirow/src/lfree2d.c index 698a730..19519e3 100644 --- a/multirow/src/lfree2d.c +++ b/multirow/src/lfree2d.c @@ -559,6 +559,41 @@ CLEANUP: return rval; } +int LFREE_print_set(const struct ConvLFreeSet *set) +{ + int rval = 0; + + log_debug("f=%12.6lf %12.6lf\n", set->f[0], set->f[1]); + + for (int i = 0; i < set->rays.nrays; i++) + { + double *ray = LFREE_get_ray(&set->rays, i); + log_debug("ray[%-3d] = ", i); + for (int j = 0; j < set->nrows; j++) + printf("%20.12lf ", ray[j]); + printf("\n"); + } + + for (int i = 0; i < set->rays.nrays; i++) + { + double beta = set->beta[i]; + log_debug("beta[%-3d] = %20.12lf\n", i, beta); + } + + for (int i = 0; i < set->rays.nrays; i++) + { + double *ray = LFREE_get_ray(&set->rays, i); + double beta = set->beta[i]; + log_debug("vertex[%-3d] = ", i); + for (int j = 0; j < set->nrows; j++) + printf("%20.12lf ", ray[j] * beta + set->f[j]); + printf("\n"); + } + +CLEANUP: + return rval; +} + void LFREE_free_conv(struct ConvLFreeSet *lfree) { if(!lfree) return;