2 #include <bernstein/bernstein.h>
3 #include <bernstein/piecewise_lst.h>
4 #include <barvinok/options.h>
5 #include <barvinok/bernstein.h>
6 #include "ex_convert.h"
8 #include "param_util.h"
9 #include "omega_interface/convert.h"
11 using namespace GiNaC
;
12 using namespace bernstein
;
15 #define ALLOC(type) (type*)malloc(sizeof(type))
17 static void extract_vars(Map
<Variable_Ref
*, GiNaC::ex
>& variableMap
,
18 const varvector
&vv
, exvector
&exvars
)
20 for (int i
= 0; i
< vv
.size(); ++i
) {
22 foreach_map(vr
,Variable_Ref
*,s
,ex
,variableMap
, {
23 if (vr
->vid
== vv
[i
]) {
29 exvars
.push_back(var
);
33 static void extract_params(Map
<Variable_Ref
*, GiNaC::ex
>& variableMap
,
34 const varvector
¶ms
, exvector
&exparams
)
36 for (int i
= 0; i
< params
.size(); ++i
) {
37 Global_Var_ID global
= params
[i
]->get_global_var();
39 foreach_map(vr
,Variable_Ref
*,s
,ex
,variableMap
, {
40 if (vr
->g
== global
) {
46 exparams
.push_back(var
);
48 exparams
.push_back(symbol(params
[i
]->char_name()));
52 void maximize(PolyFunc
*polyfunc
, Map
<Variable_Ref
*, GiNaC::ex
>& variableMap
)
59 struct barvinok_options
*options
= barvinok_options_new_with_defaults();
61 cout
<< "maximize " << polyfunc
->poly
<< " over ";
62 polyfunc
->domain
.simplify();
63 polyfunc
->domain
.print(stdout
);
65 Polyhedron
*D
= relation2Domain(polyfunc
->domain
, vv
, params
,
68 assert(polyfunc
->domain
.is_set());
69 int dim
= polyfunc
->domain
.n_set();
70 assert(D
->Dimension
== dim
+ params
.size());
71 Polyhedron
*ctx
= Universe_Polyhedron(params
.size());
73 extract_vars(variableMap
, vv
, exvars
);
74 extract_params(variableMap
, params
, exparams
);
76 PP
= Polyhedron2Param_Polyhedron(D
, ctx
, options
);
77 piecewise_lst
*pl
= new piecewise_lst(exparams
);
78 for (Param_Domain
*Q
= PP
->D
; Q
; Q
= Q
->next
) {
79 GiNaC::matrix VM
= domainVertices(PP
, Q
, exparams
);
80 lst coeffs
= bernsteinExpansion(VM
, polyfunc
->poly
, exvars
, exparams
);
81 pl
->list
.push_back(guarded_lst(Polyhedron_Copy(Q
->Domain
), coeffs
));
83 cout
<< "coefficients: " << *pl
<< endl
;
85 cout
<< "maximum: " << *pl
<< endl
;
87 Param_Polyhedron_Free(PP
);
91 barvinok_options_free(options
);
94 evalue
*summate(PolyFunc
*polyfunc
, Map
<Variable_Ref
*, GiNaC::ex
>& variableMap
)
100 struct barvinok_options
*options
= barvinok_options_new_with_defaults();
102 cout
<< "sum " << polyfunc
->poly
<< " over ";
103 polyfunc
->domain
.simplify();
104 polyfunc
->domain
.print(stdout
);
106 Polyhedron
*D
= relation2Domain(polyfunc
->domain
, vv
, params
,
109 assert(polyfunc
->domain
.is_set());
110 int dim
= polyfunc
->domain
.n_set();
111 assert(D
->Dimension
== dim
+ params
.size());
113 extract_vars(variableMap
, vv
, exvars
);
114 extract_params(variableMap
, params
, exparams
);
115 for (int i
= 0; i
< exparams
.size(); ++i
)
116 exvars
.push_back(exparams
[i
]);
118 evalue
*e
= ALLOC(evalue
);
120 value_set_si(e
->d
, 0);
121 e
->x
.p
= new_enode(::partition
, 2, D
->Dimension
);
122 EVALUE_SET_DOMAIN(e
->x
.p
->arr
[0], D
);
123 value_clear(e
->x
.p
->arr
[1].d
);
124 e
->x
.p
->arr
[1] = *ex2evalue(polyfunc
->poly
, exvars
);
126 evalue
*sum
= barvinok_summate(e
, dim
, options
);
129 barvinok_options_free(options
);