4 #include <barvinok/options.h>
5 #include <barvinok/util.h>
8 #define ALLOCN(type,n) (type*)malloc((n) * sizeof(type))
10 #define EMPTY_DOMAIN -2
12 static LPX
*solve_lp(int dir
, Matrix
*C
, Value
*f
, Value denom
)
18 unsigned dim
= C
->NbColumns
-2;
20 ind
= ALLOCN(int, 1+dim
);
21 val
= ALLOCN(double, 1+dim
);
22 lp
= lpx_create_prob();
23 lpx_set_obj_dir(lp
, dir
);
24 lpx_add_rows(lp
, C
->NbRows
);
25 lpx_add_cols(lp
, dim
);
27 for (j
= 0; j
< C
->NbRows
; ++j
) {
28 int type
= value_zero_p(C
->p
[j
][0]) ? LPX_FX
: LPX_LO
;
29 for (k
= 0, l
= 0; k
< dim
; ++k
) {
30 if (value_zero_p(C
->p
[j
][1+k
]))
33 val
[1+l
] = VALUE_TO_DOUBLE(C
->p
[j
][1+k
]);
36 lpx_set_mat_row(lp
, 1+j
, l
, ind
, val
);
37 lpx_set_row_bnds(lp
, 1+j
, type
,
38 -VALUE_TO_DOUBLE(C
->p
[j
][1+dim
]), 0);
40 for (k
= 0, l
= 0; k
< dim
; ++k
) {
41 lpx_set_col_bnds(lp
, 1+k
, LPX_FR
, 0, 0);
45 lpx_set_int_parm(lp
, LPX_K_MSGLEV
, 0);
47 /* objective function */
48 for (j
= 0; j
< dim
; ++j
)
49 lpx_set_obj_coef(lp
, 1+j
, VALUE_TO_DOUBLE(f
[j
]) /
50 VALUE_TO_DOUBLE(denom
));
51 lpx_set_obj_coef(lp
, 0, VALUE_TO_DOUBLE(f
[dim
]) /
52 VALUE_TO_DOUBLE(denom
));
60 static enum lp_result
constraints_affine_minmax(int dir
, Matrix
*C
,
61 Value
*f
, Value denom
, Value
*opt
)
63 enum lp_result res
= lp_ok
;
64 LPX
*lp
= solve_lp(dir
, C
, f
, denom
);
66 switch (lpx_get_status(lp
)) {
69 value_set_si(*opt
, (int)ceil(lpx_get_obj_val(lp
)-1e-10));
71 value_set_si(*opt
, (int)floor(lpx_get_obj_val(lp
)+1e-10));
86 static int constraints_affine_minmax_sign(int dir
, Matrix
*C
, Matrix
*T
,
92 unsigned dim
= C
->NbColumns
-2;
93 assert(dim
== T
->NbColumns
-1);
94 assert(T
->NbRows
== 2);
96 lp
= solve_lp(dir
, C
, T
->p
[0], T
->p
[1][dim
]);
97 switch (lpx_get_status(lp
)) {
99 opt
= lpx_get_obj_val(lp
);
101 sign
= opt
< 0 ? -1 : opt
> 0 ? 1 : 0;
103 if (opt
< -0.5/VALUE_TO_DOUBLE(T
->p
[1][dim
]))
105 else if (opt
> 0.5/VALUE_TO_DOUBLE(T
->p
[1][dim
]))
127 enum order_sign
glpk_polyhedron_affine_sign(Polyhedron
*D
, Matrix
*T
,
128 struct barvinok_options
*options
)
130 int rational
= !POL_ISSET(options
->MaxRays
, POL_INTEGER
);
134 return order_undefined
;
136 Polyhedron_Matrix_View(D
, &M
, D
->NbConstraints
);
137 int min
= constraints_affine_minmax_sign(LPX_MIN
, &M
, T
, rational
);
138 if (min
== EMPTY_DOMAIN
)
139 return order_undefined
;
142 int max
= constraints_affine_minmax_sign(LPX_MAX
, &M
, T
, rational
);
143 assert(max
!= EMPTY_DOMAIN
);
152 return order_unknown
;
155 enum lp_result
glpk_constraints_opt(Matrix
*C
, Value
*obj
, Value denom
,
156 enum lp_dir dir
, Value
*opt
)
158 int glpk_dir
= dir
== lp_min
? LPX_MIN
: LPX_MAX
;
159 return constraints_affine_minmax(glpk_dir
, C
, obj
, denom
, opt
);
162 enum lp_result
glpk_polyhedron_range(Polyhedron
*D
, Value
*obj
, Value denom
,
163 Value
*min
, Value
*max
,
164 struct barvinok_options
*options
)
172 Polyhedron_Matrix_View(D
, &M
, D
->NbConstraints
);
173 res
= constraints_affine_minmax(LPX_MIN
, &M
, obj
, denom
, min
);
176 res
= constraints_affine_minmax(LPX_MAX
, &M
, obj
, denom
, max
);