Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
region2d.h
1 /*
2 This file is distributed as part of the BIAS library (Basic ImageAlgorithmS)
3 but it has not been developed by the authors of BIAS.
4 
5 For copyright, author and license information see below.
6 */
7 
8 
9 /*
10 *
11 * Template Numerical Toolkit (TNT): Linear Algebra Module
12 *
13 * Mathematical and Computational Sciences Division
14 * National Institute of Technology,
15 * Gaithersburg, MD USA
16 *
17 *
18 * This software was developed at the National Institute of Standards and
19 * Technology (NIST) by employees of the Federal Government in the course
20 * of their official duties. Pursuant to title 17 Section 105 of the
21 * United States Code, this software is not subject to copyright protection
22 * and is in the public domain. The Template Numerical Toolkit (TNT) is
23 * an experimental system. NIST assumes no responsibility whatsoever for
24 * its use by other parties, and makes no guarantees, expressed or implied,
25 * about its quality, reliability, or any other characteristic.
26 *
27 * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE
28 * see http://math.nist.gov/tnt for latest updates.
29 *
30 */
31 
32 // 2D Regions for arrays and matrices
33 
34 #ifndef REGION2D_H
35 #define REGION2D_H
36 
37 #include "index.h"
38 #include <iostream>
39 #include <cassert>
40 
41 namespace TNT
42 {
43 
44  template <class Array2D>
46 
47 
48  template <class Array2D>
49  class Region2D
50  {
51  protected:
52 
53  Array2D & A_;
54  Subscript offset_[2]; // 0-offset internally
56 
57  public:
58  typedef typename Array2D::value_type T;
60  typedef T value_type;
61  typedef T element_type;
62  typedef T* pointer;
63  typedef T* iterator;
64  typedef T& reference;
65  typedef const T* const_iterator;
66  typedef const T& const_reference;
67 
68  Array2D & array() { return A_; }
69  const Array2D & array() const { return A_; }
70  Subscript lbound() const { return A_.lbound(); }
71  Subscript num_rows() const { return dim_[0]; }
72  Subscript num_cols() const { return dim_[1]; }
73  Subscript offset(Subscript i) const // 1-offset
74  {
75 #ifdef TNT_BOUNDS_CHECK
76  BIASASSERT( A_.lbound() <= i);
77  BIASASSERT( i<= dim_[0] + A_.lbound()-1);
78 #endif
79  return offset_[i-A_.lbound()];
80  }
81 
83  {
84 #ifdef TNT_BOUNDS_CHECK
85  BIASASSERT( A_.lbound() <= i);
86  BIASASSERT( i<= dim_[0] + A_.lbound()-1);
87 #endif
88  return dim_[i-A_.lbound()];
89  }
90 
91 
92 
93  Region2D(Array2D &A, Subscript i1, Subscript i2, Subscript j1,
94  Subscript j2) : A_(A)
95  {
96 #ifdef TNT_BOUNDS_CHECK
97  BIASASSERT( i1 <= i2 );
98  BIASASSERT( j1 <= j2);
99  BIASASSERT( A.lbound() <= i1);
100  BIASASSERT( i2<= A.dim(A.lbound()) + A.lbound()-1);
101  BIASASSERT( A.lbound() <= j1);
102  BIASASSERT( j2<= A.dim(A.lbound()+1) + A.lbound()-1 );
103 #endif
104 
105 
106  offset_[0] = i1-A.lbound();
107  offset_[1] = j1-A.lbound();
108  dim_[0] = i2-i1+1;
109  dim_[1] = j2-j1+1;
110  }
111 
112  Region2D(Array2D &A, const Index1D &I, const Index1D &J) : A_(A)
113  {
114 #ifdef TNT_BOUNDS_CHECK
115  BIASASSERT( I.lbound() <= I.ubound() );
116  BIASASSERT( J.lbound() <= J.ubound() );
117  BIASASSERT( A.lbound() <= I.lbound());
118  BIASASSERT( I.ubound()<= A.dim(A.lbound()) + A.lbound()-1);
119  BIASASSERT( A.lbound() <= J.lbound());
120  BIASASSERT( J.ubound() <= A.dim(A.lbound()+1) + A.lbound()-1 );
121 #endif
122 
123  offset_[0] = I.lbound()-A.lbound();
124  offset_[1] = J.lbound()-A.lbound();
125  dim_[0] = I.ubound() - I.lbound() + 1;
126  dim_[1] = J.ubound() - J.lbound() + 1;
127  }
128 
130  Subscript j1, Subscript j2) : A_(A.A_)
131  {
132 #ifdef TNT_BOUNDS_CHECK
133  BIASASSERT( i1 <= i2 );
134  BIASASSERT( j1 <= j2);
135  BIASASSERT( A.lbound() <= i1);
136  BIASASSERT( i2<= A.dim(A.lbound()) + A.lbound()-1);
137  BIASASSERT( A.lbound() <= j1);
138  BIASASSERT( j2<= A.dim(A.lbound()+1) + A.lbound()-1 );
139 #endif
140  offset_[0] = (i1 - A.lbound()) + A.offset_[0];
141  offset_[1] = (j1 - A.lbound()) + A.offset_[1];
142  dim_[0] = i2-i1 + 1;
143  dim_[1] = j2-j1+1;
144  }
145 
147  Subscript j1, Subscript j2)
148  {
149 #ifdef TNT_BOUNDS_CHECK
150  BIASASSERT( i1 <= i2 );
151  BIASASSERT( j1 <= j2);
152  BIASASSERT( A_.lbound() <= i1);
153  BIASASSERT( i2<= dim_[0] + A_.lbound()-1);
154  BIASASSERT( A_.lbound() <= j1);
155  BIASASSERT( j2<= dim_[1] + A_.lbound()-1 );
156 #endif
157  return Region2D<Array2D>(A_,
158  i1+offset_[0], offset_[0] + i2,
159  j1+offset_[1], offset_[1] + j2);
160  }
161 
162 
164  const Index1D &J)
165  {
166 #ifdef TNT_BOUNDS_CHECK
167  BIASASSERT( I.lbound() <= I.ubound() );
168  BIASASSERT( J.lbound() <= J.ubound() );
169  BIASASSERT( A_.lbound() <= I.lbound());
170  BIASASSERT( I.ubound()<= dim_[0] + A_.lbound()-1);
171  BIASASSERT( A_.lbound() <= J.lbound());
172  BIASASSERT( J.ubound() <= dim_[1] + A_.lbound()-1 );
173 #endif
174 
175  return Region2D<Array2D>(A_, I.lbound()+offset_[0],
176  offset_[0] + I.ubound(), offset_[1]+J.lbound(),
177  offset_[1] + J.ubound());
178  }
179 
181  {
182 #ifdef TNT_BOUNDS_CHECK
183  BIASASSERT( A_.lbound() <= i);
184  BIASASSERT( i<= dim_[0] + A_.lbound()-1);
185  BIASASSERT( A_.lbound() <= j);
186  BIASASSERT( j<= dim_[1] + A_.lbound()-1 );
187 #endif
188  return A_(i+offset_[0], j+offset_[1]);
189  }
190 
191  inline const T & operator() (Subscript i, Subscript j) const
192  {
193 #ifdef TNT_BOUNDS_CHECK
194  BIASASSERT( A_.lbound() <= i);
195  BIASASSERT( i<= dim_[0] + A_.lbound()-1);
196  BIASASSERT( A_.lbound() <= j);
197  BIASASSERT( j<= dim_[1] + A_.lbound()-1 );
198 #endif
199  return A_(i+offset_[0], j+offset_[1]);
200  }
201 
202 
204  {
205  Subscript M = num_rows();
206  Subscript N = num_cols();
207 
208  // make sure both sides conform
209  BIASASSERT(M == R.num_rows());
210  BIASASSERT(N == R.num_cols());
211 
212 
213  Subscript start = R.lbound();
214  Subscript Mend = start + M - 1;
215  Subscript Nend = start + N - 1;
216  for (Subscript i=start; i<=Mend; i++)
217  for (Subscript j=start; j<=Nend; j++)
218  (*this)(i,j) = R(i,j);
219 
220  return *this;
221  }
222 
224  {
225  Subscript M = num_rows();
226  Subscript N = num_cols();
227 
228  // make sure both sides conform
229  BIASASSERT(M == R.num_rows());
230  BIASASSERT(N == R.num_cols());
231 
232 
233  Subscript start = R.lbound();
234  Subscript Mend = start + M - 1;
235  Subscript Nend = start + N - 1;
236  for (Subscript i=start; i<=Mend; i++)
237  for (Subscript j=start; j<=Nend; j++)
238  (*this)(i,j) = R(i,j);
239 
240  return *this;
241  }
242 
243  Region2D<Array2D> & operator=(const Array2D &R)
244  {
245  Subscript M = num_rows();
246  Subscript N = num_cols();
247 
248  // make sure both sides conform
249  BIASASSERT(M == R.num_rows());
250  BIASASSERT(N == R.num_cols());
251 
252 
253  Subscript start = R.lbound();
254  Subscript Mend = start + M - 1;
255  Subscript Nend = start + N - 1;
256  for (Subscript i=start; i<=Mend; i++)
257  for (Subscript j=start; j<=Nend; j++)
258  (*this)(i,j) = R(i,j);
259 
260  return *this;
261  }
262 
263  Region2D<Array2D> & operator=(const T &scalar)
264  {
265  Subscript start = lbound();
266  Subscript Mend = lbound() + num_rows() - 1;
267  Subscript Nend = lbound() + num_cols() - 1;
268 
269 
270  for (Subscript i=start; i<=Mend; i++)
271  for (Subscript j=start; j<=Nend; j++)
272  (*this)(i,j) = scalar;
273 
274  return *this;
275  }
276 
277  };
278 
279  //************************
280 
281  template <class Array2D>
282  class const_Region2D
283  {
284  protected:
285 
286  const Array2D & A_;
287  Subscript offset_[2]; // 0-offset internally
289 
290  public:
291  typedef typename Array2D::value_type T;
292  typedef T value_type;
293  typedef T element_type;
294  typedef const T* const_iterator;
295  typedef const T& const_reference;
296 
297  const Array2D & array() const { return A_; }
298  Subscript lbound() const { return A_.lbound(); }
299  Subscript num_rows() const { return dim_[0]; }
300  Subscript num_cols() const { return dim_[1]; }
301  Subscript offset(Subscript i) const // 1-offset
302  {
303 #ifdef TNT_BOUNDS_CHECK
304  BIASASSERT( TNT_BASE_OFFSET <= i);
305  BIASASSERT( i<= dim_[0] + TNT_BASE_OFFSET-1);
306 #endif
307  return offset_[i-TNT_BASE_OFFSET];
308  }
309 
311  {
312 #ifdef TNT_BOUNDS_CHECK
313  BIASASSERT( TNT_BASE_OFFSET <= i);
314  BIASASSERT( i<= dim_[0] + TNT_BASE_OFFSET-1);
315 #endif
316  return dim_[i-TNT_BASE_OFFSET];
317  }
318 
319 
320  const_Region2D(const Array2D &A, Subscript i1, Subscript i2,
321  Subscript j1, Subscript j2) : A_(A)
322  {
323 #ifdef TNT_BOUNDS_CHECK
324  BIASASSERT( i1 <= i2 );
325  BIASASSERT( j1 <= j2);
326  BIASASSERT( TNT_BASE_OFFSET <= i1);
327  BIASASSERT( i2<= A.dim(TNT_BASE_OFFSET) + TNT_BASE_OFFSET-1);
328  BIASASSERT( TNT_BASE_OFFSET <= j1);
329  BIASASSERT( j2<= A.dim(TNT_BASE_OFFSET+1) + TNT_BASE_OFFSET-1 );
330 #endif
331 
332  offset_[0] = i1-TNT_BASE_OFFSET;
333  offset_[1] = j1-TNT_BASE_OFFSET;
334  dim_[0] = i2-i1+1;
335  dim_[1] = j2-j1+1;
336  }
337 
338  const_Region2D(const Array2D &A, const Index1D &I, const Index1D &J)
339  : A_(A)
340  {
341 #ifdef TNT_BOUNDS_CHECK
342  BIASASSERT( I.lbound() <= I.ubound() );
343  BIASASSERT( J.lbound() <= J.ubound() );
344  BIASASSERT( TNT_BASE_OFFSET <= I.lbound());
345  BIASASSERT( I.ubound()<= A.dim(TNT_BASE_OFFSET) + TNT_BASE_OFFSET-1);
346  BIASASSERT( TNT_BASE_OFFSET <= J.lbound());
347  BIASASSERT( J.ubound() <= A.dim(TNT_BASE_OFFSET+1) + TNT_BASE_OFFSET-1 );
348 #endif
349 
350  offset_[0] = I.lbound()-TNT_BASE_OFFSET;
351  offset_[1] = J.lbound()-TNT_BASE_OFFSET;
352  dim_[0] = I.ubound() - I.lbound() + 1;
353  dim_[1] = J.ubound() - J.lbound() + 1;
354  }
355 
356 
358  Subscript i2,
359  Subscript j1, Subscript j2) : A_(A.A_)
360  {
361 #ifdef TNT_BOUNDS_CHECK
362  BIASASSERT( i1 <= i2 );
363  BIASASSERT( j1 <= j2);
364  BIASASSERT( TNT_BASE_OFFSET <= i1);
365  BIASASSERT( i2<= A.dim(TNT_BASE_OFFSET) + TNT_BASE_OFFSET-1);
366  BIASASSERT( TNT_BASE_OFFSET <= j1);
367  BIASASSERT( j2<= A.dim(TNT_BASE_OFFSET+1) + TNT_BASE_OFFSET-1 );
368 #endif
369  offset_[0] = (i1 - TNT_BASE_OFFSET) + A.offset_[0];
370  offset_[1] = (j1 - TNT_BASE_OFFSET) + A.offset_[1];
371  dim_[0] = i2-i1 + 1;
372  dim_[1] = j2-j1+1;
373  }
374 
376  Subscript j1, Subscript j2)
377  {
378 #ifdef TNT_BOUNDS_CHECK
379  BIASASSERT( i1 <= i2 );
380  BIASASSERT( j1 <= j2);
381  BIASASSERT( TNT_BASE_OFFSET <= i1);
382  BIASASSERT( i2<= dim_[0] + TNT_BASE_OFFSET-1);
383  BIASASSERT( TNT_BASE_OFFSET <= j1);
384  BIASASSERT( j2<= dim_[0] + TNT_BASE_OFFSET-1 );
385 #endif
386  return const_Region2D<Array2D>(A_,
387  i1+offset_[0], offset_[0] + i2,
388  j1+offset_[1], offset_[1] + j2);
389  }
390 
391 
393  const Index1D &J)
394  {
395 #ifdef TNT_BOUNDS_CHECK
396  BIASASSERT( I.lbound() <= I.ubound() );
397  BIASASSERT( J.lbound() <= J.ubound() );
398  BIASASSERT( TNT_BASE_OFFSET <= I.lbound());
399  BIASASSERT( I.ubound()<= dim_[0] + TNT_BASE_OFFSET-1);
400  BIASASSERT( TNT_BASE_OFFSET <= J.lbound());
401  BIASASSERT( J.ubound() <= dim_[1] + TNT_BASE_OFFSET-1 );
402 #endif
403 
404  return const_Region2D<Array2D>(A_, I.lbound()+offset_[0],
405  offset_[0] + I.ubound(), offset_[1]+J.lbound(),
406  offset_[1] + J.ubound());
407  }
408 
409 
410  inline const T & operator() (Subscript i, Subscript j) const
411  {
412 #ifdef TNT_BOUNDS_CHECK
413  BIASASSERT( TNT_BASE_OFFSET <= i);
414  BIASASSERT( i<= dim_[0] + TNT_BASE_OFFSET-1);
415  BIASASSERT( TNT_BASE_OFFSET <= j);
416  BIASASSERT( j<= dim_[1] + TNT_BASE_OFFSET-1 );
417 #endif
418  return A_(i+offset_[0], j+offset_[1]);
419  }
420 
421  };
422 
423 
424  // ************** std::ostream algorithms *******************************
425 
426  template <class Array2D>
427  std::ostream& operator<<(std::ostream &s, const const_Region2D<Array2D> &A)
428  {
429  Subscript start = A.lbound();
430  Subscript Mend=A.lbound()+ A.num_rows() - 1;
431  Subscript Nend=A.lbound() + A.num_cols() - 1;
432 
433 
434  s << A.num_rows() << " " << A.num_cols() << "\n";
435  for (Subscript i=start; i<=Mend; i++)
436  {
437  for (Subscript j=start; j<=Nend; j++)
438  {
439  s << A(i,j) << " ";
440  }
441  s << "\n";
442  }
443 
444 
445  return s;
446  }
447 
448  template <class Array2D>
449  std::ostream& operator<<(std::ostream &s, const Region2D<Array2D> &A)
450  {
451  Subscript start = A.lbound();
452  Subscript Mend=A.lbound()+ A.num_rows() - 1;
453  Subscript Nend=A.lbound() + A.num_cols() - 1;
454 
455 
456  s << A.num_rows() << " " << A.num_cols() << "\n";
457  for (Subscript i=start; i<=Mend; i++)
458  {
459  for (Subscript j=start; j<=Nend; j++)
460  {
461  s << A(i,j) << " ";
462  }
463  s << "\n";
464  }
465 
466 
467  return s;
468 
469  }
470 
471 } // namespace TNT
472 
473 #endif
474 // REGION2D_H
const Array2D & array() const
Definition: region2d.h:69
const T & const_reference
Definition: region2d.h:66
Subscript dim(Subscript i) const
Definition: region2d.h:310
Subscript dim_[2]
Definition: region2d.h:55
Region2D< Array2D > & operator=(const T &scalar)
Definition: region2d.h:263
Subscript num_rows() const
Definition: region2d.h:299
Subscript lbound() const
Definition: index.h:51
T * iterator
Definition: region2d.h:63
Region2D< Array2D > operator()(Subscript i1, Subscript i2, Subscript j1, Subscript j2)
Definition: region2d.h:146
Region2D(Array2D &A, Subscript i1, Subscript i2, Subscript j1, Subscript j2)
Definition: region2d.h:93
Region2D< Array2D > & operator=(const const_Region2D< Array2D > &R)
Definition: region2d.h:223
const Array2D & array() const
Definition: region2d.h:297
Region2D< Array2D > operator()(const Index1D &I, const Index1D &J)
Definition: region2d.h:163
Subscript offset(Subscript i) const
Definition: region2d.h:73
Subscript ubound() const
Definition: index.h:52
const_Region2D(const Array2D &A, Subscript i1, Subscript i2, Subscript j1, Subscript j2)
Definition: region2d.h:320
Region2D< Array2D > & operator=(const Region2D< Array2D > &R)
Definition: region2d.h:203
Array2D::value_type T
Definition: region2d.h:291
Subscript offset_[2]
Definition: region2d.h:287
const T * const_iterator
Definition: region2d.h:65
TNT_SUBSCRIPT_TYPE Subscript
Definition: subscript.h:55
Subscript num_cols() const
Definition: region2d.h:72
const T * const_iterator
Definition: region2d.h:294
const_Region2D< Array2D > operator()(const Index1D &I, const Index1D &J)
Definition: region2d.h:392
Array2D::value_type T
Definition: region2d.h:58
const_Region2D(const Array2D &A, const Index1D &I, const Index1D &J)
Definition: region2d.h:338
const_Region2D< Array2D > operator()(Subscript i1, Subscript i2, Subscript j1, Subscript j2)
Definition: region2d.h:375
const T & const_reference
Definition: region2d.h:295
Array2D & array()
Definition: region2d.h:68
Subscript num_cols() const
Definition: region2d.h:300
T & reference
Definition: region2d.h:64
const_Region2D(const_Region2D< Array2D > &A, Subscript i1, Subscript i2, Subscript j1, Subscript j2)
Definition: region2d.h:357
Subscript dim(Subscript i) const
Definition: region2d.h:82
Region2D(Array2D &A, const Index1D &I, const Index1D &J)
Definition: region2d.h:112
T & operator()(Subscript i, Subscript j)
Definition: region2d.h:180
Region2D< Array2D > & operator=(const Array2D &R)
Definition: region2d.h:243
Region2D(Region2D< Array2D > &A, Subscript i1, Subscript i2, Subscript j1, Subscript j2)
Definition: region2d.h:129
Subscript lbound() const
Definition: region2d.h:70
Subscript num_rows() const
Definition: region2d.h:71
Subscript dim_[2]
Definition: region2d.h:288
Subscript offset(Subscript i) const
Definition: region2d.h:301
Subscript offset_[2]
Definition: region2d.h:54
Subscript size_type
Definition: region2d.h:59
const Array2D & A_
Definition: region2d.h:286
Array2D & A_
Definition: region2d.h:53
Subscript lbound() const
Definition: region2d.h:298