2 #include <barvinok/options.h>
3 #include <barvinok/util.h>
7 static int is_unit_row(Value
*row
, int pos
, int len
)
9 if (!value_one_p(row
[pos
]) && !value_mone_p(row
[pos
]))
11 return First_Non_Zero(row
+pos
+1, len
-(pos
+1)) == -1;
14 /* Transform the constraints of P to "standard form".
15 * In particular, if P is described by
17 * then this function returns a matrix H = A U, A = H Q, such
18 * that D x' = D Q x >= -b(p), with D a diagonal matrix with
19 * positive entries. The calling function can then construct
20 * the standard form H' x' - I s + b(p) = 0, with H' the rows of H
21 * that are not positive multiples of unit vectors
22 * (since those correspond to D x' >= -b(p)).
23 * The number of rows in H' is returned in *rows_p.
24 * Optionally returns the matrix that maps the new variables
25 * back to the old variables x = U x'.
26 * Note that the rows of H (and P) may be reordered by this function.
28 Matrix
*standard_constraints(Polyhedron
*P
, unsigned nparam
, int *rows_p
,
31 unsigned nvar
= P
->Dimension
- nparam
;
39 /* move constraints only involving parameters down
40 * and move unit vectors (if there are any) to the right place.
42 for (d
= 0, j
= P
->NbConstraints
; d
< j
; ++d
) {
44 index
= First_Non_Zero(P
->Constraint
[d
]+1, nvar
);
47 is_unit_row(P
->Constraint
[d
]+1, index
, nvar
)) {
48 Vector_Exchange(P
->Constraint
[d
], P
->Constraint
[index
],
55 while (d
< --j
&& First_Non_Zero(P
->Constraint
[j
]+1, nvar
) == -1)
59 Vector_Exchange(P
->Constraint
[d
], P
->Constraint
[j
], P
->Dimension
+2);
61 M
= Matrix_Alloc(d
, nvar
);
62 for (j
= 0; j
< d
; ++j
)
63 Vector_Copy(P
->Constraint
[j
]+1, M
->p
[j
], nvar
);
65 neg_left_hermite(M
, &H
, &Q
, &U
);
73 /* Rearrange rows such that top of H is lower diagonal and
74 * compute the number of non (multiple of) unit-vector rows.
76 rows
= H
->NbRows
-nvar
;
77 for (i
= 0; i
< H
->NbColumns
; ++i
) {
78 for (j
= i
; j
< H
->NbRows
; ++j
)
79 if (value_notzero_p(H
->p
[j
][i
]))
82 Vector_Exchange(P
->Constraint
[i
], P
->Constraint
[j
], P
->Dimension
+2);
83 Vector_Exchange(H
->p
[i
], H
->p
[j
], H
->NbColumns
);
85 if (First_Non_Zero(H
->p
[i
], i
) != -1)
94 enum order_sign
glpk_polyhedron_affine_sign(Polyhedron
*D
, Matrix
*T
,
95 struct barvinok_options
*options
)
100 enum lp_result
glpk_constraints_opt(Matrix
*C
, Value
*obj
, Value denom
,
101 enum lp_dir dir
, Value
*opt
)
106 enum lp_result
glpk_polyhedron_range(Polyhedron
*D
, Value
*obj
, Value denom
,
107 Value
*min
, Value
*max
,
108 struct barvinok_options
*options
)
114 #ifndef HAVE_LIBCDDGMP
115 enum order_sign
cdd_polyhedron_affine_sign(Polyhedron
*D
, Matrix
*T
,
116 struct barvinok_options
*options
)
121 enum order_sign
cddf_polyhedron_affine_sign(Polyhedron
*D
, Matrix
*T
,
122 struct barvinok_options
*options
)
127 enum lp_result
cdd_constraints_opt(Matrix
*C
, Value
*obj
, Value denom
,
128 enum lp_dir dir
, Value
*opt
)
133 enum lp_result
cddf_constraints_opt(Matrix
*C
, Value
*obj
, Value denom
,
134 enum lp_dir dir
, Value
*opt
)
139 enum lp_result
cdd_polyhedron_range(Polyhedron
*D
, Value
*obj
, Value denom
,
140 Value
*min
, Value
*max
,
141 struct barvinok_options
*options
)
146 enum lp_result
cddf_polyhedron_range(Polyhedron
*D
, Value
*obj
, Value denom
,
147 Value
*min
, Value
*max
,
148 struct barvinok_options
*options
)
154 enum order_sign
polyhedron_affine_sign(Polyhedron
*D
, Matrix
*T
,
155 struct barvinok_options
*options
)
157 if (options
->lp_solver
== BV_LP_POLYLIB
)
158 return PL_polyhedron_affine_sign(D
, T
, options
);
159 else if (options
->lp_solver
== BV_LP_GLPK
)
160 return glpk_polyhedron_affine_sign(D
, T
, options
);
161 else if (options
->lp_solver
== BV_LP_CDD
)
162 return cdd_polyhedron_affine_sign(D
, T
, options
);
163 else if (options
->lp_solver
== BV_LP_CDDF
)
164 return cddf_polyhedron_affine_sign(D
, T
, options
);
170 * Optimize (minimize or maximize depending on dir) the affine
171 * objective function obj (of length dimension+1), with denominator
172 * denom over the polyhedron specified by the constraints C.
173 * The result is returned in opt.
175 enum lp_result
constraints_opt(Matrix
*C
, Value
*obj
, Value denom
,
176 enum lp_dir dir
, Value
*opt
,
177 struct barvinok_options
*options
)
179 if (options
->lp_solver
== BV_LP_POLYLIB
)
180 return PL_constraints_opt(C
, obj
, denom
, dir
, opt
, options
->MaxRays
);
181 else if (options
->lp_solver
== BV_LP_GLPK
)
182 return glpk_constraints_opt(C
, obj
, denom
, dir
, opt
);
183 else if (options
->lp_solver
== BV_LP_CDD
)
184 return cdd_constraints_opt(C
, obj
, denom
, dir
, opt
);
185 else if (options
->lp_solver
== BV_LP_CDDF
)
186 return cddf_constraints_opt(C
, obj
, denom
, dir
, opt
);
187 else if (options
->lp_solver
== BV_LP_PIP
)
188 return pip_constraints_opt(C
, obj
, denom
, dir
, opt
);
194 * Optimize (minimize or maximize depending on dir) the affine
195 * objective function obj (of length dimension+1), with denominator
196 * denom over the polyhedron specified by P.
197 * The result is returned in opt.
199 enum lp_result
polyhedron_opt(Polyhedron
*P
, Value
*obj
, Value denom
,
200 enum lp_dir dir
, Value
*opt
,
201 struct barvinok_options
*options
)
203 if (options
->lp_solver
== BV_LP_POLYLIB
)
204 return PL_polyhedron_opt(P
, obj
, denom
, dir
, opt
);
207 Polyhedron_Matrix_View(P
, &M
, P
->NbConstraints
);
208 return constraints_opt(&M
, obj
, denom
, dir
, opt
, options
);
212 enum lp_result
polyhedron_range(Polyhedron
*D
, Value
*obj
, Value denom
,
213 Value
*min
, Value
*max
,
214 struct barvinok_options
*options
)
216 if (options
->lp_solver
== BV_LP_POLYLIB
)
217 return PL_polyhedron_range(D
, obj
, denom
, min
, max
, options
);
218 else if (options
->lp_solver
== BV_LP_GLPK
)
219 return glpk_polyhedron_range(D
, obj
, denom
, min
, max
, options
);
220 else if (options
->lp_solver
== BV_LP_CDD
)
221 return cdd_polyhedron_range(D
, obj
, denom
, min
, max
, options
);
222 else if (options
->lp_solver
== BV_LP_CDDF
)
223 return cddf_polyhedron_range(D
, obj
, denom
, min
, max
, options
);
224 else if (options
->lp_solver
== BV_LP_PIP
)
225 return pip_polyhedron_range(D
, obj
, denom
, min
, max
, options
);