4 #include <bernstein/bernstein.h>
5 #include <bernstein/maximize.h>
6 #include <bernstein/piecewise_lst.h>
11 using namespace GiNaC
;
15 static void print_lst(std::ostream
& os
, int sign
, lst l
)
17 for (int i
= 1; i
< l
.nops(); ++i
) {
24 l
.op(0).print(print_csrc(os
), 0);
25 for (int i
= 1; i
< l
.nops(); ++i
) {
27 l
.op(i
).print(print_csrc(os
), 0);
33 static void printpoly(std::ostream
& o
, Polyhedron
*D
, const exvector
& p
)
35 for (int i
= 0; i
< D
->NbConstraints
; ++i
) {
39 for (int j
= 0; j
< D
->Dimension
; ++j
) {
40 if (value_zero_p(D
->Constraint
[i
][1+j
]))
44 o
<< VALUE_TO_INT(D
->Constraint
[i
][1+j
]) << "*" << p
[j
];
47 if (value_notzero_p(D
->Constraint
[i
][1+D
->Dimension
])) {
50 o
<< VALUE_TO_INT(D
->Constraint
[i
][1+D
->Dimension
]);
52 if (value_zero_p(D
->Constraint
[i
][0]))
59 static void printdomain(std::ostream
& o
, Polyhedron
*D
, const exvector
& p
)
63 else for (Polyhedron
*P
= D
; P
; P
= P
->next
) {
72 std::ostream
& operator<< (std::ostream
& os
, const piecewise_lst
& pl
)
74 if (pl
.list
.size() == 1 && universeQ(pl
.list
[0].first
))
75 print_lst(os
, pl
.sign
, pl
.list
[0].second
);
77 for (int i
= 0; i
< pl
.list
.size(); ++i
) {
79 printdomain(os
, pl
.list
[i
].first
, pl
.vars
);
81 print_lst(os
, pl
.sign
, pl
.list
[i
].second
);
89 static std::vector
<guarded_lst
> combine(const std::vector
<guarded_lst
>& one
,
90 const std::vector
<guarded_lst
>& other
,
91 const GiNaC::exvector
& vars
, int sign
)
94 std::vector
<guarded_lst
> newlist
;
95 for (int j
= 0; j
< other
.size(); ++j
) {
96 assert(one
.size() >= 1);
97 fd
= DomainDifference(other
[j
].first
, one
[0].first
, 0);
99 for (int i
= 1; i
< one
.size(); ++i
) {
101 fd
= DomainDifference(fd
, one
[i
].first
, 0);
110 newlist
.push_back(guarded_lst(fd
, other
[j
].second
));
112 for (int i
= 0; i
< one
.size(); ++i
) {
114 for (int j
= 0; j
< other
.size(); ++j
) {
116 d
= DomainIntersection(other
[j
].first
, one
[i
].first
, 0);
122 fd
= DomainDifference(fd
, other
[j
].first
, 0);
123 if (t
!= one
[i
].first
)
125 lst list
= remove_redundants(d
, one
[i
].second
, other
[j
].second
,
127 newlist
.push_back(guarded_lst(d
, list
));
130 newlist
.push_back(guarded_lst(fd
, one
[i
].second
));
133 if (fd
!= one
[i
].first
)
134 Domain_Free(one
[i
].first
);
141 ostream
& operator<< (ostream
& os
, const exvector
& v
)
144 for (int i
= 0; i
< v
.size(); ++i
) {
153 void piecewise_lst::add_guarded_lst(Polyhedron
*D
, GiNaC::lst coeffs
)
155 coeffs
= remove_redundants(D
, coeffs
, coeffs
, vars
, sign
);
156 assert(coeffs
.nops() > 0);
157 list
.push_back(guarded_lst(D
, coeffs
));
160 piecewise_lst
& piecewise_lst::combine(const piecewise_lst
& other
)
162 assert(vars
== other
.vars
);
163 assert(sign
== other
.sign
);
164 list
= bernstein::combine(list
, other
.list
, vars
, sign
);
169 void piecewise_lst::maximize()
172 for (int i
= 0; i
< list
.size(); ++i
) {
173 list
[i
].second
= bernstein::maximize(list
[i
].first
, list
[i
].second
, vars
);
177 void piecewise_lst::minimize()
180 for (int i
= 0; i
< list
.size(); ++i
) {
181 list
[i
].second
= bernstein::minimize(list
[i
].first
, list
[i
].second
, vars
);
185 void piecewise_lst::simplify_domains(Polyhedron
*ctx
, unsigned MaxRays
)
187 for (int i
= 0; i
< list
.size(); ++i
) {
188 Polyhedron
*D
= list
[i
].first
;
189 list
[i
].first
= DomainSimplify(D
, ctx
, MaxRays
);
194 numeric
piecewise_lst::evaluate(const exvector
& values
)
196 Value
*v
= new Value
[values
.size()];
199 for (int i
= 0; i
< values
.size(); ++i
) {
201 assert(is_a
<numeric
>(values
[i
]));
202 numeric2value(ex_to
<numeric
>(values
[i
]), v
[i
]);
204 result
= evaluate(values
, values
.size(), v
);
205 for (int i
= 0; i
< values
.size(); ++i
)
211 void piecewise_lst::evaluate(int n
, Value
*v
, Value
*num
, Value
*den
)
215 for (int i
= 0; i
< values
.size(); ++i
)
216 values
[i
] = value2numeric(v
[i
]);
217 result
= evaluate(values
, values
.size(), v
);
218 numeric2value(result
.numer(), *num
);
219 numeric2value(result
.denom(), *den
);
222 numeric
piecewise_lst::evaluate(const exvector
& values
, int n
, Value
*v
)
226 for (int i
= 0; i
< list
.size(); ++i
) {
227 if (!in_domain(list
[i
].first
, v
))
230 for (int j
= 0; j
< n
; ++j
)
231 m
[vars
[j
]] = values
[j
];
232 ex ex_val
= list
[i
].second
.subs(m
);
233 assert(is_a
<lst
>(ex_val
));
234 lst val
= ex_to
<lst
>(ex_val
);;
236 for (int j
= 1; j
< val
.nops(); ++j
) {
238 if (sign
> 0 && val
.op(j
) > opt
)
240 if (sign
< 0 && val
.op(j
) < opt
)
243 assert(is_a
<numeric
>(opt
));
244 result
= ex_to
<numeric
>(opt
);
250 void piecewise_lst::add(const GiNaC::ex
& poly
)
252 for (int i
= 0; i
< list
.size(); ++i
) {
253 lst::const_iterator j
;
255 for (j
= list
[i
].second
.begin(); j
!= list
[i
].second
.end(); ++j
)
256 new_coeff
.append(*j
+ poly
);
257 list
[i
].second
= new_coeff
;
261 int piecewise_lst::is_equal(const piecewise_lst
& other
) const
263 if (list
.size() != other
.list
.size())
266 for (int i
= 0; i
< list
.size(); ++i
) {
269 for (j
= 0; j
< other
.list
.size(); ++j
) {
270 if (!PolyhedronIncludes(list
[i
].first
, other
.list
[j
].first
))
272 if (!PolyhedronIncludes(other
.list
[j
].first
, list
[i
].first
))
276 if (j
>= other
.list
.size())
279 l2
= other
.list
[j
].second
;
282 if (!l1
.is_equal(l2
))