00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <ppl-config.h>
00026
00027 #include "Linear_Expression.defs.hh"
00028 #include "Constraint.defs.hh"
00029 #include "Generator.defs.hh"
00030 #include "Grid_Generator.defs.hh"
00031 #include "Congruence.defs.hh"
00032 #include <stdexcept>
00033 #include <iostream>
00034
00035 namespace PPL = Parma_Polyhedra_Library;
00036
00037 PPL::Linear_Expression::Linear_Expression(const Constraint& c)
00038 : Linear_Row(c.space_dimension() + 1, Linear_Row::Flags()) {
00039 Linear_Expression& e = *this;
00040 for (dimension_type i = size(); i-- > 0; )
00041 e[i] = c[i];
00042 }
00043
00044 PPL::Linear_Expression::Linear_Expression(const Generator& g)
00045 : Linear_Row(g.space_dimension() + 1, Linear_Row::Flags()) {
00046 Linear_Expression& e = *this;
00047
00048 for (dimension_type i = size(); --i > 0; )
00049 e[i] = g[i];
00050 }
00051
00052 PPL::Linear_Expression::Linear_Expression(const Grid_Generator& g)
00053 : Linear_Row(g.space_dimension() + 1, Linear_Row::Flags()) {
00054 Linear_Expression& e = *this;
00055
00056 for (dimension_type i = size(); --i > 0; )
00057 e[i] = g[i];
00058 }
00059
00060 const PPL::Linear_Expression* PPL::Linear_Expression::zero_p = 0;
00061
00062 void
00063 PPL::Linear_Expression::initialize() {
00064 PPL_ASSERT(zero_p == 0);
00065 zero_p = new Linear_Expression(Coefficient_zero());
00066 }
00067
00068 void
00069 PPL::Linear_Expression::finalize() {
00070 PPL_ASSERT(zero_p != 0);
00071 delete zero_p;
00072 zero_p = 0;
00073 }
00074
00075 PPL::Linear_Expression::Linear_Expression(const Congruence& cg)
00076 : Linear_Row(cg.space_dimension() + 1, Linear_Row::Flags()) {
00077 Linear_Expression& e = *this;
00078 for (dimension_type i = size(); i-- > 0; )
00079 e[i] = cg[i];
00080 }
00081
00082 PPL::Linear_Expression::Linear_Expression(const Variable v)
00083 : Linear_Row(v.space_dimension() <= max_space_dimension()
00084 ? v.space_dimension() + 1
00085 : (throw std::length_error("PPL::Linear_Expression::"
00086 "Linear_Expression(v):\n"
00087 "v exceeds the maximum allowed "
00088 "space dimension."),
00089 v.space_dimension() + 1)
00090 , Linear_Row::Flags()) {
00091 ++((*this)[v.space_dimension()]);
00092 }
00093
00094 PPL::Linear_Expression::Linear_Expression(const Variable v, const Variable w)
00095 : Linear_Row() {
00096 const dimension_type v_space_dim = v.space_dimension();
00097 const dimension_type w_space_dim = w.space_dimension();
00098 const dimension_type space_dim = std::max(v_space_dim, w_space_dim);
00099 if (space_dim > max_space_dimension())
00100 throw std::length_error("PPL::Linear_Expression::"
00101 "Linear_Expression(v, w):\n"
00102 "v or w exceed the maximum allowed "
00103 "space dimension.");
00104 construct(space_dim+1, Linear_Row::Flags());
00105 if (v_space_dim != w_space_dim) {
00106 ++((*this)[v_space_dim]);
00107 --((*this)[w_space_dim]);
00108 }
00109 }
00110
00112 PPL::Linear_Expression
00113 PPL::operator+(const Linear_Expression& e1, const Linear_Expression& e2) {
00114 dimension_type e1_size = e1.size();
00115 dimension_type e2_size = e2.size();
00116 dimension_type min_size;
00117 dimension_type max_size;
00118 const Linear_Expression* p_e_max;
00119 if (e1_size > e2_size) {
00120 min_size = e2_size;
00121 max_size = e1_size;
00122 p_e_max = &e1;
00123 }
00124 else {
00125 min_size = e1_size;
00126 max_size = e2_size;
00127 p_e_max = &e2;
00128 }
00129
00130 Linear_Expression r(max_size, false);
00131 dimension_type i = max_size;
00132 while (i > min_size) {
00133 --i;
00134 r[i] = (*p_e_max)[i];
00135 }
00136 while (i > 0) {
00137 --i;
00138 r[i] = e1[i] + e2[i];
00139 }
00140
00141 return r;
00142 }
00143
00145 PPL::Linear_Expression
00146 PPL::operator+(const Variable v, const Linear_Expression& e) {
00147 const dimension_type v_space_dim = v.space_dimension();
00148 if (v_space_dim > Linear_Expression::max_space_dimension())
00149 throw std::length_error("Linear_Expression "
00150 "PPL::operator+(v, e):\n"
00151 "v exceeds the maximum allowed "
00152 "space dimension.");
00153 const dimension_type space_dim = std::max(v_space_dim, e.space_dimension());
00154 Linear_Expression r(e, space_dim+1);
00155 ++r[v_space_dim];
00156 return r;
00157 }
00158
00160 PPL::Linear_Expression
00161 PPL::operator+(Coefficient_traits::const_reference n,
00162 const Linear_Expression& e) {
00163 Linear_Expression r(e);
00164 r[0] += n;
00165 return r;
00166 }
00167
00169 PPL::Linear_Expression
00170 PPL::operator+(const Variable v, const Variable w) {
00171 const dimension_type v_space_dim = v.space_dimension();
00172 const dimension_type w_space_dim = w.space_dimension();
00173 const dimension_type space_dim = std::max(v_space_dim, w_space_dim);
00174 if (space_dim > Linear_Expression::max_space_dimension())
00175 throw std::length_error("Linear_Expression "
00176 "PPL::operator+(v, w):\n"
00177 "v or w exceed the maximum allowed "
00178 "space dimension.");
00179 Linear_Expression r(space_dim+1, true);
00180 ++r[v_space_dim];
00181 ++r[w_space_dim];
00182 return r;
00183 }
00184
00186 PPL::Linear_Expression
00187 PPL::operator-(const Linear_Expression& e) {
00188 Linear_Expression r(e);
00189 for (dimension_type i = e.size(); i-- > 0; )
00190 neg_assign(r[i]);
00191 return r;
00192 }
00193
00195 PPL::Linear_Expression
00196 PPL::operator-(const Linear_Expression& e1, const Linear_Expression& e2) {
00197 dimension_type e1_size = e1.size();
00198 dimension_type e2_size = e2.size();
00199 if (e1_size > e2_size) {
00200 Linear_Expression r(e1_size, false);
00201 dimension_type i = e1_size;
00202 while (i > e2_size) {
00203 --i;
00204 r[i] = e1[i];
00205 }
00206 while (i > 0) {
00207 --i;
00208 r[i] = e1[i] - e2[i];
00209 }
00210 return r;
00211 }
00212 else {
00213 Linear_Expression r(e2_size, false);
00214 dimension_type i = e2_size;
00215 while (i > e1_size) {
00216 --i;
00217 r[i] = -e2[i];
00218 }
00219 while (i > 0) {
00220 --i;
00221 r[i] = e1[i] - e2[i];
00222 }
00223 return r;
00224 }
00225 }
00226
00228 PPL::Linear_Expression
00229 PPL::operator-(const Variable v, const Linear_Expression& e) {
00230 const dimension_type v_space_dim = v.space_dimension();
00231 if (v_space_dim > Linear_Expression::max_space_dimension())
00232 throw std::length_error("Linear_Expression "
00233 "PPL::operator-(v, e):\n"
00234 "v exceeds the maximum allowed "
00235 "space dimension.");
00236 const dimension_type e_space_dim = e.space_dimension();
00237 const dimension_type space_dim = std::max(v_space_dim, e_space_dim);
00238 Linear_Expression r(e, space_dim+1);
00239 for (dimension_type i = e.size(); i-- > 0; )
00240 neg_assign(r[i]);
00241 ++r[v_space_dim];
00242 return r;
00243 }
00244
00246 PPL::Linear_Expression
00247 PPL::operator-(const Linear_Expression& e, const Variable v) {
00248 const dimension_type v_space_dim = v.space_dimension();
00249 if (v_space_dim > Linear_Expression::max_space_dimension())
00250 throw std::length_error("Linear_Expression "
00251 "PPL::operator-(e, v):\n"
00252 "v exceeds the maximum allowed "
00253 "space dimension.");
00254 const dimension_type space_dim = std::max(v_space_dim, e.space_dimension());
00255 Linear_Expression r(e, space_dim+1);
00256 --r[v_space_dim];
00257 return r;
00258 }
00259
00261 PPL::Linear_Expression
00262 PPL::operator-(Coefficient_traits::const_reference n,
00263 const Linear_Expression& e) {
00264 Linear_Expression r(e);
00265 for (dimension_type i = e.size(); i-- > 0; )
00266 neg_assign(r[i]);
00267 r[0] += n;
00268 return r;
00269 }
00270
00272 PPL::Linear_Expression
00273 PPL::operator*(Coefficient_traits::const_reference n,
00274 const Linear_Expression& e) {
00275 Linear_Expression r(e);
00276 for (dimension_type i = e.size(); i-- > 0; )
00277 r[i] *= n;
00278 return r;
00279 }
00280
00282 PPL::Linear_Expression&
00283 PPL::operator+=(Linear_Expression& e1, const Linear_Expression& e2) {
00284 dimension_type e1_size = e1.size();
00285 dimension_type e2_size = e2.size();
00286 if (e1_size >= e2_size)
00287 for (dimension_type i = e2_size; i-- > 0; )
00288 e1[i] += e2[i];
00289 else {
00290 Linear_Expression new_e(e2);
00291 for (dimension_type i = e1_size; i-- > 0; )
00292 new_e[i] += e1[i];
00293 e1.swap(new_e);
00294 }
00295 return e1;
00296 }
00297
00299 PPL::Linear_Expression&
00300 PPL::operator+=(Linear_Expression& e, const Variable v) {
00301 const dimension_type v_space_dim = v.space_dimension();
00302 if (v_space_dim > Linear_Expression::max_space_dimension())
00303 throw std::length_error("Linear_Expression& "
00304 "PPL::operator+=(e, v):\n"
00305 "v exceeds the maximum allowed space dimension.");
00306 const dimension_type e_size = e.size();
00307 if (e_size <= v_space_dim) {
00308 Linear_Expression new_e(e, v_space_dim+1);
00309 e.swap(new_e);
00310 }
00311 ++e[v_space_dim];
00312 return e;
00313 }
00314
00316 PPL::Linear_Expression&
00317 PPL::operator-=(Linear_Expression& e1, const Linear_Expression& e2) {
00318 dimension_type e1_size = e1.size();
00319 dimension_type e2_size = e2.size();
00320 if (e1_size >= e2_size)
00321 for (dimension_type i = e2_size; i-- > 0; )
00322 e1[i] -= e2[i];
00323 else {
00324 Linear_Expression new_e(e1, e2_size);
00325 for (dimension_type i = e2_size; i-- > 0; )
00326 new_e[i] -= e2[i];
00327 e1.swap(new_e);
00328 }
00329 return e1;
00330 }
00331
00333 PPL::Linear_Expression&
00334 PPL::operator-=(Linear_Expression& e, const Variable v) {
00335 const dimension_type v_space_dim = v.space_dimension();
00336 if (v_space_dim > Linear_Expression::max_space_dimension())
00337 throw std::length_error("Linear_Expression& "
00338 "PPL::operator-=(e, v):\n"
00339 "v exceeds the maximum allowed space dimension.");
00340 const dimension_type e_size = e.size();
00341 if (e_size <= v_space_dim) {
00342 Linear_Expression new_e(e, v_space_dim+1);
00343 e.swap(new_e);
00344 }
00345 --e[v_space_dim];
00346 return e;
00347 }
00348
00350 PPL::Linear_Expression&
00351 PPL::operator*=(Linear_Expression& e, Coefficient_traits::const_reference n) {
00352 dimension_type e_size = e.size();
00353 for (dimension_type i = e_size; i-- > 0; )
00354 e[i] *= n;
00355 return e;
00356 }
00357
00359 PPL::Linear_Expression&
00360 PPL::add_mul_assign(Linear_Expression& e,
00361 Coefficient_traits::const_reference n,
00362 const Variable v) {
00363 const dimension_type v_space_dim = v.space_dimension();
00364 if (v_space_dim > Linear_Expression::max_space_dimension())
00365 throw std::length_error("Linear_Expression& "
00366 "PPL::add_mul_assign(e, n, v):\n"
00367 "v exceeds the maximum allowed space dimension.");
00368 const dimension_type e_size = e.size();
00369 if (e_size <= v_space_dim) {
00370 Linear_Expression new_e(e, v_space_dim+1);
00371 e.swap(new_e);
00372 }
00373 e[v_space_dim] += n;
00374 return e;
00375 }
00376
00378 PPL::Linear_Expression&
00379 PPL::sub_mul_assign(Linear_Expression& e,
00380 Coefficient_traits::const_reference n,
00381 const Variable v) {
00382 const dimension_type v_space_dim = v.space_dimension();
00383 if (v_space_dim > Linear_Expression::max_space_dimension())
00384 throw std::length_error("Linear_Expression& "
00385 "PPL::sub_mul_assign(e, n, v):\n"
00386 "v exceeds the maximum allowed space dimension.");
00387 const dimension_type e_size = e.size();
00388 if (e_size <= v_space_dim) {
00389 Linear_Expression new_e(e, v_space_dim+1);
00390 e.swap(new_e);
00391 }
00392 e[v_space_dim] -= n;
00393 return e;
00394 }
00395
00396 bool
00397 PPL::Linear_Expression::OK() const {
00398 return Linear_Row::OK();
00399 }
00400
00402 std::ostream&
00403 PPL::IO_Operators::operator<<(std::ostream& s, const Linear_Expression& e) {
00404 const dimension_type num_variables = e.space_dimension();
00405 PPL_DIRTY_TEMP_COEFFICIENT(ev);
00406 bool first = true;
00407 for (dimension_type v = 0; v < num_variables; ++v) {
00408 ev = e[v+1];
00409 if (ev != 0) {
00410 if (!first) {
00411 if (ev > 0)
00412 s << " + ";
00413 else {
00414 s << " - ";
00415 neg_assign(ev);
00416 }
00417 }
00418 else
00419 first = false;
00420 if (ev == -1)
00421 s << "-";
00422 else if (ev != 1)
00423 s << ev << "*";
00424 s << PPL::Variable(v);
00425 }
00426 }
00427
00428 PPL_DIRTY_TEMP_COEFFICIENT(it);
00429 it = e[0];
00430 if (it != 0) {
00431 if (!first) {
00432 if (it > 0)
00433 s << " + ";
00434 else {
00435 s << " - ";
00436 neg_assign(it);
00437 }
00438 }
00439 else
00440 first = false;
00441 s << it;
00442 }
00443
00444 if (first)
00445
00446 s << Coefficient_zero();
00447 return s;
00448 }
00449
00450 PPL_OUTPUT_DEFINITIONS(Linear_Expression)