hyb_compute.cpp
Go to the documentation of this file.
1/** @file hyb_compute.cpp Polyhedron caluculs via PPL */
2
3#include "hyb_compute.h"
4#include <ppl.hh>
5
6
7
8namespace faudes{
9
10/** user data type for polyhedra */
11class pdata_t : public Type {
12public:
13 Parma_Polyhedra_Library::C_Polyhedron mPPLpoly;
15};
16
17
18/**
19convert a faudes style polyhedron "A x <= B" to a PPL polyhedron,
20and keep the conversion result in the UserData entry
21*/
22Parma_Polyhedra_Library::C_Polyhedron& UserData(const Polyhedron& fpoly) {
23 pdata_t* pdata= dynamic_cast<pdata_t*>(fpoly.UserData());
24 if(!pdata) {
25 pdata = new pdata_t();
26 Parma_Polyhedra_Library::C_Polyhedron& ppoly = pdata->mPPLpoly;
27 ppoly.add_space_dimensions_and_embed(fpoly.Dimension());
28 for(Idx i = 0; i < fpoly.Size(); i++) {
29 Parma_Polyhedra_Library::Linear_Expression e;
30 for(int j = 0; j < fpoly.Dimension(); j++) {
31 Parma_Polyhedra_Library::Variable xj(j);
32 e += fpoly.A().At(i,j) * xj;
33 }
34 ppoly.add_constraint(e <= fpoly.B().At(i));
35 }
36 pdata->mChanged=false;
37 fpoly.UserData(pdata);
38 pdata= dynamic_cast<pdata_t*>(fpoly.UserData());
39 }
40 if(!pdata) {
41 std::stringstream errstr;
42 errstr << "Internal Computaional Error (Convert to PPL).";
43 throw Exception("UserData", errstr.str(), 700);
44 }
45 return pdata->mPPLpoly;
46}
47
48/**
49convert PPL polyhedron back to faudes data structures;
50this is required if we manipulate a polyhedron and like
51to access it from libFAUDES
52*/
53void PolyFinalise(const Polyhedron& fpoly){
54 // nothing to do if no user data
55 if(fpoly.UserData()==NULL) return;
56 // get user data
57 Parma_Polyhedra_Library::C_Polyhedron& ppoly=UserData(fpoly);
58 Parma_Polyhedra_Library::Constraint_System consys=ppoly.minimized_constraints();
59 // sanity check
60 if(fpoly.Dimension()!=0)
61 if(ppoly.space_dimension()!= ((unsigned int) fpoly.Dimension())) {
62 std::stringstream errstr;
63 errstr << "Internal Computaional Error (Conversion from PPL, dimension mismatch).";
64 throw Exception("PolyFinalise", errstr.str(), 700);
65 }
66 /*
67 if(consys.has_equalities()){
68 std::stringstream errstr;
69 errstr << "Internal Computaional Error (Conversion from PPL, cannot hanlde equalities).";
70 throw Exception("PolyFinalise", errstr.str(), 700);
71 }
72 */
73 if(consys.has_strict_inequalities()){
74 std::stringstream errstr;
75 errstr << "Internal Computaional Error (Conversion from PPL, cannot hanlde strict inequalities).";
76 throw Exception("PolyFinalise", errstr.str(), 700);
77 }
78 // extract constraints parameters
79 Parma_Polyhedra_Library::Constraint_System::const_iterator cit = consys.begin();
80 Parma_Polyhedra_Library::Constraint_System::const_iterator cit_end = consys.end();
81 int count=0;
82 for(;cit!=cit_end;++cit) { ++count; if(cit->is_equality()) ++count; }
83 Matrix A(count,ppoly.space_dimension());
84 Vector B(count);
85 int i=0;
86 for(cit = consys.begin();cit!=cit_end;++cit) {
87 if(cit->is_nonstrict_inequality()) {
88 for(unsigned int j = 0; j < ppoly.space_dimension(); j++) {
89 Parma_Polyhedra_Library::Variable xj(j);
90 A.At(i,j,-1* cit->coefficient(xj).get_d());
91 }
92 B.At(i,cit->inhomogeneous_term().get_d());
93 ++i;
94 }
95 if(cit->is_equality()) {
96 for(unsigned int j = 0; j < ppoly.space_dimension(); j++) {
97 Parma_Polyhedra_Library::Variable xj(j);
98 A.At(i,j,-1*cit->coefficient(xj).get_d());
99 A.At(i+1,j,cit->coefficient(xj).get_d());
100 }
101 B.At(i,cit->inhomogeneous_term().get_d());
102 B.At(i+1,-1* cit->inhomogeneous_term().get_d());
103 i+=2;
104 }
105 }
106 const_cast<Polyhedron&>(fpoly).AB(A,B);
107}
108
109/** user data type for reset relation (fake faudes type) */
110class rdata_t : public Type {
111public:
112 Parma_Polyhedra_Library::C_Polyhedron mPPLrelation;
113};
114
115/**
116convert a faudes style linear relation "A' x' + A x <= B" to a PPL polyhedron,
117and keep the conversion result in the UserData entry
118*/
119Parma_Polyhedra_Library::C_Polyhedron& UserData(const LinearRelation& frelation) {
120 rdata_t* rdata= dynamic_cast<rdata_t*>(frelation.UserData());
121 if(!rdata) {
122 int dim=frelation.Dimension();
123 rdata = new rdata_t();
124 Parma_Polyhedra_Library::C_Polyhedron& prelation = rdata->mPPLrelation;
125 prelation.add_space_dimensions_and_embed(2*dim);
126 for(Idx i = 0; i < frelation.Size(); i++) {
127 Parma_Polyhedra_Library::Linear_Expression e;
128 for(int j = 0; j < dim; j++) {
129 Parma_Polyhedra_Library::Variable xj(j);
130 e += frelation.A1().At(i,j) * xj;
131 }
132 for(int j = 0; j < dim; j++) {
133 Parma_Polyhedra_Library::Variable xjprime(dim+j);
134 e += frelation.A2().At(i,j) * xjprime;
135 }
136 prelation.add_constraint(e <= frelation.B().At(i));
137 }
138 frelation.UserData(rdata);
139 rdata= dynamic_cast<rdata_t*>(frelation.UserData());
140 }
141 if(!rdata) {
142 std::stringstream errstr;
143 errstr << "Internal Computaional Error (Convert to PPL).";
144 throw Exception("UserData", errstr.str(), 700);
145 }
146 return rdata->mPPLrelation;
147}
148
149
150
151
152
153/** poly dump */
154void PolyDWrite(const Polyhedron& fpoly){
155 Parma_Polyhedra_Library::C_Polyhedron& ppoly=UserData(fpoly);
156 Parma_Polyhedra_Library::Generator_System gensys = ppoly.minimized_generators();
157 gensys.ascii_dump();
158}
159
160
161/** copy method */
162void PolyCopy(const Polyhedron& src, Polyhedron& dst) {
163 // copy faudes data
164 dst.Copy(src);
165 // bail out if there is no user data
166 pdata_t* spdata= dynamic_cast<pdata_t*>(src.UserData());
167 if(!spdata) return;
168 // copy user data
169 pdata_t* dpdata = new pdata_t();
170 dpdata->mChanged=spdata->mChanged;
171 dpdata->mPPLpoly=spdata->mPPLpoly;
172 dst.UserData(dpdata);
173}
174
175/** intersection */
176void PolyIntersection(const Polyhedron& poly, Polyhedron& res) {
177 Parma_Polyhedra_Library::C_Polyhedron& ppoly=UserData(poly);
178 Parma_Polyhedra_Library::C_Polyhedron& pres=UserData(res);
179 pres.intersection_assign(ppoly);
180 dynamic_cast<pdata_t*>(res.UserData())->mChanged=true;
181}
182
183
184
185/** test emptyness */
186bool PolyIsEmpty(const Polyhedron& poly) {
187 Parma_Polyhedra_Library::C_Polyhedron& ppoly=UserData(poly);
188 return ppoly.is_empty();
189}
190
191/** inclusion */
192bool PolyInclusion(const Polyhedron& poly, const Polyhedron& other) {
193 Parma_Polyhedra_Library::C_Polyhedron& ppoly=UserData(poly);
194 Parma_Polyhedra_Library::C_Polyhedron& opoly=UserData(other);
195 return opoly.contains(ppoly);
196}
197
198/** scratch */
199void PolyScratch(void) {
200 // diamond wint center (0,1)
201 FD_WARN("setting up diamond");
202 Parma_Polyhedra_Library::C_Polyhedron ppoly(2);
203 Parma_Polyhedra_Library::Variable x1(0);
204 Parma_Polyhedra_Library::Variable x2(1);
205 ppoly.add_constraint(x2 <= x1 + 2);
206 ppoly.add_constraint(x2 >= x1 );
207 ppoly.add_constraint(x2 <= -x1 + 2);
208 ppoly.add_constraint(x2 >= -x1 );
209 Parma_Polyhedra_Library::Generator_System gensys = ppoly.minimized_generators();
210 gensys.ascii_dump();
211 // encode reset bloat
212 Parma_Polyhedra_Library::C_Polyhedron preset = ppoly;
213 preset.add_space_dimensions_and_embed(4);
214 Parma_Polyhedra_Library::Variable z1(2);
215 Parma_Polyhedra_Library::Variable z2(3);
216 preset.add_constraint(z1 - 2*x1 <= 2 +100);
217 preset.add_constraint(-z1 + 2*x1 <= 2 - 100);
218 preset.add_constraint(z2 - 2*x2 <= 2 - 2 );
219 preset.add_constraint(-z2 + 2*x2 <= 2 + 2 );
220 // project to z1/z2
221 preset.remove_space_dimensions(Parma_Polyhedra_Library::Variables_Set(x1,x2));
222 preset.remove_higher_space_dimensions(2);
223 gensys = preset.minimized_generators();
224 gensys.ascii_dump();
225}
226
227/** apply reset relation A'x' + Ax <= B */
229 // bail out on default
230 if(reset.Identity()) return;
231 Parma_Polyhedra_Library::C_Polyhedron& preset=UserData(reset);
232 Parma_Polyhedra_Library::C_Polyhedron& ppoly=UserData(poly);
233 // sanity check
234 unsigned int dim=ppoly.space_dimension();
235 if(preset.space_dimension() != 2 * dim) {
236 std::stringstream errstr;
237 errstr << "Internal Computaional Error (dimension mismatch).";
238 throw Exception("PolyLinearRelation", errstr.str(), 700);
239 }
240 // include reset constraints with polyhedron
241 ppoly.add_space_dimensions_and_embed(dim);
242 ppoly.add_constraints(preset.constraints());
243 // drop original x variables in favour of x'
244 Parma_Polyhedra_Library::Variables_Set xvars;
245 for(unsigned int j=0; j<dim;++j) xvars.insert(Parma_Polyhedra_Library::Variable(j));
246 ppoly.remove_space_dimensions(xvars);
247 ppoly.remove_higher_space_dimensions(dim);
248}
249
250/** time elapse */
251void PolyTimeElapse(const Polyhedron& rate, Polyhedron& poly) {
252 Parma_Polyhedra_Library::C_Polyhedron& prate=UserData(rate);
253 Parma_Polyhedra_Library::C_Polyhedron& ppoly=UserData(poly);
254 if(prate.is_empty()) {
255 //FD_WARN("PolyTimeElapse(...): empty rate");
256 } else {
257 ppoly.time_elapse_assign(prate);
258 }
259 dynamic_cast<pdata_t*>(poly.UserData())->mChanged=true;
260}
261
262
263
264
265}//namespace faudes
#define FD_WARN(message)
const Vector & B(void) const
const Matrix & A2(void) const
bool Identity(void) const
int Dimension(void) const
void UserData(Type *data) const
const Matrix & A1(void) const
const Scalar::Type & At(int i, int j) const
Idx Size(void) const
void UserData(Type *data) const
const Matrix & A(void) const
int Dimension(void) const
const Vector & B(void) const
virtual Type & Copy(const Type &rSrc)
Definition cfl_types.cpp:82
const Scalar::Type & At(int i) const
Parma_Polyhedra_Library::C_Polyhedron mPPLpoly
Parma_Polyhedra_Library::C_Polyhedron mPPLrelation
void PolyFinalise(const Polyhedron &fpoly)
bool PolyInclusion(const Polyhedron &poly, const Polyhedron &other)
void PolyTimeElapse(const Polyhedron &rate, Polyhedron &poly)
void PolyDWrite(const Polyhedron &fpoly)
void PolyCopy(const Polyhedron &src, Polyhedron &dst)
void PolyIntersection(const Polyhedron &poly, Polyhedron &res)
bool PolyIsEmpty(const Polyhedron &poly)
void PolyLinearRelation(const LinearRelation &reset, Polyhedron &poly)
uint32_t Idx
Parma_Polyhedra_Library::C_Polyhedron & UserData(const Polyhedron &fpoly)
void PolyScratch(void)

libFAUDES 2.34d --- 2026.03.11 --- c++ api documentaion by doxygen