OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
PRegion.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  *
4  * The IPPL Framework
5  *
6  *
7  * Visit http://people.web.psi.ch/adelmann/ for more details
8  *
9  ***************************************************************************/
10 
11 #ifndef PREGION_H
12 #define PREGION_H
13 
14 /***********************************************************************
15  * PRegion represents a (possibly continuous) numeric interval. It is
16  * similar to Index, with the following differences:
17  * 1. It is templated on the data type; Index always uses integers
18  * 2. A PRegion is defined between two endpoints A and B; the PRegion
19  * includes values X where A <= X < B (i.e., X in [A,B) )
20  * 3. PRegion does not keep track of a base Index, and does not
21  * supply the plugBase operation. It is not designed for use in
22  * Field operations like Index is, it is meant instead for use in
23  * Particle construction and usage.
24  *
25  ***********************************************************************
26  *
27  * PRegion<T>() --> make a PRegion on [0,1)
28  * PRegion<T>(B) --> make a PRegion on [0,B)
29  * PRegion<T>(A,B) --> make a PRegion on [A,B)
30  *
31  ***********************************************************************/
32 
33 // include files
34 #include "Message/Message.h"
35 
36 #include <iostream>
37 
38 // forward declarations
39 template<class T> class PRegion;
40 template <class T>
42 template <class T>
44 template <class T>
46 template <class T>
48 template <class T>
50 template <class T>
52 template <class T>
54 template <class T>
56 template<class T>
57 std::ostream& operator<<(std::ostream&, const PRegion<T>&);
58 
59 template<class T>
60 class PRegion {
61 
62 public:
63  //
64  // Member functions. Make these inline for efficiency.
65  //
66 
67  // Constructors
68  PRegion() : First(0), Last(1) {} // [0,1)
69  PRegion(T B) : First(0), Last(B) {} // [0,B)
70  PRegion(T A, T B) : First(A), Last(B) {} // [A,B)
71 
72  // Destructor ... nothing to do
73  ~PRegion() {}
74 
75  // General query functions
76  T min() const { return (First < Last ? First : Last); } // smallest elem
77  T max() const { return (First > Last ? First : Last); } // largest elem
78  T length() const { return (max() - min()); } // length of region
79  T first() const { return First; } // first element.
80  T last() const { return Last; } // last element.
81  bool empty() const { return (First == Last);} // is it empty?
82 
83  // compute-assign operators
85  First += t;
86  Last += t;
87  return *this;
88  }
90  First -= t;
91  Last -= t;
92  return *this;
93  }
95  First *= t;
96  Last *= t;
97  return *this;
98  }
100  if (t != 0) {
101  First /= t;
102  Last /= t;
103  }
104  return *this;
105  }
106 
107  // Intersect with another PRegion. Since we have possibly continuous
108  // variables, we do not consider the stride here, just where the two
109  // intervals overlap (if at all)
110  PRegion<T> intersect(const PRegion<T>& r) const {
111  T A = 0;
112  T B = 0;
113 
114  // find min and max of both ranges
115  T Amin = min();
116  T Amax = max();
117  T Bmin = r.min();
118  T Bmax = r.max();
119 
120  // make sure these regions overlap
121  // must check special case of single points
122  if (Amin == Amax) {
123  if ((Bmin == Bmax && Amin == Bmin) ||
124  (Bmin != Bmax && Amin >= Bmin && Amin < Bmax))
125  A = B = Amin;
126  }
127  else if (Bmin == Bmax) {
128  if (Bmin >= Amin && Bmin < Amax)
129  A = B = Bmin;
130  }
131  else {
132  if (Amax > Bmin && Bmax > Amin) {
133  A = (Amin > Bmin ? Amin : Bmin);
134  B = (Amax < Bmax ? Amax : Bmax);
135  }
136  }
137 
138  // now return the intersecting region
139  return PRegion<T>(A, B);
140  }
141 
142  // Test to see if there is any overlap between two PRegions
143  bool touches(const PRegion<T>& r) const {
144  bool retval = false;
145  // find min and max of both ranges
146  T Amin = min();
147  T Amax = max();
148  T Bmin = r.min();
149  T Bmax = r.max();
150 
151  // check for overlap ... must check special case of single points
152  if (Amin == Amax) {
153  if ((Bmin == Bmax && Amin == Bmin) ||
154  (Bmin != Bmax && Amin >= Bmin && Amin < Bmax))
155  retval = true;
156  }
157  else if (Bmin == Bmax) {
158  if (Bmin >= Amin && Bmin < Amax)
159  retval = true;
160  }
161  else {
162  if (Amax > Bmin && Bmax > Amin)
163  retval = true;
164  }
165  return retval;
166  }
167 
168  // Test to see if the given PRegion is contained within this one
169  bool contains(const PRegion<T>& r) const {
170  return ( min() <= r.min() && max() >= r.max() );
171  }
172 
173  // Split one into two.
174  bool split(PRegion<T>& l, PRegion<T>& r) const {
175  T mid = First + (Last - First) / T(2);
176  l = PRegion<T>(First, mid);
177  r = PRegion<T>(mid, Last);
178  return true;
179  }
180 
181  // An operator< so we can impose some sort of ordering.
182  bool operator<(const PRegion<T>& r) const {
183  T L1 = length();
184  T L2 = r.length();
185  T Amin = min();
186  T Bmin = r.min();
187  return ( (L1 < L2) || ( (L1 == L2) && ( (Amin < Bmin) ||
188  ( (Amin == Bmin) && (L1 > 0) ) ) ) );
189  }
190 
191  // Test for equality.
192  bool operator==(const PRegion<T>& r) const {
193  return ( (Last==r.Last) && (First==r.First) );
194  }
195 
196  // put data into a message to send to another node
198  T d[2];
199  d[0] = First;
200  d[1] = Last;
201 #ifdef IPPL_USE_MEMBER_TEMPLATES
202  m.put(d, d + 2);
203 #else
204  putMessage(m,d,d+2);
205 #endif
206  return m;
207  }
208 
209  // get data out from a message
211  T d[2];
212 #ifdef IPPL_USE_MEMBER_TEMPLATES
213  m.get_iter(d);
214 #else
215  getMessage_iter(m,d);
216 #endif
217  *this = PRegion<T>(d[0], d[1]);
218  return m;
219  }
220 
221 private:
222  // The interval endpoints
224 };
225 
226 
227 // Additive operations.
228 template <class T>
229 inline
231  return PRegion<T>(r.first() + t, r.last() + t);
232 }
233 template <class T>
234 inline
236  return PRegion<T>(r.first() + t, r.last() + t);
237 }
238 template <class T>
239 inline
241  return PRegion<T>(r.first() - t, r.last() - t);
242 }
243 template <class T>
244 inline
246  return PRegion<T>(t - r.first(), t - r.last());
247 }
248 
249 // Multipplicative operations.
250 template <class T>
251 inline
253  return PRegion<T>(-r.first(), -r.last());
254 }
255 template <class T>
256 inline
258  return PRegion<T>(r.first() * t, r.last() * t);
259 }
260 template <class T>
261 inline
263  return PRegion<T>(r.first() * t, r.last() * t);
264 }
265 template <class T>
266 inline
268  if (t != 0)
269  return PRegion<T>(r.first() / t, r.last() / t);
270  else // This is an error!!
271  return r;
272 }
273 
274 // Print out PRegion.
275 template <class T>
276 inline
277 std::ostream& operator<<(std::ostream& out, const PRegion<T>& r) {
278  out << '[' << r.min();
279  out << ',' << r.max();
280  out << ')';
281  return out;
282 }
283 
284 
285 #endif // PREGION_H
286 
287 /***************************************************************************
288  * $RCSfile: PRegion.h,v $ $Author: adelmann $
289  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:32 $
290  * IPPL_VERSION_ID: $Id: PRegion.h,v 1.1.1.1 2003/01/23 07:40:32 adelmann Exp $
291  ***************************************************************************/
Matrix< T > operator+(const Matrix< T > &, const Matrix< T > &)
Matrix addition.
Definition: Matrix.h:275
Matrix< T > operator/(const Matrix< T > &, const T &)
Matrix divided by scalar.
Definition: Matrix.h:329
Definition: rbendmap.h:8
T Last
Definition: PRegion.h:223
PRegion(T B)
Definition: PRegion.h:69
bool empty() const
Definition: PRegion.h:81
PRegion< T > & operator*=(T t)
Definition: PRegion.h:94
~PRegion()
Definition: PRegion.h:73
T max() const
Definition: PRegion.h:77
Matrix< T > operator*(const Matrix< T > &, const Matrix< T > &)
Matrix multiply.
Definition: Matrix.h:297
void getMessage_iter(Message &m, OutputIterator o)
Definition: Message.h:603
PRegion< T > intersect(const PRegion< T > &r) const
Definition: PRegion.h:110
Message & get_iter(OutputIterator o)
Definition: Message.h:519
Message & putMessage(Message &m)
Definition: PRegion.h:197
PRegion< T > & operator/=(T t)
Definition: PRegion.h:99
bool split(PRegion< T > &l, PRegion< T > &r) const
Definition: PRegion.h:174
bool touches(const PRegion< T > &r) const
Definition: PRegion.h:143
PRegion< T > & operator+=(T t)
Definition: PRegion.h:84
T length() const
Definition: PRegion.h:78
bool contains(const PRegion< T > &r) const
Definition: PRegion.h:169
Message & getMessage(Message &m)
Definition: PRegion.h:210
T last() const
Definition: PRegion.h:80
bool operator==(const PRegion< T > &r) const
Definition: PRegion.h:192
Message & put(const T &val)
Definition: Message.h:414
PRegion()
Definition: PRegion.h:68
PRegion(T A, T B)
Definition: PRegion.h:70
PRegion< T > & operator-=(T t)
Definition: PRegion.h:89
Matrix< T > operator-(const Matrix< T > &, const Matrix< T > &)
Matrix subtraction.
Definition: Matrix.h:282
T First
Definition: PRegion.h:223
T min() const
Definition: PRegion.h:76
T first() const
Definition: PRegion.h:79