test_FwFFT.cxx
Go to the documentation of this file.
1 // test_FwFFT.cxx
2 //
3 // David Adams
4 // April 2019
5 //
6 // Test FwFFT.
7 
9 #include <string>
10 #include <iostream>
11 #include <fstream>
12 #include <sstream>
13 #include <vector>
14 #include <iomanip>
15 #include <cmath>
16 
17 #undef NDEBUG
18 #include <cassert>
19 
20 using std::string;
21 using std::cout;
22 using std::endl;
23 using std::ostringstream;
24 using std::ofstream;
25 using std::vector;
26 using std::setw;
27 using std::fixed;
28 
29 using Index = unsigned int;
31 using DFT = FwFFT::DFT;
32 
33 //**********************************************************************
34 
35 int test_FwFFT(Index ignorm, Index itnorm, int loglev, Index len) {
36  const string myname = "test_FwFFT: ";
37 #ifdef NDEBUG
38  cout << myname << "NDEBUG must be off." << endl;
39  abort();
40 #endif
41  string line = "-----------------------------";
42 
43  RealDftNormalization norm(ignorm, itnorm);
44  cout << line << endl;
45  cout << myname << " Global norm: " << ignorm << endl;
46  cout << myname << " Term norm: " << itnorm << endl;
47 
48  cout << myname << line << endl;
49  cout << myname << "Create data." << endl;
50  vector<float> sams = { 3.0, 6.0, 16.1, 28.6, 30.2, 27.7, 16.3, 9.6, 4.2, -1.0,
51  -2.3, -4.2, -9.2, -18.6, -21.9, -29.0, -24.3, -14.2, -5.0, -3.0};
52  if ( len > 0 ) sams.resize(len, 0.0);
53  Index nsam = sams.size();
54  assert( sams.size() == nsam );
55  cout << myname << "Sample length: " << nsam << endl;
56  float samsum = 0.0;
57  for ( float sam : sams ) samsum += sam;
58  cout << myname << "Sample mean: " << samsum/nsam << endl;
59  Index namp = (nsam+2)/2;
60  Index npha = (nsam+1)/2;
61  cout << myname << " # samples: " << nsam << endl;
62  cout << myname << "Expected amp size: " << namp << endl;
63  cout << myname << "Expected pha size: " << npha << endl;
64 
65  cout << myname << line << endl;
66  cout << myname << "Create empty DFT." << endl;
67  DFT dft(norm);
68  assert( dft.size() == 0 );
69 
70  cout << myname << line << endl;
71  cout << myname << "Transform forward." << endl;
72  FwFFT xf(50, 0);
73 
74  cout << myname << line << endl;
75  cout << myname << "Transform forward." << endl;
76  assert( xf.fftForward(sams, dft, loglev) == 0 );
77  assert( sams.size() == nsam );
78  cout << myname << "DFT size: " << dft.size() << endl;
79  assert( dft.size() == nsam );
80  assert( dft.nCompact() == namp );
81  assert( dft.nAmplitude() == namp );
82  assert( dft.nPhase() == npha );
83  cout << "Frequency components:" << endl;
84  for ( Index ifrq=0; ifrq<namp; ++ifrq ) {
85  cout << myname << setw(4) << ifrq << ": " << dft.amplitude(ifrq);
86  if ( ifrq < npha ) cout << " @ " << dft.phase(ifrq);
87  cout << endl;
88  }
89 
90  cout << myname << line << endl;
91  cout << myname << "Check power." << endl;
92  float pwr1 = 0.0;
93  for ( float sam : sams ) pwr1 += sam*sam;
94  float pwr2 = dft.power();
95  float pwr3 = 0.0;
96  float pwr4 = 0.0;
97  for ( Index ifrq=0; ifrq<nsam; ++ifrq ) {
98  float amp = dft.amplitude(ifrq);
99  float xre = dft.real(ifrq);
100  float xim = dft.imag(ifrq);
101  if ( !dft.normalization().isPower() || ifrq < dft.nCompact() ) {
102  pwr3 += amp*amp;
103  pwr4 += xre*xre + xim*xim;
104  }
105  }
106  double pfac = 1.0;
107  if ( dft.normalization().isStandard() ) pfac = 1.0/nsam;
108  if ( dft.normalization().isBin() ) pfac = nsam;
109  pwr3 *= pfac;
110  pwr4 *= pfac;
111  cout << myname << "Tick power: " << pwr1 << endl;
112  cout << myname << " DFT power: " << pwr2 << endl;
113  cout << myname << " Amp power: " << pwr3 << endl;
114  cout << myname << " ReI power: " << pwr4 << endl;
115  assert( fabs(pwr2 - pwr1) < 1.e-5*pwr1 );
116 
117  cout << myname << line << endl;
118  cout << myname << "Call inverse." << endl;
119  FloatVector sams2, xres2, xims2;
120  int rstat = xf.fftInverse(dft, sams2, loglev);
121  if ( rstat != 0 ) {
122  cout << myname << "FFT invert returned " << rstat << endl;
123  assert( false );
124  }
125 
126  assert( sams2.size() == nsam );
127  for ( Index isam=0; isam<nsam; ++isam ) {
128  cout << setw(4) << isam << ":" << setw(10) << fixed << sams[isam]
129  << " ?= " << setw(10) << fixed << sams2[isam] << endl;
130  assert( fabs(sams2[isam] - sams[isam]) < 1.e-4 );
131  }
132 
133  cout << myname << line << endl;
134  cout << myname << "Done." << endl;
135  return 0;
136 }
137 
138 //**********************************************************************
139 
140 int main(int argc, char* argv[]) {
141  Index ignorm = 1;
142  Index itnorm = 1;
143  int loglev = 0;
144  Index len = 0;
145  if ( argc > 1 ) {
146  string sarg(argv[1]);
147  if ( sarg == "-h" ) {
148  cout << "Usage: " << argv[0] << " [ignorm [itnorm [loglev [LEN]]]]" << endl;
149  return 0;
150  }
151  ignorm = std::stoi(sarg);
152  }
153  if ( argc > 2 ) {
154  string sarg(argv[2]);
155  itnorm = std::stoi(sarg);
156  }
157  if ( argc > 3 ) {
158  string sarg(argv[3]);
159  loglev = std::stoi(sarg);
160  }
161  if ( argc > 4 ) {
162  string sarg(argv[4]);
163  len = std::stoi(sarg);
164  }
165  return test_FwFFT(ignorm, itnorm, loglev, len);
166 }
167 
168 //**********************************************************************
std::string string
Definition: nybbler.cc:12
struct vector vector
int fftForward(Index nsam, const float *psam, DFT &dft, Index logLevel=0)
Definition: FwFFT.cxx:70
unsigned int Index
CompactRealDftData< float > DFT
Definition: FwFFT.h:31
F amplitude(Index ifrq) const override
F imag(Index ifrq) const override
Index size() const
Definition: RealDftData.h:35
Index nCompact() const override
F phase(Index ifrq) const override
const double e
Index nAmplitude() const
size_t size
Definition: lodepng.cpp:55
int main(int argc, char *argv[])
Definition: test_FwFFT.cxx:140
F power() const
Definition: RealDftData.h:95
auto norm(Vector const &v)
Return norm of the specified vector.
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
int test_FwFFT(Index ignorm, Index itnorm, int loglev, Index len)
Definition: test_FwFFT.cxx:35
F real(Index ifrq) const override
void line(double t, double *p, double &x, double &y, double &z)
const Norm & normalization() const override
Definition: FwFFT.h:24
Dft::FloatVector FloatVector
int fftInverse(const DFT &dft, FloatVector &sams, Index logLevel=0)
Definition: FwFFT.cxx:128
std::vector< float > FloatVector
Definition: FwFFT.h:32
QTextStream & endl(QTextStream &s)