DuneFFT.cxx
Go to the documentation of this file.
1 // DuneFFT.cxx
2 #include "DuneFFT.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 
22 int DuneFFT::
23 fftForward(Index nsam, const float* psam, DFT& dft, Index logLevel) {
24  const string myname = "DuneFFT::fftForward: ";
25  dft.reset(nsam);
26  if ( ! dft.isValid() ) return 1;
27  if ( nsam == 0 ) return 0;
28  vector<double> sams(nsam);
29  for ( Index isam=0; isam<nsam; ++isam ) sams[isam] = psam[isam];
30  int nsamInt = nsam;
31  TVirtualFFT* pfft = TVirtualFFT::FFT(1, &nsamInt, "R2C");
32  pfft->SetPoints(&sams[0]);
33  pfft->Transform();
34  double xre = 0.0;
35  double xim = 0.0;
36  Index namp = dft.nAmplitude();
37  Index npha = dft.nPhase();
38  FloatVector amps(namp);
39  FloatVector phas(npha);
40  // Loop over the compact samples.
41  float nfac = 1.0;
42  if ( dft.normalization().isConsistent() ) nfac = 1.0/sqrt(nsam);
43  if ( dft.normalization().isBin() ) nfac = 1.0/nsam;
44  for ( Index ifrq=0; ifrq<namp; ++ifrq ) {
45  pfft->GetPointComplex(ifrq, xre, xim);
46  // For an even # samples (namp = npha + 1), the Nyquist term is real
47  // and we store the sign with the amplitude.
48  double xam = ifrq < npha ? sqrt(xre*xre + xim*xim) : xre;
49  double xph = atan2(xim, xre);
50  float fac = nfac;
51  if ( dft.normalization().isPower() && dft.isAliased(ifrq) ) fac *= sqrt(2.0);
52  xam *= fac;
53  dft.setAmplitude(ifrq, xam);
54  if ( ifrq < npha ) {
55  dft.setPhase(ifrq, xph);
56  }
57  if ( logLevel >= 3 ) {
58  cout << myname << setw(4) << ifrq << ": ("
59  << setw(10) << fixed << xre << ", "
60  << setw(10) << fixed << xim << "): "
61  << setw(10) << fixed << xam;
62  if ( ifrq < npha ) cout << " @ " << setw(10) << fixed << xph;
63  cout << endl;
64  }
65  }
66  return 0;
67 }
68 
69 //**********************************************************************
70 
71 int DuneFFT::
72 fftForward(const FloatVector& sams, DFT& dft, Index logLevel) {
73  return fftForward(sams.size(), &sams[0], dft, logLevel);
74 }
75 
76 //**********************************************************************
77 
78 int DuneFFT::
79 fftInverse(const DFT& dft, FloatVector& sams, Index logLevel) {
80  const string myname = "DuneFFT::fftInverse: ";
81  if ( ! dft.isValid() ) return 1;
82  Index namp = dft.nAmplitude();
83  Index npha = dft.nPhase();
84  if ( namp == 0 || npha == 0 ) return 1;
85  if ( namp < npha ) return 2;
86  if ( namp - npha > 1 ) return 3;
87  Index nsam = namp + npha - 1;
88  int nsamInt = nsam;
89  TVirtualFFT* pfft = TVirtualFFT::FFT(1, &nsamInt, "C2R");
90  vector<double> xdres(nsam, 0.0);
91  vector<double> xdims(nsam, 0.0);
92  for ( Index ifrq=0; ifrq<nsam; ++ifrq ) {
93  double amp = dft.convAmplitude(ifrq);
94  double pha = dft.phase(ifrq);
95  double xre = amp*cos(pha);
96  double xim = amp*sin(pha);
97  xdres[ifrq] = xre;
98  xdims[ifrq] = xim;
99  }
100  pfft->SetPointsComplex(&xdres[0], &xdims[0]);
101  if ( logLevel >= 3 ) {
102  cout << myname << "Inverting" << endl;
103  cout << myname << "Real/imag components:" << endl;
104  for ( Index ifrq=0; ifrq<nsam; ++ifrq ) {
105  float xre = xdres[ifrq];
106  float xim = xdims[ifrq];
107  cout << myname << setw(4) << ifrq << ": (" << setw(10) << fixed << xre
108  << ", " << setw(10) << fixed << xim << ")" << endl;
109  }
110  }
111  pfft->Transform();
112  sams.resize(nsam);
113  float nfac = 1.0/nsam;
114  for ( Index isam=0; isam<nsam; ++isam ) sams[isam] = nfac*pfft->GetPointReal(isam);
115  return 0;
116 }
117 
118 //**********************************************************************
std::vector< float > FloatVector
Definition: DuneFFT.h:29
std::string string
Definition: nybbler.cc:12
int setPhase(Index ifrq, F val)
struct vector vector
void reset(Index nsam) override
unsigned int Index
Definition: DuneFFT.h:27
virtual bool isValid() const
Definition: RealDftData.h:42
F phase(Index ifrq) const override
Index nAmplitude() const
F convAmplitude(Index ifrq) const
Definition: RealDftData.h:70
static int fftForward(Index ntick, const float *psam, DFT &dft, Index logLevel=0)
Definition: DuneFFT.cxx:23
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
static int fftInverse(const DFT &dft, FloatVector &sams, Index logLevel=0)
Definition: DuneFFT.cxx:79
const Norm & normalization() const override
QTextStream & endl(QTextStream &s)