Real2dData.h
Go to the documentation of this file.
1 // Real2dData.h
2 //
3 // David Adams
4 // January 2021
5 //
6 // This class provides a 2D array of real numbers.
7 //
8 // It is templated so DFT elements can be stored at different levels of
9 // floating point precision.
10 
11 #ifndef Real2dData_H
12 #define Real2dData_H
13 
15 #include <complex>
16 #include <array>
17 
18 //**********************************************************************
19 
20 template<typename F> class Real2dData;
23 
24 //**********************************************************************
25 
26 template<typename F>
27 class Real2dData {
28 
29 public:
30 
31  using Float = F;
32  using DataVector = std::vector<F>;
33  using Index = unsigned int;
34  using IndexArray = std::array<Index,2>;
36  using Complex = std::complex<Float>; // same memory layout as fftw_complex
37 
38  // Data size for specified sample sizes.
39  // Returns the number of floats.
40  template<std::size_t N>
41  static Index dataSize(const std::array<Index, N>& nsams) {
42  Index ndat = 1;
43  Index ndim = nsams.size();
44  for ( Index idim=0; idim<ndim; ++idim ) {
45  Index nsam = nsams[idim];
46  ndat *= nsam;
47  }
48  return ndat;
49  }
50 
51  // Constructor.
52  Real2dData() : m_nsams({0,0}) { }
53 
54  // Constructor from dimension sizes.
55  // The data is set to zero.
56  Real2dData(const IndexArray& nsams) : m_nsams(nsams), m_data(dataSize(nsams), 0.0) { }
57 
58  // Constructor from dimension sizes and data.
59  Real2dData(const IndexArray& nsams, const DataVector& data)
60  : Real2dData(nsams) {
61  copyDataIn(data);
62  }
63 
64  // Virtual dtor so we can inherit.
65  virtual ~Real2dData() =default;
66 
67  // Clear the data, i.e. zero the # samples.
68  void clear() {
69  for ( Index& nsam : m_nsams ) nsam = 0;
70  m_data.clear();
71  }
72 
73  // Reset to (nsamx, nsamy) samples and zero the DFT.
74  void reset(const IndexArray& nsams) {
75  m_nsams = nsams;
76  m_data.clear();
77  Index ndat = dataSize(m_nsams);
78  m_data.resize(ndat, 0.0);
79  }
80 
81  // The number of dimensions.
82  Index rank() const { return 2; }
83 
84  // Number of samples in each dimension.
85  // nSample = size = # samples
86  const IndexArray& nSamples() const { return m_nsams; }
87  Index nSamples(Index idim) const {
88  if ( idim > rank() ) return 0;
89  return nSamples()[idim];
90  }
91  Index size(Index idim) const { return nSamples(idim); }
92 
93  // Size of the full data.
94  Index size() const { return m_data.size(); }
95 
96  // Return the status for a data index.
97  bool inRange(Index idim, Index idat) const { return idim < rank() && idat < size(idim); }
98  bool isZero(Index idat) const { return idat == 0; }
99 
100  // Check if this object is valid.
101  // Object must have an assigned size so that the frequency status methods work.
102  bool isValid() const {
103  if ( rank() != 2 ) return false;
104  if ( m_nsams.size() != rank() ) return false;
105  if ( size() == 0 ) return false;
106  return true;
107  }
108 
109  // Bad value.
110  // Test real and imaginary pars with isnan or self != self;
111  Float badValue() const {
112  double bad = std::numeric_limits<Float>::quiet_NaN();
113  return bad;
114  }
115 
116  // Return the data (row major order).
117  const std::vector<F>& data() const { return m_data; }
118 
119  // Copy the data in from a vector.
120  // Return 0 for success.
121  int copyDataIn(const DataVector& data) {
122  if ( ! isValid() ) return 1;
123  if ( data.size() != m_data.size() ) return 2;
124  m_data = data;
125  return 0;
126  }
127 
128  // Copy the data in from an array of any type.
129  // Return 0 for success.
130  template<typename T>
131  int copyDataIn(const T* pdat) {
132  if ( ! isValid() ) return 1;
133  Index ndat = size();
134  for ( Index idat=0; idat<ndat; ++idat ) {
135  m_data[idat] = pdat[idat];
136  }
137  return 0;
138  }
139 
140  // Copy the data out to an array of any type.
141  // Return 0 for success.
142  template<typename T>
143  int copyDataOut(T* pdat) const {
144  if ( ! isValid() ) return 1;
145  Index ndat = dataSize(nSamples());
146  for ( Index idat=0; idat<ndat; ++idat ) {
147  pdat[idat] = m_data[idat];
148  }
149  return 0;
150  }
151 
152  // Return the global index for given dimension indices.
153  // If pchk is not null, then the range of each dimension is checked.
154  Index globalIndex(const IndexArray& isams, Index* pchk =nullptr) const {
155  if ( ! isValid() ) {
156  if ( pchk != nullptr ) *pchk = 1;
157  return size();
158  }
159  if ( isams.size() != rank() ) {
160  if ( pchk != nullptr ) *pchk = 2;
161  return size();
162  }
163  if ( pchk != nullptr ) {
164  for ( Index idim=0; idim<rank(); ++idim ) {
165  if ( ! inRange(idim, isams[idim]) ) {
166  *pchk = 10 + idim;
167  return size();
168  }
169  }
170  *pchk = 0;
171  }
172  Index idat = isams[0];
173  for ( Index idim=1; idim<rank(); ++idim ) {
174  idat *= m_nsams[idim];
175  idat += isams[idim];
176  }
177  return idat;
178  }
179 
180  // Return the value for indices isams.
181  // The index arrays are checked first iff pchk != nullptr.
182  // If any of these checks fail or the calculated index is out of range,
183  // badValue(0 is returned.
184  Float value(const IndexArray& isams, Index* pchk =nullptr) const {
185  Index idat = globalIndex(isams, pchk);
186  if ( idat >= size() ) return this->badValue();
187  return m_data[idat];
188  }
189 
190  // Set the value for indices isams.
191  // Set any term, i.e. idat < nSample.
192  // The index arrays are checked if pchk != nullptr.
193  // If any of these checks fail or the calculated index is out of range,
194  // the value is not set and the size of the data is returned.
195  // If the value is set, the global index is returned.
196  // That index is guaranteed to be less than the data size.
197  Index setValue(const IndexArray& isams, Float val, Index* pchk =nullptr) {
198  Index idat = globalIndex(isams, pchk);
199  if ( pchk != nullptr && *pchk > 0 ) return size();
200  if ( idat >= size() ) return size();
201  m_data[idat] = val;
202  return idat;
203  }
204 
205  // Return the total power.
206  F power() const {
207  F pwr = 0.0;
208  IndexArray idats;
209  for ( idats[0]=0; idats[0]<size(0); ++idats[0] ) {
210  for ( idats[1]=0; idats[1]<size(1); ++idats[1] ) {
211  F val = value(idats);
212  pwr += val*val;
213  }
214  }
215  return pwr;
216  }
217 
218 private:
219 
222 
223 };
224 
225 //**********************************************************************
226 
227 #endif
const std::vector< F > & data() const
Definition: Real2dData.h:117
unsigned int Index
Definition: Real2dData.h:33
bool isZero(Index idat) const
Definition: Real2dData.h:98
const IndexArray & nSamples() const
Definition: Real2dData.h:86
Index globalIndex(const IndexArray &isams, Index *pchk=nullptr) const
Definition: Real2dData.h:154
std::complex< Float > Complex
Definition: Real2dData.h:36
Index size() const
Definition: Real2dData.h:94
virtual ~Real2dData()=default
void clear()
Definition: Real2dData.h:68
int copyDataOut(T *pdat) const
Definition: Real2dData.h:143
std::array< Index, 2 > IndexArray
Definition: Real2dData.h:34
Index size(Index idim) const
Definition: Real2dData.h:91
void reset(const IndexArray &nsams)
Definition: Real2dData.h:74
int copyDataIn(const T *pdat)
Definition: Real2dData.h:131
F power() const
Definition: Real2dData.h:206
static Index dataSize(const std::array< Index, N > &nsams)
Definition: Real2dData.h:41
Float badValue() const
Definition: Real2dData.h:111
Index rank() const
Definition: Real2dData.h:82
Float value(const IndexArray &isams, Index *pchk=nullptr) const
Definition: Real2dData.h:184
DataVector m_data
Definition: Real2dData.h:221
Real2dData(const IndexArray &nsams, const DataVector &data)
Definition: Real2dData.h:59
bool inRange(Index idim, Index idat) const
Definition: Real2dData.h:97
Index nSamples(Index idim) const
Definition: Real2dData.h:87
Real2dData(const IndexArray &nsams)
Definition: Real2dData.h:56
IndexArray m_nsams
Definition: Real2dData.h:220
int copyDataIn(const DataVector &data)
Definition: Real2dData.h:121
Index setValue(const IndexArray &isams, Float val, Index *pchk=nullptr)
Definition: Real2dData.h:197
bool isValid() const
Definition: Real2dData.h:102
unsigned int bad()
std::vector< float > DataVector
Definition: Real2dData.h:32