mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
imagingArray.hpp
Go to the documentation of this file.
1 /** \file imagingArray.hpp
2  * \brief Declares and defines a class for managing images
3  * \ingroup imaging
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  */
7 
8 
9 #ifndef imagingArray_hpp
10 #define imagingArray_hpp
11 
12 #pragma GCC system_header
13 #include <Eigen/Dense>
14 
15 #include "../math/templateBLAS.hpp"
16 #include "../math/fft/fft.hpp"
17 
18 
19 namespace mx
20 {
21 namespace wfp
22 {
23 
24 template<typename Scalar>
25 struct fftwAllocator
26 {
27  Scalar * alloc(size_t sz)
28  {
29  return (Scalar *) ::fftw_malloc(sz * sizeof(Scalar));
30  }
31 
32  void free(Scalar * ptr)
33  {
34  fftw_free(ptr);
35  }
36 };
37 
38 
39 ///Test whether a type is an imagingArray by testing whether it has a typedef of "is_imagingArray"
40 /** Used for compile-time determination of type
41  * Example usage:
42  * \code
43  * bool is_eC = is_imagingArray<eigenCube<float> >; //Evaluates to true
44  * bool is_not_eC = is_imagingArray<float>; //Evaluates to false
45  * \endcode
46  */
47 //This was taken directly from the example at http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error
48 template <typename T>
50 {
51  // Types "yes" and "no" are guaranteed to have different sizes,
52  // specifically sizeof(yes) == 1 and sizeof(no) == 2.
53  typedef char yes[1];
54  typedef char no[2];
55 
56  template <typename imageT>
57  static yes& test(typename imageT::imagingArrayT*);
58 
59  template <typename>
60  static no& test(...);
61 
62  // If the "sizeof" of the result of calling test<T>(0) would be equal to sizeof(yes),
63  // the first overload worked and T has a nested type named "is_mmatrix".
64  static const bool value = sizeof(test<T>(0)) == sizeof(yes);
65 };
66 
67 template< typename imageT,
68  typename typeT,
69  bool isScalar = is_imagingArray<typeT>::value>
70 struct imagingArrayInplaceProduct
71 {
72  imagingArrayInplaceProduct()
73  {
74  static_assert( is_imagingArray<imageT>::value, "imagingArrayInplaceProduct template parameter 1 must be an imagingArray type");
75  }
76 
77  void operator()(imageT & im, typeT & alpha)
78  {
79  math::scal<typename imageT::Scalar>(im.cols()*im.rows(), (typeT) alpha, im.data(), 1);
80  }
81 };
82 
83 template< typename imageT,
84  typename typeT>
85 struct imagingArrayInplaceProduct<imageT, typeT, true>
86 {
87  imagingArrayInplaceProduct()
88  {
89  static_assert( is_imagingArray<imageT>::value, "imagingArrayInplaceProduct template parameter 1 must be an imagingArray type");
90  }
91 
92  void operator()(imageT & im, typeT & alpha)
93  {
94  typedef typename imageT::Scalar scalarT;
95  //hadp<scalarT>(im.cols()*im.rows(), alpha.data(), im.data());
96 
97  Eigen::Map<Eigen::Array<scalarT,-1,-1> > eigY(alpha.data(), alpha.cols(), alpha.rows());
98  Eigen::Map<Eigen::Array<scalarT,-1,-1> > eigX(im.data(), im.cols(), im.rows());
99 
100  eigX *= eigY;
101 
102  }
103 };
104 
105 
106 template< typename imageT,
107  typename typeT,
108  bool isScalar = is_imagingArray<typeT>::value>
109 struct imagingArrayInplaceDivision
110 {
111  imagingArrayInplaceDivision()
112  {
113  static_assert( is_imagingArray<imageT>::value, "imagingArrayInplaceDivision template parameter 1 must be an imagingArray type");
114  }
115 
116  void operator()(imageT im, typeT alpha)
117  {
118  math::scal<typename imageT::Scalar>(im.cols()*im.rows(), ((typeT) (1))/alpha, im.data(), 1);
119  }
120 };
121 
122 template< typename imageT,
123  typename typeT>
124 struct imagingArrayInplaceDivision<imageT, typeT, true>
125 {
126  imagingArrayInplaceDivision()
127  {
128  static_assert( is_imagingArray<imageT>::value, "imagingArrayInplaceDivision template parameter 1 must be an imagingArray type");
129  }
130 
131  void operator()(imageT im, typeT alpha)
132  {
133  typedef typename imageT::Scalar scalarT;
134  math::hadd<scalarT>(im.cols()*im.rows(), (scalarT) 1.0, alpha.data(),1, im.data(), 1);
135  }
136 };
137 
138 
139 
140 template< typename imageT,
141  typename typeT,
142  bool isScalar = is_imagingArray<typeT>::value>
143 struct imagingArrayInplaceAdd
144 {
145  imagingArrayInplaceAdd()
146  {
147  static_assert( is_imagingArray<imageT>::value, "imagingArrayInplaceAdd template parameter 1 must be an imagingArray type");
148  }
149 
150  void operator()(imageT & im, typeT & alpha)
151  {
152  typedef typename imageT::Scalar scalarT;
153  Eigen::Map<Eigen::Array<scalarT,-1,-1> > eigX(im.data(), im.cols(), im.rows());
154  eigX += alpha;
155  }
156 };
157 
158 template< typename imageT,
159  typename typeT>
160 struct imagingArrayInplaceAdd<imageT, typeT, true>
161 {
162  imagingArrayInplaceAdd()
163  {
164  static_assert( is_imagingArray<imageT>::value, "imagingArrayInplaceAdd template parameter 1 must be an imagingArray type");
165  }
166 
167  void operator()(imageT & im, typeT & alpha)
168  {
169  typedef typename imageT::Scalar scalarT;
170  //hadp<scalarT>(im.cols()*im.rows(), alpha.data(), im.data());
171 
172  Eigen::Map<Eigen::Array<scalarT,-1,-1> > eigY(alpha.data(), alpha.cols(), alpha.rows());
173  Eigen::Map<Eigen::Array<scalarT,-1,-1> > eigX(im.data(), im.cols(), im.rows());
174 
175  eigX += eigY;
176 
177  }
178 };
179 
180 
181 
182 template<typename _Scalar, class _allocatorT, int cudaGPU>
183 class imagingArray;
184 
185 template<typename _Scalar, class _allocatorT>
186 class imagingArray<_Scalar, _allocatorT, 0>
187 {
188 public:
189 
190  typedef bool imagingArrayT;
191  typedef _Scalar Scalar;
192  typedef _allocatorT allocatorT;
193 
194 protected:
195  allocatorT allocator;
196 
197  Scalar * _data;
198 
199  bool _owner;
200 
201  int _cols;
202  int _rows;
203 
204 public:
205 
206  imagingArray()
207  {
208  _data = 0;
209  _owner = false;
210  _cols = 0;
211  _rows = 0;
212  }
213 
214  imagingArray(int x, int y)
215  {
216  _data = 0;
217  _owner=false;
218  _cols = 0;
219  _rows = 0;
220 
221  resize(x, y);
222  }
223 
224  template<typename eigenT>
225  explicit imagingArray(eigenT & im)
226  {
227  _data = im.data();
228  _owner=false;
229  _cols = im.cols();
230  _rows = im.rows();
231  }
232 
233  ~imagingArray()
234  {
235  free();
236  }
237 
238  void resize(int szx, int szy)
239  {
240  if(szx == _cols && szy == _rows && _owner) return;
241 
242  free();
243 
244  _cols = szx;
245  _rows = szy;
246 
247  _data = allocator.alloc(_cols*_rows);
248  _owner = true;
249  }
250 
251  void free()
252  {
253  if(_data && _owner)
254  {
255  allocator.free(_data);
256  _data = 0;
257  _cols = 0;
258  _rows = 0;
259  }
260  }
261 
262  int cols() const
263  {
264  return _cols;
265  }
266 
267  int rows() const
268  {
269  return _rows;
270  }
271 
272  Scalar * data()
273  {
274  return _data;
275  }
276 
277  Scalar * data() const
278  {
279  return _data;
280  }
281 
282  Scalar operator()(int x, int y) const
283  {
284  return _data[x + y*_cols];
285  }
286 
287  Scalar & operator()(int x, int y)
288  {
289  return _data[x + y*_cols];
290  }
291 
292  template<typename argT>
293  void set(argT val)
294  {
295  int N = _cols*_rows;
296 
297  Scalar dval = (Scalar) val;
298  for(int i=0;i<N;++i) _data[i] = dval;
299 
300  }
301 
302  void setZero()
303  {
304  set( (Scalar) 0);
305  }
306 
307 
308  imagingArray & operator=(const imagingArray & arr)
309  {
310  resize(arr.rows(), arr.cols());
311 
312  for(int i=0; i<_rows; ++i)
313  {
314  for(int j=0; j<_cols; ++j)
315  {
316  operator()(i,j) = arr(i,j);
317  }
318  }
319 
320  return (*this);
321  }
322 
323 
324  ///In-place product. Works for both scalars and imagingArray types.
325  template<typename typeT>
326  imagingArray & operator*=(typeT & alpha)
327  {
328  imagingArrayInplaceProduct<imagingArray, typeT> prod;
329  prod(*this, alpha);
330  return *this;
331  }
332 
333  ///In-place division. Works for both scalars and imagingArray types.
334  template<typename typeT>
335  imagingArray & operator/=(typeT alpha)
336  {
337  imagingArrayInplaceDivision<imagingArray, typeT> div;
338  div(*this, alpha);
339  return *this;
340  }
341 
342  ///In-place add. Works for both scalars and imagingArray types.
343  template<typename typeT>
344  imagingArray & operator+=(typeT & alpha)
345  {
346  imagingArrayInplaceAdd<imagingArray, typeT> prod;
347  prod(*this, alpha);
348  return *this;
349  }
350 
351  Scalar sum()
352  {
353  int N = _cols*_rows;
354  Scalar _sum = 0;
355 
356  for(int i=0;i<N;++i) _sum += _data[i];
357 
358  return _sum;
359  }
360 
361  Eigen::Map<Eigen::Array<Scalar,-1,-1> > eigenMap()
362  {
363  return Eigen::Map<Eigen::Array<Scalar,-1,-1> >(_data, _rows, _cols);
364  }
365 };
366 
367 
368 
369 template<typename scalarT>
370 using imagingArrayT = imagingArray<scalarT, fftwAllocator<scalarT>,0>;
371 
372 // typedef imagingArray<float,mx::fftwAllocator<float>,0> imagingArrayf;
373 // typedef imagingArray<double,mx::fftwAllocator<double>,0> imagingArrayd;
374 // typedef imagingArray<std::complex<float>,mx::fftwAllocator<std::complex<float> >,0> imagingArraycf;
375 
376 } //namespace wfp
377 } //namespace mx
378 
379 
380 #endif //imagingArray_hpp
Eigen::Map< Eigen::Array< scalarT, -1, -1 > > eigenMap
Definition of the eigenMap type, which is an alias for Eigen::Map<Array>.
Definition: eigenImage.hpp:50
realT * fftw_malloc(size_t n)
Call to fftw_malloc, with type cast.
void fftw_free(realT *p)
Call to fftw_free.
The mxlib c++ namespace.
Definition: mxError.hpp:107
Test whether a type is an imagingArray by testing whether it has a typedef of "is_imagingArray".