FwFFT.cxx
Go to the documentation of this file.
1 // FwFFT.cxx
2 #include "FwFFT.h"
3 #include <iostream>
4 #include <sstream>
5 #include <vector>
6 #include <iomanip>
7 #include "TVirtualFFT.h"
8 #include "TComplex.h"
9 
10 using std::string;
11 using std::cout;
12 using std::cin;
13 using std::endl;
14 using std::vector;
15 using std::setw;
16 using std::fixed;
17 
18 //**********************************************************************
19 // Class methods.
20 //**********************************************************************
21 
23 : m_nsamMax(nsamMax),
24  m_flag(opt==2 ? FFTW_PATIENT : opt==1 ? FFTW_MEASURE : FFTW_ESTIMATE),
25  m_inData((Float*) fftw_malloc(m_nsamMax*sizeof(Float))),
26  m_outData((Complex*) fftw_malloc(m_nsamMax*sizeof(Complex))) { }
27 
28 //**********************************************************************
29 
31  for ( auto& iplan : m_forwardPlans ) fftw_destroy_plan(iplan.second);
32  for ( auto& iplan : m_backwardPlans ) fftw_destroy_plan(iplan.second);
33  fftw_free(m_inData);
34  fftw_free(m_outData);
35 }
36 
37 //**********************************************************************
38 
40  const string myname = "FwFFT::forwardPlan";
41  static Plan badplan;
42  if ( nsam > m_nsamMax ) {
43  cout << myname << "Sample count is too large. Maximum is " << m_nsamMax << endl;
44  return badplan;
45  }
46  if ( m_forwardPlans.count(nsam) == 0 ) {
47  m_forwardPlans[nsam] = fftw_plan_dft_r2c_1d(nsam, m_inData, m_outData, m_flag);
48  }
49  return m_forwardPlans[nsam];
50 }
51 
52 //**********************************************************************
53 
55  const string myname = "FwFFT::backwardPlan";
56  static Plan badplan;
57  if ( nsam > m_nsamMax ) {
58  cout << myname << "Sample count is too large. Maximum is " << m_nsamMax << endl;
59  return badplan;
60  }
61  if ( m_backwardPlans.count(nsam) == 0 ) {
62  m_backwardPlans[nsam] = fftw_plan_dft_c2r_1d(nsam, m_outData, m_inData, m_flag);
63  }
64  return m_backwardPlans[nsam];
65 }
66 
67 //**********************************************************************
68 
69 int FwFFT::
70 fftForward(Index nsam, const float* psam, DFT& dft, Index logLevel) {
71  const string myname = "FwFFT::fftForward: ";
72  if ( nsam > m_nsamMax ) {
73  cout << myname << "Sample count is too large. Maximum is " << m_nsamMax << endl;
74  return 2;
75  }
76  dft.reset(nsam);
77  if ( ! dft.isValid() ) return 1;
78  if ( nsam == 0 ) return 0;
79  for ( Index isam=0; isam<nsam; ++isam ) m_inData[isam] = psam[isam];
80  Plan& plan = forwardPlan(nsam);
81  fftw_execute(plan);
82  double xre = 0.0;
83  double xim = 0.0;
84  Index namp = dft.nAmplitude();
85  Index npha = dft.nPhase();
86  FloatVector amps(namp);
87  FloatVector phas(npha);
88  // Loop over the compact samples.
89  float nfac = 1.0;
90  if ( dft.normalization().isConsistent() ) nfac = 1.0/sqrt(nsam);
91  if ( dft.normalization().isBin() ) nfac = 1.0/nsam;
92  for ( Index ifrq=0; ifrq<namp; ++ifrq ) {
93  xre = m_outData[ifrq][0];
94  xim = m_outData[ifrq][1];
95  // For an even # samples (namp = npha + 1), the Nyquist term is real
96  // and we store the sign with the amplitude.
97  double xam = ifrq < npha ? sqrt(xre*xre + xim*xim) : xre;
98  double xph = atan2(xim, xre);
99  float fac = nfac;
100  if ( dft.normalization().isPower() && dft.isAliased(ifrq) ) fac *= sqrt(2.0);
101  xam *= fac;
102  dft.setAmplitude(ifrq, xam);
103  if ( ifrq < npha ) {
104  dft.setPhase(ifrq, xph);
105  }
106  if ( logLevel >= 3 ) {
107  cout << myname << setw(4) << ifrq << ": ("
108  << setw(10) << fixed << xre << ", "
109  << setw(10) << fixed << xim << "): "
110  << setw(10) << fixed << xam;
111  if ( ifrq < npha ) cout << " @ " << setw(10) << fixed << xph;
112  cout << endl;
113  }
114  }
115  return 0;
116 }
117 
118 //**********************************************************************
119 
120 int FwFFT::
121 fftForward(const FloatVector& sams, DFT& dft, Index logLevel) {
122  return fftForward(sams.size(), &sams[0], dft, logLevel);
123 }
124 
125 //**********************************************************************
126 
127 int FwFFT::
128 fftInverse(const DFT& dft, FloatVector& sams, Index logLevel) {
129  const string myname = "FwFFT::fftInverse: ";
130  if ( ! dft.isValid() ) return 1;
131  Index namp = dft.nAmplitude();
132  Index npha = dft.nPhase();
133  if ( namp == 0 || npha == 0 ) return 1;
134  if ( namp < npha ) return 2;
135  if ( namp - npha > 1 ) return 3;
136  Index nsam = namp + npha - 1;
137  if ( nsam > m_nsamMax ) {
138  cout << myname << "Sample count is too large. Maximum is " << m_nsamMax << endl;
139  return 4;
140  }
141  for ( Index ifrq=0; ifrq<nsam; ++ifrq ) {
142  double amp = dft.convAmplitude(ifrq);
143  double pha = dft.phase(ifrq);
144  double xre = amp*cos(pha);
145  double xim = amp*sin(pha);
146  m_outData[ifrq][0] = xre;
147  m_outData[ifrq][1] = xim;
148  }
149  Plan& plan = backwardPlan(nsam);
150  fftw_execute(plan);
151  float nfac = 1.0/nsam;
152  sams.resize(nsam);
153  for ( Index isam=0; isam<nsam; ++isam ) sams[isam] = nfac*m_inData[isam];
154  return 0;
155 }
156 
157 //**********************************************************************
double Float
Definition: FwFFT.h:29
~FwFFT()
Definition: FwFFT.cxx:30
fftw_plan Plan
Definition: FwFFT.h:33
Index m_nsamMax
Definition: FwFFT.h:67
std::string string
Definition: nybbler.cc:12
int setPhase(Index ifrq, F val)
opt
Definition: train.py:196
struct vector vector
double * m_inData
Definition: FwFFT.h:69
int fftForward(Index nsam, const float *psam, DFT &dft, Index logLevel=0)
Definition: FwFFT.cxx:70
PlanMap m_forwardPlans
Definition: FwFFT.h:71
FwFFT(Index nsamMax, Index opt)
Definition: FwFFT.cxx:22
void reset(Index nsam) override
virtual bool isValid() const
Definition: RealDftData.h:42
Index m_flag
Definition: FwFFT.h:68
Complex * m_outData
Definition: FwFFT.h:70
F phase(Index ifrq) const override
Index nAmplitude() const
F convAmplitude(Index ifrq) const
Definition: RealDftData.h:70
unsigned int Index
Definition: FwFFT.h:28
Plan & forwardPlan(Index nsam)
Definition: FwFFT.cxx:39
int setAmplitude(Index ifrq, F val)
bool isAliased(Index ifrq) const
Definition: RealDftData.h:56
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
Plan & backwardPlan(Index nsam)
Definition: FwFFT.cxx:54
PlanMap m_backwardPlans
Definition: FwFFT.h:72
const Norm & normalization() const override
int fftInverse(const DFT &dft, FloatVector &sams, Index logLevel=0)
Definition: FwFFT.cxx:128
std::vector< float > FloatVector
Definition: FwFFT.h:32
fftw_complex Complex
Definition: FwFFT.h:30
QTextStream & endl(QTextStream &s)