infinity: make cuts more reliable

selection
Alinson S. Xavier 9 years ago
parent aa2e0e7ca6
commit fac62db36a

@ -114,32 +114,32 @@ instances/%.done: $(multirow) 2row-cont/%.yaml 2row-lift/%.yaml 3row-cont/%.yaml
2row-cont/%.yaml: $(multirow) instances/%.mps.gz bases/%.bas
@echo " 2row-cont $*..."
@$(multirow) --mir --infinity --problem instances/$*.mps.gz --basis bases/$*.bas --log 2row-cont/$*.log --stats $@ --solution solutions/$*.x || touch 2row-cont/$*.err.$$?
@$(multirow) --mir --infinity --problem instances/$*.mps.gz --basis bases/$*.bas --log 2row-cont/$*.log --stats $@ --solution solutions/$*.x
@echo " 2row-cont $* [done]"
2row-lift/%.yaml: $(multirow) instances/%.mps.gz bases/%.bas
@echo " 2row-lift $*..."
@$(multirow) --mir --infinity --problem instances/$*.mps.gz --basis bases/$*.bas --log 2row-lift/$*.log --stats $@ --solution solutions/$*.x --lift || touch 2row-lift/$*.err.$$?
@$(multirow) --mir --infinity --problem instances/$*.mps.gz --basis bases/$*.bas --log 2row-lift/$*.log --stats $@ --solution solutions/$*.x --lift
@echo " 2row-lift $* [done]"
3row-cont/%.yaml: $(multirow) instances/%.mps.gz bases/%.bas
@echo " 3row-cont $*..."
@$(multirow) --mir --infinity --problem instances/$*.mps.gz --basis bases/$*.bas --log 3row-cont/$*.log --stats $@ --solution solutions/$*.x --rows 3 || touch 3row-cont/$*.err.$$?
@$(multirow) --mir --infinity --problem instances/$*.mps.gz --basis bases/$*.bas --log 3row-cont/$*.log --stats $@ --solution solutions/$*.x --rows 3
@echo " 3row-cont $* [done]"
3row-lift/%.yaml: $(multirow) instances/%.mps.gz bases/%.bas
@echo " 3row-lift $*..."
@$(multirow) --mir --infinity --problem instances/$*.mps.gz --basis bases/$*.bas --log 3row-lift/$*.log --stats $@ --solution solutions/$*.x --rows 3 --lift || touch 3row-lift/$*.err.$$?
@$(multirow) --mir --infinity --problem instances/$*.mps.gz --basis bases/$*.bas --log 3row-lift/$*.log --stats $@ --solution solutions/$*.x --rows 3 --lift
@echo " 3row-lift $* [done]"
5row-cont/%.yaml: $(multirow) instances/%.mps.gz bases/%.bas
@echo " 5row-cont $*..."
@$(multirow) --mir --infinity --problem instances/$*.mps.gz --basis bases/$*.bas --log 5row-cont/$*.log --stats $@ --solution solutions/$*.x --rows 5 || touch 5row-cont/$*.err.$$?
@$(multirow) --mir --infinity --problem instances/$*.mps.gz --basis bases/$*.bas --log 5row-cont/$*.log --stats $@ --solution solutions/$*.x --rows 5
@echo " 5row-cont $* [done]"
5row-lift/%.yaml: $(multirow) instances/%.mps.gz bases/%.bas
@echo " 5row-lift $*..."
@$(multirow) --mir --infinity --problem instances/$*.mps.gz --basis bases/$*.bas --log 5row-lift/$*.log --stats $@ --solution solutions/$*.x --rows 5 --lift || touch 5row-lift/$*.err.$$?
@$(multirow) --mir --infinity --problem instances/$*.mps.gz --basis bases/$*.bas --log 5row-lift/$*.log --stats $@ --solution solutions/$*.x --rows 5 --lift
@echo " 5row-lift $* [done]"

@ -1,7 +1,5 @@
# This file was *autogenerated* from the file scripts/render.sage
from sage.all_cmdline import * # import sage library
_sage_const_3 = Integer(3); _sage_const_1 = Integer(1); _sage_const_0 = Integer(0); _sage_const_0p2 = RealNumber('0.2'); _sage_const_1000 = Integer(1000); _sage_const_1en10 = RealNumber('1e-10'); _sage_const_30 = Integer(30); _sage_const_20 = Integer(20)
import sys
import math
@ -44,4 +42,3 @@ for fname in sys.argv[_sage_const_1 :]:
output = "%s.png" % fname
save(p0+pf+p3+p1, output, xmin=-M, ymin=-M, xmax=M, ymax=M)

@ -14,7 +14,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define _XOPEN_SOURCE 500
#define _BSD_SOURCE 500
#include <getopt.h>
#include <unistd.h>

@ -557,14 +557,14 @@ int INFINITY_2D_generate_lfree(const struct MultiRowModel *model,
while(1)
{
log_verbose(" starting iteration %d...\n", count);
log_debug(" starting iteration %d...\n", count);
abort_if(count++ > 2 * nrays, "infinite loop");
rval = get_bounding_box(2, nrays, rays, beta, INFINITY_BIG_E, lb, ub);
abort_if(rval, "get_bounding_box failed");
log_verbose(" box=[%.2lf %.2lf] [%.2lf %.2lf]\n", lb[0], ub[0], lb[1], ub[1]);
log_debug(" box=[%.2lf %.2lf] [%.2lf %.2lf]\n", lb[0], ub[0], lb[1], ub[1]);
int best_i1, best_i2;
double best_v1[2];
@ -591,17 +591,17 @@ int INFINITY_2D_generate_lfree(const struct MultiRowModel *model,
if(epsilon >= 0 && epsilon < best_epsilon)
{
log_verbose(" found smaller epsilon: %.8lf\n", epsilon);
log_debug(" found smaller epsilon: %.8lf\n", epsilon);
rval = get_bounding_box(2, nrays, rays, beta, epsilon, lb, ub);
abort_if(rval, "get_bounding_box failed");
log_verbose(" p=%.2lf %.2lf\n", p[0], p[1]);
log_verbose(" box=[%.2lf %.2lf] [%.2lf %.2lf]\n", lb[0], ub[0],
log_debug(" p=%.2lf %.2lf\n", p[0], p[1]);
log_debug(" box=[%.2lf %.2lf] [%.2lf %.2lf]\n", lb[0], ub[0],
lb[1], ub[1]);
log_verbose(" v1=%12.8lf %12.8lf\n", v1[0], v1[1]);
log_verbose(" v2=%12.8lf %12.8lf\n", v2[0], v2[1]);
log_verbose(" rays=[%d %d]\n", i1, i2);
log_debug(" v1=%12.8lf %12.8lf\n", v1[0], v1[1]);
log_debug(" v2=%12.8lf %12.8lf\n", v2[0], v2[1]);
log_debug(" rays=[%d %d]\n", i1, i2);
best_epsilon = epsilon;
best_v1[0] = v1[0];
@ -624,21 +624,21 @@ int INFINITY_2D_generate_lfree(const struct MultiRowModel *model,
if(isinf(best_epsilon))
{
log_verbose(" best_epsilon is infinity\n");
log_debug(" best_epsilon is infinity\n");
break;
}
log_verbose(" updating beta\n");
log_debug(" updating beta\n");
if(isinf(best_v1[0]))
{
beta[best_i1] = best_epsilon;
log_verbose(" beta[%d]=%.8lf (exact)\n", best_i1, best_epsilon);
log_debug(" beta[%d]=%.8lf (exact)\n", best_i1, best_epsilon);
}
else
{
log_verbose(" v1=%.8lf %.8lf\n", best_v1[0], best_v1[1]);
log_verbose(" v2=%.8lf %.8lf\n", best_v2[0], best_v2[1]);
log_verbose(" i=%d %d\n", best_i1, best_i2);
log_debug(" v1=%.8lf %.8lf\n", best_v1[0], best_v1[1]);
log_debug(" v2=%.8lf %.8lf\n", best_v2[0], best_v2[1]);
log_debug(" i=%d %d\n", best_i1, best_i2);
for (int i = 0; i < nrays; i++)
{
@ -650,7 +650,7 @@ int INFINITY_2D_generate_lfree(const struct MultiRowModel *model,
if(!DOUBLE_geq(lambda, 0)) continue;
beta[i] = fmin(beta[i], lambda);
log_verbose(" beta[%d]=%.8lf\n", i, beta[i]);
log_debug(" beta[%d]=%.8lf\n", i, beta[i]);
}
}
@ -671,7 +671,7 @@ int INFINITY_2D_generate_lfree(const struct MultiRowModel *model,
double *split_direction = &rays[2 * k];
log_verbose(" split_direction=%.2lf %.2lf\n", split_direction[0],
log_debug(" split_direction=%.2lf %.2lf\n", split_direction[0],
split_direction[1]);
double pi[2];
@ -680,8 +680,8 @@ int INFINITY_2D_generate_lfree(const struct MultiRowModel *model,
rval = generate_split(f, split_direction, pi, &pi_zero, 10);
abort_if(rval, "generate_split failed");
log_verbose(" pi=%.2lf %.2lf\n", pi[0], pi[1]);
log_verbose(" pi_zero=%.2lf\n", pi_zero);
log_debug(" pi=%.2lf %.2lf\n", pi[0], pi[1]);
log_debug(" pi_zero=%.2lf\n", pi_zero);
if(isinf(pi[0]))
{
@ -695,7 +695,7 @@ int INFINITY_2D_generate_lfree(const struct MultiRowModel *model,
lhs = f[0] * pi[0] + f[1] * pi[1];
if(DOUBLE_eq(pi_zero, lhs) || DOUBLE_eq(lhs, pi_zero+1))
{
log_verbose(" split rejected\n");
log_debug(" split rejected\n");
is_split = 0;
}
@ -708,7 +708,7 @@ int INFINITY_2D_generate_lfree(const struct MultiRowModel *model,
if (!(DOUBLE_leq(pi_zero, lhs) && DOUBLE_leq(lhs, pi_zero+1)))
{
log_verbose(" point %.4lf %.4lf falls outside of the split\n",
log_debug(" point %.4lf %.4lf falls outside of the split\n",
f[0] + r[0]*beta[i], f[1] + r[1] * beta[i]);
is_split = 0;
}
@ -716,7 +716,7 @@ int INFINITY_2D_generate_lfree(const struct MultiRowModel *model,
if(is_split)
{
log_verbose(" split confirmed. stopping.\n");
log_debug(" split confirmed. stopping.\n");
break;
}
}

@ -590,6 +590,9 @@ static int find_interior_point_enum(const int nrows,
rval = INFINITY_psi(nrows, q, 1, &lp, &value);
abort_if(rval, "INFINITY_psi failed");
log_debug(" x=[%3d %3d %3d] value=%.12lf\n",
x1, x2, x3, value);
if(value < best_value)
{
best_value = value;
@ -599,7 +602,7 @@ static int find_interior_point_enum(const int nrows,
}
}
if(best_value < 0.999) *found = 1;
if(!DOUBLE_geq(best_value, 1)) *found = 1;
CLEANUP:
if(beta2) free(beta2);
@ -662,7 +665,7 @@ static int find_interior_point_cplex(const int nrows,
log_debug(" obj = %.8lf\n", objval);
if(objval >= 0.999)
if(DOUBLE_geq(objval, 1.0))
{
log_debug(" set is lattice-free\n");
*found = 0;
@ -1112,12 +1115,6 @@ int INFINITY_create_psi_lp(const struct ConvLFreeSet *lfree, struct LP *lp)
rval = LP_relax(lp);
abort_if(rval, "LP_relax failed");
if_verbose_level
{
rval = LP_write(lp, "psi.lp");
abort_if(rval, "LP_write failed");
}
CLEANUP:
if(rmatind) free(rmatind);
if(rmatval) free(rmatval);
@ -1218,6 +1215,8 @@ CLEANUP:
int INFINITY_ND_generate_lfree(const struct MultiRowModel *model,
struct ConvLFreeSet *lfree)
{
log_debug("INFINITY_ND_generate_lfree\n");
int rval = 0;
int nrows = model->nrows;
int nrays = model->rays.nrays;
@ -1228,6 +1227,7 @@ int INFINITY_ND_generate_lfree(const struct MultiRowModel *model,
lfree->nrows = model->nrows;
lfree->rays.nrays = nrays;
memcpy(rays, model->rays.values, nrays * nrows * sizeof(double));
memcpy(f, model->f, nrows * sizeof(double));
@ -1319,10 +1319,10 @@ int INFINITY_ND_generate_lfree(const struct MultiRowModel *model,
rval = bound(nrows, nrays, f, model->rays.values, x, beta,
&epsilon_x, tx);
abort_if(rval, "bound failed");
// epsilon_x *= 0.999;
if(isinf(epsilon_x)) break;
// epsilon_x = (floor(epsilon_x * 128) / 128);
log_debug(" epsilon_x = %.8lf\n", epsilon_x);
if(DOUBLE_eq(epsilon_x, epsilon))
@ -1348,7 +1348,6 @@ int INFINITY_ND_generate_lfree(const struct MultiRowModel *model,
if(t[i])
{
beta[i] = min(beta[i], epsilon);
// beta[i] *= 0.999;
}
else if(!skip_ahull)
{
@ -1365,11 +1364,11 @@ int INFINITY_ND_generate_lfree(const struct MultiRowModel *model,
continue;
}
// alpha = (floor(alpha * 128) / 128);
beta[i] = min(beta[i], alpha);
// beta[i] *= 0.999;
}
log_debug(" beta[%2d] = %.4lf\n", i, beta[i]);
log_debug(" beta[%2d] = %20.12lf\n", i, beta[i]);
}
log_debug("epsilon = %.6lf\n", epsilon);

@ -117,6 +117,8 @@ static int create_cut_from_lfree(const struct Tableau *tableau,
rval = LP_open(&lp);
abort_if(rval, "LP_open failed");
memcpy(lfree->f, model->f, nrows * sizeof(double));
rval = INFINITY_create_psi_lp(lfree, &lp);
abort_if(rval, "create_psi_lp failed");
@ -127,6 +129,7 @@ static int create_cut_from_lfree(const struct Tableau *tableau,
const double *q = LFREE_get_ray(rays, map->variable_to_ray[i]);
char type = tableau->column_types[map->indices[i]];
if(ENABLE_LIFTING && type == MILP_INTEGER)
{
rval = INFINITY_pi(nrows, q, map->ray_scale[i], &lp, &value);
@ -140,8 +143,18 @@ static int create_cut_from_lfree(const struct Tableau *tableau,
log_verbose(" psi[%4d] = %20.12lf %d\n", map->indices[i], value);
value *= 1.0001;
value = DOUBLE_max(value, 0.0001);
if_debug_level
{
time_printf(" q=[");
for(int j = 0; j < nrows; j++)
printf("%25.20lf ", q[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;
@ -167,11 +180,21 @@ static int filter_model(const struct MultiRowModel *original_model,
struct MultiRowModel *filtered_model)
{
int rval = 0;
double *r = 0;
double *f = filtered_model->f;
int nrows = original_model->nrows;
struct RayList *filtered_rays = &filtered_model->rays;
const struct RayList *original_rays = &original_model->rays;
memcpy(filtered_model->f, original_model->f, 2 * sizeof(double));
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");
for(double norm_cutoff = 0.00; norm_cutoff <= 5.0; norm_cutoff += 0.1)
{
@ -180,13 +203,23 @@ static int filter_model(const struct MultiRowModel *original_model,
for(int i = 0; i < original_rays->nrays; i++)
{
int keep = 1;
double *r = LFREE_get_ray(original_rays, i);
double norm = 0;
memcpy(r, LFREE_get_ray(original_rays, i), nrows * sizeof(double));
for(int j = 0; j < nrows; j++)
{
r[j] = (ceil(r[j] * 128) / 128);
norm += fabs(r[j]);
}
if(DOUBLE_iszero(norm)) continue;
for(int j = 0; j < (filtered_rays->nrays); j++)
{
double *q = LFREE_get_ray(filtered_rays, j);
double norm = 0;
norm = 0;
for(int k = 0; k < nrows; k++)
norm += fabs(r[k] - q[k]);
@ -207,6 +240,7 @@ static int filter_model(const struct MultiRowModel *original_model,
}
CLEANUP:
if(r) free(r);
return rval;
}
@ -225,59 +259,30 @@ static int append_extra_rays(struct MultiRowModel *model)
{
int rval = 0;
int nrows = model->nrows;
int n_extra_rays = 0;
double extra_rays[100];
abort_if(nrows > 3, "not implemented");
double *r = 0;
double e = 1 / 128.0;
if(nrows == 2)
{
extra_rays[0] = 0.0001;
extra_rays[1] = 0.0000;
r = (double*) malloc(nrows * sizeof(double));
abort_if(!r, "could not allocate r");
extra_rays[2] = -0.0001;
extra_rays[3] = 0.0001;
extra_rays[4] = -0.0001;
extra_rays[5] = -0.0001;
n_extra_rays = 3;
}
if(nrows == 3)
for(int i = 0; i < nrows; i++)
{
extra_rays[0] = 0.0000;
extra_rays[1] = 0.0000;
extra_rays[2] = 0.0001;
extra_rays[3] = 0.0001;
extra_rays[4] = 0.0000;
extra_rays[5] = -0.0001;
extra_rays[6] = -0.0001;
extra_rays[7] = 0.0000;
extra_rays[8] = -0.0001;
extra_rays[9] = -0.0001;
extra_rays[10] = -0.0001;
extra_rays[11] = -0.0001;
for(int j = 0; j < nrows; j++) r[j] = (i == j ? e : 0);
LFREE_push_ray(&model->rays, r);
n_extra_rays = 4;
for(int j = 0; j < nrows; j++) r[j] = (i == j ? -e : 0);
LFREE_push_ray(&model->rays, r);
}
for(int i = 0; i < n_extra_rays; i++)
if(nrows == 2)
{
double *r = &extra_rays[nrows * i];
double scale;
int found, index;
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);
rval = sort_rays_by_angle(&model->rays);
abort_if(rval, "sort_rays_by_angle failed");
}
CLEANUP:
if(r) free(r);
return rval;
}
@ -366,12 +371,6 @@ static int extract_models(const struct Tableau *tableau,
rval = filter_model(original_model, filtered_model);
abort_if(rval, "filter_model failed");
if(ENABLE_LIFTING)
{
rval = append_extra_rays(filtered_model);
abort_if(rval, "append_extra_rays failed");
}
if(tableau->nrows == 2)
{
rval = sort_rays_by_angle(&filtered_model->rays);
@ -420,12 +419,33 @@ int INFINITY_generate_cut(const struct Tableau *tableau, struct Row *cut)
goto CLEANUP;
}
rval = LFREE_init_conv(&lfree, tableau->nrows, filtered_model.rays.nrays);
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
// 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");
// if(tableau->nrows == 2)
// rval = INFINITY_2D_generate_lfree(&filtered_model, &lfree);
// else
rval = INFINITY_ND_generate_lfree(&filtered_model, &lfree);
if(rval)

@ -27,11 +27,6 @@ extern "C" {
#include "../src/infinity-nd.c"
}
int ENABLE_LIFTING = 0;
int MIN_N_ROWS = 2;
int MAX_N_ROWS = 2;
int SHOULD_DUMP_CUTS = 0;
int DUMP_CUT_N = 0;
TEST(InfinityNDTest, find_violated_cone_test)
{
@ -492,4 +487,3 @@ TEST(InfinityNDTest, scale_to_ahull_test)
CLEANUP:
if(rval) FAIL();
}

@ -19,9 +19,16 @@
#define TEST_SOURCE
extern "C" {
#include <multirow/cg.h>
#include "../src/infinity.c"
}
int ENABLE_LIFTING = 0;
int MIN_N_ROWS = 2;
int MAX_N_ROWS = 2;
int SHOULD_DUMP_CUTS = 1;
int DUMP_CUT_N = 0;
TEST(InfinityTest, cmp_ray_angle_test)
{
double r0[] = { 1.0, 0.0 };
@ -87,40 +94,287 @@ CLEANUP:
if (rval) FAIL();
}
//TEST(InfinityTest, generate_cut_test)
//{
// int rval = 0;
//
// double pi0[] = { -0.0553783449, -0.0553783449, -0.1666666667, -0.0553783449, -0.0553783449, -0.0498405104, -0.0553783449, -0.0553783449, -0.0498405104, -0.0498405104, -0.1500000000, -0.0498405104, -0.0272904483, -0.0272904483, -0.0498405104, -0.0498405104, -0.0498405104, -0.0498405104, -0.0272904483, -0.0443026759, -0.0443026759, -0.1333333333, -0.0443026759, -0.0433723197, -0.0438596491, -0.0443026759, -0.0443026759, -0.0443026759, -0.0443026759, -0.0438596491, -0.0332270069, -0.0332270069, -0.1000000000, -0.0332270069, -0.0160818713, -0.0155945419, -0.0332270069, -0.0332270069, -0.0332270069, -0.0332270069, -0.0155945419, -0.0354421407, -0.0354421407, -0.1066666667, -0.0354421407, -0.0433723197, -0.0438596491, -0.0354421407, -0.0354421407, -0.0354421407, -0.0354421407, -0.0438596491, -0.0553783449, -0.0553783449, -0.1666666667, -0.0575934786, -0.0433723197, -0.0506822612, -0.0553783449, -0.0498405104, -0.0553783449, -0.0575934786, -0.0506822612, -0.0433723197, -0.0438596491, -0.0438596491, -0.0498405104, -0.0498405104, -0.1500000000, -0.0487329435, -0.0498405104, -0.0498405104, -0.0498405104, -0.0487329435, 0.7784866206, 0.9113946482, 0.7231082757, 0.9405458090, 0.8958887117, 0.9257930179, -0.5015948963, 0.7441520468, 0.9259259259, 0.0291068581, 0.0291068581, -0.0489668616, -0.1246429204, -0.0667729931, -0.0667729931, -0.0220857700, -0.0934821903, -0.1246429204, -0.0623214602, 0.0291068581, 0.0288853447, 0.0088605352, 0.0147084884, 0.0112085770, 0.0133794081, 0.0288853447, 0.0066454014, 0.0288853447, 0.0088605352, 0.0147084884, 0.0133794081, 0.0288853447, 0.0066454014, 0.0291068581, 0.0121832359, 0.0291068581, 0.0121832359, 0.0291068581, 0.0291068581, 0.0288853447, 0.0088605352, 0.0147084884, 0.0133794081, 0.0288853447, 0.0066454014, 0.0243664717, 0.0620237462, 0.0332270069, 0.0332270069, 0.0545808967, 0.0465178097, 0.0620237462, 0.0011075669, 0.0011075669, 0.0033333333, 0.0011075669, 0.0004873294, 0.0009746589, 0.0011075669, 0.0011075669, 0.0011075669, 0.0011075669, 0.0009746589, 1.0000000000, };
// double pi1[] = { 0.5000000000, 0.8035714286, 0.2857142857, 0.8035714286, 0.9285714286, 0.8035714286, 1.3571428571, 0.4464285714, 0.6071428571, 0.4464285714, 0.3392857143, 1.0000000000, 0.6071428571, 0.6071428571, 0.4464285714, -0.0178571429, };
// int indices0[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 77, 78, 80, 81, 82, 83, 84, 89, 97, 101, 102, 103, 104, 105, 106, 107, 108, 113, 118, 119, 120, 121, 122, 123, 124, 126, 127, 128, 130, 131, 132, 137, 142, 145, 147, 153, 161, 166, 167, 168, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 199, };
// int indices1[] = { 18, 29, 40, 51, 62, 65, 84, 165, 166, 167, 168, 169, 170, 171, 172, 190, };
// struct Row row0 = {.nz = 138, .head = 199, .pi_zero = 0.1711855396, .pi = pi0, .indices = indices0 };
// struct Row row1 = {.nz = 16, .head = 169, .pi_zero = 1.3571428571, .pi = pi1, .indices = indices1 };
// struct Row* rows[] = {&row0, &row1 };
// 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, 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, 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, 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, };
// struct Tableau tableau = {.ncols = 201, .nrows = 2, .rows = rows, .column_types = column_types};
//
// double pi2[] = { -0.0861798566, -0.0861798566, -0.2593668965, -0.0861798566, -0.0861798566, -0.0775618709, -0.0861798566, -0.0861798566, -0.0775618709, -0.0775618709, -0.2334302068, -0.0775618709, -0.0424694333, -0.0424694333, -0.0775618709, -0.0775618709, -0.0775618709, -0.0775618709, -1.8155682752, -0.0689438853, -0.0689438853, -0.2074935172, -0.0689438853, -0.0674960637, -0.0682544464, -0.0689438853, -0.0689438853, -0.0689438853, -0.0689438853, -2.9178775851, -0.0517079140, -0.0517079140, -0.1556201379, -0.0517079140, -0.0250266304, -0.0242682476, -0.0517079140, -0.0517079140, -0.0517079140, -0.0517079140, -1.0374675858, -0.0551551082, -0.0551551082, -0.1659948137, -0.0551551082, -0.0674960637, -0.0682544464, -0.0551551082, -0.0551551082, -0.0551551082, -0.0551551082, -2.9178775851, -0.0861798566, -0.0861798566, -0.2593668965, -0.0896270509, -0.0674960637, -0.0788718048, -0.0861798566, -0.0775618709, -0.0861798566, -0.0896270509, -3.3717696539, -0.0674960637, -0.0682544464, -2.9178775851, -0.0775618709, -0.0775618709, -0.2334302068, -0.0758382738, -0.0775618709, -0.0775618709, -0.0775618709, -0.0758382738, -0.0946687273, -0.1108311551, -0.0879343823, -0.1143761143, -0.1089455385, -0.1125820848, -0.7805826692, -0.0904934334, -3.3717696539, -0.0035395717, -0.0035395717, -0.0762022975, -0.1939694846, -0.1039122239, -0.1039122239, -0.0343699057, -0.1454771135, -0.1939694846, -0.0969847423, -0.0035395717, -0.0035126343, -0.0010774952, -0.0017886420, -0.0013630314, -0.0016270177, -0.0035126343, -0.0008081214, -0.0035126343, -0.0010774952, -0.0017886420, -0.0016270177, -0.0035126343, -0.0008081214, -0.0035395717, -0.0014815559, -0.0035395717, -0.0014815559, -0.0035395717, -0.0035395717, -1.5831239659, -2.1080971805, -1.5693351889, -1.1802848442, -2.1322275403, -2.1080971805, -1.5727823832, -0.0029631118, -0.0075424663, -0.0040406070, -0.0040406070, -0.0066373704, -0.0056568497, -0.0075424663, -0.0001346869, -0.0001346869, -0.0004053537, -0.0001346869, -0.0001000000, -0.0001185245, -0.0001346869, -0.0001346869, -0.0001346869, -0.0001346869, -0.0273208243, };
// int indices2[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 77, 78, 80, 81, 82, 83, 84, 89, 97, 101, 102, 103, 104, 105, 106, 107, 108, 113, 118, 119, 120, 121, 122, 123, 124, 126, 127, 128, 130, 131, 132, 137, 142, 145, 147, 153, 161, 165, 166, 167, 168, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, };
// struct Row row2 = {.nz = 138, .head = 0, .pi_zero = -1.0000000000, .pi = pi2, .indices = indices2 };
//
// struct Row cut;
// LP_init_row(&cut, 138);
//
// rval = INFINITY_generate_cut(&tableau, &cut);
// abort_if(rval, "INFINITY_generate_cut failed");
//
// EXPECT_EQ(cut.nz, row2.nz);
// EXPECT_EQ(cut.head, row2.head);
// EXPECT_EQ(cut.pi_zero, row2.pi_zero);
//
// for(int i = 0; i < cut.nz; i++)
// {
// EXPECT_NEAR(cut.pi[i], pi2[i], 1e-6);
// EXPECT_EQ(cut.indices[i], indices2[i]);
// }
//
// CLEANUP:
// if(rval) FAIL();
//}
//TEST(InfinityTest, generate_cut_test_2)
//{
// int rval = 0;
//
// // Extracted from instance bell5.pre.mps (MIPLIB 3.0)
// double pi0[] = { 1.0000000000, 0.0161105463, 0.0161105463, 0.0161105463, 0.0161105463, -0.0161105463, -0.0161105463, 0.0322210925, 0.0322210925, 0.0322210925, 0.0322210925, 0.0051991866, 0.0051991866, 0.0051991866, 0.0051991866, 0.0057745633, 0.0057745633, 0.0057745633, -0.0002166328, -0.0000239740, -0.0000239740, -0.0002406068, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -1.2888437009, -1.2888437009, -1.2888437009, -1.2888437009, -0.6444218504, 1.0000000000, -0.0322210925, -0.0322210925, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -0.0002166328, -0.0002166328, -0.0002166328, -0.0002166328, -0.0002406068, -0.0002406068, -0.0002406068, -0.0002406068, -0.0002406068, -0.0002406068, -0.0002406068, -0.0000239740, -0.0000239740, -0.0002406068, -0.0002406068, -0.2888437009, };
// double pi1[] = { 0.5000000000, 1.0000000000, 0.0007440476, 0.0007440476, -0.0007440476, -0.0007440476, };
// double pi2[] = { 1.0000000000, 0.0161105463, 0.0161105463, 0.0161105463, 0.0161105463, -0.0161105463, -0.0161105463, 0.0322210925, 0.0322210925, 0.0322210925, 0.0322210925, 0.0051991866, 0.0051991866, 0.0051991866, 0.0051991866, 0.0057745633, 0.0057745633, 0.0057745633, -0.0002166328, -0.0000239740, -0.0000239740, -0.0002406068, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -1.2888437009, -1.2888437009, -1.2888437009, -1.2888437009, -0.6444218504, -0.0322210925, -0.0322210925, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -0.0002166328, -0.0002166328, -0.0002166328, -0.0002166328, -0.0002406068, -0.0002406068, -0.0002406068, -0.0002406068, -0.0002406068, -0.0002406068, -0.0002406068, -0.0000239740, -0.0000239740, -0.0002406068, -0.0002406068, -0.2888437009, };
// int indices0[] = { 11, 12, 13, 14, 15, 16, 18, 26, 27, 28, 29, 40, 41, 42, 43, 51, 52, 53, 58, 59, 61, 62, 72, 74, 75, 78, 80, 94, 95, 96, 97, 99, 104, 109, 111, 119, 120, 121, 122, 123, 125, 133, 134, 135, 136, 144, 145, 146, 147, 148, 149, 150, 151, 153, 157, 158, 159, };
// int indices1[] = { 17, 31, 59, 72, 124, 152, };
// int indices2[] = { 0, 12, 13, 14, 15, 16, 18, 26, 27, 28, 29, 40, 41, 42, 43, 51, 52, 53, 58, 59, 61, 62, 72, 74, 75, 78, 80, 94, 95, 96, 97, 99, 109, 111, 119, 120, 121, 122, 123, 125, 133, 134, 135, 136, 144, 145, 146, 147, 148, 149, 150, 151, 153, 157, 158, 159, };
// struct Row row0 = {.nz = 57, .head = 104, .pi_zero = 0.1156189343, .pi = pi0, .indices = indices0 };
// struct Row row1 = {.nz = 6, .head = 31, .pi_zero = 0.0297619048, .pi = pi1, .indices = indices1 };
// struct Row row2 = {.nz = 56, .head = 0, .pi_zero = 0.1156189343, .pi = pi2, .indices = indices2 };
// struct Row* rows[] = {&row0, &row1, &row2, };
// 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, };
// struct Tableau tableau = {.ncols = 169, .nrows = 3, .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[3];
// struct MultiRowModel model;
// struct TableauModelMap map;
//
// 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 = CG_init_model(&model, 3, 200);
//// abort_if(rval, "CG_init_model failed");
////
//// rval = CG_init_map(&map, 200, 3);
//// abort_if(rval, "CG_init_map failed");
////
//// rval = CG_extract_model(&tableau, &map, &model);
//// abort_if(rval, "CG_extract_model failed");
////
//// rval = CG_extract_f_from_tableau(&tableau, model.f);
//// abort_if(rval, "CG_extract_f_from_tableau failed");
////
//// memcpy(s, model.f, model.nrows * sizeof(double));
//// for(int i = 0; i < map.nvars; i++)
//// {
//// double *ray = LFREE_get_ray(&model.rays, map.variable_to_ray[i]);
//// for(int j = 0; j < model.nrows; j++)
//// s[j] += ray[j] * map.ray_scale[i] * x[map.indices[i]];
//// }
////
//// for(int j = 0; j < model.nrows; j++)
//// time_printf("s[%3d]=%.12lf\n", j, s[j]);
//
// lhs = CG_replace_x(&cut, x);
// EXPECT_LE(lhs, cut.pi_zero);
//
//CLEANUP:
// if(rval) FAIL();
//}
//TEST(InfinityTest, generate_cut_test_3)
//{
// int rval = 0;
//
// // Extracted from instance bell5.pre.mps (MIPLIB 3.0)
// double pi0[] = { 0.0161105463, 0.0161105463, 0.0161105463, 0.0161105463, -0.0161105463, 0.0250000000, -0.0161105463, 0.0322210925, 0.0322210925, 0.0322210925, 0.0322210925, 0.0051991866, 0.0051991866, 0.0051991866, 0.0051991866, 0.0057745633, 0.0057745633, 0.0057745633, -0.0002166328, -0.0000611764, -0.0000239740, -0.0002406068, -0.0000611764, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -0.2888437009, -0.2888437009, -0.2888437009, -0.2888437009, 1.0000000000, -0.6444218504, -0.0322210925, 0.0500000000, -0.0322210925, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, 0.0000372024, -0.0000239740, -0.0002166328, -0.0002166328, -0.0002166328, -0.0002166328, -0.0002406068, -0.0002406068, -0.0002406068, -0.0002406068, -0.0002406068, -0.0002406068, -0.0002406068, -0.0000239740, 0.0000372024, -0.0000239740, -0.0002406068, -0.0002406068, -0.2888437009, };
// double pi1[] = { 1.0000000000, -0.0250000000, 0.0000372024, 0.0000372024, -0.0500000000, -0.0000372024, -0.0000372024, };
// double pi2[] = { 1.0000000000, 0.0161105463, 0.0161105463, 0.0161105463, 0.0161105463, -0.0161105463, -0.0161105463, 0.0322210925, 0.0322210925, 0.0322210925, 0.0322210925, 0.0051991866, 0.0051991866, 0.0051991866, 0.0051991866, 0.0057745633, 0.0057745633, 0.0057745633, -0.0002166328, -0.0000239740, -0.0000239740, -0.0002406068, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -0.2888437009, -0.2888437009, -0.2888437009, -0.2888437009, -0.6444218504, -0.0322210925, -0.0322210925, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -0.0002166328, -0.0002166328, -0.0002166328, -0.0002166328, -0.0002406068, -0.0002406068, -0.0002406068, -0.0002406068, -0.0002406068, -0.0002406068, -0.0002406068, -0.0000239740, -0.0000239740, -0.0002406068, -0.0002406068, -0.2888437009, };
// int indices0[] = { 12, 13, 14, 15, 16, 17, 18, 26, 27, 28, 29, 40, 41, 42, 43, 51, 52, 53, 58, 59, 61, 62, 72, 74, 75, 78, 80, 94, 95, 96, 97, 98, 99, 109, 110, 111, 119, 120, 121, 122, 123, 124, 125, 133, 134, 135, 136, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 157, 158, 159, };
// int indices1[] = { 5, 17, 59, 72, 110, 124, 152, };
// int indices2[] = { 4, 12, 13, 14, 15, 16, 18, 26, 27, 28, 29, 40, 41, 42, 43, 51, 52, 53, 58, 59, 61, 62, 72, 74, 75, 78, 80, 94, 95, 96, 97, 99, 109, 111, 119, 120, 121, 122, 123, 125, 133, 134, 135, 136, 144, 145, 146, 147, 148, 149, 150, 151, 153, 157, 158, 159, };
// struct Row row0 = {.nz = 60, .head = 98, .pi_zero = 0.1141308390, .pi = pi0, .indices = indices0 };
// struct Row row1 = {.nz = 7, .head = 5, .pi_zero = 0.0014880952, .pi = pi1, .indices = indices1 };
// struct Row row2 = {.nz = 56, .head = 4, .pi_zero = 0.1156189343, .pi = pi2, .indices = indices2 };
// struct Row* rows[] = {&row0, &row1, &row2, };
// 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, };
// struct Tableau tableau = {.ncols = 169, .nrows = 3, .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[3];
// struct MultiRowModel model;
// struct TableauModelMap map;
//
// 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 = CG_init_model(&model, 3, 200);
// abort_if(rval, "CG_init_model failed");
//
// rval = CG_init_map(&map, 200, 3);
// abort_if(rval, "CG_init_map failed");
//
// rval = CG_extract_model(&tableau, &map, &model);
// abort_if(rval, "CG_extract_model failed");
//
// rval = CG_extract_f_from_tableau(&tableau, model.f);
// abort_if(rval, "CG_extract_f_from_tableau failed");
//
// memcpy(s, model.f, model.nrows * sizeof(double));
// for(int i = 0; i < map.nvars; i++)
// {
// double *ray = LFREE_get_ray(&model.rays, map.variable_to_ray[i]);
// for(int j = 0; j < model.nrows; j++)
// s[j] += ray[j] * map.ray_scale[i] * x[map.indices[i]];
// }
//
// for(int j = 0; j < model.nrows; j++)
// time_printf("s[%3d]=%.12lf\n", j, s[j]);
//
// lhs = CG_replace_x(&cut, x);
// EXPECT_LE(lhs, cut.pi_zero);
//
//CLEANUP:
// if(rval) FAIL();
//}
int get_lattice_point(const struct Tableau *tableau, const double *x, double *s)
{
int rval = 0;
struct MultiRowModel model;
struct TableauModelMap map;
int max_nrays = CG_total_nz(tableau);
rval = CG_init_model(&model, tableau->nrows, max_nrays);
abort_if(rval, "CG_init_model failed");
rval = CG_init_map(&map, max_nrays, tableau->nrows);
abort_if(rval, "CG_init_map failed");
rval = CG_extract_model(tableau, &map, &model);
abort_if(rval, "CG_extract_model failed");
rval = CG_extract_f_from_tableau(tableau, model.f);
abort_if(rval, "CG_extract_f_from_tableau failed");
memcpy(s, model.f, model.nrows * sizeof(double));
for(int i = 0; i < map.nvars; i++)
{
double *ray = LFREE_get_ray(&model.rays, map.variable_to_ray[i]);
for(int j = 0; j < model.nrows; j++)
s[j] += ray[j] * map.ray_scale[i] * x[map.indices[i]];
}
CLEANUP:
CG_free_model(&model);
CG_free_map(&map);
return rval;
}
TEST(InfinityTest, generate_cut_test)
{
int rval = 0;
double pi0[] = { -0.0553783449, -0.0553783449, -0.1666666667, -0.0553783449, -0.0553783449, -0.0498405104, -0.0553783449, -0.0553783449, -0.0498405104, -0.0498405104, -0.1500000000, -0.0498405104, -0.0272904483, -0.0272904483, -0.0498405104, -0.0498405104, -0.0498405104, -0.0498405104, -0.0272904483, -0.0443026759, -0.0443026759, -0.1333333333, -0.0443026759, -0.0433723197, -0.0438596491, -0.0443026759, -0.0443026759, -0.0443026759, -0.0443026759, -0.0438596491, -0.0332270069, -0.0332270069, -0.1000000000, -0.0332270069, -0.0160818713, -0.0155945419, -0.0332270069, -0.0332270069, -0.0332270069, -0.0332270069, -0.0155945419, -0.0354421407, -0.0354421407, -0.1066666667, -0.0354421407, -0.0433723197, -0.0438596491, -0.0354421407, -0.0354421407, -0.0354421407, -0.0354421407, -0.0438596491, -0.0553783449, -0.0553783449, -0.1666666667, -0.0575934786, -0.0433723197, -0.0506822612, -0.0553783449, -0.0498405104, -0.0553783449, -0.0575934786, -0.0506822612, -0.0433723197, -0.0438596491, -0.0438596491, -0.0498405104, -0.0498405104, -0.1500000000, -0.0487329435, -0.0498405104, -0.0498405104, -0.0498405104, -0.0487329435, 0.7784866206, 0.9113946482, 0.7231082757, 0.9405458090, 0.8958887117, 0.9257930179, -0.5015948963, 0.7441520468, 0.9259259259, 0.0291068581, 0.0291068581, -0.0489668616, -0.1246429204, -0.0667729931, -0.0667729931, -0.0220857700, -0.0934821903, -0.1246429204, -0.0623214602, 0.0291068581, 0.0288853447, 0.0088605352, 0.0147084884, 0.0112085770, 0.0133794081, 0.0288853447, 0.0066454014, 0.0288853447, 0.0088605352, 0.0147084884, 0.0133794081, 0.0288853447, 0.0066454014, 0.0291068581, 0.0121832359, 0.0291068581, 0.0121832359, 0.0291068581, 0.0291068581, 0.0288853447, 0.0088605352, 0.0147084884, 0.0133794081, 0.0288853447, 0.0066454014, 0.0243664717, 0.0620237462, 0.0332270069, 0.0332270069, 0.0545808967, 0.0465178097, 0.0620237462, 0.0011075669, 0.0011075669, 0.0033333333, 0.0011075669, 0.0004873294, 0.0009746589, 0.0011075669, 0.0011075669, 0.0011075669, 0.0011075669, 0.0009746589, 1.0000000000, };
double pi1[] = { 0.5000000000, 0.8035714286, 0.2857142857, 0.8035714286, 0.9285714286, 0.8035714286, 1.3571428571, 0.4464285714, 0.6071428571, 0.4464285714, 0.3392857143, 1.0000000000, 0.6071428571, 0.6071428571, 0.4464285714, -0.0178571429, };
int indices0[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 77, 78, 80, 81, 82, 83, 84, 89, 97, 101, 102, 103, 104, 105, 106, 107, 108, 113, 118, 119, 120, 121, 122, 123, 124, 126, 127, 128, 130, 131, 132, 137, 142, 145, 147, 153, 161, 166, 167, 168, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 199, };
int indices1[] = { 18, 29, 40, 51, 62, 65, 84, 165, 166, 167, 168, 169, 170, 171, 172, 190, };
struct Row row0 = {.nz = 138, .head = 199, .pi_zero = 0.1711855396, .pi = pi0, .indices = indices0 };
struct Row row1 = {.nz = 16, .head = 169, .pi_zero = 1.3571428571, .pi = pi1, .indices = indices1 };
struct Row* rows[] = {&row0, &row1 };
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, 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, 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, 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, };
struct Tableau tableau = {.ncols = 201, .nrows = 2, .rows = rows, .column_types = column_types};
// Extracted from instance bell5.pre.mps (MIPLIB 3)
double pi0[] = { 1.0000000000, -0.0250000000, 0.0000372024, 0.0000372024, -0.0500000000, -0.0000372024, -0.0000372024, };
double pi1[] = { 1.0000000000, 0.0161105463, 0.0161105463, 0.0161105463, 0.0161105463, -0.0161105463, -0.0161105463, 0.0322210925, 0.0322210925, 0.0322210925, 0.0322210925, 0.0051991866, 0.0051991866, 0.0051991866, 0.0051991866, 0.0057745633, 0.0057745633, 0.0057745633, -0.0002166328, -0.0000239740, -0.0000239740, -0.0002406068, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -1.2888437009, -1.2888437009, -1.2888437009, -1.2888437009, -0.6444218504, -0.0322210925, -0.0322210925, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -0.0000239740, -0.0002166328, -0.0002166328, -0.0002166328, -0.0002166328, -0.0002406068, -0.0002406068, -0.0002406068, -0.0002406068, -0.0002406068, -0.0002406068, -0.0002406068, -0.0000239740, -0.0000239740, -0.0002406068, -0.0002406068, -0.2888437009, };
int indices0[] = { 5, 17, 59, 72, 110, 124, 152, };
int indices1[] = { 0, 12, 13, 14, 15, 16, 18, 26, 27, 28, 29, 40, 41, 42, 43, 51, 52, 53, 58, 59, 61, 62, 72, 74, 75, 78, 80, 94, 95, 96, 97, 99, 109, 111, 119, 120, 121, 122, 123, 125, 133, 134, 135, 136, 144, 145, 146, 147, 148, 149, 150, 151, 153, 157, 158, 159, };
struct Row row0 = {.nz = 7, .head = 5, .pi_zero = 0.0014880952, .pi = pi0, .indices = indices0 };
struct Row row1 = {.nz = 56, .head = 0, .pi_zero = 0.1156189343, .pi = pi1, .indices = indices1 };
struct Row* rows[] = {&row0, &row1, };
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, };
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;
struct Row cut;
LP_init_row(&cut, CG_total_nz(&tableau));
rval = INFINITY_generate_cut(&tableau, &cut);
abort_if(rval, "INFINITY_generate_cut failed");
lhs = CG_replace_x(&cut, x);
EXPECT_LE(lhs, cut.pi_zero);
CLEANUP:
if (rval) FAIL();
}
TEST(InfinityTest, generate_cut_test_2)
{
int rval = 0;
// Extracted from instance bell5.pre.mps (MIPLIB 3)
double pi0[] = { 1.0000000000, 0.0416666667, -0.0416666667, -0.0416666667, -0.0416666667, -0.0416666667, };
double pi1[] = { 1.0000000000, -0.0250000000, 0.0000372024, 0.0000372024, -0.0500000000, -0.0000372024, -0.0000372024, };
int indices0[] = { 44, 58, 59, 60, 137, 151, };
int indices1[] = { 5, 17, 59, 72, 110, 124, 152, };
struct Row row0 = {.nz = 6, .head = 44, .pi_zero = 37.5000000000, .pi = pi0, .indices = indices0 };
struct Row row1 = {.nz = 7, .head = 5, .pi_zero = 0.0014880952, .pi = pi1, .indices = indices1 };
struct Row* rows[] = {&row0, &row1, };
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, };
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 pi2[] = { -0.0861798566, -0.0861798566, -0.2593668965, -0.0861798566, -0.0861798566, -0.0775618709, -0.0861798566, -0.0861798566, -0.0775618709, -0.0775618709, -0.2334302068, -0.0775618709, -0.0424694333, -0.0424694333, -0.0775618709, -0.0775618709, -0.0775618709, -0.0775618709, -1.8155682752, -0.0689438853, -0.0689438853, -0.2074935172, -0.0689438853, -0.0674960637, -0.0682544464, -0.0689438853, -0.0689438853, -0.0689438853, -0.0689438853, -2.9178775851, -0.0517079140, -0.0517079140, -0.1556201379, -0.0517079140, -0.0250266304, -0.0242682476, -0.0517079140, -0.0517079140, -0.0517079140, -0.0517079140, -1.0374675858, -0.0551551082, -0.0551551082, -0.1659948137, -0.0551551082, -0.0674960637, -0.0682544464, -0.0551551082, -0.0551551082, -0.0551551082, -0.0551551082, -2.9178775851, -0.0861798566, -0.0861798566, -0.2593668965, -0.0896270509, -0.0674960637, -0.0788718048, -0.0861798566, -0.0775618709, -0.0861798566, -0.0896270509, -3.3717696539, -0.0674960637, -0.0682544464, -2.9178775851, -0.0775618709, -0.0775618709, -0.2334302068, -0.0758382738, -0.0775618709, -0.0775618709, -0.0775618709, -0.0758382738, -0.0946687273, -0.1108311551, -0.0879343823, -0.1143761143, -0.1089455385, -0.1125820848, -0.7805826692, -0.0904934334, -3.3717696539, -0.0035395717, -0.0035395717, -0.0762022975, -0.1939694846, -0.1039122239, -0.1039122239, -0.0343699057, -0.1454771135, -0.1939694846, -0.0969847423, -0.0035395717, -0.0035126343, -0.0010774952, -0.0017886420, -0.0013630314, -0.0016270177, -0.0035126343, -0.0008081214, -0.0035126343, -0.0010774952, -0.0017886420, -0.0016270177, -0.0035126343, -0.0008081214, -0.0035395717, -0.0014815559, -0.0035395717, -0.0014815559, -0.0035395717, -0.0035395717, -1.5831239659, -2.1080971805, -1.5693351889, -1.1802848442, -2.1322275403, -2.1080971805, -1.5727823832, -0.0029631118, -0.0075424663, -0.0040406070, -0.0040406070, -0.0066373704, -0.0056568497, -0.0075424663, -0.0001346869, -0.0001346869, -0.0004053537, -0.0001346869, -0.0001000000, -0.0001185245, -0.0001346869, -0.0001346869, -0.0001346869, -0.0001346869, -0.0273208243, };
int indices2[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 77, 78, 80, 81, 82, 83, 84, 89, 97, 101, 102, 103, 104, 105, 106, 107, 108, 113, 118, 119, 120, 121, 122, 123, 124, 126, 127, 128, 130, 131, 132, 137, 142, 145, 147, 153, 161, 165, 166, 167, 168, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, };
struct Row row2 = {.nz = 138, .head = 0, .pi_zero = -1.0000000000, .pi = pi2, .indices = indices2 };
double lhs;
struct Row cut;
LP_init_row(&cut, CG_total_nz(&tableau));
rval = INFINITY_generate_cut(&tableau, &cut);
abort_if(rval, "INFINITY_generate_cut failed");
lhs = CG_replace_x(&cut, x);
EXPECT_LE(lhs, cut.pi_zero);
CLEANUP:
if (rval) FAIL();
}
TEST(InfinityTest, generate_cut_test_3)
{
int rval = 0;
double pi0[] = { 1.0000000000, 0.0416666667, -0.0416666667, -0.0416666667, -0.0416666667, };
double pi1[] = { 1.0000000000, -0.0250000000, 0.0000372024, 0.0000372024, -0.0500000000, -0.0000372024, };
int indices0[] = { 46, 60, 61, 139, 153, };
int indices1[] = { 7, 19, 61, 74, 112, 126, };
struct Row row0 = {.nz = 5, .head = 46, .pi_zero = 497.9166666667, .pi = pi0, .indices = indices0 };
struct Row row1 = {.nz = 6, .head = 7, .pi_zero = 0.1116071429, .pi = pi1, .indices = indices1 };
struct Row* rows[] = {&row0, &row1, };
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, };
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[3];
struct Row cut;
LP_init_row(&cut, 138);
LP_init_row(&cut, CG_total_nz(&tableau));
rval = INFINITY_generate_cut(&tableau, &cut);
abort_if(rval, "INFINITY_generate_cut failed");
EXPECT_EQ(cut.nz, row2.nz);
EXPECT_EQ(cut.head, row2.head);
EXPECT_EQ(cut.pi_zero, row2.pi_zero);
lhs = CG_replace_x(&cut, x);
EXPECT_LE(lhs, cut.pi_zero);
for(int i = 0; i < cut.nz; i++)
{
EXPECT_NEAR(cut.pi[i], pi2[i], 1e-6);
EXPECT_EQ(cut.indices[i], indices2[i]);
}
rval = get_lattice_point(&tableau, x, s);
abort_if(rval, "get_lattice_point failed");
CLEANUP:
if(rval) FAIL();
for(int i = 0; i < tableau.nrows; i++)
log_debug("s[%d] = %20.12lf\n", i, s[i]);
CLEANUP:
if (rval) FAIL();
}

@ -114,4 +114,6 @@ void CG_free_model(struct MultiRowModel *model);
int CG_total_nz(const struct Tableau *tableau);
double CG_replace_x(const struct Row *row, const double *x);
#endif //MULTIROW_CG_H

@ -47,4 +47,6 @@ int DOUBLE_to_rational(double a,
double DOUBLE_random(double min, double max);
int DOUBLE_sum(const double *list, const int count, double *result);
#endif //MULTIROW_DOUBLE_H

@ -66,7 +66,7 @@
#define MAX_SELECTED_ROWS 300
#define MAX_LATTICE_POINTS 100000
#define INFINITY_BIG_E 1e3
#define INFINITY_BIG_E 1024
#define MAX_CUT_DYNAMISM 1e8
#define INTEGRALITY_THRESHOLD 0.49

@ -170,23 +170,6 @@ CLEANUP:
return rval;
}
static void print_row(const struct CG *cg, const struct Row *row)
{
double *x = cg->integral_solution;
double *y = cg->basic_solution;
time_printf("Row:\n");
for (int i = 0; i < row->nz; i++)
{
// if(DOUBLE_iszero(x[row->indices[i]])) continue;
time_printf(" %12.6lf x%-5d", row->pi[i], row->indices[i]);
printf(" %12.6lf", x[row->indices[i]]);
printf(" %12.6lf\n", y[row->indices[i]]);
}
time_printf(" <= %20.6lf [%d]\n", row->pi_zero, row->head);
}
static int
evaluate_row_pair(const struct Row *row1, const struct Row *row2, double *score)
{
@ -224,25 +207,6 @@ CLEANUP:
return rval;
}
static double
replace_x(const double *pi, const int *indices, int nz, const double *x)
{
double lhs = 0;
for (int i = 0; i < nz; i++)
{
double pii = pi[i];
int idx = indices[i];
if (!DOUBLE_iszero(pii) && !DOUBLE_iszero(x[idx]))
log_verbose(" %12.8lf * %12.8lf (x%d)\n", pii, x[idx], idx);
lhs += pii * x[idx];
}
return lhs;
}
static int copy_solution(struct CG *cg, double *from, double **to)
{
int rval = 0;
@ -282,8 +246,7 @@ static int check_cut(struct CG *cg, struct Row *cut)
{
log_verbose("Basic solution check:\n");
double lhs = replace_x(cut->pi, cut->indices, cut->nz,
cg->basic_solution);
double lhs = CG_replace_x(cut, cg->basic_solution);
log_verbose(" %.8lf > %.8lf\n", lhs, cut->pi_zero);
abort_iff(!DOUBLE_geq(lhs, cut->pi_zero), "Cut fails to cut "
@ -294,8 +257,7 @@ static int check_cut(struct CG *cg, struct Row *cut)
{
log_verbose("Integral solution check:\n");
double lhs = replace_x(cut->pi, cut->indices, cut->nz,
cg->integral_solution);
double lhs = CG_replace_x(cut, cg->integral_solution);
log_verbose(" %.8lf <= %.8lf\n", lhs, cut->pi_zero);
abort_iff(!DOUBLE_leq(lhs, cut->pi_zero), "Cut cuts off known integral "
@ -318,7 +280,7 @@ static int add_cut(struct CG *cg, struct Row *cut, int *ignored)
rval = check_cut(cg, cut);
abort_if(rval, "check_cut failed");
lhs = replace_x(cut->pi, cut->indices, cut->nz, cg->current_solution);
lhs = CG_replace_x(cut, cg->current_solution);
*ignored = 0;
STATS_increment_generated_cuts();
@ -384,8 +346,27 @@ static void dump_row(FILE *file, const struct Row *row, int k)
fprintf(file, ".indices = indices%d };\n", k);
}
static void dump_tableau(FILE *file, const struct Tableau *tableau)
static void dump_cut(const struct Row *cut, long count)
{
char filename[100];
sprintf(filename, "cut-%03ld.c", count);
log_info("Dumping generated cut to file %s\n", filename);
FILE *file = fopen(filename, "w");
dump_row(file, cut, 0);
fclose(file);
}
static void dump_tableau(const struct Tableau *tableau, long count)
{
char filename[100];
sprintf(filename, "tableau-%03ld.c", count);
log_info("Dumping tableau to file %s\n", filename);
FILE *file = fopen(filename, "w");
for(int i = 0; i < tableau->nrows; i++)
dump_row(file, tableau->rows[i], i);
@ -404,10 +385,48 @@ static void dump_tableau(FILE *file, const struct Tableau *tableau)
fprintf(file, ".nrows = %d, ", tableau->nrows);
fprintf(file, ".rows = rows, ");
fprintf(file, ".column_types = column_types };\n");
fclose(file);
}
static void dump_integral_solution(const struct CG *cg, long count)
{
char filename[100];
sprintf(filename, "solution-%03ld.c", count);
log_info("Dumping integral solution to file %s\n", filename);
FILE *file = fopen(filename, "w");
double *x = cg->integral_solution;
fprintf(file, "x[%d] = {", cg->ncols);
for(int i = 0; i < cg->ncols; i++)
fprintf(file, "%.10lf, ", x[i]);
fprintf(file, "};\n");
fclose(file);
}
#ifndef TEST_SOURCE
double CG_replace_x(const struct Row *row, const double *x)
{
double lhs = 0;
double *terms = (double*) malloc(row->nz * sizeof(double));
for (int i = 0; i < row->nz; i++)
{
double pii = row->pi[i];
int idx = row->indices[i];
terms[i] = pii * x[idx];
}
DOUBLE_sum(terms, row->nz, &lhs);
free(terms);
return lhs;
}
/*
* Looks for a certain ray at an array of rays. Matches rays that are
* parallel to the given one. Returns whether a matching ray was found,
@ -505,6 +524,7 @@ int CG_extract_model(const struct Tableau *tableau,
rval = CG_find_ray(&model->rays, r, &found, &scale, &ray_index);
abort_if(rval, "CG_find_ray failed");
found = 0;
if (!found)
{
log_verbose(" ray is new\n");
@ -516,7 +536,8 @@ int CG_extract_model(const struct Tableau *tableau,
log_verbose(" ray equals:\n");
double *q = LFREE_get_ray(&model->rays, ray_index);
for (int j = 0; j < nrows; j++)
log_verbose(" r[%d] = %.12lf\n", j, q[j]);
log_verbose(" r[%d] = %.12lf\n", j, q[j]);
log_verbose(" scale = %.12lf\n", scale);
}
map->ray_scale[map->nvars] = scale;
@ -527,27 +548,27 @@ int CG_extract_model(const struct Tableau *tableau,
NEXT_RAY:;
}
for (int j = 0; j < model->rays.nrays; j++)
{
double *r = LFREE_get_ray(&model->rays, j);
double max_scale = 0.0;
for (int k = 0; k < map->nvars; k++)
{
if (map->variable_to_ray[k] != j) continue;
if (map->ray_scale[k] < max_scale) continue;
max_scale = map->ray_scale[k];
}
abort_if(max_scale == 0.0, "max_scale is zero");
for (int k = 0; k < map->nvars; k++)
if (map->variable_to_ray[k] == j)
map->ray_scale[k] /= max_scale;
for (int k = 0; k < nrows; k++)
r[k] *= max_scale;
}
// for (int j = 0; j < model->rays.nrays; j++)
// {
// double *r = LFREE_get_ray(&model->rays, j);
// double max_scale = 0.0;
//
// for (int k = 0; k < map->nvars; k++)
// {
// if (map->variable_to_ray[k] != j) continue;
// if (map->ray_scale[k] < max_scale) continue;
// max_scale = map->ray_scale[k];
// }
//
// abort_if(max_scale == 0.0, "max_scale is zero");
//
// for (int k = 0; k < map->nvars; k++)
// if (map->variable_to_ray[k] == j)
// map->ray_scale[k] /= max_scale;
//
// for (int k = 0; k < nrows; k++)
// r[k] *= max_scale;
// }
CLEANUP:
if (idx) free(idx);
@ -659,12 +680,12 @@ CLEANUP:
return rval;
}
int estimate_multirow_cut_count(struct CG *cg,
int nrows,
int *row_selected,
int *row_affinity,
long *total_count,
double score_cutoff)
int CG_estimate_multirow_cut_count(struct CG *cg,
int nrows,
int *row_selected,
int *row_affinity,
long *total_count,
double score_cutoff)
{
int rval = 0;
int *row_indices = 0;
@ -748,7 +769,7 @@ CLEANUP:
return rval;
}
int cut_dynamism(struct Row *cut, double *dynamism)
int CG_cut_dynamism(struct Row *cut, double *dynamism)
{
double largest = -INFINITY;
double smallest = INFINITY;
@ -797,7 +818,7 @@ int CG_add_multirow_cuts(struct CG *cg,
double cg_current_time = get_user_time() - cg_initial_time;
if (cg_current_time > CG_TIMEOUT) break;
rval = estimate_multirow_cut_count(cg, nrows, row_selected,
rval = CG_estimate_multirow_cut_count(cg, nrows, row_selected,
row_affinity, &total_count, cutoff);
abort_if(rval, "estimate_two_row_cuts_count failed");
@ -906,14 +927,7 @@ int CG_add_multirow_cuts(struct CG *cg,
.column_types = cg->column_types
};
if_verbose_level
{
char filename[100];
sprintf(filename, "tableau-%03ld.c", count);
FILE *file = fopen(filename, "w");
dump_tableau(file, &tableau);
fclose(file);
}
if_verbose_level dump_tableau(&tableau, count);
int max_nz = CG_total_nz(&tableau);
@ -933,21 +947,14 @@ int CG_add_multirow_cuts(struct CG *cg,
}
else abort_iff(rval, "generate failed (cut %d)", count);
if_verbose_level
{
char filename[100];
sprintf(filename, "cut-%03ld.c", count);
FILE *file = fopen(filename, "w");
dump_row(file, &cut, 0);
fclose(file);
}
if_verbose_level dump_cut(&cut, count);
double elapsed_time = get_user_time() - initial_time;
log_verbose(" generate: %.2lf ms\n", elapsed_time * 1000);
double dynamism;
rval = cut_dynamism(&cut, &dynamism);
abort_if(rval, "cut_dynamism failed");
rval = CG_cut_dynamism(&cut, &dynamism);
abort_if(rval, "CG_cut_dynamism failed");
if (dynamism > MAX_CUT_DYNAMISM)
{
@ -958,14 +965,12 @@ int CG_add_multirow_cuts(struct CG *cg,
int ignored;
rval = add_cut(cg, &cut, &ignored);
if (rval)
if(rval)
{
log_warn("invalid cut skipped (cut %d)\n", count);
rval = 0;
LP_free_row(&cut);
goto NEXT_COMBINATION;
dump_cut(&cut, count);
dump_tableau(&tableau, count);
dump_integral_solution(cg, count);
abort_iff(1, "add_cut failed (cut=%d)", count);
}
if_debug_level if (!ignored)

@ -132,3 +132,32 @@ int DOUBLE_to_rational(double a,
CLEANUP:
return rval;
}
static int _qsort_double_cmp(const void *a, const void *b)
{
double ia = *((double*) a);
double ib = *((double*) b);
if (ia > ib) return -1;
if (ia < ib) return 1;
return 0;
}
int DOUBLE_sum(const double *list, const int count, double *result)
{
int rval = 0;
double *list_copy = 0;
list_copy = (double*) malloc(count * sizeof(double));
abort_if(!list_copy, "could not allocate list_copy");
memcpy(list_copy, list, count * sizeof(double));
qsort(list_copy, (size_t) count, sizeof(double), _qsort_double_cmp);
*result = 0;
for(int i = 0; i < count; i++)
*result += list_copy[i];
CLEANUP:
if(list_copy) free(list_copy);
return rval;
}

@ -106,84 +106,84 @@ CLEANUP:
}
TEST(CGTest, extract_rays_from_rows_test)
{
int rval = 0;
char column_types[16] = {0};
double pi1[] = { 1.0, 1.0, 1.0, 2.0, 1.0 };
int indices1[] = { 1, 7, 8, 12, 14 };
struct Row row1 = {.nz = 5, .head = 1, .pi_zero = 1.0, .pi = pi1, .indices = indices1};
double pi2[] = { 1.0, 1.0, 2.0, 1.0, 1.0, 1.0 };
int indices2[] = { 5, 8, 12, 13, 14, 16 };
struct Row row2 = {.nz = 6, .head = 13, .pi_zero = 1.0, .pi = pi2, .indices = indices2};
double pi3[] = { 1.0, 1.0, 1.0, 1.0 };
int indices3[] = { 3, 7, 10, 16 };
struct Row row3 = {.nz = 4, .head = 7, .pi_zero = 1.0, .pi = pi3, .indices = indices3};
struct Row *rows[] = { &row1, &row2, &row3 };
struct Tableau tableau = {.ncols = 16, .nrows = 3, .rows = rows, .column_types = column_types};
int indices[1000];
int variable_to_ray[1000];
double ray_scale[1000];
struct TableauModelMap map = {variable_to_ray, ray_scale, indices, 0};
struct MultiRowModel model;
CG_init_model(&model, 3, 1000);
rval = CG_extract_model(&tableau, &map, &model);
abort_if(rval, "CG_extract_rays_from_rows failed");
EXPECT_EQ(map.nvars, 7);
EXPECT_EQ(model.rays.nrays, 4);
EXPECT_DOUBLE_EQ(model.rays.values[0], 0.0);
EXPECT_DOUBLE_EQ(model.rays.values[1], 0.0);
EXPECT_DOUBLE_EQ(model.rays.values[2], -1.0);
EXPECT_DOUBLE_EQ(model.rays.values[3], 0.0);
EXPECT_DOUBLE_EQ(model.rays.values[4], -1.0);
EXPECT_DOUBLE_EQ(model.rays.values[5], 0.0);
EXPECT_DOUBLE_EQ(model.rays.values[6], -2.0);
EXPECT_DOUBLE_EQ(model.rays.values[7], -2.0);
EXPECT_DOUBLE_EQ(model.rays.values[8], 0.0);
EXPECT_DOUBLE_EQ(model.rays.values[ 9], 0.0);
EXPECT_DOUBLE_EQ(model.rays.values[10], -1.0);
EXPECT_DOUBLE_EQ(model.rays.values[11], -1.0);
EXPECT_EQ(indices[0], 3);
EXPECT_EQ(indices[1], 5);
EXPECT_EQ(indices[2], 8);
EXPECT_EQ(indices[3], 10);
EXPECT_EQ(indices[4], 12);
EXPECT_EQ(indices[5], 14);
EXPECT_EQ(indices[6], 16);
EXPECT_EQ(ray_scale[0], 1.0);
EXPECT_EQ(ray_scale[1], 1.0);
EXPECT_EQ(ray_scale[2], 0.5);
EXPECT_EQ(ray_scale[3], 1.0);
EXPECT_EQ(ray_scale[4], 1.0);
EXPECT_EQ(ray_scale[5], 0.5);
EXPECT_EQ(ray_scale[6], 1.0);
EXPECT_EQ(variable_to_ray[0], 0);
EXPECT_EQ(variable_to_ray[1], 1);
EXPECT_EQ(variable_to_ray[2], 2);
EXPECT_EQ(variable_to_ray[3], 0);
EXPECT_EQ(variable_to_ray[4], 2);
EXPECT_EQ(variable_to_ray[5], 2);
EXPECT_EQ(variable_to_ray[6], 3);
CLEANUP:
if(rval) FAIL();
}
//TEST(CGTest, extract_rays_from_rows_test)
//{
// int rval = 0;
//
// char column_types[16] = {0};
// double pi1[] = { 1.0, 1.0, 1.0, 2.0, 1.0 };
// int indices1[] = { 1, 7, 8, 12, 14 };
// struct Row row1 = {.nz = 5, .head = 1, .pi_zero = 1.0, .pi = pi1, .indices = indices1};
//
// double pi2[] = { 1.0, 1.0, 2.0, 1.0, 1.0, 1.0 };
// int indices2[] = { 5, 8, 12, 13, 14, 16 };
// struct Row row2 = {.nz = 6, .head = 13, .pi_zero = 1.0, .pi = pi2, .indices = indices2};
//
// double pi3[] = { 1.0, 1.0, 1.0, 1.0 };
// int indices3[] = { 3, 7, 10, 16 };
// struct Row row3 = {.nz = 4, .head = 7, .pi_zero = 1.0, .pi = pi3, .indices = indices3};
//
// struct Row *rows[] = { &row1, &row2, &row3 };
// struct Tableau tableau = {.ncols = 16, .nrows = 3, .rows = rows, .column_types = column_types};
//
// int indices[1000];
// int variable_to_ray[1000];
// double ray_scale[1000];
//
// struct TableauModelMap map = {variable_to_ray, ray_scale, indices, 0};
//
// struct MultiRowModel model;
// CG_init_model(&model, 3, 1000);
//
// rval = CG_extract_model(&tableau, &map, &model);
// abort_if(rval, "CG_extract_rays_from_rows failed");
//
// EXPECT_EQ(map.nvars, 7);
//
// EXPECT_EQ(model.rays.nrays, 4);
// EXPECT_DOUBLE_EQ(model.rays.values[0], 0.0);
// EXPECT_DOUBLE_EQ(model.rays.values[1], 0.0);
// EXPECT_DOUBLE_EQ(model.rays.values[2], -1.0);
//
// EXPECT_DOUBLE_EQ(model.rays.values[3], 0.0);
// EXPECT_DOUBLE_EQ(model.rays.values[4], -1.0);
// EXPECT_DOUBLE_EQ(model.rays.values[5], 0.0);
//
// EXPECT_DOUBLE_EQ(model.rays.values[6], -2.0);
// EXPECT_DOUBLE_EQ(model.rays.values[7], -2.0);
// EXPECT_DOUBLE_EQ(model.rays.values[8], 0.0);
//
// EXPECT_DOUBLE_EQ(model.rays.values[ 9], 0.0);
// EXPECT_DOUBLE_EQ(model.rays.values[10], -1.0);
// EXPECT_DOUBLE_EQ(model.rays.values[11], -1.0);
//
// EXPECT_EQ(indices[0], 3);
// EXPECT_EQ(indices[1], 5);
// EXPECT_EQ(indices[2], 8);
// EXPECT_EQ(indices[3], 10);
// EXPECT_EQ(indices[4], 12);
// EXPECT_EQ(indices[5], 14);
// EXPECT_EQ(indices[6], 16);
//
// EXPECT_EQ(ray_scale[0], 1.0);
// EXPECT_EQ(ray_scale[1], 1.0);
// EXPECT_EQ(ray_scale[2], 0.5);
// EXPECT_EQ(ray_scale[3], 1.0);
// EXPECT_EQ(ray_scale[4], 1.0);
// EXPECT_EQ(ray_scale[5], 0.5);
// EXPECT_EQ(ray_scale[6], 1.0);
//
// EXPECT_EQ(variable_to_ray[0], 0);
// EXPECT_EQ(variable_to_ray[1], 1);
// EXPECT_EQ(variable_to_ray[2], 2);
// EXPECT_EQ(variable_to_ray[3], 0);
// EXPECT_EQ(variable_to_ray[4], 2);
// EXPECT_EQ(variable_to_ray[5], 2);
// EXPECT_EQ(variable_to_ray[6], 3);
//
// CLEANUP:
// if(rval) FAIL();
//}
TEST(CGTest, boost_variable_test)
{