It is worth discussing the difference between DComplexFFTServer and DoubleFFTServer. Say you want to transform a real sequence of N points V(j), j=0, ..., N–1. Note that the transform of a real sequence is a complex conjugate-even sequence, that is, a sequence where C(j) = conj(C(–j)) = conj(C(N–j)). How can you calculate the transform? In general, you have two choices:
Convert the real sequence to a complex sequence with imaginary parts set to 0 and transform that;
Take advantage of the fact that the imaginary parts of the sequence are 0 and transform the N-point real sequence as an N/2-point complex sequence.
The DoubleFFTServer uses the second approach. Because the result is a complex conjugate-even sequence, the DoubleFFTServer returns only the lower half of the sequence, which saves considerable time. Here is an example illustrating the two approaches:
#include <rw/dfft.h> #include <rw/cfft.h> #include <iostream.h> const unsigned npts = 12; int main() { // Real sequence to be transformed (a linear ramp): RWMathVec<double> V(npts, 0.0, 1.0); // Print it out: cout << "Original (real) sequence:\n" << V << "\n"; /***************** Approach 1 **********************/ RWMathVec<DComplex> Vcomplex(V); // Convert to complex // Construct a complex FFT server: DComplexFFTServer dcffts; // Vtrans1 will be 12 points long // and complex-conjugate even: RWMathVec<DComplex> Vtrans1 = dcffts.fourier(Vcomplex); /************ An alternative (approach 2) ***********/ DoubleFFTServer dffts; // Use a double FFT server // Vtrans2 will be 7 points long: the // lower half of Vtrans1: RWMathVec<DComplex> Vtrans2 = dffts.fourier(V); cout << "Transform using approach 1:\n" << Vtrans1; cout << endl; cout << "Transform using approach 2:\n" << Vtrans2; cout << endl; } |
Program output (exact results depend on machine precision):
Original (real) sequence: [ 0 1 2 3 4 5 6 7 8 9 10 11 ] Transform using Approach 1: [ (66, 0) (-6, 22.3923) (-6, 10.3923) (-6, 6) (-6, 3.4641) (-6, 1.6077) (-6, 0) (-6, -1.6077) (-6, -3.4641) (-6, -6) (-6, -10.3923) (-6, -22.3923) ] Transform using Approach 2: [ (66, 0) (-6, 22.3923) (-6, 10.3923) (-6, 6) (-6, 3.4641) (-6, 1.6077) (-6, 0) ] |
A close inspection shows that the full transformed sequence using the first approach is complex-conjugate even. The second approach, using the DoubleFFTServer, returns only the lower half of that sequence. The global function expandConjugateEven() can be used to expand it into the full N-point conjugate-even sequence. See the RWMathVec description in the SourcePro C++ API Reference Guide for more information.
Copyright © Rogue Wave Software, Inc. All Rights Reserved.
The Rogue Wave name and logo, and SourcePro, are registered trademarks of Rogue Wave Software. All other trademarks are the property of their respective owners.
Provide feedback to Rogue Wave about its documentation.