From 0ee68e01bc1c8216234d2baea3ac12cdd9c46fa6 Mon Sep 17 00:00:00 2001 From: Alinson Xavier Date: Sun, 30 Apr 2017 16:46:21 -0400 Subject: [PATCH] Reorganize files; remove dead code --- infinity/library/CMakeLists.txt | 22 +- infinity/library/include/infinity/greedy-nd.h | 74 - .../{greedy-bsearch.h => infinity-nd.h} | 33 +- infinity/library/src/greedy-bsearch.c | 246 --- .../src/{greedy-nd.c => infinity-nd.c} | 1607 +++++++++-------- infinity/library/src/infinity.c | 12 +- ...reedy-nd-test.cpp => infinity-nd-test.cpp} | 99 +- 7 files changed, 926 insertions(+), 1167 deletions(-) delete mode 100644 infinity/library/include/infinity/greedy-nd.h rename infinity/library/include/infinity/{greedy-bsearch.h => infinity-nd.h} (52%) delete mode 100644 infinity/library/src/greedy-bsearch.c rename infinity/library/src/{greedy-nd.c => infinity-nd.c} (86%) rename infinity/library/tests/{greedy-nd-test.cpp => infinity-nd-test.cpp} (77%) diff --git a/infinity/library/CMakeLists.txt b/infinity/library/CMakeLists.txt index 0ef1fe3..2b35c4f 100644 --- a/infinity/library/CMakeLists.txt +++ b/infinity/library/CMakeLists.txt @@ -1,21 +1,19 @@ set(COMMON_SOURCES - src/infinity-2d.c - src/greedy-nd.c - src/greedy-bsearch.c - src/infinity.c - include/infinity/infinity-2d.h - include/infinity/greedy-nd.h - include/infinity/greedy-bsearch.h - include/infinity/infinity.h) + src/infinity-2d.c + src/infinity-nd.c + src/infinity.c + include/infinity/infinity-2d.h + include/infinity/infinity-nd.h + include/infinity/infinity.h) set(TEST_SOURCES - tests/infinity-2d-test.cpp - tests/greedy-nd-test.cpp - tests/infinity-test.cpp) + tests/infinity-2d-test.cpp + tests/infinity-nd-test.cpp + tests/infinity-test.cpp) add_library(infinity_static ${COMMON_SOURCES}) set_target_properties(infinity_static PROPERTIES OUTPUT_NAME infinity) -target_include_directories (infinity_static PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(infinity_static PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) add_executable(infinity-test.run ${COMMON_SOURCES} ${TEST_SOURCES}) target_link_libraries(infinity-test.run gtest_main multirow_static lifting_static) diff --git a/infinity/library/include/infinity/greedy-nd.h b/infinity/library/include/infinity/greedy-nd.h deleted file mode 100644 index d37c4b8..0000000 --- a/infinity/library/include/infinity/greedy-nd.h +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2015 Alinson Xavier - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef MULTIROW_GREEDY_ND_H -#define MULTIROW_GREEDY_ND_H - -int GREEDY_create_psi_lp(const struct ConvLFreeSet *lfree, struct LP *lp); - -int GREEDY_ND_psi(const int nrows, - const double *q, - const double q_scale, - struct LP *lp, - double *value); - -int GREEDY_ND_pi(const int nrows, - const double *q, - const double q_scale, - struct LP *lp, - double *value); - -int INFINITY_ND_generate_lfree(const struct MultiRowModel *model, - struct ConvLFreeSet *lfree); - -int GREEDY_ND_cone_bound(int nrows, - int nrays, - const double *f, - const double *rays, - const int *rx, - const double *x, - const double *beta, - double *epsilon); - -int GREEDY_ND_find_violated_cone(int nrows, - int nrays, - const double *f, - const double *rays, - const double *x, - const double *beta, - double epsilon, - int *rx, - double *sbar, - int *violated_found); - -int GREEDY_ND_find_tight_rays(int nrows, - int nrays, - const double *f, - const double *rays, - const double *x, - const double *beta, - double epsilon, - int *tx); - -int GREEDY_ND_scale_to_ahull(int nrows, - int nrays, - const double *rays, - const int *rx, - const double *beta, - double epsilon, - const double *d, - double *alpha); - -#endif //MULTIROW_GREEDY_ND_H diff --git a/infinity/library/include/infinity/greedy-bsearch.h b/infinity/library/include/infinity/infinity-nd.h similarity index 52% rename from infinity/library/include/infinity/greedy-bsearch.h rename to infinity/library/include/infinity/infinity-nd.h index 49160cc..81753d5 100644 --- a/infinity/library/include/infinity/greedy-bsearch.h +++ b/infinity/library/include/infinity/infinity-nd.h @@ -13,21 +13,24 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#ifndef MULTIROW_GREEDY_BSEARCH_H -#define MULTIROW_GREEDY_BSEARCH_H +#ifndef MULTIROW_INFINITY_ND_H +#define MULTIROW_INFINITY_ND_H -int create_sfree_mip(int nrows, - int nrays, - const double *f, - const double *rays, - const double *bounds, - double e, - struct LP *lp); +int INFINITY_create_psi_lp(const struct ConvLFreeSet *lfree, struct LP *lp); -int GREEDY_BSEARCH_compute_bounds(int nrows, - int nrays, - const double *f, - const double *rays, - double *bounds); +int INFINITY_psi(const int nrows, + const double *q, + const double q_scale, + struct LP *lp, + double *value); -#endif //MULTIROW_GREEDY_BSEARCH_H +int INFINITY_pi(const int nrows, + const double *q, + const double q_scale, + struct LP *lp, + double *value); + +int INFINITY_ND_generate_lfree(const struct MultiRowModel *model, + struct ConvLFreeSet *lfree); + +#endif //MULTIROW_INFINITY_ND_H diff --git a/infinity/library/src/greedy-bsearch.c b/infinity/library/src/greedy-bsearch.c deleted file mode 100644 index b4bdfb2..0000000 --- a/infinity/library/src/greedy-bsearch.c +++ /dev/null @@ -1,246 +0,0 @@ -/* Copyright (c) 2015 Alinson Xavier - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include -#include -#include -#include -#include - -#include - -int create_sfree_mip(int nrows, - int nrays, - const double *f, - const double *rays, - const double *bounds, - double e, - struct LP *lp) -{ - int rval = 0; - - double rhs; - char sense; - - int rmatbeg = 0; - int* rmatind = 0; - double *rmatval = 0; - - rmatind = (int *) malloc((nrows + nrays) * sizeof(int)); - rmatval = (double *) malloc((nrows + nrays) * sizeof(double)); - abort_if(!rmatind, "could not allocate rmatind"); - abort_if(!rmatval, "could not allocate rmatval"); - - rval = LP_create(lp, "greedy"); - abort_if(rval, "LP_create failed"); - - // create x (basic) variables - for (int i = 0; i < nrows; i++) - { - rval = LP_new_col(lp, 0, -MILP_INFINITY, MILP_INFINITY, 'I'); - abort_if(rval, "LP_new_col failed"); - } - - // create s (non-basic) variables - for (int i = 0; i < nrays; i++) - { - rval = LP_new_col(lp, 1.0, 0, MILP_INFINITY, 'C'); - abort_if(rval, "LP_new_col failed"); - } - - // add constraint \sum_{i=1}^m s_i \leq 1 - sense = 'L'; - rhs = 1.0; - - for (int i = 0; i < nrays; i++) - { - rmatind[i] = i + nrows; - rmatval[i] = 1.0; - } - - rval = LP_add_rows(lp, 1, nrays, &rhs, &sense, &rmatbeg, rmatind, rmatval); - abort_if(rval, "LP_add_rows failed"); - - // add constraints x_i - \sum_{j=1}^m min{e,e_j} s_j R_ji = f_i - for (int i = 0; i < nrows; i++) - { - int k = 0; - sense = 'E'; - rhs = f[i]; - - rmatind[k] = i; - rmatval[k] = 1.0; - k++; - - for (int j = 0; j < nrays; j++) - { - rmatind[k] = j + nrows; - rmatval[k] = -rays[nrows * j + i] * fmin(e, bounds[j]); - k++; - } - - rval = LP_add_rows(lp, 1, nrays + 1, &rhs, &sense, &rmatbeg, rmatind, - rmatval); - abort_if(rval, "LP_add_rows failed"); - } - -CLEANUP: - if (rmatind) free(rmatind); - if (rmatval) free(rmatval); - return rval; -} - -int GREEDY_BSEARCH_compute_bounds(int nrows, - int nrays, - const double *f, - const double *rays, - double *bounds) -{ - int rval = 0; - - struct LP lp; - double e_upper = 2 * GREEDY_BIG_E; - double e_lower = 0.0; - - int cplex_count = 0; - double cplex_time = 0; - - int iteration_count = 0; - - double *x = 0; - - x = (double *) malloc((nrays + nrows) * sizeof(double)); - abort_if(!x, "could not allocate x"); - - for (int i = 0; i < nrays; i++) - bounds[i] = GREEDY_BIG_E; - - for (int it = 0;; it++) - { - abort_if(it > 2*nrays, "stuck in an infinite loop"); - - log_verbose("Starting iteration %d...\n", it); - - iteration_count++; - - - int solution_found = 0; - int inner_count = 0; - - while (fabs(e_upper - e_lower) > GREEDY_MAX_GAP) - { - inner_count++; - - double e = (e_upper + e_lower) / 2; - log_verbose(" e=%.12lf\n", e); - - rval = LP_open(&lp); - abort_if(rval, "LP_open failed"); - - rval = create_sfree_mip(nrows, nrays, f, rays, bounds, e, &lp); - abort_if(rval, "create_sfree_mip failed"); - - if_verbose_level - { - rval = LP_write(&lp, "greedy.lp"); - abort_if(rval, "LP_write failed"); - } - - int infeasible; - cplex_count++; - - double initial_time = get_user_time(); - - log_verbose(" Optimizing...\n"); - rval = LP_optimize(&lp, &infeasible); - if (rval) - { - // Workaround for CPLEX bug. If CPLEX tell us that this problem - // is unbounded, we disable presolve and try again. - LP_free(&lp); - LP_open(&lp); - - rval = create_sfree_mip(nrows, nrays, f, rays, bounds, e, &lp); - abort_if(rval, "create_sfree_mip failed"); - - LP_disable_presolve(&lp); - - rval = LP_optimize(&lp, &infeasible); - abort_if(rval, "LP_optimize failed"); - } - - cplex_time += get_user_time() - initial_time; - - if (infeasible) - { - e_lower = e; - log_verbose(" infeasible\n"); - if (e > GREEDY_BIG_E-1) - { - LP_free(&lp); - goto OUT; - } - } - else - { - log_verbose(" feasible\n"); - e_upper = e; - solution_found = 1; - - rval = LP_get_x(&lp, x); - abort_if(rval, "LP_get_x failed"); - } - - LP_free(&lp); - } - - if (solution_found) - { - for (int j = 0; j < nrays; j++) - { - if (!DOUBLE_geq(x[nrows + j], 0.001)) continue; - bounds[j] = fmin(bounds[j] * 0.99, e_lower * 0.99); - } - } - - log_verbose(" %d iterations %12.8lf gap\n", inner_count, e_upper - - e_lower); - - e_lower = e_upper; - e_upper = 2 * GREEDY_BIG_E; - } - -OUT: - log_debug(" %6d IPs (%.2lfms per call, %.2lfs total)\n", cplex_count, - cplex_time * 1000.0 / cplex_count, cplex_time); - - for(int i = 0; i < nrays; i++) - abort_if(DOUBLE_iszero(bounds[i]), "bounds should be positive"); - - if_verbose_level - { - time_printf("Bounds:\n"); - for (int k = 0; k < nrays; k++) - time_printf(" %12.8lf %12.8lf\n", k, bounds[k], 1 / bounds[k]); - } - -CLEANUP: - if (x) free(x); - return rval; -} diff --git a/infinity/library/src/greedy-nd.c b/infinity/library/src/infinity-nd.c similarity index 86% rename from infinity/library/src/greedy-nd.c rename to infinity/library/src/infinity-nd.c index 1adfdf9..6203f38 100644 --- a/infinity/library/src/greedy-nd.c +++ b/infinity/library/src/infinity-nd.c @@ -21,8 +21,7 @@ #include #include -#include -#include +#include static long lp_count = 0; static double lp_time = 0; @@ -42,232 +41,84 @@ static double sfree_mip_time = 0; static long scale_ahull_lp_count = 0; static double scale_ahull_lp_time = 0; -static int find_interior_point_enum(const int nrows, - const int nrays, - const double *f, - const double *rays, - const double *beta, - const double epsilon, - double *x, - int *found) -{ - int rval = 0; - - int M = 1; - struct LP lp; - double best_value = INFINITY; - double *beta2 = 0; - - abort_if(nrows != 3, "not implemented"); - - beta2 = (double *) malloc(nrays * sizeof(double)); - abort_if(!beta2, "could not allocate beta2"); - - for(int i = 0; i < nrays; i++) - { - beta2[i] = fmin(epsilon, beta[i]); - } - - rval = LP_open(&lp); - abort_if(rval, "LP_open failed"); - - struct ConvLFreeSet lfree; - lfree.f = (double*) f; - lfree.nrows = nrows; - lfree.rays.dim = nrows; - lfree.rays.nrays = nrays; - lfree.rays.values = (double*) rays; - lfree.beta = beta2; - - rval = GREEDY_create_psi_lp(&lfree, &lp); - abort_if(rval, "GREEDY_create_psi_lp failed"); - - *found = 0; - - for(int x1 = -M; x1 <= M; x1++) - for(int x2 = -M; x2 <= M; x2++) - for(int x3 = -M; x3 <= M; x3++) - { - double value; - double q[3] = {x1 - f[0], - x2 - f[1], - x3 - f[2]}; - - rval = GREEDY_ND_psi(nrows, q, 1, &lp, &value); - abort_if(rval, "GREEDY_ND_psi failed"); - - if(value < best_value) - { - best_value = value; - x[0] = x1; - x[1] = x2; - x[2] = x3; - } - } - - if(best_value < 0.999) *found = 1; - -CLEANUP: - if(beta2) free(beta2); - LP_free(&lp); - return rval; -} - -static int find_interior_point_cplex(const int nrows, - const int nrays, - const double *f, - const double *rays, - const double *beta, - const double epsilon, - double *x, - int *found) +static int create_sfree_mip(int nrows, + int nrays, + const double *f, + const double *rays, + const double *bounds, + double e, + struct LP *lp) { int rval = 0; - struct LP lp; - double initial_time; - int infeasible; - double objval; - rval = LP_open(&lp); - abort_if(rval, "LP_open failed"); + double rhs; + char sense; - lp_count++; - sfree_mip_count++; - initial_time = get_user_time(); + int rmatbeg = 0; + int* rmatind = 0; + double *rmatval = 0; - rval = create_sfree_mip(nrows, nrays, f, rays, beta, epsilon, &lp); - abort_if(rval, "greate_sfree_mip failed"); + rmatind = (int *) malloc((nrows + nrays) * sizeof(int)); + rmatval = (double *) malloc((nrows + nrays) * sizeof(double)); + abort_if(!rmatind, "could not allocate rmatind"); + abort_if(!rmatval, "could not allocate rmatval"); - log_debug(" solving sfree mip...\n"); - rval = LP_optimize(&lp, &infeasible); - if(rval == ERR_MIP_TIMEOUT) goto CLEANUP; - abort_if(rval, "LP_optimize failed"); + rval = LP_create(lp, "greedy"); + abort_if(rval, "LP_create failed"); - if(infeasible) + // create x (basic) variables + for (int i = 0; i < nrows; i++) { - log_debug(" mip is infeasible. Stopping.\n"); - *found = 0; - goto CLEANUP; + rval = LP_new_col(lp, 0, -MILP_INFINITY, MILP_INFINITY, 'I'); + abort_if(rval, "LP_new_col failed"); } - rval = LP_get_x(&lp, x); - abort_if(rval, "LP_get_x failed"); - - if_verbose_level + // create s (non-basic) variables + for (int i = 0; i < nrays; i++) { - for(int i = 0; i < nrows; i++) - log_verbose(" x%d = %.8lf\n", i, x[i]); - - for(int i = 0; i < nrays; i++) - if(x[i + nrows] > 0.00001) - log_verbose(" t%d = %.8lf\n", i, x[i + nrows]); + rval = LP_new_col(lp, 1.0, 0, MILP_INFINITY, 'C'); + abort_if(rval, "LP_new_col failed"); } - rval = LP_get_obj_val(&lp, &objval); - abort_if(rval, "LP_get_obj_val failed"); - - log_debug(" obj = %.8lf\n", objval); + // add constraint \sum_{i=1}^m s_i \leq 1 + sense = 'L'; + rhs = 1.0; - if(objval >= 0.999) + for (int i = 0; i < nrays; i++) { - log_debug(" set is lattice-free\n"); - *found = 0; - goto CLEANUP; + rmatind[i] = i + nrows; + rmatval[i] = 1.0; } - *found = 1; - - sfree_mip_time += get_user_time() - initial_time; - lp_time += get_user_time() - initial_time; - -CLEANUP: - LP_free(&lp); - return rval; -} - -static int bound(int nrows, - int nrays, - const double *f, - const double *rays, - const double *x, - const double *beta, - double *epsilon, - int *tx) -{ - int rval = 0; - - int found; - int *rx = 0; - double *fbar = 0; - double *sbar = 0; - - double prev_epsilon; - int count = 0; - *epsilon = GREEDY_BIG_E; - - rx = (int *) malloc(nrays * sizeof(int)); - fbar = (double *) malloc(nrows * sizeof(double)); - sbar = (double *) malloc(nrays * sizeof(double)); - - abort_if(!rx, "could not allocate rx"); - abort_if(!fbar, "could not allocate fbar"); - abort_if(!sbar, "could not allocate sbar"); + rval = LP_add_rows(lp, 1, nrays, &rhs, &sense, &rmatbeg, rmatind, rmatval); + abort_if(rval, "LP_add_rows failed"); - while(1) + // add constraints x_i - \sum_{j=1}^m min{e,e_j} s_j R_ji = f_i + for (int i = 0; i < nrows; i++) { - count++; - abort_if(count > 100, "infinite loop"); - - rval = GREEDY_ND_find_violated_cone(nrows, nrays, f, rays, x, beta, - *epsilon, rx, sbar, &found); - abort_if(rval, "GREEDY_ND_find_violated_cone failed"); - - if(!found) break; + int k = 0; + sense = 'E'; + rhs = f[i]; - for(int i = 0; i < nrows; i++) - fbar[i] = x[i]; + rmatind[k] = i; + rmatval[k] = 1.0; + k++; - for(int j = 0; j < nrays; j++) + for (int j = 0; j < nrays; j++) { - if(!rx[j]) continue; - const double *r = &rays[nrows * j]; - - for(int i = 0; i < nrows; i++) - fbar[i] -= min(*epsilon, beta[j]) * r[i] * sbar[j]; + rmatind[k] = j + nrows; + rmatval[k] = -rays[nrows * j + i] * fmin(e, bounds[j]); + k++; } - log_verbose("%.12lf %.12lf\n", f[0], f[1]); - log_verbose("%.12lf %.12lf\n", fbar[0], fbar[1]); - - prev_epsilon = *epsilon; - - rval = GREEDY_ND_cone_bound(nrows, nrays, fbar, rays, rx, x, beta, - epsilon); - abort_if(rval, "GREEDY_ND_cone_bound failed"); - - log_verbose(" e=%.12lf\n", *epsilon); - abort_if(prev_epsilon < *epsilon, "epsilon should never increase"); - } - - for(int i = 0; i < nrays; i++) - tx[i] = 0; - - if(DOUBLE_geq(*epsilon, GREEDY_BIG_E)) - { - *epsilon = INFINITY; - goto CLEANUP; - } - else - { - rval = GREEDY_ND_find_tight_rays(nrows, nrays, fbar, rays, x, beta, - *epsilon, tx); - abort_if(rval, "GREEDY_ND_find_tight_rays failed"); + rval = LP_add_rows(lp, 1, nrays + 1, &rhs, &sense, &rmatbeg, rmatind, + rmatval); + abort_if(rval, "LP_add_rows failed"); } CLEANUP: - if(sbar) free(sbar); - if(fbar) free(fbar); - if(rx) free(rx); + if (rmatind) free(rmatind); + if (rmatval) free(rmatval); return rval; } @@ -422,14 +273,15 @@ CLEANUP: return rval; } -static int create_violated_cone_lp(int nrows, - int nrays, - const double *f, - const double *rays, - const double *x, - const double *beta, - double epsilon, - struct LP *lp) +static int create_tight_rays_lp(int nrows, + int nrays, + const double *f, + const double *rays, + const double *x, + const double *beta, + double epsilon, + double delta, + struct LP *lp) { int rval = 0; @@ -445,17 +297,24 @@ static int create_violated_cone_lp(int nrows, abort_if(!rmatind, "could not allocate rmatind"); abort_if(!rmatval, "could not allocate rmatval"); - rval = LP_create(lp, "violated_cone"); + rval = LP_create(lp, "tight_rays"); abort_if(rval, "LP_create failed"); - // create s variables + // create lambda variables for(int i = 0; i < nrays; i++) { rval = LP_new_col(lp, 1.0, 0.0, MILP_INFINITY, 'C'); abort_if(rval, "LP_new_col failed"); } - // create constraint x = f + \sum(min{e, beta[r]} * r * s_r) + // create s variables + for(int i = 0; i < nrays; i++) + { + rval = LP_new_col(lp, 0.0, 0.0, MILP_INFINITY, 'C'); + abort_if(rval, "LP_new_col failed"); + } + + // create constraint x = f + \sum_{r \in R} min{e, beta[r]} * r * s_r for(int j = 0; j < nrows; j++) { sense = 'E'; @@ -464,7 +323,7 @@ static int create_violated_cone_lp(int nrows, for(int i = 0; i < nrays; i++) { const double *ri = &rays[i * nrows]; - rmatind[i] = i; + rmatind[i] = nrays + i; rmatval[i] = min(epsilon, beta[i]) * ri[j]; if(DOUBLE_iszero(rmatval[i])) rmatval[i] = 0.0; } @@ -474,20 +333,114 @@ static int create_violated_cone_lp(int nrows, abort_if(rval, "LP_add_rows failed"); } - rval = LP_relax(lp); - abort_if(rval, "LP_relax failed"); + // create constraint \sum_{r \in R} s_r = 1 + sense = 'E'; + rhs = 1.0; - //rval = LP_write(lp, "violated-cone.lp"); - //abort_if(rval, "LP_write failed"); - //UTIL_pause(); + for(int i = 0; i < nrays; i++) + { + rmatind[i] = nrays + i; + rmatval[i] = 1.0; + } -CLEANUP: - if(rmatind) free(rmatind); - if(rmatval) free(rmatval); - return rval; -} + rval = LP_add_rows(lp, 1, nrays, &rhs, &sense, &rmatbeg, rmatind, rmatval); + abort_if(rval, "LP_add_rows failed"); -static int create_scale_to_ahull_lp(int nrows, + // create constraints \lambda_r + s_r \geq \delta + for(int i = 0; i < nrays; i++) + { + sense = 'G'; + rhs = delta; + + rmatind[0] = i; + rmatval[0] = 1.0; + + rmatind[1] = nrays + i; + rmatval[1] = 1.0; + + rval = LP_add_rows(lp, 1, 2, &rhs, &sense, &rmatbeg, rmatind, rmatval); + abort_if(rval, "LP_add_rows failed"); + } + + rval = LP_relax(lp); + abort_if(rval, "LP_relax failed"); + + //rval = LP_write(lp, "tight-rays.lp"); + //abort_if(rval, "LP_write failed"); + + +CLEANUP: + if(rmatind) free(rmatind); + if(rmatval) free(rmatval); + return rval; +} + +static int create_violated_cone_lp(int nrows, + int nrays, + const double *f, + const double *rays, + const double *x, + const double *beta, + double epsilon, + struct LP *lp) +{ + int rval = 0; + + double rhs; + char sense; + + int rmatbeg = 0; + int *rmatind = 0; + double *rmatval = 0; + + rmatind = (int *) malloc(nrays * sizeof(int)); + rmatval = (double *) malloc(nrays * sizeof(double)); + abort_if(!rmatind, "could not allocate rmatind"); + abort_if(!rmatval, "could not allocate rmatval"); + + rval = LP_create(lp, "violated_cone"); + abort_if(rval, "LP_create failed"); + + // create s variables + for(int i = 0; i < nrays; i++) + { + rval = LP_new_col(lp, 1.0, 0.0, MILP_INFINITY, 'C'); + abort_if(rval, "LP_new_col failed"); + } + + // create constraint x = f + \sum(min{e, beta[r]} * r * s_r) + for(int j = 0; j < nrows; j++) + { + sense = 'E'; + rhs = x[j] - f[j]; + + for(int i = 0; i < nrays; i++) + { + const double *ri = &rays[i * nrows]; + rmatind[i] = i; + rmatval[i] = min(epsilon, beta[i]) * ri[j]; + if(DOUBLE_iszero(rmatval[i])) rmatval[i] = 0.0; + } + + rval = LP_add_rows(lp, 1, nrays, &rhs, &sense, &rmatbeg, rmatind, + rmatval); + abort_if(rval, "LP_add_rows failed"); + } + + rval = LP_relax(lp); + abort_if(rval, "LP_relax failed"); + + //rval = LP_write(lp, "violated-cone.lp"); + //abort_if(rval, "LP_write failed"); + //UTIL_pause(); + +CLEANUP: + if(rmatind) free(rmatind); + if(rmatval) free(rmatval); + return rval; +} + +static int create_scale_to_ahull_lp(int nrows, int nrays, const double *rays, const int *rx, @@ -583,754 +536,880 @@ CLEANUP: return rval; } -static int create_tight_rays_lp(int nrows, - int nrays, - const double *f, - const double *rays, - const double *x, - const double *beta, - double epsilon, - double delta, - struct LP *lp) +static int find_interior_point_enum(const int nrows, + const int nrays, + const double *f, + const double *rays, + const double *beta, + const double epsilon, + double *x, + int *found) { int rval = 0; - double rhs; - char sense; - - int rmatbeg = 0; - int *rmatind = 0; - double *rmatval = 0; - - rmatind = (int *) malloc(nrays * sizeof(int)); - rmatval = (double *) malloc(nrays * sizeof(double)); - abort_if(!rmatind, "could not allocate rmatind"); - abort_if(!rmatval, "could not allocate rmatval"); - - rval = LP_create(lp, "tight_rays"); - abort_if(rval, "LP_create failed"); - - // create lambda variables - for(int i = 0; i < nrays; i++) - { - rval = LP_new_col(lp, 1.0, 0.0, MILP_INFINITY, 'C'); - abort_if(rval, "LP_new_col failed"); - } - - // create s variables - for(int i = 0; i < nrays; i++) - { - rval = LP_new_col(lp, 0.0, 0.0, MILP_INFINITY, 'C'); - abort_if(rval, "LP_new_col failed"); - } - - // create constraint x = f + \sum_{r \in R} min{e, beta[r]} * r * s_r - for(int j = 0; j < nrows; j++) - { - sense = 'E'; - rhs = x[j] - f[j]; - - for(int i = 0; i < nrays; i++) - { - const double *ri = &rays[i * nrows]; - rmatind[i] = nrays + i; - rmatval[i] = min(epsilon, beta[i]) * ri[j]; - if(DOUBLE_iszero(rmatval[i])) rmatval[i] = 0.0; - } + int M = 1; + struct LP lp; + double best_value = INFINITY; + double *beta2 = 0; - rval = LP_add_rows(lp, 1, nrays, &rhs, &sense, &rmatbeg, rmatind, - rmatval); - abort_if(rval, "LP_add_rows failed"); - } + abort_if(nrows != 3, "not implemented"); - // create constraint \sum_{r \in R} s_r = 1 - sense = 'E'; - rhs = 1.0; + beta2 = (double *) malloc(nrays * sizeof(double)); + abort_if(!beta2, "could not allocate beta2"); for(int i = 0; i < nrays; i++) { - rmatind[i] = nrays + i; - rmatval[i] = 1.0; + beta2[i] = fmin(epsilon, beta[i]); } - rval = LP_add_rows(lp, 1, nrays, &rhs, &sense, &rmatbeg, rmatind, rmatval); - abort_if(rval, "LP_add_rows failed"); + rval = LP_open(&lp); + abort_if(rval, "LP_open failed"); - // create constraints \lambda_r + s_r \geq \delta - for(int i = 0; i < nrays; i++) - { - sense = 'G'; - rhs = delta; + struct ConvLFreeSet lfree; + lfree.f = (double*) f; + lfree.nrows = nrows; + lfree.rays.dim = nrows; + lfree.rays.nrays = nrays; + lfree.rays.values = (double*) rays; + lfree.beta = beta2; - rmatind[0] = i; - rmatval[0] = 1.0; + rval = INFINITY_create_psi_lp(&lfree, &lp); + abort_if(rval, "INFINITY_create_psi_lp failed"); - rmatind[1] = nrays + i; - rmatval[1] = 1.0; + *found = 0; - rval = LP_add_rows(lp, 1, 2, &rhs, &sense, &rmatbeg, rmatind, rmatval); - abort_if(rval, "LP_add_rows failed"); - } + for(int x1 = -M; x1 <= M; x1++) + for(int x2 = -M; x2 <= M; x2++) + for(int x3 = -M; x3 <= M; x3++) + { + double value; + double q[3] = {x1 - f[0], + x2 - f[1], + x3 - f[2]}; - rval = LP_relax(lp); - abort_if(rval, "LP_relax failed"); + rval = INFINITY_psi(nrows, q, 1, &lp, &value); + abort_if(rval, "INFINITY_psi failed"); - //rval = LP_write(lp, "tight-rays.lp"); - //abort_if(rval, "LP_write failed"); + if(value < best_value) + { + best_value = value; + x[0] = x1; + x[1] = x2; + x[2] = x3; + } + } + if(best_value < 0.999) *found = 1; CLEANUP: - if(rmatind) free(rmatind); - if(rmatval) free(rmatval); + if(beta2) free(beta2); + LP_free(&lp); return rval; } -#ifndef TEST_SOURCE - -int GREEDY_create_psi_lp(const struct ConvLFreeSet *lfree, struct LP *lp) +static int find_interior_point_cplex(const int nrows, + const int nrays, + const double *f, + const double *rays, + const double *beta, + const double epsilon, + double *x, + int *found) { int rval = 0; + struct LP lp; + double initial_time; + int infeasible; + double objval; - int rmatbeg = 0; - int *rmatind = 0; - double *rmatval = 0; - - int nrows = lfree->nrows; - int nrays = lfree->rays.nrays; - double *rays = lfree->rays.values; - double *beta = lfree->beta; + rval = LP_open(&lp); + abort_if(rval, "LP_open failed"); - rmatind = (int *) malloc(nrays * sizeof(int)); - rmatval = (double *) malloc(nrays * sizeof(double)); - abort_if(!rmatind, "could not allocate rmatind"); - abort_if(!rmatval, "could not allocate rmatval"); + lp_count++; + sfree_mip_count++; + initial_time = get_user_time(); - rval = LP_create(lp, "psi"); - abort_if(rval, "LP_create failed"); + rval = create_sfree_mip(nrows, nrays, f, rays, beta, epsilon, &lp); + abort_if(rval, "greate_sfree_mip failed"); - // create lambda variables - for(int i = 0; i < nrays; i++) + log_debug(" solving sfree mip...\n"); + rval = LP_optimize(&lp, &infeasible); + if(rval == ERR_MIP_TIMEOUT) goto CLEANUP; + abort_if(rval, "LP_optimize failed"); + + if(infeasible) { - rval = LP_new_col(lp, 1.0, 0, MILP_INFINITY, 'C'); - abort_if(rval, "LP_new_col failed"); + log_debug(" mip is infeasible. Stopping.\n"); + *found = 0; + goto CLEANUP; } - // create constraint 0 = \sum_{i=1}^m \lambda_i r^i_j beta_i - for(int j = 0; j < nrows; j++) + rval = LP_get_x(&lp, x); + abort_if(rval, "LP_get_x failed"); + + if_verbose_level { - char sense = 'E'; - double rhs = 0; - int nz = 0; + for(int i = 0; i < nrows; i++) + log_verbose(" x%d = %.8lf\n", i, x[i]); for(int i = 0; i < nrays; i++) - { - const double *ri = &rays[i * nrows]; - rmatind[nz] = i; - rmatval[nz] = ri[j] * beta[i]; - nz++; - } - - rval = LP_add_rows(lp, 1, nz, &rhs, &sense, &rmatbeg, rmatind, rmatval); - abort_if(rval, "LP_add_rows failed"); + if(x[i + nrows] > 0.00001) + log_verbose(" t%d = %.8lf\n", i, x[i + nrows]); } - rval = LP_relax(lp); - abort_if(rval, "LP_relax failed"); + rval = LP_get_obj_val(&lp, &objval); + abort_if(rval, "LP_get_obj_val failed"); - if_verbose_level + log_debug(" obj = %.8lf\n", objval); + + if(objval >= 0.999) { - rval = LP_write(lp, "psi.lp"); - abort_if(rval, "LP_write failed"); + log_debug(" set is lattice-free\n"); + *found = 0; + goto CLEANUP; } + *found = 1; + + sfree_mip_time += get_user_time() - initial_time; + lp_time += get_user_time() - initial_time; + CLEANUP: - if(rmatind) free(rmatind); - if(rmatval) free(rmatval); + LP_free(&lp); return rval; } -int GREEDY_ND_pi(const int nrows, - const double *q, - const double q_scale, - struct LP *lp, - double *value) +static int cone_bound(int nrows, + int nrays, + const double *f, + const double *rays, + const int *rx, + const double *x, + const double *beta, + double *epsilon) { + log_verbose(" find_epsilon\n"); int rval = 0; - abort_if(nrows > 3, "not implemented"); + int *t = 0; + long it = 0; - double best_value = 1e100; + t = (int *) malloc(nrays * sizeof(int)); + abort_if(!t, "could not allocate t"); - if(nrows == 2) + for(int i = 0; i < nrays; i++) + t[i] = 0; + + while(1) { - int M = 2; - for(int k0 = -M; k0 <= M; k0++) - for(int k1 = -M; k1 <= M; k1++) - { - double v; - double qk[] = {frac(q[0] * q_scale) + k0, - frac(q[1] * q_scale) + k1}; + it++; + log_verbose("Starting iteration %d...\n", it); - rval = GREEDY_ND_psi(nrows, qk, 1, lp, &v); - abort_if(rval, "GREEDY_ND_psi failed"); + struct LP lp; - best_value = min(best_value, v); - } - } + double initial_time = get_user_time(); + rval = LP_open(&lp); + abort_if(rval, "LP_open failed"); - if(nrows == 3) - { - int M = 2; - for(int k0 = -M; k0 <= M; k0++) - for(int k1 = -M; k1 <= M; k1++) - for(int k2 = -M; k2 <= M; k2++) - { - double v; - double qk[] = {frac(q[0] * q_scale) + k0, - frac(q[1] * q_scale) + k1, - frac(q[2] * q_scale) + k2}; + rval = create_find_epsilon_lp(nrows, nrays, f, rays, t, rx, x, beta, + &lp); + abort_if(rval, "create_find_epsilon_lp failed"); - rval = GREEDY_ND_psi(nrows, qk, 1, lp, &v); - abort_if(rval, "GREEDY_ND_psi failed"); + int infeasible; + rval = LP_optimize(&lp, &infeasible); + abort_if(rval, "LP_optimize failed"); - best_value = min(best_value, v); - } - } + lp_count++; + lp_time += get_user_time() - initial_time; - *value = best_value; + epsilon_lp_count++; + epsilon_lp_time += get_user_time() - initial_time; -CLEANUP: - return rval; -} + if(infeasible) + { + *epsilon = INFINITY; + log_verbose(" infeasible\n"); + LP_free(&lp); + goto CLEANUP; + } -/* - * Given a point f, a list of rays r1,...,rm, some real numbers b1,...,bm, a - * point q, and a real number q_scale, this function evaluates psi_B(q * - * q_scale), where B is the convex hull of {f + ri * bi}_i=1^m. - */ -int GREEDY_ND_psi(const int nrows, - const double *q, - const double q_scale, - struct LP *lp, - double *value) -{ - int rval = 0; + double obj; + rval = LP_get_obj_val(&lp, &obj); + abort_if(rval, "LP_get_obj_val failed"); - for(int j = 0; j < nrows; j++) - { - rval = LP_change_rhs(lp, j, q[j] * q_scale); - abort_if(rval, "LP_change_rhs failed"); - } + log_verbose(" obj=%.6lf\n", obj); - int infeasible; - rval = LP_optimize(lp, &infeasible); - abort_if(rval, "LP_optimize failed"); + for(int i = 0; i < nrays; i++) + { + if(!rx[i]) continue; + log_verbose(" beta[%d]=%.6lf\n", i, beta[i]); + } - if(infeasible) - { - *value = INFINITY; - } - else - { - rval = LP_get_obj_val(lp, value); - abort_if(rval, "LP_get_obj_val failed"); + LP_free(&lp); + + double e_min = INFINITY; + double e_max = -INFINITY; + + for(int i = 0; i < nrays; i++) + { + if(!rx[i] || t[i]) continue; + e_min = min(e_min, beta[i]); + } + + for(int i = 0; i < nrays; i++) + { + if(!rx[i]) continue; + e_max = fmax(e_max, beta[i]); + } + + log_verbose(" e_max=%.6lf\n", e_max); + log_verbose(" e_min=%.6lf\n", e_min); + + if(DOUBLE_leq(obj, e_min)) + { + if(DOUBLE_geq(obj, e_max)) + *epsilon = INFINITY; + else + *epsilon = obj; + + goto CLEANUP; + } + else + { + for(int i = 0; i < nrays; i++) + if(rx[i] && DOUBLE_eq(beta[i], e_min)) + t[i] = 1; + } } CLEANUP: + log_verbose(" e=%.6lf\n", *epsilon); + if(t) free(t); return rval; } -int INFINITY_ND_generate_lfree(const struct MultiRowModel *model, - struct ConvLFreeSet *lfree) +static int find_tight_rays(int nrows, + int nrays, + const double *f, + const double *rays, + const double *x, + const double *beta, + double epsilon, + int *tx) { + log_verbose(" find_tight_rays\n"); int rval = 0; - int nrows = model->nrows; - int nrays = model->rays.nrays; + int infeasible = 0; + double initial_time = 0; + const double delta = 0.001; - double *f = lfree->f; - double *rays = lfree->rays.values; - double *beta = lfree->beta; + struct LP lp; + double *sbar = 0; - lfree->nrows = model->nrows; - lfree->rays.nrays = nrays; - memcpy(rays, model->rays.values, nrays * nrows * sizeof(double)); - memcpy(f, model->f, nrows * sizeof(double)); + sbar = (double *) malloc(2 * nrays * sizeof(double)); + abort_if(!sbar, "could not allocate sbar"); - double *x = 0; + initial_time = get_user_time(); + rval = LP_open(&lp); + abort_if(rval, "LP_open failed"); - int *t = 0; - int *tx = 0; + rval = create_tight_rays_lp(nrows, nrays, f, rays, x, beta, epsilon, delta, + &lp); + abort_if(rval, "create_tight_rays_lp failed"); - t = (int *) malloc(nrays * sizeof(int)); - tx = (int *) malloc(nrays * sizeof(int)); - abort_if(!t, "could not allocate t"); - abort_if(!tx, "could not allocate tx"); + rval = LP_optimize(&lp, &infeasible); + abort_if(rval, "LP_optimize failed"); - x = (double *) malloc((nrows + nrays) * sizeof(double)); - abort_if(!x, "could not allocate x"); + lp_count++; + lp_time += get_user_time() - initial_time; - for(int i = 0; i < nrays; i++) - beta[i] = GREEDY_BIG_E; + tight_lp_count++; + tight_lp_time += get_user_time() - initial_time; - int it = 0; + abort_if(infeasible, "tight_rays_lp is infeasible"); - //lp_time = 0; - //lp_count = 0; + rval = LP_get_x(&lp, sbar); + abort_if(rval, "LP_get_x failed"); - //epsilon_lp_count = 0; - //epsilon_lp_time = 0; - // - //sfree_mip_count = 0; - //sfree_mip_time = 0; + for(int i = 0; i < nrays; i++) + tx[i] = DOUBLE_iszero(sbar[i]); - //tight_lp_count = 0; - //tight_lp_time = 0; + for(int i = 0; i < nrays; i++) + log_verbose(" tx[%d]=%d\n", i, tx[i]); - //violated_lp_count = 0; - //violated_lp_time = 0; +CLEANUP: + if(sbar) free(sbar); + LP_free(&lp); + return rval; +} - //scale_ahull_lp_time = 0; - //scale_ahull_lp_count = 0; +static int find_violated_cone(int nrows, + int nrays, + const double *f, + const double *rays, + const double *x, + const double *beta, + double epsilon, + int *rx, + double *sbar, + int *violated_found) +{ + log_verbose(" find_violated_cone\n"); + int rval = 0; - long x_count = 0; - double epsilon; + struct LP lp; - for(int i = 0; i < nrows; i++) - log_verbose(" f[%d] = %.12lf\n", i, f[i]); + double initial_time = get_user_time(); - while(1) - { - it++; - abort_if(it > 10 * nrays, "infinite loop"); + rval = LP_open(&lp); + abort_if(rval, "LP_open failed"); - log_debug("Starting iteration %d...\n", it); - epsilon = INFINITY; + rval = create_violated_cone_lp(nrows, nrays, f, rays, x, beta, epsilon, + &lp); + abort_if(rval, "create_violated_cone_lp failed"); - for(int i = 0; i < nrays; i++) - t[i] = 0; + int infeasible; + rval = LP_optimize(&lp, &infeasible); + abort_if(rval, "LP_optimize failed"); - for(int i = 0; i < nrows; i++) - x[i] = 0; + lp_count++; + lp_time += get_user_time() - initial_time; - while(1) - { - log_debug(" epsilon = %.8lf\n", epsilon); + violated_lp_count++; + violated_lp_time += get_user_time() - initial_time; - int found = 0; + rval = LP_get_x(&lp, sbar); + abort_if(rval, "LP_get_x failed"); - if(nrows == 3) - { - rval = find_interior_point_enum(nrows, nrays, f, - model->rays.values, beta, epsilon, x, &found); - abort_if(rval, "find_interior_point_enum failed"); - } + for(int i = 0; i < nrays; i++) + rx[i] = 0; - if(!found) - { - rval = find_interior_point_cplex(nrows, nrays, f, - model->rays.values, beta, epsilon, x, &found); - if(rval == ERR_MIP_TIMEOUT) goto CLEANUP; - abort_if(rval, "find_interior_point_cplex failed"); - if(!found) break; - } + if(infeasible) + goto CLEANUP; - log_debug(" found interior point:\n"); - for(int i = 0; i < nrows; i++) log_debug(" %.2lf\n", x[i]); + double obj; + rval = LP_get_obj_val(&lp, &obj); + abort_if(rval, "LP_get_obj_val failed"); - x_count++; - abort_if(x_count > 1000, "infinite loop"); + log_verbose(" o=%.8lf\n", obj); - double epsilon_x; - rval = bound(nrows, nrays, f, model->rays.values, x, beta, - &epsilon_x, tx); - abort_if(rval, "bound failed"); -// epsilon_x *= 0.999; + if(DOUBLE_geq(obj, 0.999)) + { + *violated_found = 0; + } + else + { + *violated_found = 1; - if(isinf(epsilon_x)) break; + log_verbose("Violated cone found\n"); + log_verbose(" f=%.8lf %.8lf\n", f[0], f[1]); + log_verbose(" x=%.8lf %.8lf\n", x[0], x[1]); - log_debug(" epsilon_x = %.8lf\n", epsilon_x); + for(int i = 0; i < nrays; i++) + { + rx[i] = (sbar[i] > 1e-9); - if(DOUBLE_eq(epsilon_x, epsilon)) + if(rx[i]) if_verbose_level { - for(int i = 0; i < nrays; i++) - if(tx[i]) t[i] = 1; - } - else if(epsilon_x < epsilon) - { - epsilon = epsilon_x; - for(int i = 0; i < nrays; i++) - t[i] = tx[i]; + double m = min(epsilon, beta[i]); + const double *r = &rays[nrows * i]; + time_printf(" r[%d]=%.8lf %.8lf\n", i, r[0], r[1]); + time_printf(" r[%d]=%.8lf %.8lf\n", i, m * r[0], m * r[1]); } } + } - if(isinf(epsilon)) - break; +CLEANUP: + LP_free(&lp); + return rval; +} - int skip_ahull = 0; +static int bound(int nrows, + int nrays, + const double *f, + const double *rays, + const double *x, + const double *beta, + double *epsilon, + int *tx) +{ + int rval = 0; - for(int i = 0; i < nrays; i++) - { - if(t[i]) - { - beta[i] = min(beta[i], epsilon); -// beta[i] *= 0.999; - } - else if(!skip_ahull) - { - double alpha; - const double *d = LFREE_get_ray(&model->rays, i); + int found; + int *rx = 0; + double *fbar = 0; + double *sbar = 0; - rval = GREEDY_ND_scale_to_ahull(nrows, nrays, - model->rays.values, t, beta, epsilon, d, &alpha); - abort_if(rval, "GREEDY_ND_scale_to_ahull failed"); + double prev_epsilon; + int count = 0; + *epsilon = GREEDY_BIG_E; - if(DOUBLE_iszero(alpha)) - { - skip_ahull = 1; - continue; - } + rx = (int *) malloc(nrays * sizeof(int)); + fbar = (double *) malloc(nrows * sizeof(double)); + sbar = (double *) malloc(nrays * sizeof(double)); - beta[i] = min(beta[i], alpha); -// beta[i] *= 0.999; - } + abort_if(!rx, "could not allocate rx"); + abort_if(!fbar, "could not allocate fbar"); + abort_if(!sbar, "could not allocate sbar"); - log_debug(" beta[%2d] = %.4lf\n", i, beta[i]); - } + while(1) + { + count++; + abort_if(count > 100, "infinite loop"); - log_debug("epsilon = %.6lf\n", epsilon); - } + rval = find_violated_cone(nrows, nrays, f, rays, x, beta, *epsilon, rx, + sbar, &found); + abort_if(rval, "find_violated_cone failed"); - log_debug(" %6ld lattice points, %ld iterations\n", x_count, it); + if(!found) break; - log_debug(" %6ld MIPs (%.2lf ms per call, %.0lf ms total)\n", lp_count, - lp_time * 1000 / lp_count, lp_time * 1000); + for(int i = 0; i < nrows; i++) + fbar[i] = x[i]; - log_debug( - " %6ld S-free MIPs (%.2lf ms per call, %.0lf ms total)\n", - sfree_mip_count, sfree_mip_time * 1000 / sfree_mip_count, - sfree_mip_time * 1000); + for(int j = 0; j < nrays; j++) + { + if(!rx[j]) continue; + const double *r = &rays[nrows * j]; - log_debug( - " %6ld epsilon LPs (%.2lf ms per call, %.0lf ms total)\n", - epsilon_lp_count, epsilon_lp_time * 1000 / epsilon_lp_count, - epsilon_lp_time * 1000); + for(int i = 0; i < nrows; i++) + fbar[i] -= min(*epsilon, beta[j]) * r[i] * sbar[j]; + } - log_debug( - " %6ld tight-rays LPs (%.2lf ms per call, %.0lf ms total)\n", - tight_lp_count, tight_lp_time * 1000 / tight_lp_count, - tight_lp_time * 1000); + log_verbose("%.12lf %.12lf\n", f[0], f[1]); + log_verbose("%.12lf %.12lf\n", fbar[0], fbar[1]); - log_debug( - " %6ld violated-cone LPs (%.2lf ms per call, %.0lf ms total)\n", - violated_lp_count, violated_lp_time * 1000 / violated_lp_count, - violated_lp_time * 1000); + prev_epsilon = *epsilon; - log_debug( - " %6ld scale-to-ahull LPs (%.2lf ms per call, %.0lf ms total)\n", - scale_ahull_lp_count, - scale_ahull_lp_time * 1000 / scale_ahull_lp_count, - scale_ahull_lp_time * 1000); + rval = cone_bound(nrows, nrays, fbar, rays, rx, x, beta, epsilon); + abort_if(rval, "cone_bound failed"); + + log_verbose(" e=%.12lf\n", *epsilon); + abort_if(prev_epsilon < *epsilon, "epsilon should never increase"); + } + + for(int i = 0; i < nrays; i++) + tx[i] = 0; + + if(DOUBLE_geq(*epsilon, GREEDY_BIG_E)) + { + *epsilon = INFINITY; + goto CLEANUP; + } + else + { + rval = find_tight_rays(nrows, nrays, fbar, rays, x, beta, *epsilon, tx); + abort_if(rval, "find_tight_rays failed"); + } CLEANUP: - if(x) free(x); - if(t) free(t); - if(tx) free(tx); + if(sbar) free(sbar); + if(fbar) free(fbar); + if(rx) free(rx); return rval; } -int GREEDY_ND_cone_bound(int nrows, - int nrays, - const double *f, - const double *rays, - const int *rx, - const double *x, - const double *beta, - double *epsilon) +static int scale_to_ahull(int nrows, + int nrays, + const double *rays, + const int *rx, + const double *beta, + double epsilon, + const double *d, + double *alpha) { - log_verbose(" find_epsilon\n"); + log_verbose(" scale_to_ahull\n"); int rval = 0; + *alpha = INFINITY; - int *t = 0; - long it = 0; + struct LP lp; + double *x = 0; + double initial_time; - t = (int *) malloc(nrays * sizeof(int)); - abort_if(!t, "could not allocate t"); + x = (double *) malloc((nrays + 1) * sizeof(double)); + abort_if(!x, "could not allocate x"); - for(int i = 0; i < nrays; i++) - t[i] = 0; + initial_time = get_user_time(); + rval = LP_open(&lp); + abort_if(rval, "LP_open failed"); - while(1) - { - it++; - log_verbose("Starting iteration %d...\n", it); + rval = create_scale_to_ahull_lp(nrows, nrays, rays, rx, beta, epsilon, d, + &lp); + abort_if(rval, "create_scale_to_ahull_lp failed"); - struct LP lp; + int infeasible; + rval = LP_optimize(&lp, &infeasible); + abort_if(rval, "LP_optimize failed"); - double initial_time = get_user_time(); - rval = LP_open(&lp); - abort_if(rval, "LP_open failed"); + lp_count++; + lp_time += get_user_time() - initial_time; - rval = create_find_epsilon_lp(nrows, nrays, f, rays, t, rx, x, beta, - &lp); - abort_if(rval, "create_find_epsilon_lp failed"); + scale_ahull_lp_count++; + scale_ahull_lp_time += get_user_time() - initial_time; - int infeasible; - rval = LP_optimize(&lp, &infeasible); - abort_if(rval, "LP_optimize failed"); + if(infeasible) + goto CLEANUP; - lp_count++; - lp_time += get_user_time() - initial_time; + rval = LP_get_x(&lp, x); + abort_if(rval, "LP_get_x failed"); - epsilon_lp_count++; - epsilon_lp_time += get_user_time() - initial_time; + *alpha = x[0]; - if(infeasible) - { - *epsilon = INFINITY; - log_verbose(" infeasible\n"); - LP_free(&lp); - goto CLEANUP; - } +CLEANUP: + if(x) free(x); + LP_free(&lp); + return rval; +} - double obj; - rval = LP_get_obj_val(&lp, &obj); - abort_if(rval, "LP_get_obj_val failed"); +#ifndef TEST_SOURCE - log_verbose(" obj=%.6lf\n", obj); +int INFINITY_create_psi_lp(const struct ConvLFreeSet *lfree, struct LP *lp) +{ + int rval = 0; - for(int i = 0; i < nrays; i++) - { - if(!rx[i]) continue; - log_verbose(" beta[%d]=%.6lf\n", i, beta[i]); - } + int rmatbeg = 0; + int *rmatind = 0; + double *rmatval = 0; - LP_free(&lp); + int nrows = lfree->nrows; + int nrays = lfree->rays.nrays; + double *rays = lfree->rays.values; + double *beta = lfree->beta; - double e_min = INFINITY; - double e_max = -INFINITY; + rmatind = (int *) malloc(nrays * sizeof(int)); + rmatval = (double *) malloc(nrays * sizeof(double)); + abort_if(!rmatind, "could not allocate rmatind"); + abort_if(!rmatval, "could not allocate rmatval"); - for(int i = 0; i < nrays; i++) - { - if(!rx[i] || t[i]) continue; - e_min = min(e_min, beta[i]); - } + rval = LP_create(lp, "psi"); + abort_if(rval, "LP_create failed"); + + // create lambda variables + for(int i = 0; i < nrays; i++) + { + rval = LP_new_col(lp, 1.0, 0, MILP_INFINITY, 'C'); + abort_if(rval, "LP_new_col failed"); + } + + // create constraint 0 = \sum_{i=1}^m \lambda_i r^i_j beta_i + for(int j = 0; j < nrows; j++) + { + char sense = 'E'; + double rhs = 0; + int nz = 0; for(int i = 0; i < nrays; i++) { - if(!rx[i]) continue; - e_max = fmax(e_max, beta[i]); + const double *ri = &rays[i * nrows]; + rmatind[nz] = i; + rmatval[nz] = ri[j] * beta[i]; + nz++; } - log_verbose(" e_max=%.6lf\n", e_max); - log_verbose(" e_min=%.6lf\n", e_min); + rval = LP_add_rows(lp, 1, nz, &rhs, &sense, &rmatbeg, rmatind, rmatval); + abort_if(rval, "LP_add_rows failed"); + } - if(DOUBLE_leq(obj, e_min)) - { - if(DOUBLE_geq(obj, e_max)) - *epsilon = INFINITY; - else - *epsilon = obj; + rval = LP_relax(lp); + abort_if(rval, "LP_relax failed"); - goto CLEANUP; - } - else - { - for(int i = 0; i < nrays; i++) - if(rx[i] && DOUBLE_eq(beta[i], e_min)) - t[i] = 1; - } + if_verbose_level + { + rval = LP_write(lp, "psi.lp"); + abort_if(rval, "LP_write failed"); } CLEANUP: - log_verbose(" e=%.6lf\n", *epsilon); - if(t) free(t); + if(rmatind) free(rmatind); + if(rmatval) free(rmatval); return rval; } -int GREEDY_ND_scale_to_ahull(int nrows, - int nrays, - const double *rays, - const int *rx, - const double *beta, - double epsilon, - const double *d, - double *alpha) +int INFINITY_pi(const int nrows, + const double *q, + const double q_scale, + struct LP *lp, + double *value) { - log_verbose(" scale_to_ahull\n"); int rval = 0; - *alpha = INFINITY; - struct LP lp; - double *x = 0; + abort_if(nrows > 3, "not implemented"); - x = (double *) malloc((nrays + 1) * sizeof(double)); - abort_if(!x, "could not allocate x"); + double best_value = 1e100; - double initial_time = get_user_time(); - rval = LP_open(&lp); - abort_if(rval, "LP_open failed"); + if(nrows == 2) + { + int M = 2; + for(int k0 = -M; k0 <= M; k0++) + for(int k1 = -M; k1 <= M; k1++) + { + double v; + double qk[] = {frac(q[0] * q_scale) + k0, + frac(q[1] * q_scale) + k1}; - rval = create_scale_to_ahull_lp(nrows, nrays, rays, rx, beta, epsilon, d, - &lp); - abort_if(rval, "create_scale_to_ahull_lp failed"); + rval = INFINITY_psi(nrows, qk, 1, lp, &v); + abort_if(rval, "INFINITY_psi failed"); + + best_value = min(best_value, v); + } + } + + if(nrows == 3) + { + int M = 2; + for(int k0 = -M; k0 <= M; k0++) + for(int k1 = -M; k1 <= M; k1++) + for(int k2 = -M; k2 <= M; k2++) + { + double v; + double qk[] = {frac(q[0] * q_scale) + k0, + frac(q[1] * q_scale) + k1, + frac(q[2] * q_scale) + k2}; + + rval = INFINITY_psi(nrows, qk, 1, lp, &v); + abort_if(rval, "INFINITY_psi failed"); + + best_value = min(best_value, v); + } + } + + *value = best_value; + +CLEANUP: + return rval; +} + +/* + * Given a point f, a list of rays r1,...,rm, some real numbers b1,...,bm, a + * point q, and a real number q_scale, this function evaluates psi_B(q * + * q_scale), where B is the convex hull of {f + ri * bi}_i=1^m. + */ +int INFINITY_psi(const int nrows, + const double *q, + const double q_scale, + struct LP *lp, + double *value) +{ + int rval = 0; + + for(int j = 0; j < nrows; j++) + { + rval = LP_change_rhs(lp, j, q[j] * q_scale); + abort_if(rval, "LP_change_rhs failed"); + } int infeasible; - rval = LP_optimize(&lp, &infeasible); + rval = LP_optimize(lp, &infeasible); abort_if(rval, "LP_optimize failed"); - lp_count++; - lp_time += get_user_time() - initial_time; - - scale_ahull_lp_count++; - scale_ahull_lp_time += get_user_time() - initial_time; - if(infeasible) - goto CLEANUP; - - rval = LP_get_x(&lp, x); - abort_if(rval, "LP_get_x failed"); - - *alpha = x[0]; + { + *value = INFINITY; + } + else + { + rval = LP_get_obj_val(lp, value); + abort_if(rval, "LP_get_obj_val failed"); + } CLEANUP: - if(x) free(x); - LP_free(&lp); return rval; } -int GREEDY_ND_find_tight_rays(int nrows, - int nrays, - const double *f, - const double *rays, - const double *x, - const double *beta, - double epsilon, - int *tx) +int INFINITY_ND_generate_lfree(const struct MultiRowModel *model, + struct ConvLFreeSet *lfree) { - log_verbose(" find_tight_rays\n"); int rval = 0; - const double delta = 0.001; + int nrows = model->nrows; + int nrays = model->rays.nrays; - struct LP lp; - double *sbar = 0; + double *f = lfree->f; + double *rays = lfree->rays.values; + double *beta = lfree->beta; - sbar = (double *) malloc(2 * nrays * sizeof(double)); - abort_if(!sbar, "could not allocate sbar"); + lfree->nrows = model->nrows; + lfree->rays.nrays = nrays; + memcpy(rays, model->rays.values, nrays * nrows * sizeof(double)); + memcpy(f, model->f, nrows * sizeof(double)); - double initial_time = get_user_time(); - rval = LP_open(&lp); - abort_if(rval, "LP_open failed"); + double *x = 0; - rval = create_tight_rays_lp(nrows, nrays, f, rays, x, beta, epsilon, delta, - &lp); - abort_if(rval, "create_tight_rays_lp failed"); + int *t = 0; + int *tx = 0; - int infeasible = 0; - rval = LP_optimize(&lp, &infeasible); - abort_if(rval, "LP_optimize failed"); + t = (int *) malloc(nrays * sizeof(int)); + tx = (int *) malloc(nrays * sizeof(int)); + abort_if(!t, "could not allocate t"); + abort_if(!tx, "could not allocate tx"); - lp_count++; - lp_time += get_user_time() - initial_time; + x = (double *) malloc((nrows + nrays) * sizeof(double)); + abort_if(!x, "could not allocate x"); - tight_lp_count++; - tight_lp_time += get_user_time() - initial_time; + for(int i = 0; i < nrays; i++) + beta[i] = GREEDY_BIG_E; - abort_if(infeasible, "tight_rays_lp is infeasible"); + int it = 0; - rval = LP_get_x(&lp, sbar); - abort_if(rval, "LP_get_x failed"); + //lp_time = 0; + //lp_count = 0; - for(int i = 0; i < nrays; i++) - tx[i] = DOUBLE_iszero(sbar[i]); + //epsilon_lp_count = 0; + //epsilon_lp_time = 0; + // + //sfree_mip_count = 0; + //sfree_mip_time = 0; - for(int i = 0; i < nrays; i++) - log_verbose(" tx[%d]=%d\n", i, tx[i]); + //tight_lp_count = 0; + //tight_lp_time = 0; -CLEANUP: - if(sbar) free(sbar); - LP_free(&lp); - return rval; -} + //violated_lp_count = 0; + //violated_lp_time = 0; -int GREEDY_ND_find_violated_cone(int nrows, - int nrays, - const double *f, - const double *rays, - const double *x, - const double *beta, - double epsilon, - int *rx, - double *sbar, - int *violated_found) -{ - log_verbose(" find_violated_cone\n"); - int rval = 0; + //scale_ahull_lp_time = 0; + //scale_ahull_lp_count = 0; - struct LP lp; + long x_count = 0; + double epsilon; - double initial_time = get_user_time(); + for(int i = 0; i < nrows; i++) + log_verbose(" f[%d] = %.12lf\n", i, f[i]); - rval = LP_open(&lp); - abort_if(rval, "LP_open failed"); + while(1) + { + it++; + abort_if(it > 10 * nrays, "infinite loop"); - rval = create_violated_cone_lp(nrows, nrays, f, rays, x, beta, epsilon, - &lp); - abort_if(rval, "create_violated_cone_lp failed"); + log_debug("Starting iteration %d...\n", it); + epsilon = INFINITY; - int infeasible; - rval = LP_optimize(&lp, &infeasible); - abort_if(rval, "LP_optimize failed"); + for(int i = 0; i < nrays; i++) + t[i] = 0; - lp_count++; - lp_time += get_user_time() - initial_time; + for(int i = 0; i < nrows; i++) + x[i] = 0; - violated_lp_count++; - violated_lp_time += get_user_time() - initial_time; + while(1) + { + log_debug(" epsilon = %.8lf\n", epsilon); - rval = LP_get_x(&lp, sbar); - abort_if(rval, "LP_get_x failed"); + int found = 0; - for(int i = 0; i < nrays; i++) - rx[i] = 0; + if(nrows == 3) + { + rval = find_interior_point_enum(nrows, nrays, f, + model->rays.values, beta, epsilon, x, &found); + abort_if(rval, "find_interior_point_enum failed"); + } - if(infeasible) - goto CLEANUP; + if(!found) + { + rval = find_interior_point_cplex(nrows, nrays, f, + model->rays.values, beta, epsilon, x, &found); + if(rval == ERR_MIP_TIMEOUT) goto CLEANUP; + abort_if(rval, "find_interior_point_cplex failed"); + if(!found) break; + } - double obj; - rval = LP_get_obj_val(&lp, &obj); - abort_if(rval, "LP_get_obj_val failed"); + log_debug(" found interior point:\n"); + for(int i = 0; i < nrows; i++) log_debug(" %.2lf\n", x[i]); - log_verbose(" o=%.8lf\n", obj); + x_count++; + abort_if(x_count > 1000, "infinite loop"); - if(DOUBLE_geq(obj, 0.999)) - { - *violated_found = 0; - } - else - { - *violated_found = 1; + double epsilon_x; + rval = bound(nrows, nrays, f, model->rays.values, x, beta, + &epsilon_x, tx); + abort_if(rval, "bound failed"); +// epsilon_x *= 0.999; - log_verbose("Violated cone found\n"); + if(isinf(epsilon_x)) break; - log_verbose(" f=%.8lf %.8lf\n", f[0], f[1]); - log_verbose(" x=%.8lf %.8lf\n", x[0], x[1]); + log_debug(" epsilon_x = %.8lf\n", epsilon_x); + + if(DOUBLE_eq(epsilon_x, epsilon)) + { + for(int i = 0; i < nrays; i++) + if(tx[i]) t[i] = 1; + } + else if(epsilon_x < epsilon) + { + epsilon = epsilon_x; + for(int i = 0; i < nrays; i++) + t[i] = tx[i]; + } + } + + if(isinf(epsilon)) + break; + + int skip_ahull = 0; for(int i = 0; i < nrays; i++) { - rx[i] = (sbar[i] > 1e-9); - - if(rx[i]) + if(t[i]) { - double m = min(epsilon, beta[i]); - const double *r = &rays[nrows * i]; - log_verbose(" r[%d]=%.8lf %.8lf\n", i, r[0], r[1]); - log_verbose(" r[%d]=%.8lf %.8lf\n", i, m * r[0], m * r[1]); + beta[i] = min(beta[i], epsilon); +// beta[i] *= 0.999; + } + else if(!skip_ahull) + { + double alpha; + const double *d = LFREE_get_ray(&model->rays, i); + + rval = scale_to_ahull(nrows, nrays, model->rays.values, t, beta, + epsilon, d, &alpha); + abort_if(rval, "scale_to_ahull failed"); + + if(DOUBLE_iszero(alpha)) + { + skip_ahull = 1; + continue; + } + + beta[i] = min(beta[i], alpha); +// beta[i] *= 0.999; } + + log_debug(" beta[%2d] = %.4lf\n", i, beta[i]); } + + log_debug("epsilon = %.6lf\n", epsilon); } + log_debug(" %6ld lattice points, %ld iterations\n", x_count, it); + + log_debug(" %6ld MIPs (%.2lf ms per call, %.0lf ms total)\n", lp_count, + lp_time * 1000 / lp_count, lp_time * 1000); + + log_debug( + " %6ld S-free MIPs (%.2lf ms per call, %.0lf ms total)\n", + sfree_mip_count, sfree_mip_time * 1000 / sfree_mip_count, + sfree_mip_time * 1000); + + log_debug( + " %6ld epsilon LPs (%.2lf ms per call, %.0lf ms total)\n", + epsilon_lp_count, epsilon_lp_time * 1000 / epsilon_lp_count, + epsilon_lp_time * 1000); + + log_debug( + " %6ld tight-rays LPs (%.2lf ms per call, %.0lf ms total)\n", + tight_lp_count, tight_lp_time * 1000 / tight_lp_count, + tight_lp_time * 1000); + + log_debug( + " %6ld violated-cone LPs (%.2lf ms per call, %.0lf ms total)\n", + violated_lp_count, violated_lp_time * 1000 / violated_lp_count, + violated_lp_time * 1000); + + log_debug( + " %6ld scale-to-ahull LPs (%.2lf ms per call, %.0lf ms total)\n", + scale_ahull_lp_count, + scale_ahull_lp_time * 1000 / scale_ahull_lp_count, + scale_ahull_lp_time * 1000); + CLEANUP: - LP_free(&lp); + if(x) free(x); + if(t) free(t); + if(tx) free(tx); return rval; } diff --git a/infinity/library/src/infinity.c b/infinity/library/src/infinity.c index 6494f8c..ede040e 100644 --- a/infinity/library/src/infinity.c +++ b/infinity/library/src/infinity.c @@ -22,7 +22,7 @@ #include #include -#include +#include #include /** @@ -117,7 +117,7 @@ static int create_cut_from_lfree(const struct Tableau *tableau, rval = LP_open(&lp); abort_if(rval, "LP_open failed"); - rval = GREEDY_create_psi_lp(lfree, &lp); + rval = INFINITY_create_psi_lp(lfree, &lp); abort_if(rval, "create_psi_lp failed"); cut->nz = nvars; @@ -129,13 +129,13 @@ static int create_cut_from_lfree(const struct Tableau *tableau, if(ENABLE_LIFTING && type == MILP_INTEGER) { - rval = GREEDY_ND_pi(nrows, q, map->ray_scale[i], &lp, &value); - abort_if(rval, "GREEDY_ND_pi failed"); + rval = INFINITY_pi(nrows, q, map->ray_scale[i], &lp, &value); + abort_if(rval, "INFINITY_pi failed"); } else { - rval = GREEDY_ND_psi(nrows, q, map->ray_scale[i], &lp, &value); - abort_if(rval, "GREEDY_ND_psi failed"); + rval = INFINITY_psi(nrows, q, map->ray_scale[i], &lp, &value); + abort_if(rval, "INFINITY_psi failed"); } log_verbose(" psi[%4d] = %20.12lf %d\n", map->indices[i], value); diff --git a/infinity/library/tests/greedy-nd-test.cpp b/infinity/library/tests/infinity-nd-test.cpp similarity index 77% rename from infinity/library/tests/greedy-nd-test.cpp rename to infinity/library/tests/infinity-nd-test.cpp index fdd8f56..0f566ed 100644 --- a/infinity/library/tests/greedy-nd-test.cpp +++ b/infinity/library/tests/infinity-nd-test.cpp @@ -19,13 +19,12 @@ #define TEST_SOURCE extern "C" { -#include #include #include #include #include -#include -#include "../src/greedy-nd.c" +#include +#include "../src/infinity-nd.c" } int ENABLE_LIFTING = 0; @@ -34,7 +33,7 @@ int MAX_N_ROWS = 2; int SHOULD_DUMP_CUTS = 0; int DUMP_CUT_N = 0; -TEST(GreedyNDTest, find_violated_cone_test) +TEST(InfinityNDTest, find_violated_cone_test) { int rval = 0; @@ -56,9 +55,9 @@ TEST(GreedyNDTest, find_violated_cone_test) int rx[nrays]; int found; - rval = GREEDY_ND_find_violated_cone(nrows, nrays, f, rays, x, beta, - 1.0, rx, sbar, &found); - abort_if(rval, "GREEDY_ND_find_violated_cone failed"); + rval = find_violated_cone(nrows, nrays, f, rays, x, beta, 1.0, rx, sbar, + &found); + abort_if(rval, "find_violated_cone failed"); EXPECT_TRUE(found); EXPECT_FALSE(rx[0]); @@ -66,9 +65,9 @@ TEST(GreedyNDTest, find_violated_cone_test) EXPECT_TRUE(rx[2]); EXPECT_FALSE(rx[3]); - rval = GREEDY_ND_find_violated_cone(nrows, nrays, f, rays, x, beta, - 0.5, rx, sbar, &found); - abort_if(rval, "GREEDY_ND_find_violated_cone failed"); + rval = find_violated_cone(nrows, nrays, f, rays, x, beta, 0.5, rx, sbar, + &found); + abort_if(rval, "find_violated_cone failed"); EXPECT_FALSE(found); @@ -76,7 +75,7 @@ TEST(GreedyNDTest, find_violated_cone_test) if(rval) FAIL(); } -TEST(GreedyNDTest, find_tight_rays_test_1) +TEST(InfinityNDTest, find_tight_rays_test_1) { int rval = 0; @@ -97,8 +96,8 @@ TEST(GreedyNDTest, find_tight_rays_test_1) int tx[6]; - rval = GREEDY_ND_find_tight_rays(2, 6, f, rays, x, beta, epsilon, tx); - abort_if(rval, "GREEDY_ND_find_tight_rays failed"); + rval = find_tight_rays(2, 6, f, rays, x, beta, epsilon, tx); + abort_if(rval, "find_tight_rays failed"); EXPECT_TRUE(tx[0]); EXPECT_FALSE(tx[1]); @@ -111,7 +110,7 @@ TEST(GreedyNDTest, find_tight_rays_test_1) if(rval) FAIL(); } -TEST(GreedyNDTest, find_tight_rays_test_2) +TEST(InfinityNDTest, find_tight_rays_test_2) { int rval = 0; @@ -131,8 +130,8 @@ TEST(GreedyNDTest, find_tight_rays_test_2) int tx[6]; - rval = GREEDY_ND_find_tight_rays(2, 6, f, rays, x, beta, epsilon, tx); - abort_if(rval, "GREEDY_ND_find_tight_rays failed"); + rval = find_tight_rays(2, 6, f, rays, x, beta, epsilon, tx); + abort_if(rval, "find_tight_rays failed"); EXPECT_TRUE(tx[0]); EXPECT_FALSE(tx[1]); @@ -145,7 +144,7 @@ TEST(GreedyNDTest, find_tight_rays_test_2) if(rval) FAIL(); } -TEST(GreedyNDTest, cone_bound_test_1) +TEST(InfinityNDTest, cone_bound_test_1) { int rval = 0; @@ -168,19 +167,19 @@ TEST(GreedyNDTest, cone_bound_test_1) double epsilon; - rval = GREEDY_ND_cone_bound(2, 6, f, rays, rx1, x, beta, &epsilon); - abort_if(rval, "GREEDY_ND_cone_bound failed"); + rval = cone_bound(2, 6, f, rays, rx1, x, beta, &epsilon); + abort_if(rval, "cone_bound failed"); EXPECT_NEAR(0.5, epsilon, 1e-6); - rval = GREEDY_ND_cone_bound(2, 6, f, rays, rx2, x, beta, &epsilon); - abort_if(rval, "GREEDY_ND_cone_bound failed"); + rval = cone_bound(2, 6, f, rays, rx2, x, beta, &epsilon); + abort_if(rval, "cone_bound failed"); EXPECT_NEAR(1.0, epsilon, 1e-6); CLEANUP: if(rval) FAIL(); } -TEST(GreedyNDTest, cone_bound_test_2) +TEST(InfinityNDTest, cone_bound_test_2) { int rval = 0; @@ -201,27 +200,27 @@ TEST(GreedyNDTest, cone_bound_test_2) double epsilon; - rval = GREEDY_ND_cone_bound(2, 2, f, rays, rx, x1, beta1, &epsilon); - abort_if(rval, "GREEDY_ND_cone_bound failed"); + rval = cone_bound(2, 2, f, rays, rx, x1, beta1, &epsilon); + abort_if(rval, "cone_bound failed"); EXPECT_NEAR(1.0, epsilon, 1e-6); - rval = GREEDY_ND_cone_bound(2, 2, f, rays, rx, x1, beta2, &epsilon); - abort_if(rval, "GREEDY_ND_cone_bound failed"); + rval = cone_bound(2, 2, f, rays, rx, x1, beta2, &epsilon); + abort_if(rval, "cone_bound failed"); EXPECT_EQ(INFINITY, epsilon); - rval = GREEDY_ND_cone_bound(2, 2, f, rays, rx, x2, beta2, &epsilon); - abort_if(rval, "GREEDY_ND_cone_bound failed"); + rval = cone_bound(2, 2, f, rays, rx, x2, beta2, &epsilon); + abort_if(rval, "cone_bound failed"); EXPECT_NEAR(1.0, epsilon, 1e-6); - rval = GREEDY_ND_cone_bound(2, 2, f, rays, rx, x2, beta3, &epsilon); - abort_if(rval, "GREEDY_ND_cone_bound failed"); + rval = cone_bound(2, 2, f, rays, rx, x2, beta3, &epsilon); + abort_if(rval, "cone_bound failed"); EXPECT_EQ(INFINITY, epsilon); CLEANUP: if(rval) FAIL(); } -TEST(GreedyNDTest, bound_test_1) +TEST(InfinityNDTest, bound_test_1) { int rval = 0; @@ -277,7 +276,7 @@ CLEANUP: if(rval) FAIL(); } -TEST(GreedyNDTest, psi_test) +TEST(InfinityNDTest, psi_test) { int rval = 0; @@ -309,14 +308,14 @@ TEST(GreedyNDTest, psi_test) rval = LP_open(&lp); abort_if(rval, "LP_open failed"); - rval = GREEDY_create_psi_lp(&lfree, &lp); - abort_if(rval, "GREEDY_create_psi_lp failed"); + rval = INFINITY_create_psi_lp(&lfree, &lp); + abort_if(rval, "INFINITY_create_psi_lp failed"); - rval = GREEDY_ND_psi(2, q1, 1.0, &lp, &value); + rval = INFINITY_psi(2, q1, 1.0, &lp, &value); abort_if(rval, "GREDDY_ND_psi failed"); EXPECT_NEAR(value, 2.0, 1e-6); - rval = GREEDY_ND_psi(2, q2, 2.0, &lp, &value); + rval = INFINITY_psi(2, q2, 2.0, &lp, &value); abort_if(rval, "GREDDY_ND_psi failed"); EXPECT_NEAR(value, 8.0, 1e-6); @@ -325,7 +324,7 @@ CLEANUP: if(rval) FAIL(); } -TEST(GreedyNDTest, psi_test_2) +TEST(InfinityNDTest, psi_test_2) { int rval = 0; @@ -361,14 +360,14 @@ TEST(GreedyNDTest, psi_test_2) rval = LP_open(&lp); abort_if(rval, "LP_open failed"); - rval = GREEDY_create_psi_lp(&lfree, &lp); - abort_if(rval, "GREEDY_create_psi_lp failed"); + rval = INFINITY_create_psi_lp(&lfree, &lp); + abort_if(rval, "INFINITY_create_psi_lp failed"); - rval = GREEDY_ND_psi(3, q1, 1.0, &lp, &value); + rval = INFINITY_psi(3, q1, 1.0, &lp, &value); abort_if(rval, "GREDDY_ND_psi failed"); EXPECT_NEAR(value, 1.0, 1e-6); - rval = GREEDY_ND_psi(3, q2, 1.0, &lp, &value); + rval = INFINITY_psi(3, q2, 1.0, &lp, &value); abort_if(rval, "GREDDY_ND_psi failed"); EXPECT_NEAR(value, 2.0, 1e-6); @@ -376,7 +375,7 @@ CLEANUP: if(rval) FAIL(); } -TEST(GreedyNDTest, generate_cut_test_1) +TEST(InfinityNDTest, generate_cut_test_1) { int rval = 0; @@ -415,7 +414,7 @@ CLEANUP: if(rval) FAIL(); } -TEST(GreedyNDTest, generate_cut_test_2) +TEST(InfinityNDTest, generate_cut_test_2) { int rval = 0; @@ -456,7 +455,7 @@ CLEANUP: if(rval) FAIL(); } -TEST(GreedyNTest, scale_to_ahull_test) +TEST(InfinityNDTest, scale_to_ahull_test) { int rval = 0; @@ -478,16 +477,16 @@ TEST(GreedyNTest, scale_to_ahull_test) double alpha; - rval = GREEDY_ND_scale_to_ahull(3, 4, rays, rx, beta, epsilon, d1, &alpha); - abort_if(rval, "GREEDY_ND_scale_to_ahull failed"); + rval = scale_to_ahull(3, 4, rays, rx, beta, epsilon, d1, &alpha); + abort_if(rval, "scale_to_ahull failed"); EXPECT_DOUBLE_EQ(1 / 3.0, alpha); - rval = GREEDY_ND_scale_to_ahull(3, 4, rays, rx, beta, epsilon, d2, &alpha); - abort_if(rval, "GREEDY_ND_scale_to_ahull failed"); + rval = scale_to_ahull(3, 4, rays, rx, beta, epsilon, d2, &alpha); + abort_if(rval, "scale_to_ahull failed"); EXPECT_DOUBLE_EQ(0.25, alpha); - rval = GREEDY_ND_scale_to_ahull(3, 4, rays, rx, beta, epsilon, d3, &alpha); - abort_if(rval, "GREEDY_ND_scale_to_ahull failed"); + rval = scale_to_ahull(3, 4, rays, rx, beta, epsilon, d3, &alpha); + abort_if(rval, "scale_to_ahull failed"); EXPECT_EQ(INFINITY, alpha); CLEANUP: