Remove warnings
This commit is contained in:
@@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 2.8)
|
|||||||
project(multirow)
|
project(multirow)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
|
||||||
find_package(CPLEX REQUIRED)
|
find_package(CPLEX REQUIRED)
|
||||||
|
|||||||
@@ -18,5 +18,4 @@ 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})
|
add_executable(infinity-test.run ${COMMON_SOURCES} ${TEST_SOURCES})
|
||||||
target_compile_options(infinity-test.run PRIVATE "-fpermissive")
|
|
||||||
target_link_libraries(infinity-test.run gtest_main multirow_static lifting_static)
|
target_link_libraries(infinity-test.run gtest_main multirow_static lifting_static)
|
||||||
|
|||||||
@@ -16,28 +16,15 @@
|
|||||||
#ifndef MULTIROW_GREEDY_ND_H
|
#ifndef MULTIROW_GREEDY_ND_H
|
||||||
#define MULTIROW_GREEDY_ND_H
|
#define MULTIROW_GREEDY_ND_H
|
||||||
|
|
||||||
int GREEDY_create_psi_lp(const int nrows,
|
int GREEDY_create_psi_lp(const struct ConvLFreeSet *lfree, struct LP *lp);
|
||||||
const int nrays,
|
|
||||||
const double *f,
|
|
||||||
const double *rays,
|
|
||||||
const double *beta,
|
|
||||||
struct LP *lp);
|
|
||||||
|
|
||||||
int GREEDY_ND_psi(const int nrows,
|
int GREEDY_ND_psi(const int nrows,
|
||||||
const int nrays,
|
|
||||||
const double *f,
|
|
||||||
const double *rays,
|
|
||||||
const double *beta,
|
|
||||||
const double *q,
|
const double *q,
|
||||||
const double q_scale,
|
const double q_scale,
|
||||||
struct LP *lp,
|
struct LP *lp,
|
||||||
double *value);
|
double *value);
|
||||||
|
|
||||||
int GREEDY_ND_pi(const int nrows,
|
int GREEDY_ND_pi(const int nrows,
|
||||||
const int nrays,
|
|
||||||
const double *f,
|
|
||||||
const double *rays,
|
|
||||||
const double *beta,
|
|
||||||
const double *q,
|
const double *q,
|
||||||
const double q_scale,
|
const double q_scale,
|
||||||
struct LP *lp,
|
struct LP *lp,
|
||||||
|
|||||||
@@ -53,9 +53,13 @@ static int find_interior_point_enum(const int nrows,
|
|||||||
{
|
{
|
||||||
int rval = 0;
|
int rval = 0;
|
||||||
|
|
||||||
|
int M = 1;
|
||||||
|
struct LP lp;
|
||||||
|
double best_value = INFINITY;
|
||||||
|
double *beta2 = 0;
|
||||||
|
|
||||||
abort_if(nrows != 3, "not implemented");
|
abort_if(nrows != 3, "not implemented");
|
||||||
|
|
||||||
double *beta2 = 0;
|
|
||||||
beta2 = (double *) malloc(nrays * sizeof(double));
|
beta2 = (double *) malloc(nrays * sizeof(double));
|
||||||
abort_if(!beta2, "could not allocate beta2");
|
abort_if(!beta2, "could not allocate beta2");
|
||||||
|
|
||||||
@@ -64,18 +68,22 @@ static int find_interior_point_enum(const int nrows,
|
|||||||
beta2[i] = fmin(epsilon, beta[i]);
|
beta2[i] = fmin(epsilon, beta[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LP lp;
|
|
||||||
|
|
||||||
rval = LP_open(&lp);
|
rval = LP_open(&lp);
|
||||||
abort_if(rval, "LP_open failed");
|
abort_if(rval, "LP_open failed");
|
||||||
|
|
||||||
rval = GREEDY_create_psi_lp(nrows, nrays, f, rays, beta2, &lp);
|
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");
|
abort_if(rval, "GREEDY_create_psi_lp failed");
|
||||||
|
|
||||||
*found = 0;
|
*found = 0;
|
||||||
double best_value = INFINITY;
|
|
||||||
|
|
||||||
int M = 1;
|
|
||||||
for(int x1 = -M; x1 <= M; x1++)
|
for(int x1 = -M; x1 <= M; x1++)
|
||||||
for(int x2 = -M; x2 <= M; x2++)
|
for(int x2 = -M; x2 <= M; x2++)
|
||||||
for(int x3 = -M; x3 <= M; x3++)
|
for(int x3 = -M; x3 <= M; x3++)
|
||||||
@@ -85,8 +93,7 @@ static int find_interior_point_enum(const int nrows,
|
|||||||
x2 - f[1],
|
x2 - f[1],
|
||||||
x3 - f[2]};
|
x3 - f[2]};
|
||||||
|
|
||||||
rval = GREEDY_ND_psi(nrows, nrays, f, rays, beta2, q, 1, &lp,
|
rval = GREEDY_ND_psi(nrows, q, 1, &lp, &value);
|
||||||
&value);
|
|
||||||
abort_if(rval, "GREEDY_ND_psi failed");
|
abort_if(rval, "GREEDY_ND_psi failed");
|
||||||
|
|
||||||
if(value < best_value)
|
if(value < best_value)
|
||||||
@@ -117,20 +124,20 @@ static int find_interior_point_cplex(const int nrows,
|
|||||||
{
|
{
|
||||||
int rval = 0;
|
int rval = 0;
|
||||||
struct LP lp;
|
struct LP lp;
|
||||||
|
double initial_time;
|
||||||
|
int infeasible;
|
||||||
|
double objval;
|
||||||
|
|
||||||
rval = LP_open(&lp);
|
rval = LP_open(&lp);
|
||||||
abort_if(rval, "LP_open failed");
|
abort_if(rval, "LP_open failed");
|
||||||
|
|
||||||
lp_count++;
|
lp_count++;
|
||||||
sfree_mip_count++;
|
sfree_mip_count++;
|
||||||
double initial_time = get_user_time();
|
initial_time = get_user_time();
|
||||||
|
|
||||||
rval = create_sfree_mip(nrows, nrays, f, rays, beta, epsilon, &lp);
|
rval = create_sfree_mip(nrows, nrays, f, rays, beta, epsilon, &lp);
|
||||||
abort_if(rval, "greate_sfree_mip failed");
|
abort_if(rval, "greate_sfree_mip failed");
|
||||||
|
|
||||||
int infeasible;
|
|
||||||
double objval;
|
|
||||||
|
|
||||||
log_debug(" solving sfree mip...\n");
|
log_debug(" solving sfree mip...\n");
|
||||||
rval = LP_optimize(&lp, &infeasible);
|
rval = LP_optimize(&lp, &infeasible);
|
||||||
if(rval == ERR_MIP_TIMEOUT) goto CLEANUP;
|
if(rval == ERR_MIP_TIMEOUT) goto CLEANUP;
|
||||||
@@ -194,6 +201,10 @@ static int bound(int nrows,
|
|||||||
double *fbar = 0;
|
double *fbar = 0;
|
||||||
double *sbar = 0;
|
double *sbar = 0;
|
||||||
|
|
||||||
|
double prev_epsilon;
|
||||||
|
int count = 0;
|
||||||
|
*epsilon = GREEDY_BIG_E;
|
||||||
|
|
||||||
rx = (int *) malloc(nrays * sizeof(int));
|
rx = (int *) malloc(nrays * sizeof(int));
|
||||||
fbar = (double *) malloc(nrows * sizeof(double));
|
fbar = (double *) malloc(nrows * sizeof(double));
|
||||||
sbar = (double *) malloc(nrays * sizeof(double));
|
sbar = (double *) malloc(nrays * sizeof(double));
|
||||||
@@ -202,10 +213,6 @@ static int bound(int nrows,
|
|||||||
abort_if(!fbar, "could not allocate fbar");
|
abort_if(!fbar, "could not allocate fbar");
|
||||||
abort_if(!sbar, "could not allocate sbar");
|
abort_if(!sbar, "could not allocate sbar");
|
||||||
|
|
||||||
*epsilon = GREEDY_BIG_E;
|
|
||||||
double prev_epsilon;
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
@@ -284,6 +291,7 @@ static int create_find_epsilon_lp(int nrows,
|
|||||||
int rmatbeg = 0;
|
int rmatbeg = 0;
|
||||||
int *rmatind = 0;
|
int *rmatind = 0;
|
||||||
double *rmatval = 0;
|
double *rmatval = 0;
|
||||||
|
int rx_count = 0;
|
||||||
|
|
||||||
map = (int *) malloc(nrays * sizeof(int));
|
map = (int *) malloc(nrays * sizeof(int));
|
||||||
abort_if(!map, "could not allocate map");
|
abort_if(!map, "could not allocate map");
|
||||||
@@ -297,8 +305,6 @@ static int create_find_epsilon_lp(int nrows,
|
|||||||
abort_if(rval, "LP_create failed");
|
abort_if(rval, "LP_create failed");
|
||||||
|
|
||||||
// create lambda variables
|
// create lambda variables
|
||||||
int rx_count = 0;
|
|
||||||
|
|
||||||
for(int i = 0; i < nrays + 1; i++)
|
for(int i = 0; i < nrays + 1; i++)
|
||||||
{
|
{
|
||||||
if(i < nrays && !rx[i]) continue;
|
if(i < nrays && !rx[i]) continue;
|
||||||
@@ -681,12 +687,7 @@ CLEANUP:
|
|||||||
|
|
||||||
#ifndef TEST_SOURCE
|
#ifndef TEST_SOURCE
|
||||||
|
|
||||||
int GREEDY_create_psi_lp(const int nrows,
|
int GREEDY_create_psi_lp(const struct ConvLFreeSet *lfree, struct LP *lp)
|
||||||
const int nrays,
|
|
||||||
const double *f,
|
|
||||||
const double *rays,
|
|
||||||
const double *beta,
|
|
||||||
struct LP *lp)
|
|
||||||
{
|
{
|
||||||
int rval = 0;
|
int rval = 0;
|
||||||
|
|
||||||
@@ -694,6 +695,11 @@ int GREEDY_create_psi_lp(const int nrows,
|
|||||||
int *rmatind = 0;
|
int *rmatind = 0;
|
||||||
double *rmatval = 0;
|
double *rmatval = 0;
|
||||||
|
|
||||||
|
int nrows = lfree->nrows;
|
||||||
|
int nrays = lfree->rays.nrays;
|
||||||
|
double *rays = lfree->rays.values;
|
||||||
|
double *beta = lfree->beta;
|
||||||
|
|
||||||
rmatind = (int *) malloc(nrays * sizeof(int));
|
rmatind = (int *) malloc(nrays * sizeof(int));
|
||||||
rmatval = (double *) malloc(nrays * sizeof(double));
|
rmatval = (double *) malloc(nrays * sizeof(double));
|
||||||
abort_if(!rmatind, "could not allocate rmatind");
|
abort_if(!rmatind, "could not allocate rmatind");
|
||||||
@@ -744,10 +750,6 @@ CLEANUP:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int GREEDY_ND_pi(const int nrows,
|
int GREEDY_ND_pi(const int nrows,
|
||||||
const int nrays,
|
|
||||||
const double *f,
|
|
||||||
const double *rays,
|
|
||||||
const double *beta,
|
|
||||||
const double *q,
|
const double *q,
|
||||||
const double q_scale,
|
const double q_scale,
|
||||||
struct LP *lp,
|
struct LP *lp,
|
||||||
@@ -765,15 +767,14 @@ int GREEDY_ND_pi(const int nrows,
|
|||||||
for(int k0 = -M; k0 <= M; k0++)
|
for(int k0 = -M; k0 <= M; k0++)
|
||||||
for(int k1 = -M; k1 <= M; k1++)
|
for(int k1 = -M; k1 <= M; k1++)
|
||||||
{
|
{
|
||||||
|
double v;
|
||||||
double qk[] = {frac(q[0] * q_scale) + k0,
|
double qk[] = {frac(q[0] * q_scale) + k0,
|
||||||
frac(q[1] * q_scale) + k1};
|
frac(q[1] * q_scale) + k1};
|
||||||
double value;
|
|
||||||
|
|
||||||
rval = GREEDY_ND_psi(nrows, nrays, f, rays, beta, qk, 1, lp,
|
rval = GREEDY_ND_psi(nrows, qk, 1, lp, &v);
|
||||||
&value);
|
|
||||||
abort_if(rval, "GREEDY_ND_psi failed");
|
abort_if(rval, "GREEDY_ND_psi failed");
|
||||||
|
|
||||||
best_value = min(best_value, value);
|
best_value = min(best_value, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -784,16 +785,15 @@ int GREEDY_ND_pi(const int nrows,
|
|||||||
for(int k1 = -M; k1 <= M; k1++)
|
for(int k1 = -M; k1 <= M; k1++)
|
||||||
for(int k2 = -M; k2 <= M; k2++)
|
for(int k2 = -M; k2 <= M; k2++)
|
||||||
{
|
{
|
||||||
|
double v;
|
||||||
double qk[] = {frac(q[0] * q_scale) + k0,
|
double qk[] = {frac(q[0] * q_scale) + k0,
|
||||||
frac(q[1] * q_scale) + k1,
|
frac(q[1] * q_scale) + k1,
|
||||||
frac(q[2] * q_scale) + k2};
|
frac(q[2] * q_scale) + k2};
|
||||||
double value;
|
|
||||||
|
|
||||||
rval = GREEDY_ND_psi(nrows, nrays, f, rays, beta, qk, 1, lp,
|
rval = GREEDY_ND_psi(nrows, qk, 1, lp, &v);
|
||||||
&value);
|
|
||||||
abort_if(rval, "GREEDY_ND_psi failed");
|
abort_if(rval, "GREEDY_ND_psi failed");
|
||||||
|
|
||||||
best_value = min(best_value, value);
|
best_value = min(best_value, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -809,10 +809,6 @@ CLEANUP:
|
|||||||
* q_scale), where B is the convex hull of {f + ri * bi}_i=1^m.
|
* q_scale), where B is the convex hull of {f + ri * bi}_i=1^m.
|
||||||
*/
|
*/
|
||||||
int GREEDY_ND_psi(const int nrows,
|
int GREEDY_ND_psi(const int nrows,
|
||||||
const int nrays,
|
|
||||||
const double *f,
|
|
||||||
const double *rays,
|
|
||||||
const double *beta,
|
|
||||||
const double *q,
|
const double *q,
|
||||||
const double q_scale,
|
const double q_scale,
|
||||||
struct LP *lp,
|
struct LP *lp,
|
||||||
|
|||||||
@@ -477,7 +477,9 @@ static int bound(const double *rays,
|
|||||||
log_verbose(" pp %20.12lf %20.12lf\n", pp[0], pp[1]);
|
log_verbose(" pp %20.12lf %20.12lf\n", pp[0], pp[1]);
|
||||||
log_verbose(" lambda %20.12lf %20.12lf\n", lambda1, lambda2);
|
log_verbose(" lambda %20.12lf %20.12lf\n", lambda1, lambda2);
|
||||||
|
|
||||||
double r1bound[2] = { r1[0] * bounds[i1], r1[1] * bounds[i1] };
|
{
|
||||||
|
double r1bound[2] = {r1[0] * bounds[i1],
|
||||||
|
r1[1] * bounds[i1]};
|
||||||
|
|
||||||
rval = scale_cone_to_point(r1, r2, pp, &e1);
|
rval = scale_cone_to_point(r1, r2, pp, &e1);
|
||||||
abort_if(rval, "scale_cone_to_point failed");
|
abort_if(rval, "scale_cone_to_point failed");
|
||||||
@@ -489,6 +491,7 @@ static int bound(const double *rays,
|
|||||||
log_verbose(" e2=%20.12lf\n", e2);
|
log_verbose(" e2=%20.12lf\n", e2);
|
||||||
log_verbose(" b1=%20.12lf\n", bounds[i1]);
|
log_verbose(" b1=%20.12lf\n", bounds[i1]);
|
||||||
log_verbose(" b2=%20.12lf\n", bounds[i2]);
|
log_verbose(" b2=%20.12lf\n", bounds[i2]);
|
||||||
|
}
|
||||||
|
|
||||||
switch(DOUBLE_cmp(e1, bounds[i1]))
|
switch(DOUBLE_cmp(e1, bounds[i1]))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,6 +25,9 @@
|
|||||||
#include <infinity/greedy-nd.h>
|
#include <infinity/greedy-nd.h>
|
||||||
#include <infinity/infinity-2d.h>
|
#include <infinity/infinity-2d.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auxiliary structure for sorting with qsort.
|
||||||
|
*/
|
||||||
struct SortPair
|
struct SortPair
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
@@ -51,6 +54,9 @@ static int _qsort_cmp_rays_angle(const void *p1, const void *p2)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sorts a list of rays according to their angle.
|
* Sorts a list of rays according to their angle.
|
||||||
|
*
|
||||||
|
* @param rays the list to be sorted
|
||||||
|
* @return zero if successful, non-zero otherwise
|
||||||
*/
|
*/
|
||||||
static int sort_rays_by_angle(struct RayList *rays)
|
static int sort_rays_by_angle(struct RayList *rays)
|
||||||
{
|
{
|
||||||
@@ -85,6 +91,16 @@ CLEANUP:
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an intersection cut from the given lattice-free set.
|
||||||
|
*
|
||||||
|
* @param tableau the tableau that was used to generate the model
|
||||||
|
* @param map the mapping between the tableau and model
|
||||||
|
* @param model the multi-row model that was used to generate the cut
|
||||||
|
* @param lfree the lattice-free set
|
||||||
|
* @param[out] cut the generated cut
|
||||||
|
* @return zero if successful, non-zero otherwise
|
||||||
|
*/
|
||||||
static int create_cut_from_lfree(const struct Tableau *tableau,
|
static int create_cut_from_lfree(const struct Tableau *tableau,
|
||||||
const struct TableauModelMap *map,
|
const struct TableauModelMap *map,
|
||||||
const struct MultiRowModel *model,
|
const struct MultiRowModel *model,
|
||||||
@@ -96,13 +112,12 @@ static int create_cut_from_lfree(const struct Tableau *tableau,
|
|||||||
struct LP lp;
|
struct LP lp;
|
||||||
int nvars = map->nvars;
|
int nvars = map->nvars;
|
||||||
int nrows = tableau->nrows;
|
int nrows = tableau->nrows;
|
||||||
struct RayList *rays = &model->rays;
|
const struct RayList *rays = &model->rays;
|
||||||
|
|
||||||
rval = LP_open(&lp);
|
rval = LP_open(&lp);
|
||||||
abort_if(rval, "LP_open failed");
|
abort_if(rval, "LP_open failed");
|
||||||
|
|
||||||
rval = GREEDY_create_psi_lp(nrows, lfree->rays.nrays, lfree->f,
|
rval = GREEDY_create_psi_lp(lfree, &lp);
|
||||||
lfree->rays.values, lfree->beta, &lp);
|
|
||||||
abort_if(rval, "create_psi_lp failed");
|
abort_if(rval, "create_psi_lp failed");
|
||||||
|
|
||||||
cut->nz = nvars;
|
cut->nz = nvars;
|
||||||
@@ -110,20 +125,16 @@ static int create_cut_from_lfree(const struct Tableau *tableau,
|
|||||||
{
|
{
|
||||||
double value;
|
double value;
|
||||||
const double *q = LFREE_get_ray(rays, map->variable_to_ray[i]);
|
const double *q = LFREE_get_ray(rays, map->variable_to_ray[i]);
|
||||||
|
char type = tableau->column_types[map->indices[i]];
|
||||||
|
|
||||||
if(ENABLE_LIFTING &&
|
if(ENABLE_LIFTING && type == MILP_INTEGER)
|
||||||
tableau->column_types[map->indices[i]] == MILP_INTEGER)
|
|
||||||
{
|
{
|
||||||
rval = GREEDY_ND_pi(nrows, lfree->rays.nrays, lfree->f,
|
rval = GREEDY_ND_pi(nrows, q, map->ray_scale[i], &lp, &value);
|
||||||
lfree->rays.values, lfree->beta, q, map->ray_scale[i], &lp,
|
|
||||||
&value);
|
|
||||||
abort_if(rval, "GREEDY_ND_pi failed");
|
abort_if(rval, "GREEDY_ND_pi failed");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rval = GREEDY_ND_psi(nrows, lfree->rays.nrays, lfree->f,
|
rval = GREEDY_ND_psi(nrows, q, map->ray_scale[i], &lp, &value);
|
||||||
lfree->rays.values, lfree->beta, q, map->ray_scale[i], &lp,
|
|
||||||
&value);
|
|
||||||
abort_if(rval, "GREEDY_ND_psi failed");
|
abort_if(rval, "GREEDY_ND_psi failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,13 +154,22 @@ CLEANUP:
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an original multi-row model, returns a simplified model with fewer
|
||||||
|
* rays. For each subset of rays that are very close to each other, only one ray
|
||||||
|
* is selected for the new model.
|
||||||
|
*
|
||||||
|
* @param original_model the original model
|
||||||
|
* @param[out] filtered_model the simplified model
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
static int filter_model(const struct MultiRowModel *original_model,
|
static int filter_model(const struct MultiRowModel *original_model,
|
||||||
struct MultiRowModel *filtered_model)
|
struct MultiRowModel *filtered_model)
|
||||||
{
|
{
|
||||||
int rval = 0;
|
int rval = 0;
|
||||||
int nrows = original_model->nrows;
|
int nrows = original_model->nrows;
|
||||||
struct RayList *filtered_rays = &filtered_model->rays;
|
struct RayList *filtered_rays = &filtered_model->rays;
|
||||||
struct RayList *original_rays = &original_model->rays;
|
const struct RayList *original_rays = &original_model->rays;
|
||||||
|
|
||||||
memcpy(filtered_model->f, original_model->f, 2 * sizeof(double));
|
memcpy(filtered_model->f, original_model->f, 2 * sizeof(double));
|
||||||
|
|
||||||
@@ -190,11 +210,21 @@ CLEANUP:
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int append_extra_rays(const struct Tableau *tableau,
|
/**
|
||||||
struct MultiRowModel *model)
|
* Appends a few extra rays to the model, so that the resulting
|
||||||
|
* lattice-free set is a little larger than it would be otherwise.
|
||||||
|
* Although this does not change the coefficients for the continuous
|
||||||
|
* variables, it might help with lifting.
|
||||||
|
*
|
||||||
|
* The model is modified in-place.
|
||||||
|
*
|
||||||
|
* @param model the model to be modified
|
||||||
|
* @return zero if successful, non-zero otherwise
|
||||||
|
*/
|
||||||
|
static int append_extra_rays(struct MultiRowModel *model)
|
||||||
{
|
{
|
||||||
int rval = 0;
|
int rval = 0;
|
||||||
int nrows = tableau->nrows;
|
int nrows = model->nrows;
|
||||||
int n_extra_rays = 0;
|
int n_extra_rays = 0;
|
||||||
double extra_rays[100];
|
double extra_rays[100];
|
||||||
|
|
||||||
@@ -251,25 +281,33 @@ CLEANUP:
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_sage_file(const struct MultiRowModel *model,
|
/**
|
||||||
const struct ConvLFreeSet *lfree,
|
* Writes a given lattice-free set to a sage file.
|
||||||
|
*
|
||||||
|
* This file can be rendered by the script 'benchmark/scripts/render.sage'
|
||||||
|
*
|
||||||
|
* @param lfree the lattice-free set to be written
|
||||||
|
* @param filename the name of the file
|
||||||
|
* @return zero if successful, non-zero otherwise
|
||||||
|
*/
|
||||||
|
static int write_lfree_to_sage_file(const struct ConvLFreeSet *lfree,
|
||||||
const char *filename)
|
const char *filename)
|
||||||
{
|
{
|
||||||
int rval = 0;
|
int rval = 0;
|
||||||
int nrows = model->nrows;
|
int nrows = lfree->nrows;
|
||||||
|
|
||||||
FILE *fsage = fopen(filename, "w");
|
FILE *fsage = fopen(filename, "w");
|
||||||
abort_iff(!fsage, "could not open %s", filename);
|
abort_iff(!fsage, "could not open %s", filename);
|
||||||
|
|
||||||
fprintf(fsage, "f=vector([");
|
fprintf(fsage, "f=vector([");
|
||||||
for(int i = 0; i < nrows; i++)
|
for(int i = 0; i < nrows; i++)
|
||||||
fprintf(fsage, "%.20lf,", model->f[i]);
|
fprintf(fsage, "%.20lf,", lfree->f[i]);
|
||||||
fprintf(fsage, "])\n");
|
fprintf(fsage, "])\n");
|
||||||
|
|
||||||
fprintf(fsage, "R=matrix([\n");
|
fprintf(fsage, "R=matrix([\n");
|
||||||
for(int i = 0; i < model->rays.nrays; i++)
|
for(int i = 0; i < lfree->rays.nrays; i++)
|
||||||
{
|
{
|
||||||
double *r = LFREE_get_ray(&model->rays, i);
|
double *r = LFREE_get_ray(&lfree->rays, i);
|
||||||
fprintf(fsage, " [");
|
fprintf(fsage, " [");
|
||||||
for(int j = 0; j < nrows; j++)
|
for(int j = 0; j < nrows; j++)
|
||||||
fprintf(fsage, "%.20lf,", r[j]);
|
fprintf(fsage, "%.20lf,", r[j]);
|
||||||
@@ -278,7 +316,7 @@ static int write_sage_file(const struct MultiRowModel *model,
|
|||||||
fprintf(fsage, "])\n");
|
fprintf(fsage, "])\n");
|
||||||
|
|
||||||
fprintf(fsage, "pi=vector([\n");
|
fprintf(fsage, "pi=vector([\n");
|
||||||
for(int k = 0; k < model->rays.nrays; k++)
|
for(int k = 0; k < lfree->rays.nrays; k++)
|
||||||
fprintf(fsage, " %.12lf,\n", 1 / lfree->beta[k]);
|
fprintf(fsage, " %.12lf,\n", 1 / lfree->beta[k]);
|
||||||
fprintf(fsage, "])\n");
|
fprintf(fsage, "])\n");
|
||||||
|
|
||||||
@@ -287,8 +325,7 @@ CLEANUP:
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dump_cut(const struct MultiRowModel *model,
|
static int dump_cut(const struct ConvLFreeSet *lfree)
|
||||||
const struct ConvLFreeSet *lfree)
|
|
||||||
{
|
{
|
||||||
int rval = 0;
|
int rval = 0;
|
||||||
|
|
||||||
@@ -296,13 +333,23 @@ static int dump_cut(const struct MultiRowModel *model,
|
|||||||
sprintf(filename, "cut-%03d.sage", DUMP_CUT_N++);
|
sprintf(filename, "cut-%03d.sage", DUMP_CUT_N++);
|
||||||
|
|
||||||
time_printf("Writing %s...\n", filename);
|
time_printf("Writing %s...\n", filename);
|
||||||
rval = write_sage_file(model, lfree, filename);
|
rval = write_lfree_to_sage_file(lfree, filename);
|
||||||
abort_if(rval, "write_sage_file failed");
|
abort_if(rval, "write_lfree_to_sage_file failed");
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a tableau, extracts the original multi-row model, along with
|
||||||
|
* its mapping, in addition to a simplified version of this model.
|
||||||
|
*
|
||||||
|
* @param tableau the tableau
|
||||||
|
* @param original_model the original multi-row model obtained from the tableau
|
||||||
|
* @param filtered_model the simplified multi-row model obtained from the tableau
|
||||||
|
* @param original_map the mapping between the tableau and the original model
|
||||||
|
* @return zero if successful, non-zero otherwise
|
||||||
|
*/
|
||||||
static int extract_models(const struct Tableau *tableau,
|
static int extract_models(const struct Tableau *tableau,
|
||||||
struct MultiRowModel *original_model,
|
struct MultiRowModel *original_model,
|
||||||
struct MultiRowModel *filtered_model,
|
struct MultiRowModel *filtered_model,
|
||||||
@@ -321,7 +368,7 @@ static int extract_models(const struct Tableau *tableau,
|
|||||||
|
|
||||||
if(ENABLE_LIFTING)
|
if(ENABLE_LIFTING)
|
||||||
{
|
{
|
||||||
rval = append_extra_rays(tableau, filtered_model);
|
rval = append_extra_rays(filtered_model);
|
||||||
abort_if(rval, "append_extra_rays failed");
|
abort_if(rval, "append_extra_rays failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,6 +384,13 @@ CLEANUP:
|
|||||||
|
|
||||||
#ifndef TEST_SOURCE
|
#ifndef TEST_SOURCE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the infinity cut for a given tableau.
|
||||||
|
*
|
||||||
|
* @param tableau the tableau that should be used to generate the cut
|
||||||
|
* @param[out] cut the resulting infinity cut
|
||||||
|
* @return zero if successful, non-zero otherwise
|
||||||
|
*/
|
||||||
int INFINITY_generate_cut(const struct Tableau *tableau, struct Row *cut)
|
int INFINITY_generate_cut(const struct Tableau *tableau, struct Row *cut)
|
||||||
{
|
{
|
||||||
int rval = 0;
|
int rval = 0;
|
||||||
@@ -382,7 +436,7 @@ int INFINITY_generate_cut(const struct Tableau *tableau, struct Row *cut)
|
|||||||
|
|
||||||
if(SHOULD_DUMP_CUTS)
|
if(SHOULD_DUMP_CUTS)
|
||||||
{
|
{
|
||||||
rval = dump_cut(&filtered_model, &lfree);
|
rval = dump_cut(&lfree);
|
||||||
abort_if(rval, "dump_cut failed");
|
abort_if(rval, "dump_cut failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -296,20 +296,27 @@ TEST(GreedyNDTest, psi_test)
|
|||||||
double q1[] = { 1.0, 1.0 };
|
double q1[] = { 1.0, 1.0 };
|
||||||
double q2[] = { -2.0, 0.0 };
|
double q2[] = { -2.0, 0.0 };
|
||||||
|
|
||||||
|
struct ConvLFreeSet lfree;
|
||||||
|
lfree.f = f;
|
||||||
|
lfree.beta = beta;
|
||||||
|
lfree.rays.nrays = 6;
|
||||||
|
lfree.rays.values = rays;
|
||||||
|
lfree.nrows = lfree.rays.dim = 2;
|
||||||
|
|
||||||
double value;
|
double value;
|
||||||
struct LP lp;
|
struct LP lp;
|
||||||
|
|
||||||
rval = LP_open(&lp);
|
rval = LP_open(&lp);
|
||||||
abort_if(rval, "LP_open failed");
|
abort_if(rval, "LP_open failed");
|
||||||
|
|
||||||
rval = GREEDY_create_psi_lp(2, 6, f, rays, beta, &lp);
|
rval = GREEDY_create_psi_lp(&lfree, &lp);
|
||||||
abort_if(rval, "GREEDY_create_psi_lp failed");
|
abort_if(rval, "GREEDY_create_psi_lp failed");
|
||||||
|
|
||||||
rval = GREEDY_ND_psi(2, 6, f, rays, beta, q1, 1.0, &lp, &value);
|
rval = GREEDY_ND_psi(2, q1, 1.0, &lp, &value);
|
||||||
abort_if(rval, "GREDDY_ND_psi failed");
|
abort_if(rval, "GREDDY_ND_psi failed");
|
||||||
EXPECT_NEAR(value, 2.0, 1e-6);
|
EXPECT_NEAR(value, 2.0, 1e-6);
|
||||||
|
|
||||||
rval = GREEDY_ND_psi(2, 6, f, rays, beta, q2, 2.0, &lp, &value);
|
rval = GREEDY_ND_psi(2, q2, 2.0, &lp, &value);
|
||||||
abort_if(rval, "GREDDY_ND_psi failed");
|
abort_if(rval, "GREDDY_ND_psi failed");
|
||||||
EXPECT_NEAR(value, 8.0, 1e-6);
|
EXPECT_NEAR(value, 8.0, 1e-6);
|
||||||
|
|
||||||
@@ -341,20 +348,27 @@ TEST(GreedyNDTest, psi_test_2)
|
|||||||
double q1[] = { 0.5, 0.5, 0.5 };
|
double q1[] = { 0.5, 0.5, 0.5 };
|
||||||
double q2[] = { 1, 0, 0 };
|
double q2[] = { 1, 0, 0 };
|
||||||
|
|
||||||
|
struct ConvLFreeSet lfree;
|
||||||
|
lfree.f = f;
|
||||||
|
lfree.beta = beta;
|
||||||
|
lfree.rays.nrays = 8;
|
||||||
|
lfree.rays.values = rays;
|
||||||
|
lfree.nrows = lfree.rays.dim = 3;
|
||||||
|
|
||||||
double value;
|
double value;
|
||||||
struct LP lp;
|
struct LP lp;
|
||||||
|
|
||||||
rval = LP_open(&lp);
|
rval = LP_open(&lp);
|
||||||
abort_if(rval, "LP_open failed");
|
abort_if(rval, "LP_open failed");
|
||||||
|
|
||||||
rval = GREEDY_create_psi_lp(3, 8, f, rays, beta, &lp);
|
rval = GREEDY_create_psi_lp(&lfree, &lp);
|
||||||
abort_if(rval, "GREEDY_create_psi_lp failed");
|
abort_if(rval, "GREEDY_create_psi_lp failed");
|
||||||
|
|
||||||
rval = GREEDY_ND_psi(3, 8, f, rays, beta, q1, 1.0, &lp, &value);
|
rval = GREEDY_ND_psi(3, q1, 1.0, &lp, &value);
|
||||||
abort_if(rval, "GREDDY_ND_psi failed");
|
abort_if(rval, "GREDDY_ND_psi failed");
|
||||||
EXPECT_NEAR(value, 1.0, 1e-6);
|
EXPECT_NEAR(value, 1.0, 1e-6);
|
||||||
|
|
||||||
rval = GREEDY_ND_psi(3, 8, f, rays, beta, q2, 1.0, &lp, &value);
|
rval = GREEDY_ND_psi(3, q2, 1.0, &lp, &value);
|
||||||
abort_if(rval, "GREDDY_ND_psi failed");
|
abort_if(rval, "GREDDY_ND_psi failed");
|
||||||
EXPECT_NEAR(value, 2.0, 1e-6);
|
EXPECT_NEAR(value, 2.0, 1e-6);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user