3 #include <barvinok/options.h>
4 #include <barvinok/util.h>
7 #define ALLOCN(type,n) (type*)malloc((n) * sizeof(type))
9 #define EMPTY_DOMAIN -2
11 static LPX
*solve_lp(int dir
, Polyhedron
*P
, Value
*f
, Value denom
)
18 ind
= ALLOCN(int, 1+P
->Dimension
);
19 val
= ALLOCN(double, 1+P
->Dimension
);
20 lp
= lpx_create_prob();
21 lpx_set_obj_dir(lp
, dir
);
22 lpx_add_rows(lp
, P
->NbConstraints
);
23 lpx_add_cols(lp
, P
->Dimension
);
25 for (j
= 0; j
< P
->NbConstraints
; ++j
) {
26 int type
= j
< P
->NbEq
? LPX_FX
: LPX_LO
;
27 for (k
= 0, l
= 0; k
< P
->Dimension
; ++k
) {
28 if (value_zero_p(P
->Constraint
[j
][1+k
]))
31 val
[1+l
] = VALUE_TO_DOUBLE(P
->Constraint
[j
][1+k
]);
34 lpx_set_mat_row(lp
, 1+j
, l
, ind
, val
);
35 lpx_set_row_bnds(lp
, 1+j
, type
,
36 -VALUE_TO_DOUBLE(P
->Constraint
[j
][1+P
->Dimension
]), 0);
38 for (k
= 0, l
= 0; k
< P
->Dimension
; ++k
) {
39 lpx_set_col_bnds(lp
, 1+k
, LPX_FR
, 0, 0);
43 lpx_set_int_parm(lp
, LPX_K_MSGLEV
, 0);
45 /* objective function */
46 for (j
= 0; j
< P
->Dimension
; ++j
)
47 lpx_set_obj_coef(lp
, 1+j
, VALUE_TO_DOUBLE(f
[j
]) /
48 VALUE_TO_DOUBLE(denom
));
49 lpx_set_obj_coef(lp
, 0, VALUE_TO_DOUBLE(f
[P
->Dimension
]) /
50 VALUE_TO_DOUBLE(denom
));
58 static enum lp_result
polyhedron_affine_minmax(int dir
, Polyhedron
*P
,
59 Value
*f
, Value denom
, Value
*opt
)
61 enum lp_result res
= lp_ok
;
62 LPX
*lp
= solve_lp(dir
, P
, f
, denom
);
64 switch (lpx_get_status(lp
)) {
67 value_set_si(*opt
, (int)ceil(lpx_get_obj_val(lp
)-1e-10));
69 value_set_si(*opt
, (int)floor(lpx_get_obj_val(lp
)+1e-10));
84 static int polyhedron_affine_minmax_sign(int dir
, Polyhedron
*P
, Matrix
*T
,
90 assert(P
->Dimension
== T
->NbColumns
-1);
91 assert(T
->NbRows
== 2);
93 lp
= solve_lp(dir
, P
, T
->p
[0], T
->p
[1][P
->Dimension
]);
94 switch (lpx_get_status(lp
)) {
96 opt
= lpx_get_obj_val(lp
);
98 sign
= opt
< 0 ? -1 : opt
> 0 ? 1 : 0;
100 if (opt
< -0.5/VALUE_TO_DOUBLE(T
->p
[1][P
->Dimension
]))
102 else if (opt
> 0.5/VALUE_TO_DOUBLE(T
->p
[1][P
->Dimension
]))
124 enum order_sign
glpk_polyhedron_affine_sign(Polyhedron
*D
, Matrix
*T
,
125 struct barvinok_options
*options
)
127 int rational
= !POL_ISSET(options
->MaxRays
, POL_INTEGER
);
130 return order_undefined
;
132 int min
= polyhedron_affine_minmax_sign(LPX_MIN
, D
, T
, rational
);
133 if (min
== EMPTY_DOMAIN
)
134 return order_undefined
;
137 int max
= polyhedron_affine_minmax_sign(LPX_MAX
, D
, T
, rational
);
138 assert(max
!= EMPTY_DOMAIN
);
147 return order_unknown
;
150 enum lp_result
glpk_polyhedron_range(Polyhedron
*D
, Value
*obj
, Value denom
,
151 Value
*min
, Value
*max
,
152 struct barvinok_options
*options
)
159 res
= polyhedron_affine_minmax(LPX_MIN
, D
, obj
, denom
, min
);
162 res
= polyhedron_affine_minmax(LPX_MAX
, D
, obj
, denom
, max
);