00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef PPL_Generator_inlines_hh
00024 #define PPL_Generator_inlines_hh 1
00025
00026 namespace Parma_Polyhedra_Library {
00027
00028 inline
00029 Generator::Generator(Linear_Expression& e, Type type, Topology topology) {
00030 assert(type != CLOSURE_POINT || topology == NOT_NECESSARILY_CLOSED);
00031 Linear_Row::swap(e);
00032 flags() = Flags(topology, (type == LINE
00033 ? LINE_OR_EQUALITY
00034 : RAY_OR_POINT_OR_INEQUALITY));
00035 }
00036
00037 inline
00038 Generator::Generator(const Generator& g)
00039 : Linear_Row(g) {
00040 }
00041
00042 inline
00043 Generator::Generator(const Generator& g, dimension_type dimension)
00044 : Linear_Row(g, dimension, dimension) {
00045 }
00046
00047 inline
00048 Generator::~Generator() {
00049 }
00050
00051 inline Generator&
00052 Generator::operator=(const Generator& g) {
00053 Linear_Row::operator=(g);
00054 return *this;
00055 }
00056
00057 inline dimension_type
00058 Generator::max_space_dimension() {
00059 return Linear_Row::max_space_dimension();
00060 }
00061
00062 inline dimension_type
00063 Generator::space_dimension() const {
00064 return Linear_Row::space_dimension();
00065 }
00066
00067 inline bool
00068 Generator::is_line() const {
00069 return is_line_or_equality();
00070 }
00071
00072 inline bool
00073 Generator::is_ray_or_point() const {
00074 return is_ray_or_point_or_inequality();
00075 }
00076
00077 inline bool
00078 Generator::is_line_or_ray() const {
00079 return (*this)[0] == 0;
00080 }
00081
00082 inline bool
00083 Generator::is_ray() const {
00084 return is_ray_or_point() && is_line_or_ray();
00085 }
00086
00087 inline Generator::Type
00088 Generator::type() const {
00089 if (is_line())
00090 return LINE;
00091 if (is_line_or_ray())
00092 return RAY;
00093 if (is_necessarily_closed())
00094 return POINT;
00095 else {
00096
00097 const Generator& g = *this;
00098 return (g[size() - 1] == 0) ? CLOSURE_POINT : POINT;
00099 }
00100 }
00101
00102 inline bool
00103 Generator::is_point() const {
00104 return type() == POINT;
00105 }
00106
00107 inline bool
00108 Generator::is_closure_point() const {
00109 return type() == CLOSURE_POINT;
00110 }
00111
00112 inline void
00113 Generator::set_is_line() {
00114 set_is_line_or_equality();
00115 }
00116
00117 inline void
00118 Generator::set_is_ray_or_point() {
00119 set_is_ray_or_point_or_inequality();
00120 }
00121
00122 inline Coefficient_traits::const_reference
00123 Generator::coefficient(const Variable v) const {
00124 if (v.space_dimension() > space_dimension())
00125 throw_dimension_incompatible("coefficient(v)", "v", v);
00126 return Linear_Row::coefficient(v.id());
00127 }
00128
00129 inline Coefficient_traits::const_reference
00130 Generator::divisor() const {
00131 Coefficient_traits::const_reference d = Linear_Row::inhomogeneous_term();
00132 if (!is_ray_or_point() || d == 0)
00133 throw_invalid_argument("divisor()",
00134 "*this is neither a point nor a closure point");
00135 return d;
00136 }
00137
00138 inline memory_size_type
00139 Generator::external_memory_in_bytes() const {
00140 return Linear_Row::external_memory_in_bytes();
00141 }
00142
00143 inline memory_size_type
00144 Generator::total_memory_in_bytes() const {
00145 return Linear_Row::total_memory_in_bytes();
00146 }
00147
00148 inline const Generator&
00149 Generator::zero_dim_point() {
00150 assert(zero_dim_point_p != 0);
00151 return *zero_dim_point_p;
00152 }
00153
00154 inline const Generator&
00155 Generator::zero_dim_closure_point() {
00156 assert(zero_dim_closure_point_p != 0);
00157 return *zero_dim_closure_point_p;
00158 }
00159
00161 inline Generator
00162 line(const Linear_Expression& e) {
00163 return Generator::line(e);
00164 }
00165
00167 inline Generator
00168 ray(const Linear_Expression& e) {
00169 return Generator::ray(e);
00170 }
00171
00173 inline Generator
00174 point(const Linear_Expression& e, Coefficient_traits::const_reference d) {
00175 return Generator::point(e, d);
00176 }
00177
00179 inline Generator
00180 closure_point(const Linear_Expression& e,
00181 Coefficient_traits::const_reference d) {
00182 return Generator::closure_point(e, d);
00183 }
00184
00186 inline bool
00187 operator==(const Generator& x, const Generator& y) {
00188 return x.is_equivalent_to(y);
00189 }
00190
00192 inline bool
00193 operator!=(const Generator& x, const Generator& y) {
00194 return !x.is_equivalent_to(y);
00195 }
00196
00197 inline void
00198 Generator::ascii_dump(std::ostream& s) const {
00199 Linear_Row::ascii_dump(s);
00200 }
00201
00202 inline bool
00203 Generator::ascii_load(std::istream& s) {
00204 return Linear_Row::ascii_load(s);
00205 }
00206
00207 inline void
00208 Generator::swap(Generator& y) {
00209 Linear_Row::swap(y);
00210 }
00211
00212 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS
00213
00214 #endif // defined(PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS)
00215 template <typename Specialization, typename Temp, typename To>
00216 inline bool
00217 l_m_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00218 const Generator& x,
00219 const Generator& y,
00220 const Rounding_Dir dir,
00221 Temp& tmp0,
00222 Temp& tmp1,
00223 Temp& tmp2) {
00224
00225
00226 if (x.is_line_or_ray() || y.is_line_or_ray())
00227 return false;
00228 const dimension_type x_space_dim = x.space_dimension();
00229
00230 if (x_space_dim != y.space_dimension())
00231 return false;
00232
00233
00234 if (x_space_dim == 0) {
00235 assign_r(r, 0, ROUND_NOT_NEEDED);
00236 return true;
00237 }
00238
00239 DIRTY_TEMP0(mpq_class, x_coord);
00240 DIRTY_TEMP0(mpq_class, y_coord);
00241 DIRTY_TEMP0(mpq_class, x_div);
00242 DIRTY_TEMP0(mpq_class, y_div);
00243 assign_r(x_div, x.divisor(), ROUND_NOT_NEEDED);
00244 assign_r(y_div, y.divisor(), ROUND_NOT_NEEDED);
00245
00246 assign_r(tmp0, 0, ROUND_NOT_NEEDED);
00247 for (dimension_type i = x_space_dim; i-- > 0; ) {
00248 assign_r(x_coord, x.coefficient(Variable(i)), ROUND_NOT_NEEDED);
00249 div_assign_r(x_coord, x_coord, x_div, ROUND_NOT_NEEDED);
00250 assign_r(y_coord, y.coefficient(Variable(i)), ROUND_NOT_NEEDED);
00251 div_assign_r(y_coord, y_coord, y_div, ROUND_NOT_NEEDED);
00252 const Temp* tmp1p;
00253 const Temp* tmp2p;
00254
00255 if (x_coord > y_coord) {
00256 maybe_assign(tmp1p, tmp1, x_coord, dir);
00257 maybe_assign(tmp2p, tmp2, y_coord, inverse(dir));
00258 }
00259 else {
00260 maybe_assign(tmp1p, tmp1, y_coord, dir);
00261 maybe_assign(tmp2p, tmp2, x_coord, inverse(dir));
00262 }
00263 sub_assign_r(tmp1, *tmp1p, *tmp2p, dir);
00264 assert(sgn(tmp1) >= 0);
00265 Specialization::combine(tmp0, tmp1, dir);
00266 }
00267 Specialization::finalize(tmp0, dir);
00268 assign_r(r, tmp0, dir);
00269 return true;
00270 }
00271
00273 template <typename Temp, typename To>
00274 inline bool
00275 rectilinear_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00276 const Generator& x,
00277 const Generator& y,
00278 const Rounding_Dir dir,
00279 Temp& tmp0,
00280 Temp& tmp1,
00281 Temp& tmp2) {
00282 return l_m_distance_assign<Rectilinear_Distance_Specialization<Temp> >
00283 (r, x, y, dir, tmp0, tmp1, tmp2);
00284 }
00285
00287 template <typename Temp, typename To>
00288 inline bool
00289 rectilinear_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00290 const Generator& x,
00291 const Generator& y,
00292 const Rounding_Dir dir) {
00293 typedef Checked_Number<Temp, Extended_Number_Policy> Checked_Temp;
00294 DIRTY_TEMP(Checked_Temp, tmp0);
00295 DIRTY_TEMP(Checked_Temp, tmp1);
00296 DIRTY_TEMP(Checked_Temp, tmp2);
00297 return rectilinear_distance_assign(r, x, y, dir, tmp0, tmp1, tmp2);
00298 }
00299
00301 template <typename To>
00302 inline bool
00303 rectilinear_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00304 const Generator& x,
00305 const Generator& y,
00306 const Rounding_Dir dir) {
00307 return rectilinear_distance_assign<To, To>(r, x, y, dir);
00308 }
00309
00311 template <typename Temp, typename To>
00312 inline bool
00313 euclidean_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00314 const Generator& x,
00315 const Generator& y,
00316 const Rounding_Dir dir,
00317 Temp& tmp0,
00318 Temp& tmp1,
00319 Temp& tmp2) {
00320 return l_m_distance_assign<Euclidean_Distance_Specialization<Temp> >
00321 (r, x, y, dir, tmp0, tmp1, tmp2);
00322 }
00323
00325 template <typename Temp, typename To>
00326 inline bool
00327 euclidean_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00328 const Generator& x,
00329 const Generator& y,
00330 const Rounding_Dir dir) {
00331 typedef Checked_Number<Temp, Extended_Number_Policy> Checked_Temp;
00332 DIRTY_TEMP(Checked_Temp, tmp0);
00333 DIRTY_TEMP(Checked_Temp, tmp1);
00334 DIRTY_TEMP(Checked_Temp, tmp2);
00335 return euclidean_distance_assign(r, x, y, dir, tmp0, tmp1, tmp2);
00336 }
00337
00339 template <typename To>
00340 inline bool
00341 euclidean_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00342 const Generator& x,
00343 const Generator& y,
00344 const Rounding_Dir dir) {
00345 return euclidean_distance_assign<To, To>(r, x, y, dir);
00346 }
00347
00349 template <typename Temp, typename To>
00350 inline bool
00351 l_infinity_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00352 const Generator& x,
00353 const Generator& y,
00354 const Rounding_Dir dir,
00355 Temp& tmp0,
00356 Temp& tmp1,
00357 Temp& tmp2) {
00358 return l_m_distance_assign<L_Infinity_Distance_Specialization<Temp> >
00359 (r, x, y, dir, tmp0, tmp1, tmp2);
00360 }
00361
00363 template <typename Temp, typename To>
00364 inline bool
00365 l_infinity_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00366 const Generator& x,
00367 const Generator& y,
00368 const Rounding_Dir dir) {
00369 typedef Checked_Number<Temp, Extended_Number_Policy> Checked_Temp;
00370 DIRTY_TEMP(Checked_Temp, tmp0);
00371 DIRTY_TEMP(Checked_Temp, tmp1);
00372 DIRTY_TEMP(Checked_Temp, tmp2);
00373 return l_infinity_distance_assign(r, x, y, dir, tmp0, tmp1, tmp2);
00374 }
00375
00377 template <typename To>
00378 inline bool
00379 l_infinity_distance_assign(Checked_Number<To, Extended_Number_Policy>& r,
00380 const Generator& x,
00381 const Generator& y,
00382 const Rounding_Dir dir) {
00383 return l_infinity_distance_assign<To, To>(r, x, y, dir);
00384 }
00385
00386 }
00387
00388 namespace std {
00389
00391 inline void
00392 swap(Parma_Polyhedra_Library::Generator& x,
00393 Parma_Polyhedra_Library::Generator& y) {
00394 x.swap(y);
00395 }
00396
00397 }
00398
00399 #endif // !defined(PPL_Generator_inlines_hh)