Port dim2.h from svn -r3422
authorAlpar Juttner <alpar@cs.elte.hu>
Thu, 20 Dec 2007 16:11:56 +0000
changeset 8a1b1d672f37a
parent 7 4d461e9867da
child 9 6ae00527c178
child 17 d0dd44af6fec
Port dim2.h from svn -r3422
lemon/Makefile.am
lemon/dim2.h
test/Makefile.am
test/dim_test.cc
     1.1 --- a/lemon/Makefile.am	Thu Dec 20 15:59:06 2007 +0000
     1.2 +++ b/lemon/Makefile.am	Thu Dec 20 16:11:56 2007 +0000
     1.3 @@ -13,6 +13,7 @@
     1.4  lemon_libemon_la_LDFLAGS = $(GLPK_LIBS) $(CPLEX_LIBS) $(SOPLEX_LIBS)
     1.5  
     1.6  lemon_HEADERS += \
     1.7 +        lemon/dim2.h \
     1.8  	lemon/list_graph.h \
     1.9          lemon/tolerance.h
    1.10  
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/lemon/dim2.h	Thu Dec 20 16:11:56 2007 +0000
     2.3 @@ -0,0 +1,689 @@
     2.4 +/* -*- C++ -*-
     2.5 + *
     2.6 + * This file is a part of LEMON, a generic C++ optimization library
     2.7 + *
     2.8 + * Copyright (C) 2003-2007
     2.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    2.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
    2.11 + *
    2.12 + * Permission to use, modify and distribute this software is granted
    2.13 + * provided that this copyright notice appears in all copies. For
    2.14 + * precise terms see the accompanying LICENSE file.
    2.15 + *
    2.16 + * This software is provided "AS IS" with no warranty of any kind,
    2.17 + * express or implied, and with no claim as to its suitability for any
    2.18 + * purpose.
    2.19 + *
    2.20 + */
    2.21 +
    2.22 +#ifndef LEMON_DIM2_H
    2.23 +#define LEMON_DIM2_H
    2.24 +
    2.25 +#include <iostream>
    2.26 +#include <lemon/bits/utility.h>
    2.27 +
    2.28 +///\ingroup misc
    2.29 +///\file
    2.30 +///\brief A simple two dimensional vector and a bounding box implementation 
    2.31 +///
    2.32 +/// The class \ref lemon::dim2::Point "dim2::Point" implements
    2.33 +///a two dimensional vector with the usual
    2.34 +/// operations.
    2.35 +///
    2.36 +/// The class \ref lemon::dim2::BoundingBox "dim2::BoundingBox"
    2.37 +/// can be used to determine
    2.38 +/// the rectangular bounding box of a set of
    2.39 +/// \ref lemon::dim2::Point "dim2::Point"'s.
    2.40 +///
    2.41 +///\author Attila Bernath
    2.42 +
    2.43 +
    2.44 +namespace lemon {
    2.45 +
    2.46 +  ///Tools for handling two dimensional coordinates
    2.47 +
    2.48 +  ///This namespace is a storage of several
    2.49 +  ///tools for handling two dimensional coordinates
    2.50 +  namespace dim2 {
    2.51 +
    2.52 +  /// \addtogroup misc
    2.53 +  /// @{
    2.54 +
    2.55 +  /// A simple two dimensional vector (plainvector) implementation
    2.56 +
    2.57 +  /// A simple two dimensional vector (plainvector) implementation
    2.58 +  ///with the usual vector
    2.59 +  /// operators.
    2.60 +  ///
    2.61 +  template<typename T>
    2.62 +    class Point {
    2.63 +
    2.64 +    public:
    2.65 +
    2.66 +      typedef T Value;
    2.67 +
    2.68 +      ///First co-ordinate
    2.69 +      T x;
    2.70 +      ///Second co-ordinate
    2.71 +      T y;     
    2.72 +      
    2.73 +      ///Default constructor
    2.74 +      Point() {}
    2.75 +
    2.76 +      ///Construct an instance from coordinates
    2.77 +      Point(T a, T b) : x(a), y(b) { }
    2.78 +
    2.79 +      ///The dimension of the vector.
    2.80 +
    2.81 +      ///This class give back always 2.
    2.82 +      ///
    2.83 +      int size() const { return 2; }
    2.84 +
    2.85 +      ///Subscripting operator
    2.86 +
    2.87 +      ///\c p[0] is \c p.x and \c p[1] is \c p.y
    2.88 +      ///
    2.89 +      T& operator[](int idx) { return idx == 0 ? x : y; }
    2.90 +
    2.91 +      ///Const subscripting operator
    2.92 +
    2.93 +      ///\c p[0] is \c p.x and \c p[1] is \c p.y
    2.94 +      ///
    2.95 +      const T& operator[](int idx) const { return idx == 0 ? x : y; }
    2.96 +
    2.97 +      ///Conversion constructor
    2.98 +      template<class TT> Point(const Point<TT> &p) : x(p.x), y(p.y) {}
    2.99 +
   2.100 +      ///Give back the square of the norm of the vector
   2.101 +      T normSquare() const {
   2.102 +        return x*x+y*y;
   2.103 +      }
   2.104 +  
   2.105 +      ///Increment the left hand side by u
   2.106 +      Point<T>& operator +=(const Point<T>& u) {
   2.107 +        x += u.x;
   2.108 +        y += u.y;
   2.109 +        return *this;
   2.110 +      }
   2.111 +  
   2.112 +      ///Decrement the left hand side by u
   2.113 +      Point<T>& operator -=(const Point<T>& u) {
   2.114 +        x -= u.x;
   2.115 +        y -= u.y;
   2.116 +        return *this;
   2.117 +      }
   2.118 +
   2.119 +      ///Multiply the left hand side with a scalar
   2.120 +      Point<T>& operator *=(const T &u) {
   2.121 +        x *= u;
   2.122 +        y *= u;
   2.123 +        return *this;
   2.124 +      }
   2.125 +
   2.126 +      ///Divide the left hand side by a scalar
   2.127 +      Point<T>& operator /=(const T &u) {
   2.128 +        x /= u;
   2.129 +        y /= u;
   2.130 +        return *this;
   2.131 +      }
   2.132 +  
   2.133 +      ///Return the scalar product of two vectors
   2.134 +      T operator *(const Point<T>& u) const {
   2.135 +        return x*u.x+y*u.y;
   2.136 +      }
   2.137 +  
   2.138 +      ///Return the sum of two vectors
   2.139 +      Point<T> operator+(const Point<T> &u) const {
   2.140 +        Point<T> b=*this;
   2.141 +        return b+=u;
   2.142 +      }
   2.143 +
   2.144 +      ///Return the neg of the vectors
   2.145 +      Point<T> operator-() const {
   2.146 +        Point<T> b=*this;
   2.147 +        b.x=-b.x; b.y=-b.y;
   2.148 +        return b;
   2.149 +      }
   2.150 +
   2.151 +      ///Return the difference of two vectors
   2.152 +      Point<T> operator-(const Point<T> &u) const {
   2.153 +        Point<T> b=*this;
   2.154 +        return b-=u;
   2.155 +      }
   2.156 +
   2.157 +      ///Return a vector multiplied by a scalar
   2.158 +      Point<T> operator*(const T &u) const {
   2.159 +        Point<T> b=*this;
   2.160 +        return b*=u;
   2.161 +      }
   2.162 +
   2.163 +      ///Return a vector divided by a scalar
   2.164 +      Point<T> operator/(const T &u) const {
   2.165 +        Point<T> b=*this;
   2.166 +        return b/=u;
   2.167 +      }
   2.168 +
   2.169 +      ///Test equality
   2.170 +      bool operator==(const Point<T> &u) const {
   2.171 +        return (x==u.x) && (y==u.y);
   2.172 +      }
   2.173 +
   2.174 +      ///Test inequality
   2.175 +      bool operator!=(Point u) const {
   2.176 +        return  (x!=u.x) || (y!=u.y);
   2.177 +      }
   2.178 +
   2.179 +    };
   2.180 +
   2.181 +  ///Return an Point 
   2.182 +
   2.183 +  ///Return an Point
   2.184 +  ///\relates Point
   2.185 +  template <typename T>
   2.186 +  inline Point<T> makePoint(const T& x, const T& y) {
   2.187 +    return Point<T>(x, y);
   2.188 +  }
   2.189 +
   2.190 +  ///Return a vector multiplied by a scalar
   2.191 +
   2.192 +  ///Return a vector multiplied by a scalar
   2.193 +  ///\relates Point
   2.194 +  template<typename T> Point<T> operator*(const T &u,const Point<T> &x) {
   2.195 +    return x*u;
   2.196 +  }
   2.197 +
   2.198 +  ///Read a plainvector from a stream
   2.199 +
   2.200 +  ///Read a plainvector from a stream
   2.201 +  ///\relates Point
   2.202 +  ///
   2.203 +  template<typename T>
   2.204 +  inline std::istream& operator>>(std::istream &is, Point<T> &z) {
   2.205 +    char c;
   2.206 +    if (is >> c) {
   2.207 +      if (c != '(') is.putback(c);
   2.208 +    } else {
   2.209 +      is.clear();
   2.210 +    }
   2.211 +    if (!(is >> z.x)) return is;
   2.212 +    if (is >> c) {
   2.213 +      if (c != ',') is.putback(c);
   2.214 +    } else {
   2.215 +      is.clear();
   2.216 +    }
   2.217 +    if (!(is >> z.y)) return is;
   2.218 +    if (is >> c) {
   2.219 +      if (c != ')') is.putback(c);
   2.220 +    } else {
   2.221 +      is.clear();
   2.222 +    }
   2.223 +    return is;
   2.224 +  }
   2.225 +
   2.226 +  ///Write a plainvector to a stream
   2.227 +
   2.228 +  ///Write a plainvector to a stream
   2.229 +  ///\relates Point
   2.230 +  ///
   2.231 +  template<typename T>
   2.232 +  inline std::ostream& operator<<(std::ostream &os, const Point<T>& z)
   2.233 +  {
   2.234 +    os << "(" << z.x << ", " << z.y << ")";
   2.235 +    return os;
   2.236 +  }
   2.237 +
   2.238 +  ///Rotate by 90 degrees
   2.239 +
   2.240 +  ///Returns its parameter rotated by 90 degrees in positive direction.
   2.241 +  ///\relates Point
   2.242 +  ///
   2.243 +  template<typename T>
   2.244 +  inline Point<T> rot90(const Point<T> &z)
   2.245 +  {
   2.246 +    return Point<T>(-z.y,z.x);
   2.247 +  }
   2.248 +
   2.249 +  ///Rotate by 180 degrees
   2.250 +
   2.251 +  ///Returns its parameter rotated by 180 degrees.
   2.252 +  ///\relates Point
   2.253 +  ///
   2.254 +  template<typename T>
   2.255 +  inline Point<T> rot180(const Point<T> &z)
   2.256 +  {
   2.257 +    return Point<T>(-z.x,-z.y);
   2.258 +  }
   2.259 +
   2.260 +  ///Rotate by 270 degrees
   2.261 +
   2.262 +  ///Returns its parameter rotated by 90 degrees in negative direction.
   2.263 +  ///\relates Point
   2.264 +  ///
   2.265 +  template<typename T>
   2.266 +  inline Point<T> rot270(const Point<T> &z)
   2.267 +  {
   2.268 +    return Point<T>(z.y,-z.x);
   2.269 +  }
   2.270 +
   2.271 +  
   2.272 +
   2.273 +  /// A class to calculate or store the bounding box of plainvectors.
   2.274 +
   2.275 +  /// A class to calculate or store the bounding box of plainvectors.
   2.276 +  ///
   2.277 +  ///\author Attila Bernath
   2.278 +    template<typename T>
   2.279 +    class BoundingBox {
   2.280 +      Point<T> bottom_left, top_right;
   2.281 +      bool _empty;
   2.282 +    public:
   2.283 +      
   2.284 +      ///Default constructor: creates an empty bounding box
   2.285 +      BoundingBox() { _empty = true; }
   2.286 +
   2.287 +      ///Construct an instance from one point
   2.288 +      BoundingBox(Point<T> a) { bottom_left=top_right=a; _empty = false; }
   2.289 +      
   2.290 +      ///Construct an instance from two points
   2.291 +      
   2.292 +      ///Construct an instance from two points
   2.293 +      ///\warning The coordinates of the bottom-left corner must be no more
   2.294 +      ///than those of the top-right one
   2.295 +      BoundingBox(Point<T> a,Point<T> b)
   2.296 +      {
   2.297 +	bottom_left=a;
   2.298 +	top_right=b;
   2.299 +	_empty = false;
   2.300 +      }
   2.301 +      
   2.302 +      ///Construct an instance from four numbers
   2.303 +
   2.304 +      ///Construct an instance from four numbers
   2.305 +      ///\warning The coordinates of the bottom-left corner must be no more
   2.306 +      ///than those of the top-right one
   2.307 +      BoundingBox(T l,T b,T r,T t)
   2.308 +      {
   2.309 +	bottom_left=Point<T>(l,b);
   2.310 +	top_right=Point<T>(r,t);
   2.311 +	_empty = false;
   2.312 +      }
   2.313 +      
   2.314 +      ///Were any points added?
   2.315 +      bool empty() const {
   2.316 +        return _empty;
   2.317 +      }
   2.318 +      
   2.319 +      ///Make the BoundingBox empty
   2.320 +      void clear() {
   2.321 +        _empty=1;
   2.322 +      }
   2.323 +
   2.324 +      ///Give back the bottom left corner
   2.325 +
   2.326 +      ///Give back the bottom left corner.
   2.327 +      ///If the bounding box is empty, then the return value is not defined.
   2.328 +      Point<T> bottomLeft() const {
   2.329 +        return bottom_left;
   2.330 +      }
   2.331 +
   2.332 +      ///Set the bottom left corner
   2.333 +
   2.334 +      ///Set the bottom left corner.
   2.335 +      ///It should only bee used for non-empty box.
   2.336 +      void bottomLeft(Point<T> p) {
   2.337 +	bottom_left = p;
   2.338 +      }
   2.339 +
   2.340 +      ///Give back the top right corner
   2.341 +
   2.342 +      ///Give back the top right corner.
   2.343 +      ///If the bounding box is empty, then the return value is not defined.
   2.344 +      Point<T> topRight() const {
   2.345 +        return top_right;
   2.346 +      }
   2.347 +
   2.348 +      ///Set the top right corner
   2.349 +
   2.350 +      ///Set the top right corner.
   2.351 +      ///It should only bee used for non-empty box.
   2.352 +      void topRight(Point<T> p) {
   2.353 +	top_right = p;
   2.354 +      }
   2.355 +
   2.356 +      ///Give back the bottom right corner
   2.357 +
   2.358 +      ///Give back the bottom right corner.
   2.359 +      ///If the bounding box is empty, then the return value is not defined.
   2.360 +      Point<T> bottomRight() const {
   2.361 +        return Point<T>(top_right.x,bottom_left.y);
   2.362 +      }
   2.363 +
   2.364 +      ///Set the bottom right corner
   2.365 +
   2.366 +      ///Set the bottom right corner.
   2.367 +      ///It should only bee used for non-empty box.
   2.368 +      void bottomRight(Point<T> p) {
   2.369 +	top_right.x = p.x;
   2.370 +	bottom_left.y = p.y;
   2.371 +      }
   2.372 + 
   2.373 +      ///Give back the top left corner
   2.374 +
   2.375 +      ///Give back the top left corner.
   2.376 +      ///If the bounding box is empty, then the return value is not defined.
   2.377 +      Point<T> topLeft() const {
   2.378 +        return Point<T>(bottom_left.x,top_right.y);
   2.379 +      }
   2.380 +
   2.381 +      ///Set the top left corner
   2.382 +
   2.383 +      ///Set the top left corner.
   2.384 +      ///It should only bee used for non-empty box.
   2.385 +      void topLeft(Point<T> p) {
   2.386 +	top_right.y = p.y;
   2.387 +	bottom_left.x = p.x;
   2.388 +      }
   2.389 +
   2.390 +      ///Give back the bottom of the box
   2.391 +
   2.392 +      ///Give back the bottom of the box.
   2.393 +      ///If the bounding box is empty, then the return value is not defined.
   2.394 +      T bottom() const {
   2.395 +        return bottom_left.y;
   2.396 +      }
   2.397 +
   2.398 +      ///Set the bottom of the box
   2.399 +
   2.400 +      ///Set the bottom of the box.
   2.401 +      ///It should only bee used for non-empty box.
   2.402 +      void bottom(T t) {
   2.403 +	bottom_left.y = t;
   2.404 +      }
   2.405 +
   2.406 +      ///Give back the top of the box
   2.407 +
   2.408 +      ///Give back the top of the box.
   2.409 +      ///If the bounding box is empty, then the return value is not defined.
   2.410 +      T top() const {
   2.411 +        return top_right.y;
   2.412 +      }
   2.413 +
   2.414 +      ///Set the top of the box
   2.415 +
   2.416 +      ///Set the top of the box.
   2.417 +      ///It should only bee used for non-empty box.
   2.418 +      void top(T t) {
   2.419 +	top_right.y = t;
   2.420 +      }
   2.421 +
   2.422 +      ///Give back the left side of the box
   2.423 +
   2.424 +      ///Give back the left side of the box.
   2.425 +      ///If the bounding box is empty, then the return value is not defined.
   2.426 +      T left() const {
   2.427 +        return bottom_left.x;
   2.428 +      }
   2.429 + 
   2.430 +      ///Set the left side of the box
   2.431 +
   2.432 +      ///Set the left side of the box.
   2.433 +      ///It should only bee used for non-empty box
   2.434 +      void left(T t) {
   2.435 +	bottom_left.x = t;
   2.436 +      }
   2.437 +
   2.438 +      /// Give back the right side of the box
   2.439 +
   2.440 +      /// Give back the right side of the box.
   2.441 +      ///If the bounding box is empty, then the return value is not defined.
   2.442 +      T right() const {
   2.443 +        return top_right.x;
   2.444 +      }
   2.445 +
   2.446 +      ///Set the right side of the box
   2.447 +
   2.448 +      ///Set the right side of the box.
   2.449 +      ///It should only bee used for non-empty box
   2.450 +      void right(T t) {
   2.451 +	top_right.x = t;
   2.452 +      }
   2.453 +
   2.454 +      ///Give back the height of the box
   2.455 +
   2.456 +      ///Give back the height of the box.
   2.457 +      ///If the bounding box is empty, then the return value is not defined.
   2.458 +      T height() const {
   2.459 +        return top_right.y-bottom_left.y;
   2.460 +      }
   2.461 +
   2.462 +      ///Give back the width of the box
   2.463 +
   2.464 +      ///Give back the width of the box.
   2.465 +      ///If the bounding box is empty, then the return value is not defined.
   2.466 +      T width() const {
   2.467 +        return top_right.x-bottom_left.x;
   2.468 +      }
   2.469 +
   2.470 +      ///Checks whether a point is inside a bounding box
   2.471 +      bool inside(const Point<T>& u){
   2.472 +        if (_empty)
   2.473 +          return false;
   2.474 +        else{
   2.475 +          return ((u.x-bottom_left.x)*(top_right.x-u.x) >= 0 &&
   2.476 +              (u.y-bottom_left.y)*(top_right.y-u.y) >= 0 );
   2.477 +        }
   2.478 +      }
   2.479 +  
   2.480 +      ///Increments a bounding box with a point
   2.481 +      BoundingBox& add(const Point<T>& u){
   2.482 +        if (_empty){
   2.483 +          bottom_left=top_right=u;
   2.484 +          _empty = false;
   2.485 +        }
   2.486 +        else{
   2.487 +          if (bottom_left.x > u.x) bottom_left.x = u.x;
   2.488 +          if (bottom_left.y > u.y) bottom_left.y = u.y;
   2.489 +          if (top_right.x < u.x) top_right.x = u.x;
   2.490 +          if (top_right.y < u.y) top_right.y = u.y;
   2.491 +        }
   2.492 +        return *this;
   2.493 +      }
   2.494 +    
   2.495 +      ///Increments a bounding to contain another bounding box
   2.496 +      BoundingBox& add(const BoundingBox &u){
   2.497 +        if ( !u.empty() ){
   2.498 +          this->add(u.bottomLeft());
   2.499 +	  this->add(u.topRight());
   2.500 +        }
   2.501 +        return *this;
   2.502 +      }
   2.503 +  
   2.504 +      ///Intersection of two bounding boxes
   2.505 +      BoundingBox operator &(const BoundingBox& u){
   2.506 +        BoundingBox b;
   2.507 +	b.bottom_left.x=std::max(this->bottom_left.x,u.bottom_left.x);
   2.508 +	b.bottom_left.y=std::max(this->bottom_left.y,u.bottom_left.y);
   2.509 +	b.top_right.x=std::min(this->top_right.x,u.top_right.x);
   2.510 +	b.top_right.y=std::min(this->top_right.y,u.top_right.y);
   2.511 +	b._empty = this->_empty || u._empty ||
   2.512 +	  b.bottom_left.x>top_right.x && b.bottom_left.y>top_right.y;
   2.513 +        return b;
   2.514 +      }
   2.515 +
   2.516 +    };//class Boundingbox
   2.517 +
   2.518 +
   2.519 +  ///Map of x-coordinates of a dim2::Point<>-map
   2.520 +
   2.521 +  ///\ingroup maps
   2.522 +  ///Map of x-coordinates of a dim2::Point<>-map
   2.523 +  ///
   2.524 +  template<class M>
   2.525 +  class XMap 
   2.526 +  {
   2.527 +    M& _map;
   2.528 +  public:
   2.529 +
   2.530 +    typedef typename M::Value::Value Value;
   2.531 +    typedef typename M::Key Key;
   2.532 +    ///\e
   2.533 +    XMap(M& map) : _map(map) {}
   2.534 +    Value operator[](Key k) const {return _map[k].x;}
   2.535 +    void set(Key k,Value v) {_map.set(k,typename M::Value(v,_map[k].y));}
   2.536 +  };
   2.537 +    
   2.538 +  ///Returns an \ref XMap class
   2.539 +
   2.540 +  ///This function just returns an \ref XMap class.
   2.541 +  ///
   2.542 +  ///\ingroup maps
   2.543 +  ///\relates XMap
   2.544 +  template<class M> 
   2.545 +  inline XMap<M> xMap(M &m) 
   2.546 +  {
   2.547 +    return XMap<M>(m);
   2.548 +  }
   2.549 +
   2.550 +  template<class M> 
   2.551 +  inline XMap<M> xMap(const M &m) 
   2.552 +  {
   2.553 +    return XMap<M>(m);
   2.554 +  }
   2.555 +
   2.556 +  ///Constant (read only) version of \ref XMap
   2.557 +
   2.558 +  ///\ingroup maps
   2.559 +  ///Constant (read only) version of \ref XMap
   2.560 +  ///
   2.561 +  template<class M>
   2.562 +  class ConstXMap 
   2.563 +  {
   2.564 +    const M& _map;
   2.565 +  public:
   2.566 +
   2.567 +    typedef typename M::Value::Value Value;
   2.568 +    typedef typename M::Key Key;
   2.569 +    ///\e
   2.570 +    ConstXMap(const M &map) : _map(map) {}
   2.571 +    Value operator[](Key k) const {return _map[k].x;}
   2.572 +  };
   2.573 +    
   2.574 +  ///Returns a \ref ConstXMap class
   2.575 +
   2.576 +  ///This function just returns an \ref ConstXMap class.
   2.577 +  ///
   2.578 +  ///\ingroup maps
   2.579 +  ///\relates ConstXMap
   2.580 +  template<class M> 
   2.581 +  inline ConstXMap<M> xMap(const M &m) 
   2.582 +  {
   2.583 +    return ConstXMap<M>(m);
   2.584 +  }
   2.585 +
   2.586 +  ///Map of y-coordinates of a dim2::Point<>-map
   2.587 +    
   2.588 +  ///\ingroup maps
   2.589 +  ///Map of y-coordinates of a dim2::Point<>-map
   2.590 +  ///
   2.591 +  template<class M>
   2.592 +  class YMap 
   2.593 +  {
   2.594 +    M& _map;
   2.595 +  public:
   2.596 +
   2.597 +    typedef typename M::Value::Value Value;
   2.598 +    typedef typename M::Key Key;
   2.599 +    ///\e
   2.600 +    YMap(M& map) : _map(map) {}
   2.601 +    Value operator[](Key k) const {return _map[k].y;}
   2.602 +    void set(Key k,Value v) {_map.set(k,typename M::Value(_map[k].x,v));}
   2.603 +  };
   2.604 +
   2.605 +  ///Returns an \ref YMap class
   2.606 +
   2.607 +  ///This function just returns an \ref YMap class.
   2.608 +  ///
   2.609 +  ///\ingroup maps
   2.610 +  ///\relates YMap
   2.611 +  template<class M> 
   2.612 +  inline YMap<M> yMap(M &m) 
   2.613 +  {
   2.614 +    return YMap<M>(m);
   2.615 +  }
   2.616 +
   2.617 +  template<class M> 
   2.618 +  inline YMap<M> yMap(const M &m) 
   2.619 +  {
   2.620 +    return YMap<M>(m);
   2.621 +  }
   2.622 +
   2.623 +  ///Constant (read only) version of \ref YMap
   2.624 +
   2.625 +  ///\ingroup maps
   2.626 +  ///Constant (read only) version of \ref YMap
   2.627 +  ///
   2.628 +  template<class M>
   2.629 +  class ConstYMap 
   2.630 +  {
   2.631 +    const M& _map;
   2.632 +  public:
   2.633 +
   2.634 +    typedef typename M::Value::Value Value;
   2.635 +    typedef typename M::Key Key;
   2.636 +    ///\e
   2.637 +    ConstYMap(const M &map) : _map(map) {}
   2.638 +    Value operator[](Key k) const {return _map[k].y;}
   2.639 +  };
   2.640 +    
   2.641 +  ///Returns a \ref ConstYMap class
   2.642 +
   2.643 +  ///This function just returns an \ref ConstYMap class.
   2.644 +  ///
   2.645 +  ///\ingroup maps
   2.646 +  ///\relates ConstYMap
   2.647 +  template<class M> 
   2.648 +  inline ConstYMap<M> yMap(const M &m) 
   2.649 +  {
   2.650 +    return ConstYMap<M>(m);
   2.651 +  }
   2.652 +
   2.653 +
   2.654 +    ///\brief Map of the \ref Point::normSquare() "normSquare()"
   2.655 +    ///of an \ref Point "Point"-map
   2.656 +    ///
   2.657 +    ///Map of the \ref Point::normSquare() "normSquare()"
   2.658 +    ///of an \ref Point "Point"-map
   2.659 +    ///\ingroup maps
   2.660 +    ///
   2.661 +  template<class M>
   2.662 +  class NormSquareMap 
   2.663 +  {
   2.664 +    const M& _map;
   2.665 +  public:
   2.666 +
   2.667 +    typedef typename M::Value::Value Value;
   2.668 +    typedef typename M::Key Key;
   2.669 +    ///\e
   2.670 +    NormSquareMap(const M &map) : _map(map) {}
   2.671 +    Value operator[](Key k) const {return _map[k].normSquare();}
   2.672 +  };
   2.673 +    
   2.674 +  ///Returns a \ref NormSquareMap class
   2.675 +
   2.676 +  ///This function just returns an \ref NormSquareMap class.
   2.677 +  ///
   2.678 +  ///\ingroup maps
   2.679 +  ///\relates NormSquareMap
   2.680 +  template<class M> 
   2.681 +  inline NormSquareMap<M> normSquareMap(const M &m) 
   2.682 +  {
   2.683 +    return NormSquareMap<M>(m);
   2.684 +  }
   2.685 +
   2.686 +  /// @}
   2.687 +
   2.688 +  } //namespce dim2
   2.689 +  
   2.690 +} //namespace lemon
   2.691 +
   2.692 +#endif //LEMON_DIM2_H
     3.1 --- a/test/Makefile.am	Thu Dec 20 15:59:06 2007 +0000
     3.2 +++ b/test/Makefile.am	Thu Dec 20 16:11:56 2007 +0000
     3.3 @@ -5,11 +5,13 @@
     3.4          test/test_tools.h
     3.5   
     3.6  check_PROGRAMS += \
     3.7 +        test/dim_test \
     3.8          test/test_tools_fail \
     3.9          test/test_tools_pass
    3.10   
    3.11  TESTS += $(check_PROGRAMS)
    3.12  XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
    3.13  
    3.14 +test_dim_test_SOURCES = test/dim_test.cc
    3.15  test_test_tools_fail_SOURCES = test/test_tools_fail.cc
    3.16  test_test_tools_pass_SOURCES = test/test_tools_pass.cc
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/test/dim_test.cc	Thu Dec 20 16:11:56 2007 +0000
     4.3 @@ -0,0 +1,86 @@
     4.4 +/* -*- C++ -*-
     4.5 + *
     4.6 + * This file is a part of LEMON, a generic C++ optimization library
     4.7 + *
     4.8 + * Copyright (C) 2003-2007
     4.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    4.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
    4.11 + *
    4.12 + * Permission to use, modify and distribute this software is granted
    4.13 + * provided that this copyright notice appears in all copies. For
    4.14 + * precise terms see the accompanying LICENSE file.
    4.15 + *
    4.16 + * This software is provided "AS IS" with no warranty of any kind,
    4.17 + * express or implied, and with no claim as to its suitability for any
    4.18 + * purpose.
    4.19 + *
    4.20 + */
    4.21 +
    4.22 +#include <lemon/dim2.h>
    4.23 +#include <iostream>
    4.24 +#include "test_tools.h"
    4.25 +
    4.26 +using namespace std;
    4.27 +using namespace lemon;
    4.28 +int main()
    4.29 +{
    4.30 +
    4.31 +  cout << "Testing classes `dim2::Point' and `dim2::BoundingBox'." << endl;
    4.32 +
    4.33 +  typedef dim2::Point<int> Point;
    4.34 +	
    4.35 +  Point seged;
    4.36 +  check(seged.size()==2, "Wrong vector addition");
    4.37 +
    4.38 +  Point a(1,2);
    4.39 +  Point b(3,4);
    4.40 +
    4.41 +  check(a[0]==1 && a[1]==2, "Wrong vector addition");
    4.42 +
    4.43 +  seged = a+b;
    4.44 +  check(seged.x==4 && seged.y==6, "Wrong vector addition");
    4.45 +
    4.46 +  seged = a-b;
    4.47 +  check(seged.x==-2 && seged.y==-2, "a-b");
    4.48 +
    4.49 +  check(a.normSquare()==5,"Wrong norm calculation");
    4.50 +  check(a*b==11, "a*b");
    4.51 +
    4.52 +  int l=2;
    4.53 +  seged = a*l;
    4.54 +  check(seged.x==2 && seged.y==4, "a*l");
    4.55 +
    4.56 +  seged = b/l;
    4.57 +  check(seged.x==1 && seged.y==2, "b/l");
    4.58 +
    4.59 +  typedef dim2::BoundingBox<int> BB;
    4.60 +  BB doboz1;
    4.61 +  check(doboz1.empty(), "It should be empty.");
    4.62 +	
    4.63 +  doboz1.add(a);
    4.64 +  check(!doboz1.empty(), "It should not be empty.");
    4.65 +  doboz1.add(b);
    4.66 +
    4.67 +  check(doboz1.bottomLeft().x==1 && 
    4.68 +        doboz1.bottomLeft().y==2 &&
    4.69 +        doboz1.topRight().x==3 && 
    4.70 +        doboz1.topRight().y==4,  
    4.71 +        "added points to box");
    4.72 +
    4.73 +  seged.x=2;seged.y=3;
    4.74 +  check(doboz1.inside(seged),"It should be inside.");
    4.75 +
    4.76 +  seged.x=1;seged.y=3;
    4.77 +  check(doboz1.inside(seged),"It should be inside.");
    4.78 +
    4.79 +  seged.x=0;seged.y=3;
    4.80 +  check(!doboz1.inside(seged),"It should not be inside.");
    4.81 +
    4.82 +  BB doboz2(seged);
    4.83 +  check(!doboz2.empty(),
    4.84 +        "It should not be empty. Constructed from 1 point.");
    4.85 +
    4.86 +  doboz2.add(doboz1);
    4.87 +  check(doboz2.inside(seged),
    4.88 +        "It should be inside. Incremented a box with another one.");
    4.89 +}