CompactRealDftData.h
Go to the documentation of this file.
1 // CompactRealDftData.h
2 //
3 // David Adams
4 // April 2019
5 //
6 // Concrete class that holds a compact representation of 1D DFT data.
7 
8 #ifndef CompactRealDftData_H
9 #define CompactRealDftData_H
10 
12 
13 //**********************************************************************
14 
15 template<typename F>
16 class CompactRealDftData : public RealDftData<F> {
17 
18 public:
19 
20  using typename RealDftData<F>::Index;
21  using FloatVector = std::vector<F>;
23 
24  // Default ctor.
25  CompactRealDftData() =default;
26 
27  // Ctor from normalization. Leaves object empty and so invalid.
29  : m_norm(norm) { }
30 
31  // Ctor from normalization.
33  : m_norm(norm) {
34  reset(nsam);
35  }
36 
37  // Ctor from normalization and data.
38  // Must have amps.size() - phas.size() = 0 or 1 for valid DFT.
39  // If not, the object is left empty.
40  CompactRealDftData(Norm norm, const FloatVector& amps, const FloatVector& phas)
41  : m_norm(norm), m_amps(amps), m_phas(phas) {
42  Index namp = amps.size();
43  Index npha = phas.size();
44  if ( namp < npha || namp > npha + 1 ) clear();
45  }
46 
47  // Ctor from data with default normalization.
48  // Must have amps.size() - phas.size() = 0 or 1 for valid DFT.
49  // If not, the object is left empty.
50  CompactRealDftData(const FloatVector& amps, const FloatVector& phas)
51  : m_amps(amps), m_phas(phas) {
52  Index namp = amps.size();
53  Index npha = phas.size();
54  if ( namp < npha || namp > npha + 1 ) clear();
55  }
56 
57  // Copy ctor. Changes representation and normalization if needed.
59  if ( &rhs == this ) return;
60  if ( ! rhs.isValid() ) return;
61  Index nsam = rhs.nSample();
62  if ( nsam == 0 ) return;
63  Index namp = rhs.nCompact();
64  Index npha = nsam - namp + 1;
65  if ( namp < npha || namp > npha + 1 ) { clear(); return; }
66  m_amps.resize(namp);
67  m_phas.resize(npha);
68  if ( nsam == 0 ) return;
69  F gfac = 1.0;
70  if ( rhs.isPower() ) gfac *= sqrt(nsam);
71  if ( rhs.isBin() ) gfac *= nsam;
72  if ( this->isPower() ) gfac /= sqrt(nsam);
73  if ( this->isBin() ) gfac /= nsam;
74  F tfac = 1.0;
75  if ( rhs.isUnit() && ! this->isUnit() ) tfac = 1/sqrt(2.0);
76  if ( ! rhs.isUnit() && this->isUnit() ) tfac = sqrt(2.0);
77  for ( Index ifrq=0; ifrq<namp; ++ifrq ) {
78  F amp = gfac*rhs.amplitude(ifrq);
79  if ( this->isAliased(ifrq) ) amp *= tfac;
80  m_amps[ifrq] = amp;
81  if ( ifrq < npha ) m_phas[ifrq] = rhs.phase(ifrq);
82  }
83  }
84 
85  // Normalization.
86  const Norm& normalization() const override { return m_norm; }
87 
88  // Clear data.
89  void clear() override {
90  m_amps.clear();
91  m_phas.clear();
92  }
93 
94  // Reset the DFT data.
95  void reset(Index nsam) override {
96  Index namp = nsam > 0 ? nsam/2 + 1 : 0;
97  Index npha = (nsam + 1)/2;
98  m_amps.resize(namp);
99  m_phas.resize(npha);
100  for ( F& amp : m_amps ) amp = 0.0;
101  for ( F& pha : m_phas ) pha = 0.0;
102  }
103 
104  // Move data in.
105  int moveIn(FloatVector& amps, FloatVector& phas) {
106  Index namp = amps.size();
107  Index npha = phas.size();
108  if ( namp < npha || namp > npha + 1 ) {
109  clear();
110  return 1;
111  }
112  m_amps = std::move(amps);
113  m_phas = std::move(phas);
114  return 0;
115  }
116 
117  // Copy data in.
118  int copyIn(const FloatVector& amps, const FloatVector& phas) {
119  Index namp = amps.size();
120  Index npha = phas.size();
121  if ( namp < npha || namp > npha + 1 ) {
122  clear();
123  return 1;
124  }
125  m_amps = amps;
126  m_phas = phas;
127  return 0;
128  }
129 
130  // Set the data.
131  int setAmplitude(Index ifrq, F val) {
132  if ( ifrq >= nAmplitude() ) return 1;
133  m_amps[ifrq] = val;
134  return 0;
135  }
136  int setPhase(Index ifrq, F val) {
137  if ( ifrq >= nPhase() ) return 1;
138  m_phas[ifrq] = val;
139  return 0;
140  }
141 
142  // Move data out.
143  int moveOut(FloatVector& amps, FloatVector& phas) {
144  amps = std::move(m_amps);
145  phas = std::move(m_phas);
146  return 0;
147  }
148 
149  // Copy the data out.
150  int copyOut(FloatVector& amps, FloatVector& phas) const {
151  amps = m_amps;
152  phas = m_phas;
153  return 0;
154  }
155 
156  // Check and return dimension information.
157  Index nSample() const override { return nCompact() ? nCompact() + nPhase() - 1 : 0; }
158  Index nCompact() const override { return nAmplitude(); }
159 
160  // Overide methods that return DFT terms for any representation.
161  F amplitude(Index ifrq) const override {
162  return ifrq < this->nAmplitude() ? this->compactAmplitude(ifrq) :
163  ifrq < this->size() ? this->compactAmplitude(this->size()-ifrq) :
164  this->badValue();
165  }
166  F phase(Index ifrq) const override {
167  return ifrq < this->nPhase() ? this->compactPhase(ifrq) :
168  2*ifrq == this->size() ? 0.0 :
169  ifrq < this->size() ? -this->compactPhase(this->size()-ifrq) :
170  this->badValue();
171  }
172  F real(Index ifrq) const override {
173  return ifrq < this->size() ? amplitude(ifrq)*cos(phase(ifrq)) :
174  this->badValue();
175  }
176  F imag(Index ifrq) const override {
177  return ifrq < this->nPhase() ? amplitude(ifrq)*sin(phase(ifrq)) :
178  2*ifrq == this->size() ? 0.0 :
179  ifrq < this->size() ? -amplitude(ifrq)*sin(phase(ifrq)) :
180  this->badValue();
181  }
182 
183  // Return the compact data.
184  Index nAmplitude() const { return m_amps.size(); }
185  Index nPhase() const { return m_phas.size(); }
186  F compactAmplitude(Index ifrq) const {
187  return this->inRange(ifrq) ? m_amps[ifrq] : this->badValue();
188  }
189  F compactPhase(Index ifrq) const {
190  return this->inRange(ifrq) ? m_phas[ifrq] : this->badValue();
191  }
192 
193 private:
194 
195  // Data.
199 
200 };
201 
202 //**********************************************************************
203 
204 #endif
bool inRange(Index ifrq) const
Definition: RealDftData.h:52
CompactRealDftData(Norm norm, const FloatVector &amps, const FloatVector &phas)
virtual F phase(Index ifrq) const =0
virtual F amplitude(Index ifrq) const =0
void clear() override
CompactRealDftData(Norm norm)
int setPhase(Index ifrq, F val)
CompactRealDftData(const RealDftData< F > &rhs)
void reset(Index nsam) override
int copyOut(FloatVector &amps, FloatVector &phas) const
F amplitude(Index ifrq) const override
virtual bool isValid() const
Definition: RealDftData.h:42
F imag(Index ifrq) const override
Index size() const
Definition: RealDftData.h:35
Index nCompact() const override
virtual Index nSample() const =0
F phase(Index ifrq) const override
F compactAmplitude(Index ifrq) const
Index nAmplitude() const
unsigned int Index
Definition: RealDftData.h:25
def move(depos, offset)
Definition: depos.py:107
F compactPhase(Index ifrq) const
int setAmplitude(Index ifrq, F val)
virtual F badValue() const
Definition: RealDftData.h:59
bool isAliased(Index ifrq) const
Definition: RealDftData.h:56
auto norm(Vector const &v)
Return norm of the specified vector.
Index nSample() const override
CompactRealDftData(const FloatVector &amps, const FloatVector &phas)
virtual Index nCompact() const
Definition: RealDftData.h:36
F real(Index ifrq) const override
std::vector< F > FloatVector
CompactRealDftData(Norm norm, Index nsam)
CompactRealDftData()=default
int moveIn(FloatVector &amps, FloatVector &phas)
const Norm & normalization() const override
int moveOut(FloatVector &amps, FloatVector &phas)
int copyIn(const FloatVector &amps, const FloatVector &phas)