OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
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  m.put(d, d + 2);
202  return m;
203  }
204 
205  // get data out from a message
207  T d[2];
208  m.get_iter(d);
209  *this = PRegion<T>(d[0], d[1]);
210  return m;
211  }
212 
213 private:
214  // The interval endpoints
216 };
217 
218 
219 // Additive operations.
220 template <class T>
221 inline
223  return PRegion<T>(r.first() + t, r.last() + t);
224 }
225 template <class T>
226 inline
228  return PRegion<T>(r.first() + t, r.last() + t);
229 }
230 template <class T>
231 inline
233  return PRegion<T>(r.first() - t, r.last() - t);
234 }
235 template <class T>
236 inline
238  return PRegion<T>(t - r.first(), t - r.last());
239 }
240 
241 // Multipplicative operations.
242 template <class T>
243 inline
245  return PRegion<T>(-r.first(), -r.last());
246 }
247 template <class T>
248 inline
250  return PRegion<T>(r.first() * t, r.last() * t);
251 }
252 template <class T>
253 inline
255  return PRegion<T>(r.first() * t, r.last() * t);
256 }
257 template <class T>
258 inline
260  if (t != 0)
261  return PRegion<T>(r.first() / t, r.last() / t);
262  else // This is an error!!
263  return r;
264 }
265 
266 // Print out PRegion.
267 template <class T>
268 inline
269 std::ostream& operator<<(std::ostream& out, const PRegion<T>& r) {
270  out << '[' << r.min();
271  out << ',' << r.max();
272  out << ')';
273  return out;
274 }
275 
276 
277 #endif // PREGION_H
278 
279 /***************************************************************************
280  * $RCSfile: PRegion.h,v $ $Author: adelmann $
281  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:32 $
282  * IPPL_VERSION_ID: $Id: PRegion.h,v 1.1.1.1 2003/01/23 07:40:32 adelmann Exp $
283  ***************************************************************************/
std::ostream & operator<<(std::ostream &, const PRegion< T > &)
Definition: PRegion.h:269
PRegion< T > operator+(const PRegion< T > &, T)
Definition: PRegion.h:222
PRegion< T > operator-(const PRegion< T > &, T)
Definition: PRegion.h:232
PRegion< T > operator/(const PRegion< T > &, T)
Definition: PRegion.h:259
PRegion< T > operator*(const PRegion< T > &, T)
Definition: PRegion.h:249
Message & put(const T &val)
Definition: Message.h:406
Message & get_iter(OutputIterator o)
Definition: Message.h:511
PRegion(T B)
Definition: PRegion.h:69
bool split(PRegion< T > &l, PRegion< T > &r) const
Definition: PRegion.h:174
bool contains(const PRegion< T > &r) const
Definition: PRegion.h:169
Message & putMessage(Message &m)
Definition: PRegion.h:197
PRegion< T > & operator*=(T t)
Definition: PRegion.h:94
PRegion(T A, T B)
Definition: PRegion.h:70
~PRegion()
Definition: PRegion.h:73
PRegion< T > & operator-=(T t)
Definition: PRegion.h:89
T max() const
Definition: PRegion.h:77
bool operator<(const PRegion< T > &r) const
Definition: PRegion.h:182
T Last
Definition: PRegion.h:215
bool operator==(const PRegion< T > &r) const
Definition: PRegion.h:192
Message & getMessage(Message &m)
Definition: PRegion.h:206
bool touches(const PRegion< T > &r) const
Definition: PRegion.h:143
PRegion()
Definition: PRegion.h:68
T first() const
Definition: PRegion.h:79
bool empty() const
Definition: PRegion.h:81
PRegion< T > intersect(const PRegion< T > &r) const
Definition: PRegion.h:110
T min() const
Definition: PRegion.h:76
PRegion< T > & operator+=(T t)
Definition: PRegion.h:84
T last() const
Definition: PRegion.h:80
PRegion< T > & operator/=(T t)
Definition: PRegion.h:99
T First
Definition: PRegion.h:215
T length() const
Definition: PRegion.h:78