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 
8 namespace faudes{
9 
10 /** user data type for polyhedra */
11 class pdata_t : public Type {
12 public:
13  Parma_Polyhedra_Library::C_Polyhedron mPPLpoly;
14  bool mChanged;
15 };
16 
17 
18 /**
19 convert a faudes style polyhedron "A x <= B" to a PPL polyhedron,
20 and keep the conversion result in the UserData entry
21 */
22 Parma_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 /**
49 convert PPL polyhedron back to faudes data structures;
50 this is required if we manipulate a polyhedron and like
51 to access it from libFAUDES
52 */
53 void 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) */
110 class rdata_t : public Type {
111 public:
112  Parma_Polyhedra_Library::C_Polyhedron mPPLrelation;
113 };
114 
115 /**
116 convert a faudes style linear relation "A' x' + A x <= B" to a PPL polyhedron,
117 and keep the conversion result in the UserData entry
118 */
119 Parma_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 */
154 void 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 */
162 void PolyCopy(const Polyhedron& src, Polyhedron& dst) {
163  // copy faudes data
164  dst.Assign(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 */
176 void 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 */
186 bool PolyIsEmpty(const Polyhedron& poly) {
187  Parma_Polyhedra_Library::C_Polyhedron& ppoly=UserData(poly);
188  return ppoly.is_empty();
189 }
190 
191 /** inclusion */
192 bool 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 */
199 void 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 */
228 void PolyLinearRelation(const LinearRelation& reset, Polyhedron& poly) {
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 */
251 void 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)
Debug: always report warnings.
Faudes exception class.
Linear relation on R^n.
const Vector & B(void) const
Get B vector.
Idx Size(void) const
Get size.
const Matrix & A2(void) const
Get A2 matrix.
bool Identity(void) const
Test for data format.
int Dimension(void) const
Get dimension.
void UserData(Type *data) const
Set user data.
const Matrix & A1(void) const
Get A1 matrix.
Matrix of scalars.
Definition: hyb_parameter.h:64
const Scalar::Type & At(int i, int j) const
Get entry.
Polyhedron in R^n.
Idx Size(void) const
Get size.
void UserData(Type *data) const
Set user data.
const Matrix & A(void) const
Get A matrix.
int Dimension(void) const
Get dimension.
const Vector & B(void) const
Get B vector.
Base class of all libFAUDES objects that participate in the run-time interface.
Definition: cfl_types.h:239
virtual Type & Assign(const Type &rSrc)
Assign configuration data from other object.
Definition: cfl_types.cpp:77
Vector of scalars.
const Scalar::Type & At(int i) const
Get entry.
user data type for polyhedra
Definition: hyb_compute.cpp:11
Parma_Polyhedra_Library::C_Polyhedron mPPLpoly
Definition: hyb_compute.cpp:13
user data type for reset relation (fake faudes type)
Parma_Polyhedra_Library::C_Polyhedron mPPLrelation
void PolyFinalise(const Polyhedron &fpoly)
convert PPL polyhedron back to faudes data structures; this is required if we manipulate a polyhedron...
Definition: hyb_compute.cpp:53
bool PolyInclusion(const Polyhedron &poly, const Polyhedron &other)
inclusion
void PolyTimeElapse(const Polyhedron &rate, Polyhedron &poly)
time elapse
void PolyDWrite(const Polyhedron &fpoly)
poly dump
void PolyCopy(const Polyhedron &src, Polyhedron &dst)
copy method
void PolyIntersection(const Polyhedron &poly, Polyhedron &res)
intersection
bool PolyIsEmpty(const Polyhedron &poly)
test emptyness
void PolyLinearRelation(const LinearRelation &reset, Polyhedron &poly)
apply reset relation A'x' + Ax <= B
libFAUDES resides within the namespace faudes.
uint32_t Idx
Type definition for index type (allways 32bit)
Parma_Polyhedra_Library::C_Polyhedron & UserData(const Polyhedron &fpoly)
convert a faudes style polyhedron "A x <= B" to a PPL polyhedron, and keep the conversion result in t...
Definition: hyb_compute.cpp:22
void PolyScratch(void)
scratch

libFAUDES 2.32b --- 2024.03.01 --- c++ api documentaion by doxygen