evalue.c: reorder_terms: fix typo
[barvinok.git] / basis_reduction_glpk.c
blob09acf6363f7238fec896b38009a4b09628be98a4
1 #include <math.h>
2 #include <glpk.h>
3 #include <barvinok/basis_reduction.h>
5 static LPX *init_lp(Polyhedron *P);
6 static void set_lp_obj(LPX *lp, Value *row, int dim);
7 static void solve_lp(LPX *lp);
8 static void get_obj_val(LPX* lp, double *F);
9 static int add_lp_row(LPX *lp, Value *row, int dim);
10 static void get_alpha(LPX* lp, int row, double *alpha);
11 static void del_lp_row(LPX *lp);
13 #define GBR_LP LPX
14 #define GBR_type double
15 #define GBR_init(v) do { } while(0)
16 #define GBR_clear(v) do { } while(0)
17 #define GBR_set(a,b) a = b
18 #define GBR_set_ui(a,b) a = b
19 #define GBR_mul(a,b,c) a = b * c
20 #define GBR_lt(a,b) (a < b)
21 #define GBR_floor(a,b) value_set_si(a,(int)floor(b+1e-10))
22 #define GBR_ceil(a,b) value_set_si(a,(int)ceil(b-1e-10))
23 #define GBR_lp_init(P) init_lp(P)
24 #define GBR_lp_set_obj(lp, obj, dim) set_lp_obj(lp, obj, dim)
25 #define GBR_lp_solve(lp) solve_lp(lp)
26 #define GBR_lp_get_obj_val(lp, F) get_obj_val(lp, F)
27 #define GBR_lp_delete(lp) lpx_delete_prob(lp)
28 #define GBR_lp_next_row(lp) lpx_get_num_rows(lp)+1
29 #define GBR_lp_add_row(lp, row, dim) add_lp_row(lp, row, dim)
30 #define GBR_lp_get_alpha(lp, row, alpha) get_alpha(lp, row, alpha)
31 #define GBR_lp_del_row(lp) del_lp_row(lp);
32 #define Polyhedron_Reduced_Basis glpk_Polyhedron_Reduced_Basis
33 #include "basis_reduction_templ.c"
35 static LPX *init_lp(Polyhedron *P)
37 LPX *lp;
38 int *ind;
39 double *val;
40 int i, j, k, l;
42 ind = ALLOCN(int, 1+P->Dimension);
43 val = ALLOCN(double, 1+P->Dimension);
44 lp = lpx_create_prob();
45 lpx_set_obj_dir(lp, LPX_MAX);
46 lpx_add_rows(lp, 2*P->NbConstraints);
47 lpx_add_cols(lp, 2*P->Dimension);
48 for (i = 0; i < 2; ++i) {
49 for (j = 0; j < P->NbConstraints; ++j) {
50 int type = j < P->NbEq ? LPX_FX : LPX_LO;
51 for (k = 0, l = 0; k < P->Dimension; ++k) {
52 if (value_zero_p(P->Constraint[j][1+k]))
53 continue;
54 ind[1+l] = 1+i*P->Dimension+k;
55 val[1+l] = VALUE_TO_DOUBLE(P->Constraint[j][1+k]);
56 ++l;
58 lpx_set_mat_row(lp, 1+i*P->NbConstraints+j, l, ind, val);
59 lpx_set_row_bnds(lp, 1+i*P->NbConstraints+j, type,
60 -VALUE_TO_DOUBLE(P->Constraint[j][1+P->Dimension]), 0);
62 for (k = 0, l = 0; k < P->Dimension; ++k) {
63 lpx_set_col_bnds(lp, 1+i*P->Dimension+k, LPX_FR, 0, 0);
66 free(ind);
67 free(val);
68 lpx_set_int_parm(lp, LPX_K_MSGLEV, 0);
69 return lp;
72 static void set_lp_obj(LPX *lp, Value *row, int dim)
74 int j;
75 for (j = 0; j < dim; ++j) {
76 lpx_set_obj_coef(lp, 1+j, VALUE_TO_DOUBLE(row[j]));
77 lpx_set_obj_coef(lp, 1+dim+j, -VALUE_TO_DOUBLE(row[j]));
81 static void solve_lp(LPX *lp)
83 lpx_adv_basis(lp);
84 lpx_simplex(lp);
87 static void get_obj_val(LPX* lp, double *F)
89 assert(lpx_get_status(lp) == LPX_OPT);
90 *F = lpx_get_obj_val(lp);
91 assert(*F > -1e-10);
92 if (*F < 0)
93 *F = 0;
96 static int add_lp_row(LPX *lp, Value *row, int dim)
98 int j, l;
99 int nr = lpx_add_rows(lp, 1);
100 int *ind;
101 double *val;
103 ind = ALLOCN(int, 1+2*dim);
104 val = ALLOCN(double, 1+2*dim);
105 for (j = 0, l = 0; j < dim; ++j) {
106 if (value_zero_p(row[j]))
107 continue;
108 ind[1+l] = 1+j;
109 val[1+l] = VALUE_TO_DOUBLE(row[j]);
110 ind[1+l+1] = 1+dim+j;
111 val[1+l+1] = -VALUE_TO_DOUBLE(row[j]);
112 l += 2;
114 lpx_set_mat_row(lp, nr, l, ind, val);
115 lpx_set_row_bnds(lp, nr, LPX_FX, 0, 0);
116 free(ind);
117 free(val);
119 return nr;
122 static void get_alpha(LPX* lp, int row, double *alpha)
124 *alpha = -lpx_get_row_dual(lp, row);
127 static void del_lp_row(LPX *lp)
129 int rows[2];
130 rows[1] = lpx_get_num_rows(lp);
131 lpx_del_rows(lp, 1, rows);