Real2dDftData.h
Go to the documentation of this file.
1 // Real2dDftData.h
2 //
3 // David Adams
4 // January 2021
5 //
6 // This class provides an interface and partial implementation for the data describing
7 // a 2D DFT (discrete Fourier transform) of real data. Subclasses add the
8 // normalization and DFT data.
9 //
10 // It is templated so DFT elements can be stored at different levels of
11 // floating point precision.
12 
13 #ifndef Real2dDftData_H
14 #define Real2dDftData_H
15 
17 #include <complex>
18 #include <array>
19 
20 template<typename F>
22 
23 public:
24 
25  using Float = F;
26  using Index = unsigned int;
27  using IndexArray = std::array<Index,2>;
29  using Complex = std::complex<Float>; // same memory layout as fftw_complex
30 
31  // Data size for specified sample sizes.
32  // Returns the number of floats.
33  template<std::size_t N>
34  static Index dataSize(const std::array<Index, N>& nsams) {
35  Index ndat = 1;
36  Index ndim = nsams.size();
37  for ( Index idim=0; idim<ndim; ++idim ) {
38  Index nsam = nsams[idim];
39  ndat *= nsam;
40  }
41  return ndat;
42  }
43 
44  // Dtor.
45  virtual ~Real2dDftData() =default;
46 
47  // Clear the DFT, i.e. zero the # samples.
48  // The normalization is retained.
49  virtual void clear() =0;
50 
51  // Reset to (nsamx, nsamy) samples and zero the DFT.
52  virtual void reset(const IndexArray& nsams) =0;
53 
54  // Return the normalization.
55  // Same is used for all dimensions.
56  virtual Norm normalization() const =0;
57 
58  // The number of dimensions.
59  Index rank() const { return 2; }
60 
61  // Number of samples in each dimension.
62  // nSample = size = # samples
63  virtual const IndexArray& nSamples() const =0;
64  virtual Index nSample(Index idim) const {
65  if ( idim > rank() ) return 0;
66  return nSamples()[idim];
67  }
68  Index size(Index idim) const { return nSample(idim); }
69 
70  // Return the status for a frequency index.
71  bool inRange(Index idim, Index ifrq) const { return idim < rank() && ifrq < size(idim); }
72  bool isZero(Index ifrq) const { return ifrq == 0; }
73  bool isNyquist(Index idim, Index ifrq) const { return idim < rank() && 2*ifrq == size(idim); }
74 
75  // Check if this object is valid.
76  // Object must have an assigned size so that the frequency status methods work.
77  virtual bool isValid() const {
78  return normalization().isValid() && dataSize(nSamples()) > 0;
79  }
80 
81  // Bad complex.
82  // Test real and imaginary pars with isnan or self != self;
83  Complex badValue() const {
84  double badDouble = std::numeric_limits<double>::quiet_NaN();
85  return Complex(badDouble, badDouble);
86  }
87 
88  // Return any term, i.e. ifrq < nSample.
89  // Values depend on global and term normalizations.
90  virtual Complex value(const IndexArray& ifrqs) const =0;
91  virtual F power( const IndexArray& ifrqs) const { return std::norm(value(ifrqs)); };
92  virtual F amplitude(const IndexArray& ifrqs) const { return sqrt(power(ifrqs)); };
93  virtual F phase( const IndexArray& ifrqs) const { return std::arg(value(ifrqs)); };
94  virtual F real( const IndexArray& ifrqs) const { return std::real(value(ifrqs)); };
95  virtual F imag( const IndexArray& ifrqs) const { return std::imag(value(ifrqs)); };
96 
97  // Return the total power.
98  F power() const {
99  F pwr = 0.0;
100  IndexArray ifrqs;
101  for ( ifrqs[0]=0; ifrqs[0]<size(0); ++ifrqs[0] ) {
102  for ( ifrqs[1]=0; ifrqs[1]<size(1); ++ifrqs[1] ) {
103  F amp = amplitude(ifrqs);
104  pwr += amp*amp;
105  }
106  }
107  return pwr;
108  }
109 
110 };
111 
112 //**********************************************************************
113 
114 #endif
virtual const IndexArray & nSamples() const =0
bool isNyquist(Index idim, Index ifrq) const
Definition: Real2dDftData.h:73
std::array< Index, 2 > IndexArray
Definition: Real2dDftData.h:27
virtual F phase(const IndexArray &ifrqs) const
Definition: Real2dDftData.h:93
F power() const
Definition: Real2dDftData.h:98
virtual F real(const IndexArray &ifrqs) const
Definition: Real2dDftData.h:94
Index rank() const
Definition: Real2dDftData.h:59
virtual Complex value(const IndexArray &ifrqs) const =0
virtual Norm normalization() const =0
virtual F imag(const IndexArray &ifrqs) const
Definition: Real2dDftData.h:95
virtual ~Real2dDftData()=default
virtual bool isValid() const
Definition: Real2dDftData.h:77
virtual void reset(const IndexArray &nsams)=0
static Index dataSize(const std::array< Index, N > &nsams)
Definition: Real2dDftData.h:34
Index size(Index idim) const
Definition: Real2dDftData.h:68
bool inRange(Index idim, Index ifrq) const
Definition: Real2dDftData.h:71
unsigned int Index
Definition: Real2dDftData.h:26
auto norm(Vector const &v)
Return norm of the specified vector.
Complex badValue() const
Definition: Real2dDftData.h:83
bool isZero(Index ifrq) const
Definition: Real2dDftData.h:72
std::complex< Float > Complex
Definition: Real2dDftData.h:29
virtual Index nSample(Index idim) const
Definition: Real2dDftData.h:64
virtual F power(const IndexArray &ifrqs) const
Definition: Real2dDftData.h:91
virtual F amplitude(const IndexArray &ifrqs) const
Definition: Real2dDftData.h:92
virtual void clear()=0