doc: update evalue_bernstein_coefficients
[barvinok.git] / doc / Internal.tex
blob38e502aee81434c4a6428609ce312422c716185d
1 \section{Internal Representation of the \protect\ai[\tt]{barvinok} library}
3 Our \barvinok/ library is built on top of \PolyLib/
4 \shortcite{Wilde1993,Loechner1999}.
5 In particular, it reuses the implementations
6 of the algorithm of
7 \shortciteN{Loechner97parameterized}
8 for computing parametric vertices
9 and the algorithm of
10 \shortciteN{Clauss1998parametric}
11 for computing chamber decompositions.
12 Initially, our library was meant to be a replacement
13 for the algorithm of \shortciteN{Clauss1998parametric},
14 also implemented in \PolyLib/, for computing quasi-polynomials.
15 To ease the transition of application programs we
16 tried to reuse the existing data structures as much as possible.
18 \subsection{Existing Data Structures}
19 \label{a:existing}
21 Inside \PolyLib/ integer values are represented by the
22 \ai[\tt]{Value} data type.
23 Depending on a configure option, the data type may
24 either by a 32-bit integer, a 64-bit integer
25 or an arbitrary precision integer using \ai[\tt]{GMP}.
26 The \barvinok/ library requires that \PolyLib/ is compiled
27 with support for arbitrary precision integers.
29 The basic structure for representing (unions of) polyhedra is a
30 \ai[\tt]{Polyhedron}.
31 \begin{verbatim}
32 typedef struct polyhedron {
33 unsigned Dimension, NbConstraints, NbRays, NbEq, NbBid;
34 Value **Constraint;
35 Value **Ray;
36 Value *p_Init;
37 int p_Init_size;
38 struct polyhedron *next;
39 } Polyhedron;
40 \end{verbatim}
41 The attribute \ai[\tt]{Dimension} is the dimension
42 of the ambient space, i.e., the number of variables.
43 The attributes \ai[\tt]{Constraint}
44 and \ai[\tt]{Ray} point to two-dimensional arrays
45 of constraints and generators, respectively.
46 The number of rows is stored in
47 \ai[\tt]{NbConstraints} and
48 \ai[\tt]{NbRays}, respectively.
49 The number of columns in both arrays is equal
50 to \verb!1+Dimension+1!.
51 The first column of \ai[\tt]{Constraint} is either
52 $0$ or $1$ depending on whether the constraint
53 is an equality ($0$) or an inequality ($1$).
54 The number of equalities is stored in \ai[\tt]{NbEq}.
55 If the constraint is $\sp a x + c \ge 0$, then
56 the next columns contain the coefficients $a_i$
57 and the final column contains the constant $c$.
58 The first column of \ai[\tt]{Ray} is either
59 $0$ or $1$ depending on whether the generator
60 is a line ($0$) or a vertex or ray ($1$).
61 The number of lines is stored in \ai[\tt]{NbBid}.
62 Let $d$ be the \ac{lcm} of the denominators of the coordinates
63 of a vertex $\vec v$, then the next columns contain
64 $d v_i$ and the final column contains $d$.
65 For a ray, the final column contains $0$.
66 The field \ai[\tt]{next} points to the next polyhedron in
67 the union of polyhedra.
68 It is \verb+0+ if this is the last (or only) polyhedron in the union.
69 For more information on this structure, we refer to \shortciteN{Wilde1993}.
71 Quasi-polynomials are represented using the
72 \ai[\tt]{evalue} and \ai[\tt]{enode} structures.
73 \begin{verbatim}
74 typedef enum { polynomial, periodic, evector } enode_type;
76 typedef struct _evalue {
77 Value d; /* denominator */
78 union {
79 Value n; /* numerator (if denominator != 0) */
80 struct _enode *p; /* pointer (if denominator == 0) */
81 } x;
82 } evalue;
84 typedef struct _enode {
85 enode_type type; /* polynomial or periodic or evector */
86 int size; /* number of attached pointers */
87 int pos; /* parameter position */
88 evalue arr[1]; /* array of rational/pointer */
89 } enode;
90 \end{verbatim}
91 If the field \ai[\tt]{d} of an \ai[\tt]{evalue} is zero, then
92 the \ai[\tt]{evalue} is a placeholder for a pointer to
93 an \ai[\tt]{enode}, stored in \ai[\tt]{x.p}.
94 Otherwise, the \ai[\tt]{evalue} is a rational number with
95 numerator \ai[\tt]{x.n} and denominator \ai[\tt]{d}.
96 An \ai[\tt]{enode} is either a \ai[\tt]{polynomial}
97 or a \ai[\tt]{periodic}, depending on the value
98 of \ai[\tt]{type}.
99 The length of the array \ai[\tt]{arr} is stored in \ai[\tt]{size}.
100 For a \ai[\tt]{polynomial}, \ai[\tt]{arr} contains the coefficients.
101 For a \ai[\tt]{periodic}, it contains the values for the different
102 residue classes modulo the parameter indicated by \ai[\tt]{pos}.
103 For a polynomial, \ai[\tt]{pos} refers to the variable
104 of the polynomial.
105 The value of \ai[\tt]{pos} is \verb+1+ for the first parameter.
106 That is, if the value of \ai[\tt]{pos} is \verb+1+ and the first
107 parameter is $p$, and if the length of the array is $l$,
108 then in case it is a polynomial, the
109 \ai[\tt]{enode} represents
111 \verb+arr[0]+ + \verb+arr[1]+ p + \verb+arr[2]+ p^2 + \cdots +
112 \verb+arr[l-1]+ p^{l-1}
115 If it is a periodic, then it represents
117 \left[
118 \verb+arr[0]+, \verb+arr[1]+, \verb+arr[2]+, \ldots,
119 \verb+arr[l-1]+
120 \right]_p
123 Note that the elements of a \ai[\tt]{periodic} may themselves
124 be other \ai[\tt]{periodic}s or even \ai[\tt]{polynomial}s.
125 In our library, we only allow the elements of a \ai[\tt]{periodic}
126 to be other \ai[\tt]{periodic}s or rational numbers.
127 The chambers and their corresponding quasi-polynomial are
128 stored in \ai[\tt]{Enumeration} structures.
129 \begin{verbatim}
130 typedef struct _enumeration {
131 Polyhedron *ValidityDomain; /* constraints on the parameters */
132 evalue EP; /* dimension = combined space */
133 struct _enumeration *next; /* Ehrhart Polynomial,
134 corresponding to parameter
135 values inside the domain
136 ValidityDomain above */
137 } Enumeration;
138 \end{verbatim}
139 For more information on these structures, we refer to \shortciteN{Loechner1999}.
141 \begin{example}
142 Figure~\ref{f:Loechner} is a skillful reconstruction
143 of Figure~2 from \shortciteN{Loechner1999}.
144 It shows the contents of the \ai[\tt]{enode} structures
145 representing the quasi-polynomial
147 [1,2]_p p^2 + 3 p + \frac 5 2
150 \begin{figure}
151 \begin{xy}
152 \POS(0,0)*!UL{\hbox{
154 \begin{tabular}{|c|c|c|}
155 \hline
156 \multicolumn{2}{|c|}{type} & polynomial \\
157 \hline
158 \multicolumn{2}{|c|}{size} & 3 \\
159 \hline
160 \multicolumn{2}{|c|}{pos} & 1 \\
161 \hline
162 \smash{\lower 6.25pt\hbox{arr[0]}} & d & 2 \\
163 \cline{2-3}
164 & x.n & 5 \\
165 \hline
166 \smash{\lower 6.25pt\hbox{arr[1]}} & d & 1 \\
167 \cline{2-3}
168 & x.n & 3 \\
169 \hline
170 \smash{\lower 6.25pt\hbox{arr[2]}} & d & 0 \\
171 \cline{2-3}
172 & x.p & \\
173 \hline
174 \end{tabular}
176 }="box1"
177 +DR*!DR\hbox{\strut\hskip 1.5\tabcolsep\phantom{\tt polynomial}\hskip 1.5\tabcolsep}+C="a"
178 \POS(60,-15)*!UL{\hbox{
180 \begin{tabular}{|c|c|c|}
181 \hline
182 \multicolumn{2}{|c|}{type} & periodic \\
183 \hline
184 \multicolumn{2}{|c|}{size} & 2 \\
185 \hline
186 \multicolumn{2}{|c|}{pos} & 1 \\
187 \hline
188 \smash{\lower 6.25pt\hbox{arr[0]}} & d & 1 \\
189 \cline{2-3}
190 & x.n & 1 \\
191 \hline
192 \smash{\lower 6.25pt\hbox{arr[1]}} & d & 1 \\
193 \cline{2-3}
194 & x.n & 2 \\
195 \hline
196 \end{tabular}
198 }="box2"
199 +UL+<0.5\tabcolsep,0pt>*!UL\hbox{\strut}+CL="b"
200 \POS"a"\ar@(r,l) "b"
201 \POS"box1"+UC*++!D\hbox{\tt enode}
202 \POS"box2"+UC*++!D\hbox{\tt enode}
203 \end{xy}
204 \caption{The quasi-polynomial $[1,2]_p p^2 + 3 p + \frac 5 2$.}
205 \label{f:Loechner}
206 \end{figure}
207 \end{example}
209 \subsection{Options}
210 \label{a:options}
212 The \ai[\tt]{barvinok\_options} structure contains various
213 options that influence the behavior of the library.
215 \begin{verbatim}
216 struct barvinok_options {
217 /* PolyLib options */
218 unsigned MaxRays;
220 /* NTL options */
221 /* LLL reduction parameter delta=LLL_a/LLL_b */
222 long LLL_a;
223 long LLL_b;
225 /* barvinok options */
227 * 0: no
228 * 1: depth first
229 * 2: breadth first
231 int incremental_specialization;
234 struct barvinok_options *barvinok_options_new_with_defaults();
235 \end{verbatim}
237 The function \ai[\tt]{barvinok\_options\_new\_with\_defaults}
238 can be used to create a \ai[\tt]{barvinok\_options} structure
239 with default values.
241 \begin{itemize}
242 \item \PolyLib/ options
244 \begin{itemize}
246 \item \ai[\tt]{MaxRays}
248 The value of \ai[\tt]{MaxRays} is passed to various \PolyLib/
249 functions and defines the
250 maximum size of a table used in the \ai{double description} computation
251 in the \PolyLib/ function \ai[\tt]{Chernikova}.
252 In earlier versions of \PolyLib/,
253 this parameter had to be conservatively set
254 to a high number to ensure successful operation,
255 resulting in significant memory overhead.
256 Our change to allow this table to grow
257 dynamically is available in recent versions of \PolyLib/.
258 In these versions, the value no longer indicates the maximal
259 table size, but rather the size of the initial allocation.
260 This value may be set to \verb+0+ or left as set
261 by \ai[\tt]{barvinok\_options\_new\_with\_defaults}.
263 \end{itemize}
265 \item \ai[\tt]{NTL} options
267 \begin{itemize}
269 \item \ai[\tt]{LLL\_a}
270 \item \ai[\tt]{LLL\_b}
272 The values used for the \ai{reduction parameter}
273 in the call to \ai[\tt]{NTL}'s implementation of \indac{LLL}.
275 \end{itemize}
277 \item \ai[\tt]{barvinok} specific options
279 \begin{itemize}
281 \item \ai[\tt]{incremental\_specialization}
283 Selects the \ai{specialization} algorithm to be used.
284 If set to {\tt 0} then a direct specialization is performed
285 using a random vector.
286 Value {\tt 1} selects a depth first incremental specialization,
287 while value {\tt 2} selects a breadth first incremental specialization.
288 The default is selected by the \ai[\tt]{--enable-incremental}
289 \ai[\tt]{configure} option.
290 For more information we refer to~\citeN[Section~4.4.3]{Verdoolaege2005PhD}.
292 \end{itemize}
294 \end{itemize}
296 \subsection{Data Structures for Quasi-polynomials}
297 \label{a:data}
299 Internally, we do not represent our \ai{quasi-polynomial}s
300 as step-polynomials, but, similarly to \shortciteN{Loechner1999},
301 as polynomials with periodic numbers for coefficients.
302 However, we also allow our periodic numbers to be represented by
303 fractional parts of degree-$1$ polynomials rather than
304 an explicit enumeration using the \ai[\tt]{periodic} type.
305 By default, the current version of \barvinok/ uses
306 \ai[\tt]{periodic}s, but this can be changed through
307 the \ai[\tt]{--enable-fractional} configure option.
308 In the latter case, the quasi-polynomial using fractional
309 parts can also be converted to an actual step-polynomial
310 using \ai[\tt]{evalue\_frac2floor}, but this is not fully
311 supported yet.
313 For reasons of compatibility,%
314 \footnote{Also known as laziness.}
315 we shoehorned our representations for piecewise quasi-polynomials
316 into the existing data structures.
317 To this effect, we introduced four new types,
318 \ai[\tt]{fractional}, \ai[\tt]{relation},
319 \ai[\tt]{partition} and \ai[\tt]{flooring}.
320 \begin{verbatim}
321 typedef enum { polynomial, periodic, evector, fractional,
322 relation, partition, flooring } enode_type;
323 \end{verbatim}
324 The field \ai[\tt]{pos} is not used in most of these
325 additional types and is therefore set to \verb+-1+.
327 The types \ai[\tt]{fractional} and \ai[\tt]{flooring}
328 represent polynomial expressions in a fractional part or a floor respectively.
329 The generator is stored in \verb+arr[0]+, while the
330 coefficients are stored in the remaining array elements.
331 That is, an \ai[\tt]{enode} of type \ai[\tt]{fractional}
332 represents
334 \verb+arr[1]+ + \verb+arr[2]+ \{\verb+arr[0]+\} +
335 \verb+arr[3]+ \{\verb+arr[0]+\}^2 + \cdots +
336 \verb+arr[l-1]+ \{\verb+arr[0]+\}^{l-2}
339 An \ai[\tt]{enode} of type \ai[\tt]{flooring}
340 represents
342 \verb+arr[1]+ + \verb+arr[2]+ \lfloor\verb+arr[0]+\rfloor +
343 \verb+arr[3]+ \lfloor\verb+arr[0]+\rfloor^2 + \cdots +
344 \verb+arr[l-1]+ \lfloor\verb+arr[0]+\rfloor^{l-2}
348 \begin{example}
349 The internal representation of the quasi-polynomial
350 $$\left(1+2 \left\{\frac p 2\right\}\right) p^2 + 3 p + \frac 5 2$$
351 is shown in Figure~\ref{f:fractional}.
353 \begin{figure}
354 \begin{xy}
355 \POS(0,0)*!UL{\hbox{
357 \begin{tabular}{|c|c|c|}
358 \hline
359 \multicolumn{2}{|c|}{type} & polynomial \\
360 \hline
361 \multicolumn{2}{|c|}{size} & 3 \\
362 \hline
363 \multicolumn{2}{|c|}{pos} & 1 \\
364 \hline
365 \smash{\lower 6.25pt\hbox{arr[0]}} & d & 2 \\
366 \cline{2-3}
367 & x.n & 5 \\
368 \hline
369 \smash{\lower 6.25pt\hbox{arr[1]}} & d & 1 \\
370 \cline{2-3}
371 & x.n & 3 \\
372 \hline
373 \smash{\lower 6.25pt\hbox{arr[2]}} & d & 0 \\
374 \cline{2-3}
375 & x.p & \\
376 \hline
377 \end{tabular}
379 }="box1"
380 +DR*!DR\hbox{\strut\hskip 1.5\tabcolsep\phantom{\tt polynomial}\hskip 1.5\tabcolsep}+C="a"
381 \POS(60,0)*!UL{\hbox{
383 \begin{tabular}{|c|c|c|}
384 \hline
385 \multicolumn{2}{|c|}{type} & fractional \\
386 \hline
387 \multicolumn{2}{|c|}{size} & 3 \\
388 \hline
389 \multicolumn{2}{|c|}{pos} & -1 \\
390 \hline
391 \smash{\lower 6.25pt\hbox{arr[0]}} & d & 0 \\
392 \cline{2-3}
393 & x.p & \\
394 \hline
395 \smash{\lower 6.25pt\hbox{arr[1]}} & d & 1 \\
396 \cline{2-3}
397 & x.n & 1 \\
398 \hline
399 \smash{\lower 6.25pt\hbox{arr[2]}} & d & 1 \\
400 \cline{2-3}
401 & x.n & 2 \\
402 \hline
403 \end{tabular}
405 }="box2"
406 +UL+<0.5\tabcolsep,0pt>*!UL\hbox{\strut}+CL="b"
407 \POS"a"\ar@(r,l) "b"
408 \POS"box2"+UR*!UR{\hbox{
410 \begin{tabular}{|c|}
411 \hline
412 fractional \\
413 \hline
414 3 \\
415 \hline
416 -1 \\
417 \hline
418 0 \\
419 \hline
420 \end{tabular}
422 }+CD*!U{\strut}+C="c"
423 \POS(60,-50)*!UL{\hbox{
425 \begin{tabular}{|c|c|c|}
426 \hline
427 \multicolumn{2}{|c|}{type} & polynomial \\
428 \hline
429 \multicolumn{2}{|c|}{size} & 2 \\
430 \hline
431 \multicolumn{2}{|c|}{pos} & 1 \\
432 \hline
433 \smash{\lower 6.25pt\hbox{arr[0]}} & d & 1 \\
434 \cline{2-3}
435 & x.n & 0 \\
436 \hline
437 \smash{\lower 6.25pt\hbox{arr[1]}} & d & 2 \\
438 \cline{2-3}
439 & x.n & 1 \\
440 \hline
441 \end{tabular}
443 }="box3"
444 +UR-<0.8\tabcolsep,0pt>*!UR\hbox{\strut}+CR="d"
445 \POS"c"\ar@(r,r) "d"
446 \POS"box1"+UC*++!D\hbox{\tt enode}
447 \POS"box2"+UC*++!D\hbox{\tt enode}
448 \POS"box3"+UC*++!D\hbox{\tt enode}
449 \end{xy}
450 \caption{The quasi-polynomial
451 $\left(1+2 \left\{\frac p 2\right\}\right) p^2 + 3 p + \frac 5 2$.}
452 \label{f:fractional}
453 \end{figure}
455 \end{example}
457 The \ai[\tt]{relation} type is used to represent \ai{stride}s.
458 In particular, if the value of \ai[\tt]{size} is 2, then
459 the value of a \ai[\tt]{relation} is (in pseudo-code):
460 \begin{verbatim}
461 (value(arr[0]) == 0) ? value(arr[1]) : 0
462 \end{verbatim}
463 If the size is 3, then the value is:
464 \begin{verbatim}
465 (value(arr[0]) == 0) ? value(arr[1]) : value(arr[2])
466 \end{verbatim}
467 The type of \verb+arr[0]+ is typically \ai[\tt]{fractional}.
469 Finally, the \ai[\tt]{partition} type is used to
470 represent piecewise quasi-polynomials.
471 We prefer to encode this information inside \ai[\tt]{evalue}s
472 themselves
473 rather than using \ai[\tt]{Enumeration}s since we want
474 to perform the same kinds of operations on both quasi-polynomials
475 and piecewise quasi-polynomials.
476 An \ai[\tt]{enode} of type \ai[\tt]{partition} may not be nested
477 inside another \ai[\tt]{enode}.
478 The size of the array is twice the number of ``chambers''.
479 Pointers to chambers are stored in the even slots,
480 whereas pointer to the associated quasi-polynomials
481 are stored in the odd slots.
482 To be able to store pointers to chambers, the
483 definition of \ai[\tt]{evalue} was changed as follows.
484 \begin{verbatim}
485 typedef struct _evalue {
486 Value d; /* denominator */
487 union {
488 Value n; /* numerator (if denominator > 0) */
489 struct _enode *p; /* pointer (if denominator == 0) */
490 Polyhedron *D; /* domain (if denominator == -1) */
491 } x;
492 } evalue;
493 \end{verbatim}
494 Note that we allow a ``chamber'' to be a union of polyhedra
495 as discussed in \citeN[Section~4.5.1]{Verdoolaege2005PhD}.
496 Chambers with extra variables, i.e., those of
497 \citeN[Section~4.6.5]{Verdoolaege2005PhD},
498 are only partially supported.
499 The field \ai[\tt]{pos} is set to the actual dimension,
500 i.e., the number of parameters.
502 \subsection{Operations on Quasi-polynomials}
503 \label{a:operations}
505 In this section we discuss some of the more important
506 operations on \ai[\tt]{evalue}s provided by the
507 \barvinok/ library.
508 Some of these operations are extensions
509 of the functions from \PolyLib/ with the same name.
511 \begin{verbatim}
512 void eadd(const evalue *e1,evalue *res);
513 void emul (evalue *e1, evalue *res );
514 \end{verbatim}
515 The functions \ai[\tt]{eadd} and \ai[\tt]{emul} takes
516 two (pointers to) \ai[\tt]{evalue}s \verb+e1+ and \verb+res+
517 and computes their sum and product respectively.
518 The result is stored in \verb+res+, overwriting (and deallocating)
519 the original value of \verb+res+.
520 It is an error if exactly one of
521 the arguments of \ai[\tt]{eadd} is of type \ai[\tt]{partition}
522 (unless the other argument is \verb+0+).
523 The addition and multiplication operations are described
524 in \citeN[Section~4.5.1]{Verdoolaege2005PhD}
525 and~\citeN[Section~4.5.2]{Verdoolaege2005PhD}
526 respectively.
528 The function \ai[\tt]{eadd} is an extension of the function
529 \ai[\tt]{new\_eadd} from \shortciteN{Seghir2002}.
530 Apart from supporting the additional types from Section~\ref{a:data},
531 the new version also additionally imposes an order on the nesting of
532 different \ai[\tt]{enode}s.
533 Without such an ordering, \ai[\tt]{evalue}s could be constructed
534 representing for example
536 (0 y^ 0 + ( 0 x^0 + 1 x^1 ) y^1 ) x^0 + (0 y^0 - 1 y^1) x^1
539 which is just a funny way of saying $0$.
541 \begin{verbatim}
542 void eor(evalue *e1, evalue *res);
543 \end{verbatim}
544 The function \ai[\tt]{eor} implements the \ai{union}
545 operation from \citeN[Section~4.5.3]{Verdoolaege2005PhD}. Both arguments
546 are assumed to correspond to indicator functions.
548 \begin{verbatim}
549 evalue *esum(evalue *E, int nvar);
550 \end{verbatim}
551 The function \ai[\tt]{esum} performs the summation
552 operation from \citeN[Section~4.5.4]{Verdoolaege2005PhD}.
553 The piecewise step-polynomial represented by \verb+E+ is summated
554 over its first \verb+nvar+ variables.
555 Note that \verb+E+ must be zero or of type \ai[\tt]{partition}.
556 The function returns the result in a newly allocated
557 \ai[\tt]{evalue}.
558 Note also that \verb+E+ needs to have been converted
559 from \ai[\tt]{fractional}s to \ai[\tt]{flooring}s using
560 the function \ai[\tt]{evalue\_frac2floor}.
561 \begin{verbatim}
562 void evalue_frac2floor(evalue *e);
563 \end{verbatim}
564 This function also ensures that the arguments of the
565 \ai[\tt]{flooring}s are positive in the relevant chambers.
566 It currently assumes that the argument of each
567 \ai[\tt]{fractional} in the original \ai[\tt]{evalue}
568 has a minimum in the corresponding chamber.
570 \begin{verbatim}
571 double compute_evalue(evalue *e,Value *list_args);
572 Value *compute_poly(Enumeration *en,Value *list_args);
573 \end{verbatim}
574 The functions \ai[\tt]{compute\_evalue} and
575 \ai[\tt]{compute\_poly} evaluate a (piecewise) quasi-polynomial
576 at a certain point. The argument \verb+list_args+
577 points to an array of \ai[\tt]{Value}s that is assumed
578 to be long enough.
579 The \verb+double+ return value of \ai[\tt]{compute\_evalue}
580 is inherited from \PolyLib/.
582 \begin{verbatim}
583 void print_evalue(FILE *DST,evalue *e,char **pname);
584 \end{verbatim}
585 The function \ai[\tt]{print\_evalue} dumps a human-readable
586 representation to the stream pointed to by \verb+DST+.
587 The argument \verb+pname+ points
588 to an array of character strings representing the parameter names.
589 The array is assumed to be long enough.
591 \begin{verbatim}
592 int eequal(evalue *e1,evalue *e2);
593 \end{verbatim}
594 The function \ai[\tt]{eequal} return true (\verb+1+) if its
595 two arguments are structurally identical.
596 I.e., it does {\em not\/} check whether the two
597 (piecewise) quasi-polynomial represent the same function.
599 \begin{verbatim}
600 void reduce_evalue (evalue *e);
601 \end{verbatim}
602 The function \ai[\tt]{reduce\_evalue} performs some
603 simplifications on \ai[\tt]{evalue}s.
604 Here, we only describe the simplifications that are directly
605 related to the internal representation.
606 Some other simplifications are explained in
607 \citeN[Section~4.7.2]{Verdoolaege2005PhD}.
608 If the highest order coefficients of a \ai[\tt]{polynomial},
609 \ai[\tt]{fractional} or \ai[\tt]{flooring} are zero (possibly
610 after some other simplifications), then the size of the array
611 is reduced. If only the constant term remains, i.e.,
612 the size is reduced to $1$ for \ai[\tt]{polynomial} or to $2$
613 for the other types, then the whole node is replaced by
614 the constant term.
615 Additionally, if the argument of a \ai[\tt]{fractional}
616 has been reduced to a constant, then the whole node
617 is replaced by its partial evaluation.
618 A \ai[\tt]{relation} is similarly reduced if its second
619 branch or both its branches are zero.
620 Chambers with zero associated quasi-polynomials are
621 discarded from a \ai[\tt]{partition}.
623 \subsection{Generating Functions}
625 The representation of \rgf/s uses
626 some basic types from the \ai[\tt]{NTL} library \shortcite{NTL}
627 for representing arbitrary precision integers
628 (\ai[\tt]{ZZ})
629 as well as vectors (\ai[\tt]{vec\_ZZ}) and matrices (\ai[\tt]{mat\_ZZ})
630 of such integers.
631 We further introduces a type \ai[\tt]{QQ} for representing a rational
632 number and use vectors (\ai[\tt]{vec\_QQ}) of such numbers.
633 \begin{verbatim}
634 struct QQ {
635 ZZ n;
636 ZZ d;
639 NTL_vector_decl(QQ,vec_QQ);
640 \end{verbatim}
642 Each term in a \rgf/ is represented by a \ai[\tt]{short\_rat}
643 structure.
644 \begin{verbatim}
645 struct short_rat {
646 struct {
647 /* rows: terms in numerator */
648 vec_QQ coeff;
649 mat_ZZ power;
650 } n;
651 struct {
652 /* rows: factors in denominator */
653 mat_ZZ power;
654 } d;
656 \end{verbatim}
657 The fields \ai[\tt]{n} and \ai[\tt]{d} represent the
658 numerator and the denominator respectively.
659 Note that in our implementation we combine terms
660 with the same denominator.
661 In the numerator, each element of \ai[\tt]{coeff} and each row of \ai[\tt]{power}
662 represents a single such term.
663 The vector \ai[\tt]{coeff} contains the rational coefficients
664 $\alpha_i$ of each term.
665 The columns of \ai[\tt]{power} correspond to the powers
666 of the variables.
667 In the denominator, each row of \ai[\tt]{power}
668 corresponds to the power $\vec b_{ij}$ of a
669 factor in the denominator.
671 \begin{example}
672 Figure~\ref{fig:rat}
673 shows the internal representation of
675 \frac{\frac 3 2 \, x_0^2 x_1^3 + 2 \, x_0^5 x_1^{-7}}
676 { (1 - x_0 x_1^{-3}) (1 - x_1^2)}
680 \begin{figure}
681 \begin{center}
682 \begin{minipage}{0cm}
683 \begin{xy}
684 *\hbox{
686 \begin{tabular}{|c|c|c|}
687 \hline
688 n.coeff & 3 & 2 \\
689 \cline{2-3}
690 & 2 & 1 \\
691 \hline
692 n.power & 2 & 3 \\
693 \cline{2-3}
694 & 5 & -7 \\
695 \hline
696 d.power & 1 & -3 \\
697 \cline{2-3}
698 & 0 & 2 \\
699 \hline
700 \end{tabular}
701 }+UC*++!D\hbox{\tt short\_rat}
702 \end{xy}
703 \end{minipage}
704 \end{center}
705 \caption{Representation of
707 \left(\frac 3 2 \, x_0^2 x_1^3 + 2 \, x_0^5 x_1^{-7}\right)
708 / \left( (1 - x_0 x_1^{-3}) (1 - x_1^2)\right)
710 \label{fig:rat}
711 \end{figure}
713 \end{example}
715 The whole \rgf/ is represented by a \ai[\tt]{gen\_fun}
716 structure.
717 \begin{verbatim}
718 struct gen_fun {
719 std::vector< short_rat * > term;
720 Polyhedron *context;
722 void add(const QQ& c, const vec_ZZ& num, const mat_ZZ& den);
723 void add(const QQ& c, const gen_fun *gf);
724 void substitute(Matrix *CP);
725 gen_fun *Hadamard_product(const gen_fun *gf,
726 barvinok_options *options);
727 void print(std::ostream& os,
728 unsigned int nparam, char **param_name) const;
729 operator evalue *() const;
730 void coefficient(Value* params, Value* c) const;
732 gen_fun(Polyhedron *C = NULL);
733 gen_fun(Value c);
734 gen_fun(const gen_fun *gf);
735 ~gen_fun();
737 \end{verbatim}
738 A new \ai[\tt]{gen\_fun} can be constructed either as empty \rgf/ (possibly
739 with a given context \verb+C+), as a copy of an existing \rgf/ \verb+gf+, or as
740 constant \rgf/ with value for the constant term specified by \verb+c+.
742 The first \ai[\tt]{gen\_fun::add} method adds a new term to the \rgf/,
743 described by the coefficient \verb+c+, the numerator \verb+num+ and the
744 denominator \verb+den+.
745 It makes all powers in the denominator lexico-positive,
746 orders them in lexicographical order and inserts the new
747 term in \ai[\tt]{term} according to the lexicographical
748 order of the combined powers in the denominator.
749 The second \ai[\tt]{gen\_fun::add} method adds \verb+c+ times \verb+gf+
750 to the \rgf/.
752 The method \ai[\tt]{gen\_fun::operator evalue *} performs
753 the conversion from \rgf/ to \psp/ explained in
754 \citeN[Section~4.5.5]{Verdoolaege2005PhD}.
755 The \ai[\tt]{Polyhedron} \ai[\tt]{context} is the superset
756 of all points where the enumerator is non-zero used during this conversion,
757 i.e., it is the set $Q$ from \citeN[Equation~4.31]{Verdoolaege2005PhD}.
758 If \ai[\tt]{context} is \verb+NULL+ the maximal
759 allowed context is assumed, i.e., the maximal
760 region with lexico-positive rays.
762 The method \ai[\tt]{gen\_fun::coefficient} computes the coefficient
763 of the term with power given by \verb+params+ and stores the result
764 in \verb+c+.
765 This method performs essentially the same computations as
766 \ai[\tt]{gen\_fun::operator evalue *}, except that it adds extra
767 equality constraints based on the specified values for the power.
769 The method \ai[\tt]{gen\_fun::substitute} performs the
770 \ai{monomial substitution} specified by the homogeneous matrix \verb+CP+
771 that maps a set of ``\ai{compressed parameter}s'' \shortcite{Meister2004PhD}
772 to the original set of parameters.
773 That is, if we are given a \rgf/ $G(\vec z)$ that encodes the
774 explicit function $g(\vec i')$, where $\vec i'$ are the coordinates of
775 the transformed space, and \verb+CP+ represents the map
776 $\vec i = A \vec i' + \vec a$ back to the original space with coordinates $\vec i$,
777 then this method transforms the \rgf/ to $F(\vec x)$ encoding the
778 same explicit function $f(\vec i)$, i.e.,
779 $$f(\vec i) = f(A \vec i' + \vec a) = g(\vec i ').$$
780 This means that the coefficient of the term
781 $\vec x^{\vec i} = \vec x^{A \vec i' + \vec a}$ in $F(\vec x)$ should be equal to the
782 coefficient of the term $\vec z^{\vec i'}$ in $G(\vec z)$.
783 In other words, if
785 G(\vec z) =
786 \sum_i \epsilon_i \frac{\vec z^{\vec v_i}}{\prod_j (1-\vec z^{\vec b_{ij}})}
788 then
790 F(\vec x) =
791 \sum_i \epsilon_i \frac{\vec x^{A \vec v_i + \vec a}}
792 {\prod_j (1-\vec x^{A \vec b_{ij}})}
796 The method \ai[\tt]{gen\_fun::Hadamard\_product} computes the
797 \ai{Hadamard product} of the current \rgf/ with the \rgf/ \verb+gf+,
798 as explained in \citeN[Section~4.5.2]{Verdoolaege2005PhD}.
800 \subsection{Counting Functions}
801 \label{a:counting:functions}
803 Our library provides essentially three different counting functions:
804 one for non-parametric polytopes, one for parametric polytopes
805 and one for parametric sets with existential variables.
806 The old versions of these functions have a ``\ai[\tt]{MaxRays}''
807 argument, while the new versions have a more general
808 \ai[\tt]{barvinok\_options} argument.
809 For more information on \ai[\tt]{barvinok\_options}, see Section~\ref{a:options}.
811 \begin{verbatim}
812 void barvinok_count(Polyhedron *P, Value* result,
813 unsigned NbMaxCons);
814 void barvinok_count_with_options(Polyhedron *P, Value* result,
815 struct barvinok_options *options);
816 \end{verbatim}
817 The function \ai[\tt]{barvinok\_count} or
818 \ai[\tt]{barvinok\_count\_with\_options} enumerates the non-parametric
819 polytope \verb+P+ and returns the result in the \ai[\tt]{Value}
820 pointed to by \verb+result+, which needs to have been allocated
821 and initialized.
822 If \verb+P+ is a union, then only the first set in the union will
823 be taken into account.
824 For the meaning of the argument \verb+NbMaxCons+, see
825 the discussion on \ai[\tt]{MaxRays} in Section~\ref{a:options}.
827 The function \ai[\tt]{barvinok\_enumerate} for enumerating
828 parametric polytopes was meant to be
829 a drop-in replacement of \PolyLib/'s \ai[\tt]{Polyhedron\_Enumerate}
830 function.
831 Unfortunately, the latter has been changed to
832 accept an extra argument in recent versions of \PolyLib/ as shown below.
833 \begin{verbatim}
834 Enumeration* barvinok_enumerate(Polyhedron *P, Polyhedron* C,
835 unsigned MaxRays);
836 extern Enumeration *Polyhedron_Enumerate(Polyhedron *P,
837 Polyhedron *C, unsigned MAXRAYS, char **pname);
838 \end{verbatim}
839 The argument \verb+MaxRays+ has the same meaning as the argument
840 \verb+NbMaxCons+ above.
841 The argument \verb+P+ refers to the $(d+n)$-dimensional
842 polyhedron defining the parametric polytope.
843 The argument \verb+C+ is an $n$-dimensional polyhedron containing
844 extra constraints on the parameter space.
845 Its primary use is to indicate how many of the dimensions
846 in \verb+P+ refer to parameters as any constraint in \verb+C+
847 could equally well have been added to \verb+P+ itself.
848 Note that the dimensions referring to the parameters should
849 appear {\em last}.
850 If either \verb+P+ or \verb+C+ is a union,
851 then only the first set in the union will be taken into account.
852 The result is a newly allocated \ai[\tt]{Enumeration}.
853 As an alternative we also provide a function
854 (\ai[\tt]{barvinok\_enumerate\_ev} or
855 \ai[\tt]{barvinok\_enumerate\_with\_options}) that returns
856 an \ai[\tt]{evalue}.
857 \begin{verbatim}
858 evalue* barvinok_enumerate_ev(Polyhedron *P, Polyhedron* C,
859 unsigned MaxRays);
860 evalue* barvinok_enumerate_with_options(Polyhedron *P,
861 Polyhedron* C, struct barvinok_options *options);
862 \end{verbatim}
864 For enumerating parametric sets with existentially quantified variables,
865 we provide two functions:
866 \ai[\tt]{barvinok\_enumerate\_e}
868 \ai[\tt]{barvinok\_enumerate\_pip}.
869 \begin{verbatim}
870 evalue* barvinok_enumerate_e(Polyhedron *P,
871 unsigned exist, unsigned nparam, unsigned MaxRays);
872 evalue* barvinok_enumerate_e_with_options(Polyhedron *P,
873 unsigned exist, unsigned nparam,
874 struct barvinok_options *options);
875 evalue *barvinok_enumerate_pip(Polyhedron *P,
876 unsigned exist, unsigned nparam, unsigned MaxRays);
877 evalue* barvinok_enumerate_pip_with_options(Polyhedron *P,
878 unsigned exist, unsigned nparam,
879 struct barvinok_options *options);
880 evalue *barvinok_enumerate_scarf(Polyhedron *P,
881 unsigned exist, unsigned nparam,
882 struct barvinok_options *options);
883 \end{verbatim}
884 The first function tries the simplification rules from
885 \citeN[Section~4.6.2]{Verdoolaege2005PhD} before resorting to the method
886 based on \indac{PIP} from \citeN[Section~4.6.3]{Verdoolaege2005PhD}.
887 The second function immediately applies the technique from
888 \citeN[Section~4.6.3]{Verdoolaege2005PhD}.
889 The argument \verb+exist+ refers to the number of existential variables,
890 whereas
891 the argument \verb+nparam+ refers to the number of parameters.
892 The order of the dimensions in \verb+P+ is:
893 counted variables first, then existential variables and finally
894 the parameters.
895 The function \ai[\tt]{barvinok\_enumerate\_scarf} performs the same
896 computation as the function \ai[\tt]{barvinok\_enumerate\_scarf\_series}
897 below, but produces an explicit representation instead of a generating function.
899 \begin{verbatim}
900 gen_fun * barvinok_series(Polyhedron *P, Polyhedron* C,
901 unsigned MaxRays);
902 gen_fun * barvinok_series_with_options(Polyhedron *P,
903 Polyhedron* C, barvinok_options *options);
904 gen_fun *barvinok_enumerate_scarf_series(Polyhedron *P,
905 unsigned exist, unsigned nparam,
906 barvinok_options *options);
907 \end{verbatim}
908 The function
909 \ai[\tt]{barvinok\_series} or
910 \ai[\tt]{barvinok\_series\_with\_options} enumerates parametric polytopes
911 in the form of a \rgf/.
912 The polyhedron \verb+P+ is assumed to have only
913 revlex-positive rays.
915 The function \ai[\tt]{barvinok\_enumerate\_scarf\_series} computes a
916 generating function for the number of point in the parametric set
917 defined by \verb+P+ with \verb+exist+ existentially quantified
918 variables, which is assumed to be 2.
919 This function implements the technique of
920 \shortciteN{Scarf2006Neighborhood} using the \ai{neighborhood complex}
921 description of \shortciteN{Scarf1981indivisibilities:II}.
922 It is currently restricted to problems with 3 or 4 constraints involving
923 the existentially quantified variables.
925 \subsection{Auxiliary Functions}
927 In this section we briefly mention some auxiliary functions
928 available in the \barvinok/ library.
930 \begin{verbatim}
931 void Polyhedron_Polarize(Polyhedron *P);
932 \end{verbatim}
933 The function \ai[\tt]{Polyhedron\_Polarize}
934 polarizes its argument and is explained
935 in \citeN[Section~4.4.2]{Verdoolaege2005PhD}.
937 \begin{verbatim}
938 Matrix * unimodular_complete(Vector *row);
939 \end{verbatim}
940 The function \ai[\tt]{unimodular\_complete} extends
941 \verb+row+ to a \ai{unimodular matrix} using the
942 algorithm of \shortciteN{Bik1996PhD}.
944 \begin{verbatim}
945 int DomainIncludes(Polyhedron *D1, Polyhedron *D2);
946 \end{verbatim}
947 The function \ai[\tt]{DomainIncludes} extends
948 the function \ai[\tt]{PolyhedronIncludes}
949 provided by \PolyLib/
950 to unions of polyhedra.
951 It checks whether every polyhedron in the union {\tt D2}
952 is included in some polyhedron of {\tt D1}.
954 \begin{verbatim}
955 Polyhedron *DomainConstraintSimplify(Polyhedron *P,
956 unsigned MaxRays);
957 \end{verbatim}
958 The value returned by
959 \ai[\tt]{DomainConstraintSimplify} is a pointer to
960 a newly allocated \ai[\tt]{Polyhedron} that contains the
961 same integer points as its first argument but possibly
962 has simpler constraints.
963 Each constraint $ g \sp a x \ge c $
964 is replaced by $ \sp a x \ge \ceil{ \frac c g } $,
965 where $g$ is the \ac{gcd} of the coefficients in the original
966 constraint.
967 The \ai[\tt]{Polyhedron} pointed to by \verb+P+ is destroyed.
969 \begin{verbatim}
970 Polyhedron* Polyhedron_Project(Polyhedron *P, int dim);
971 \end{verbatim}
972 The function \ai[\tt]{Polyhedron\_Project} projects
973 \verb+P+ onto its last \verb+dim+ dimensions.
975 \sindex{reduced}{basis}
976 \sindex{generalized}{reduced basis}
977 \begin{verbatim}
978 Matrix *Polyhedron_Reduced_Basis(Polyhedron *P);
979 \end{verbatim}
980 \ai[\tt]{Polyhedron\_Reduced\_Basis} computes
981 a \ai{generalized reduced basis} of {\tt P}, which
982 is assumed to be a polytope, using the algorithm
983 of~\shortciteN{Cook1993implementation}.
984 The basis vectors are stored in the rows of the matrix returned.
985 This function currently uses \ai[\tt]{GLPK}~\shortcite{GLPK}
986 to perform the linear optimizations and so is only available
987 if you have \ai[\tt]{GLPK}.
989 \begin{verbatim}
990 Vector *Polyhedron_Sample(Polyhedron *P, unsigned MaxRays);
991 \end{verbatim}
992 \ai[\tt]{Polyhedron\_Sample} returns an \ai{integer point} of {\tt P}
993 or {\tt NULL} if {\tt P} contains no integer points.
994 The integer point is found using the algorithm
995 of~\shortciteN{Cook1993implementation} and uses
996 \ai[\tt]{Polyhedron\_Reduced\_Basis} to compute the reduced bases
997 and therefore also requires \ai[\tt]{GLPK}.
999 \subsection{\protect\ai[\tt]{bernstein} Data Structures and Functions}
1001 The \bernstein/ library used \ai[\tt]{GiNaC} data structures to
1002 represent the data it manipulates.
1003 In particular, a polynomial is stored in a \ai[\tt]{GiNaC::ex},
1004 a list of variable or parameter names is stored in a \ai[\tt]{GiNaC::exvector},
1005 while the parametric vertices or generators are stored in a \ai[\tt]{GiNaC::matrix},
1006 where the rows refer to the generators and the columns to the coordinates
1007 of each generator.
1009 \begin{verbatim}
1010 namespace bernstein {
1011 GiNaC::exvector constructParameterVector(
1012 const char * const *param_names, unsigned nbParams);
1013 GiNaC::exvector constructVariableVector(unsigned nbVariables,
1014 const char *prefix);
1016 \end{verbatim}
1017 The functions \ai[\tt]{constructParameterVector}
1018 and \ai[\tt]{constructVariableVector} construct a list of variable
1019 names either from a list of {\tt char *}s or
1020 by suffixing {\tt prefix} with a number starting from 0.
1021 Such lists are needed for the functions
1022 \ai[\tt]{domainVertices}, \ai[\tt]{bernsteinExpansion}
1023 and \ai[\tt]{evalue\_bernstein\_coefficients}.
1025 \begin{verbatim}
1026 namespace bernstein {
1027 GiNaC::matrix domainVertices(Param_Polyhedron *PP, Param_Domain *Q,
1028 const GiNaC::exvector& params);
1030 \end{verbatim}
1031 The function \ai[\tt]{domainVertices} constructs a matrix representing the
1032 generators (in this case vertices) of the \ai[\tt]{Param\_Polyhedron} {\tt PP}
1033 for the \ai[\tt]{Param\_Domain} {\tt Q}, to be used
1034 in a call to \ai[\tt]{bernsteinExpansion}.
1035 The elements of {\tt params} are used in the resulting matrix
1036 to refer to the parameters.
1038 \begin{verbatim}
1039 namespace bernstein {
1040 GiNaC::lst bernsteinExpansion(const GiNaC::matrix& vert,
1041 const GiNaC::ex& poly,
1042 const GiNaC::exvector& vars,
1043 const GiNaC::exvector& params);
1045 \end{verbatim}
1046 The function \ai[\tt]{bernsteinExpansion} computes the
1047 \ai{Bernstein coefficient}s of the polynomial \verb+poly+
1048 over the \ai{parametric polytope} that is the \ai{convex hull}
1049 of the rows in \verb+vert+. The vectors \verb+vars+
1050 and \verb+params+ identify the variables (i.e., the coordinates
1051 of the space in which the parametric polytope lives) and
1052 the parameters, respectively.
1054 \begin{verbatim}
1055 namespace bernstein {
1057 typedef std::pair< Polyhedron *, GiNaC::lst > guarded_lst;
1059 struct piecewise_lst {
1060 const GiNaC::exvector vars;
1061 std::vector<guarded_lst> list;
1063 piecewise_lst::piecewise_lst(const GiNaC::exvector& vars);
1064 piecewise_lst& combine(const piecewise_lst& other);
1065 void maximize();
1066 void simplify_domains(Polyhedron *ctx, unsigned MaxRays);
1067 GiNaC::numeric evaluate(const GiNaC::exvector& values);
1068 void add(const GiNaC::ex& poly);
1072 \end{verbatim}
1073 A \ai[\tt]{piecewise\_list} structure represents a list of (disjoint)
1074 polyhedral domains, each with an associated \ai[\tt]{GiNaC::lst}
1075 of polynomials.
1076 The \ai[\tt]{vars} member contains the variable names of the
1077 dimensions of the polyhedral domains.
1079 \ai[\tt]{piecewise\_lst::combine} computes the \ai{common refinement}
1080 of the polyhedral domains in \verb+this+ and \verb+other+ and associates
1081 to each of the resulting subdomains the union of the sets of polynomials
1082 associated to the domains from \verb+this+ and \verb+other+ that contain
1083 the subdomain.
1084 The result is stored in \verb+this+.
1086 \ai[\tt]{piecewise\_lst::maximize} removes polynomials from domains that evaluate
1087 to a value that is smaller than or equal to the value of some
1088 other polynomial associated to the same domain for each point in the domain.
1090 \ai[\tt]{piecewise\_lst::evaluate} ``evaluates'' the \ai[\tt]{piecewise\_list}
1091 by looking for the domain (if any) that contains the point given by
1092 \verb+values+ and computing the maximal value attained by any of the
1093 associated polynomials evaluated at that point.
1095 \ai[\tt]{piecewise\_lst::add} adds the polynomial \verb+poly+
1096 to each of the polynomial associated to each of the domains.
1098 \ai[\tt]{piecewise\_lst::simplify\_domains} ``simplifies'' the domains
1099 by removing the constraints that are implied by the constraints
1100 in \verb+ctx+, basically by calling \PolyLib/'s
1101 \ai[\tt]{DomainSimplify}. Note that you should only do this
1102 at the end of your computation. In particular, you do not
1103 want to call this method before calling
1104 \ai[\tt]{piecewise\_lst::maximize}, since this method will then
1105 have less information on the domains to exploit.
1108 \begin{verbatim}
1109 namespace barvinok {
1110 bernstein::piecewise_lst *evalue_bernstein_coefficients(
1111 bernstein::piecewise_lst *pl_all, evalue *e,
1112 Polyhedron *ctx, const GiNaC::exvector& params);
1113 bernstein::piecewise_lst *evalue_bernstein_coefficients(
1114 bernstein::piecewise_lst *pl_all, evalue *e,
1115 Polyhedron *ctx, const GiNaC::exvector& params,
1116 barvinok_options *options);
1118 \end{verbatim}
1119 The \ai[\tt]{evalue\_bernstein\_coefficients} function will compute the
1120 \ai{Bernstein coefficient}s of the piecewise parametric polynomial stored in the
1121 \ai[\tt]{evalue} \verb+e+.
1122 The \verb+params+ vector specifies the names to be used for the parameters,
1123 while the context \ai[\tt]{Polyhedron} \verb+ctx+ specifies extra constraints
1124 on the parameters.
1125 The dimension of \verb+ctx+ needs to be the same as the length of \verb+params+.
1126 The \ai[\tt]{evalue} \verb+e+ is assumed to be of type \ai[\tt]{partition}
1127 and each of the domains in this \ai[\tt]{partition} is interpreted
1128 as a parametric polytope in the given parameters. The procedure
1129 will compute the \ai{Bernstein coefficient}s of the associated polynomial
1130 over each such parametric polytope.
1131 The resulting \ai[\tt]{bernstein::piecewise\_lst} collects the
1132 Bernstein coefficients over all parametric polytopes in \verb+e+.
1133 If \verb+pl_all+ is not \verb+NULL+ then this list will be combined
1134 with the list computed by calling \ai[\tt]{piecewise\_lst::combine}.
1135 If \ai[\tt]{bernstein\_optimize} is set to \ai[\tt]{BV\_BERNSTEIN\_MAX}
1136 in \verb+options+, then this combination will remove obviously
1137 redundant Bernstein coefficients with respect to upper bound computation
1138 and similarly for \ai[\tt]{BV\_BERNSTEIN\_MIN}.
1139 The default (\ai[\tt]{BV\_BERNSTEIN\_NONE}) is to only remove duplicate
1140 Bernstein coefficients.